[isidorus-cvs] r488 - in branches/gdl-frontend/src/GDL_frontend: . GDL_TmEngine GDL_TmEngine/.settings GDL_TmEngine/lib GDL_TmEngine/src GDL_TmEngine/src/us GDL_TmEngine/src/us/isidor GDL_TmEngine/src/us/isidor/gdl GDL_TmEngine/src/us/isidor/gdl/anaToMia GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine GDL_TmEngine/test GDL_TmEngine/test-classes GDL_TmEngine/test-classes/us GDL_TmEngine/test-classes/us/isidor GDL_TmEngine/test-classes/us/isidor/gdl GDL_TmEngine/test-classes/us/isidor/gdl/anaToMia GDL_TmEngine/test-classes/us/isidor/gdl/anaToMia/TmEngine GDL_TmEngine/test/us GDL_TmEngine/test/us/isidor GDL_TmEngine/test/us/isidor/gdl GDL_TmEngine/test/us/isidor/gdl/anaToMia GDL_TmEngine/test/us/isidor/gdl/anaToMia/TmEngine GDL_TmEngine/war GDL_TmEngine/war/WEB-INF GDL_TmEngine/war/WEB-INF/classes GDL_TmEngine/war/WEB-INF/classes/us GDL_TmEngine/war/WEB-INF/classes/us/isidor GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine GDL_TmEngine/war/WEB-INF/deploy GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine/rpcPolicyManifest GDL_TmEngine/war/WEB-INF/lib GDL_TmEngine/war/gdl_tmengine GDL_TmEngine/war/gdl_tmengine/gwt GDL_TmEngine/war/gdl_tmengine/gwt/clean GDL_TmEngine/war/gdl_tmengine/gwt/clean/images GDL_TmEngine/war/gdl_tmengine/lib

lgiessmann at common-lisp.net lgiessmann at common-lisp.net
Mon Jun 20 09:03:16 UTC 2011


Author: lgiessmann
Date: Mon Jun 20 02:03:15 2011
New Revision: 488

Log:
GDL_frontend: added the startup project for the GWT Topic Maps engine used for the GDL frontend.

Added:
   branches/gdl-frontend/src/GDL_frontend/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.classpath
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.project
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/com.google.gdt.eclipse.core.prefs
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/com.google.gwt.eclipse.core.prefs
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/tm.js
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/tm.min.js
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/GDL_TmEngine.gwt.xml
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/GDL_TmEngine.java
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/TestClass.java
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test-classes/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test-classes/us/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test-classes/us/isidor/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test-classes/us/isidor/gdl/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test-classes/us/isidor/gdl/anaToMia/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test-classes/us/isidor/gdl/anaToMia/TmEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test/us/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test/us/isidor/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test/us/isidor/gdl/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test/us/isidor/gdl/anaToMia/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/test/us/isidor/gdl/anaToMia/TmEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/GDL_TmEngine.css
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/GDL_TmEngine.html
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/GDL_TmEngine.gwt.xml
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/GDL_TmEngine.class   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/TestClass.class   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/deploy/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine/rpcPolicyManifest/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine/rpcPolicyManifest/manifest.txt
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/lib/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/lib/gwt-servlet.jar   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/web.xml
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/clear.cache.gif   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gdl_tmengine.nocache.js
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/clean.css
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/clean_rtl.css
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/circles.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/circles_ie6.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/corner.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/corner_ie6.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/hborder.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/hborder_ie6.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/thumb_horz.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/thumb_vertical.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/vborder.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/vborder_ie6.png   (contents, props changed)
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/hosted.html
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/tm.js
   branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/tm.min.js

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.classpath
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.classpath	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="test-classes" path="test"/>
+	<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="war/WEB-INF/classes"/>
+</classpath>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.project
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.project	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>GDL_TmEngine</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>com.google.gwt.eclipse.core.gwtNature</nature>
+	</natures>
+</projectDescription>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/com.google.gdt.eclipse.core.prefs
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/com.google.gdt.eclipse.core.prefs	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,4 @@
+#Mon Jun 20 10:13:13 CEST 2011
+eclipse.preferences.version=1
+warSrcDir=war
+warSrcDirIsOutput=true

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/com.google.gwt.eclipse.core.prefs
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/.settings/com.google.gwt.eclipse.core.prefs	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,3 @@
+#Mon Jun 20 10:13:13 CEST 2011
+eclipse.preferences.version=1
+filesCopiedToWebInfLib=gwt-servlet.jar

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/tm.js
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/tm.js	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,3926 @@
+// tmjs, version 0.4.0
+// http://github.com/jansc/tmjs
+// Copyright (c) 2010 Jan Schreiber <jans at ravn.no>
+// Licensed under the MIT-License.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+/*jslint browser: true, devel: true, onevar: true, undef: true,
+  nomen: false, eqeqeq: true, plusplus: true, bitwise: true,
+  regexp: true, newcap: true, immed: true, indent: 4 */
+/*global exports*/ 
+
+var TM, TopicMapSystemFactory;
+
+/**
+ * @namespace Global namespace that holds all Topic Maps related objects.
+ * @author Jan Schreiber <jans at ravn.no>
+ * @copyright 2010 Jan Schreiber <http://purl.org/net/jans>
+ * Date: Wed Dec 1 08:39:28 2010 +0100
+ */
+TM = (function () {
+    var Version, Hash, XSD, TMDM, Locator, EventType, Topic, Association,
+        Scoped, Construct, Typed, Reifiable,
+        DatatypeAware, TopicMap, Role, Name,
+        Variant, Occurrence, TopicMapSystemMemImpl,
+        Index, TypeInstanceIndex, ScopedIndex, 
+        SameTopicMapHelper, ArrayHelper, IndexHelper, addScope,
+        DuplicateRemover,
+        SignatureGenerator, MergeHelper, CopyHelper,
+        TypeInstanceHelper;
+
+    Version = '0.4.0';
+
+    // -----------------------------------------------------------------------
+    // Our swiss army knife for mixin of functions.
+    // See http://javascript.crockford.com/inheritance.html
+    Function.prototype.swiss = function (parnt) {
+        var i, name;
+        for (i = 1; i < arguments.length; i += 1) {
+            name = arguments[i];
+            this.prototype[name] = parnt.prototype[name];
+        }
+        return this;
+    };
+
+    // -----------------------------------------------------------------------
+    // Simple hash table for lookup tables
+    Hash = function () {
+        this.hash = {};
+        this.length = 0;
+    };
+
+    /**
+     * @class Simple hash implementation.
+     */
+    Hash.prototype = {
+        /**
+         * Returns the object belonging to the key key or undefined if the
+         * key does not exist.
+         * @param key {String} The hash key.
+         * @returns {object} The stored object or undefined.
+         */        
+        get: function (key) {
+            return this.hash[key];
+        },
+
+        /**
+         * Checks if the key exists in the hash table.
+         * @param key {String} The hash key.
+         * @returns {boolean} True if key exists in the hash table. False
+         *          otherwise.
+         */
+        contains: function (key) {
+            return this.get(key) !== undefined;
+        },
+
+        /**
+         * Stores an object in the hash table.
+         * @param key {String} The hash key.
+         * @param val {object} The value to be stored in the hash table.
+         * @returns val {object} A reference to the stored object.
+         */
+        put: function (key, val) {
+            if (!this.hash[key]) {
+                this.length += 1;
+            }
+            this.hash[key] = val;
+            return val;
+        },
+
+        /**
+         * Removes the key and the corresponding value from the hash table.
+         * @param key {String} Removes value corresponding to key and the key
+         *             from the hash table
+         * @returns {Hash} The hash table itself.
+         */
+        remove: function (key) {
+            delete this.hash[key];
+            this.length -= 1;
+            return this;
+        },
+
+        /**
+         * Returns an array with keys of the hash table.
+         * @returns {Array} An array with strings.
+         */
+        keys: function () {
+            var ret = [], key;
+            for (key in this.hash) {
+                if (this.hash.hasOwnProperty(key)) {
+                    ret.push(key);
+                }
+            }
+            return ret;
+        },
+
+        /**
+         * Returns an array with all values of the hash table.
+         * @returns {Array} An array with all objects stored as a value in
+         *          the hash table.
+         */
+        values: function () {
+            var ret = [], key;
+            for (key in this.hash) {
+                if (this.hash.hasOwnProperty(key)) {
+                    ret.push(this.hash[key]);
+                }
+            }
+            return ret;
+        },
+
+        /**
+         * Empties the hash table by removing the reference to all objects.
+         * Note that the store objects themselves are not touched.
+         * @returns undefined
+         */
+        empty: function () {
+            this.hash = {};
+            this.length = 0;
+        },
+
+        /**
+         * Returns the size of the hash table, that is the count of all
+         * key/value pairs.
+         * @returns {Number} The count of all key/value pairs stored in the
+         *          hash table.
+         */
+        size: function () {
+            return this.length;
+        }
+    };
+
+    // -----------------------------------------------------------------------
+    // Internal event handling system
+    EventType = {};
+    EventType.ADD_ASSOCIATION = 1;
+    EventType.ADD_NAME = 2;
+    EventType.ADD_OCCURRENCE = 3;
+    EventType.ADD_ROLE = 4;
+    EventType.ADD_THEME = 5;
+    EventType.ADD_TOPIC = 6;
+    EventType.ADD_TYPE = 7;
+    EventType.REMOVE_ASSOCIATION = 8;
+    EventType.REMOVE_NAME = 9;
+    EventType.REMOVE_OCCURRENCE = 10;
+    EventType.REMOVE_ROLE = 11;
+    EventType.REMOVE_THEME = 12;
+    EventType.REMOVE_TOPIC = 13;
+    EventType.REMOVE_TYPE = 14;
+    EventType.SET_TYPE = 15;
+
+    /**
+     * @namespace Namespace for XML Schema URIs. // FIXME!!
+     */
+    XSD = {
+        'string': "http://www.w3.org/2001/XMLSchema#string",
+        'integer': "http://www.w3.org/2001/XMLSchema#integer",
+        'anyURI': "http://www.w3.org/2001/XMLSchema#anyURI"
+
+        // TODO: Add all build-in types
+    };
+
+    TMDM = {
+        'TYPE_INSTANCE': 'http://psi.topicmaps.org/iso13250/model/type-instance',
+        'TYPE': 'http://psi.topicmaps.org/iso13250/model/type',
+        'INSTANCE': 'http://psi.topicmaps.org/iso13250/model/instance',
+        'TOPIC_NAME': 'http://psi.topicmaps.org/iso13250/model/topic-name'
+    };
+
+    // -----------------------------------------------------------------------
+    // TODO: The locator functions need some more work. Implement resolve()
+    // and toExternalForm()
+
+    /**
+     * @class Immutable representation of an IRI.
+     */
+    Locator = function (parnt, iri) {
+        this.parnt = parnt;
+        this.iri = iri;
+    };
+
+    /**
+     * Returns the IRI.
+     * @returns {String} A lexical representation of the IRI.
+     */
+    Locator.prototype.getReference = function () {
+        return this.iri;
+    };
+
+    /**
+     * Returns true if the other object is equal to this one.
+     * @param other The object to compare this object against.
+     * @returns <code>(other instanceof Locator &&
+     *     this.getReference().equals(((Locator)other).getReference()))</code>
+     */
+    Locator.prototype.equals = function (other) {
+        return (this.iri === other.getReference());
+    };
+
+    /**
+     * Returns the external form of the IRI. Any special character will be
+     * escaped using the escaping conventions of RFC 3987.
+     * @returns {String} A string representation of this locator suitable for
+     * output or passing to APIs which will parse the locator anew.
+     */
+    Locator.prototype.toExternalForm = function () {
+        throw {name: 'NotImplemented', message: 'Locator.toExternalForm() not implemented'};
+    };
+
+
+    // -----------------------------------------------------------------------
+    /**
+     * @class Represents a Topic Maps construct.
+     */
+    Construct = function () {};
+
+    /** 
+     * Adds an item identifier.
+     * @param {Locator} itemIdentifier The item identifier to add.
+     * @returns {Construct} The construct itself (for chaining support)
+     * @throws {ModelConstraintException} If the itemidentifier is null.
+     * @throws {IdentityConstraintException} If another Topic Maps construct with
+     *         the same item identifier exists.
+     */
+    Construct.prototype.addItemIdentifier = function (itemIdentifier) {
+        var existing;
+        if (itemIdentifier === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'addItemIdentifier(null) is illegal'};
+        }
+        existing = this.getTopicMap()._ii2construct.get(itemIdentifier.getReference());
+        if (existing) {
+            throw {name: 'IdentityConstraintException',
+                message: 'Topic Maps constructs with the same item identifier ' +
+                        'are not allowed',
+                reporter: this,
+                existing: existing,
+                locator: itemIdentifier};
+        }
+        this.itemIdentifiers.push(itemIdentifier);
+        this.getTopicMap()._ii2construct.put(itemIdentifier.getReference(), this);
+        return this;
+    };
+
+    /**
+     * Returns true if the other object is equal to this one. Equality must be
+     * the result of comparing the identity (<code>this == other</code>) of the
+     * two objects.
+     * Note: This equality test does not reflect any equality rule according to
+     * the Topic Maps - Data Model (TMDM) by intention.
+     * @param {String} other The object to compare this object against.
+     */
+    Construct.prototype.equals = function (other) {
+        return (this.id === other.id);
+    };
+    
+    /**
+     * Returns the identifier of this construct. This property has no
+     * representation in the Topic Maps - Data Model.
+     *
+     * The ID can be anything, so long as no other Construct in the same topic
+     * map has the same ID.
+     * @returns {String} An identifier which identifies this construct uniquely
+     * within a topic map.
+     */
+    Construct.prototype.getId = function () {
+        return this.id;
+    };
+    
+    /**
+     * Returns the item identifiers of this Topic Maps construct. The return
+     * value may be empty but must never be <code>null</code>.
+     * @returns {Array} An array of Locators representing the item identifiers.
+     * The array MUST NOT be modified.
+     */
+    Construct.prototype.getItemIdentifiers = function () {
+        return this.itemIdentifiers;
+    };
+    
+    /**
+     * Returns the parent of this construct. This method returns
+     * <code>null</code> iff this construct is a TopicMap instance.
+     * @returns {Construct} The parent of this construct or <code>null</code>
+     * iff the construct is an instance of TopicMap.
+     */
+    Construct.prototype.getParent = function () {
+        return this.parnt;
+    };
+    
+    /**
+     * Returns the TopicMap instance to which this Topic Maps construct belongs.
+     * A TopicMap instance returns itself.
+     * @returns {Construct} The topic map instance to which this construct belongs.
+     */
+    Construct.prototype.getTopicMap = function () {
+        throw {name: 'NotImplemented', message: 'getTopicMap() not implemented'};
+    };
+    
+    /**
+     * Returns the hash code value.
+     * TODO: Is this needed?
+     */
+    Construct.prototype.hashCode = function () {
+        throw {name: 'NotImplemented', message: 'hashCode() not implemented'};
+    };
+    
+    /**
+     * Returns the parent of this construct. This method returns
+     * <code>null</code> iff this construct is a TopicMap instance.
+     * @returns {Construct} The parent of this construct or <code>null</code>
+     * iff the construct is an instance of {@link TopicMap}.
+     */
+    Construct.prototype.remove = function () {
+        throw {name: 'NotImplemented', message: 'remove() not implemented'};
+    };
+    
+    /**
+     * Removes an item identifier.
+     * @param {Locator} itemIdentifier The item identifier to be removed from
+     * this construct, if present (<code>null</code> is ignored).
+     * @returns {Construct} The construct itself (for chaining support)
+     */
+    Construct.prototype.removeItemIdentifier = function (itemIdentifier) {
+        if (itemIdentifier === null) {
+            return;
+        }
+        for (var i = 0; i < this.itemIdentifiers.length; i += 1) {
+            if (this.itemIdentifiers[i].getReference() ===
+                    itemIdentifier.getReference()) {
+                this.itemIdentifiers.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._ii2construct.remove(itemIdentifier.getReference());
+        return this;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link TopicMap}-object
+     * @returns <code>true</code> if the construct is a {@link TopicMap}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isTopicMap = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Topic}-object
+     * @returns <code>true</code> if the construct is a {@link Topic}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isTopic = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is an {@link Association}-object
+     * @returns <code>true</code> if the construct is an {@link Association}-
+     *     object, <code>false</code> otherwise.
+     */
+    Construct.prototype.isAssociation = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Role}-object
+     * @returns <code>true</code> if the construct is a {@link Role}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isRole = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Name}-object
+     * @returns <code>true</code> if the construct is a {@link Name}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isName = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is an {@link Occurrenct}-object
+     * @returns <code>true</code> if the construct is an {@link Occurrence}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isOccurrence = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Variant}-object
+     * @returns <code>true</code> if the construct is a {@link Variant}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isVariant = function () {
+        return false;
+    };
+
+    // --------------------------------------------------------------------------
+    Typed = function () {};
+    
+    // Returns the type of this construct.
+    Typed.prototype.getType = function () {
+        return this.type;
+    };
+    
+    /**
+     * Sets the type of this construct.
+     * @throws {ModelConstraintException} If type is null.
+     * @returns {Typed} The type itself (for chaining support)
+     */
+    Typed.prototype.setType = function (type) {
+        if (type === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'Topic.setType cannot be called without type'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), type);
+        this.getTopicMap().setTypeEvent.fire(this, {old: this.type, type: type});
+        this.type = type;
+        return this;
+    };
+    
+    // --------------------------------------------------------------------------
+    /**
+     * @class Indicates that a statement (Topic Maps construct) has a scope.
+     * Associations, Occurrences, Names, and Variants are scoped.
+     */
+    Scoped = function () {};
+    
+    /**
+     * Adds a topic to the scope.
+     * @throws {ModelConstraintException} If theme is null.
+     * @returns {Typed} The type itself (for chaining support)
+     */
+    Scoped.prototype.addTheme = function (theme) {
+        if (theme === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'addTheme(null) is illegal'}; 
+        }
+        // Check if theme is part of the scope
+        for (var i = 0; i < this.scope.length; i += 1) {
+            if (this.scope[i] === theme) {
+                return false;
+            }
+        }
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), theme);
+        this.scope.push(theme);
+        this.getTopicMap().addThemeEvent.fire(this, {theme: theme});
+        // Special case for names: add the theme to all variants
+        if (this.isName()) {
+            for (i = 0; i < this.variants.length; i += 1) {
+                this.getTopicMap().addThemeEvent.fire(this.variants[i], {theme: theme});
+            }
+        }
+        return this;
+    };
+    
+    /**
+     * Returns the topics which define the scope.
+     * @returns {Array} A possible empty Array with Topic objects.
+     */
+    Scoped.prototype.getScope = function () {
+        if (this.isVariant()) {
+            var i, tmp = new Hash(), parent_scope = this.parnt.getScope();
+            for (i = 0; i < parent_scope.length; i += 1) {
+                tmp.put(parent_scope[i].getId(), parent_scope[i]);
+            }
+            for (i = 0; i < this.scope.length; i += 1) {
+                tmp.put(this.scope[i].getId(), this.scope[i]);
+            }
+            return tmp.values();
+        }
+        return this.scope;
+    };
+    
+    /**
+     * Removes a topic from the scope. 
+     * @returns {Scoped} The scoped object itself (for chaining support)
+     */
+    Scoped.prototype.removeTheme = function (theme) {
+        var i, j, scope, found;
+        for (i = 0; i < this.scope.length; i += 1) {
+            if (this.scope[i] === theme) {
+                this.getTopicMap().removeThemeEvent.fire(this, {theme: this.scope[i]});
+                this.scope.splice(i, 1);
+                break;
+            }
+        }
+        // Special case for names: remove the theme from index for all variants
+        if (this.isName()) {
+            for (i = 0; i < this.variants.length; i += 1) {
+                scope = this.variants[i].scope;
+                // Check if the the variant has theme as scope
+                found = false;
+                for (j = 0; j < scope.length; j += 1) {
+                    if (theme.equals(scope[j])) {
+                        found = true;
+                    }
+                }
+                if (!found) {
+                    this.getTopicMap().removeThemeEvent.fire(this.variants[i], {theme: theme});
+                }
+            }
+        }
+        return this;
+    };
+    
+    
+    // --------------------------------------------------------------------------
+    /**
+     * @class Indicates that a Construct is reifiable. Every Topic Maps
+     * construct that is not a Topic is reifiable.
+     */
+    Reifiable = function () {};
+    
+    /**
+     * Returns the reifier of this construct.
+     */
+    Reifiable.prototype.getReifier = function () {
+        return this.reifier;
+    };
+    
+    /**
+     * Sets the reifier of the construct.
+     * @throws {ModelConstraintException} If reifier already reifies another
+     * construct.
+     * @returns {Reifiable} The reified object itself (for chaining support)
+     */
+    Reifiable.prototype.setReifier = function (reifier) {
+        if (reifier && reifier.getReified() !== null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Reifies already another construct'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), reifier);
+        if (this.reifier) {
+            this.reifier._setReified(null);
+        }
+        if (reifier) {
+            reifier._setReified(this);
+        }
+        this.reifier = reifier;
+        return this;
+    };
+    
+    // --------------------------------------------------------------------------
+    /**
+     * @class Common base interface for Occurrences and Variants.
+     * Inherits Scoped, Reifiable
+     */
+    DatatypeAware = function () {};
+    
+    /**
+     * Returns the BigDecimal representation of the value.
+     */
+    DatatypeAware.prototype.decimalValue = function () {
+        // FIXME Implement!
+    };
+    
+    /**
+     * Returns the float representation of the value.
+     * @throws {NumberFormatException} If the value is not convertable to float.
+     */
+    DatatypeAware.prototype.floatValue = function () {
+        var ret = parseFloat(this.value);
+        if (isNaN(ret)) {
+            throw {name: 'NumberFormatException',
+                message: '"' + this.value + '" is not a float'};
+        }
+        return ret;
+    };
+    
+    /**
+     * Returns the Locator identifying the datatype of the value.
+     */
+    DatatypeAware.prototype.getDatatype = function () {
+        return this.datatype;
+    };
+    
+    /**
+     * Returns the lexical representation of the value.
+     */
+    DatatypeAware.prototype.getValue = function () {
+        if (typeof this.value === 'object' && this.value instanceof Locator) {
+            return this.value.getReference();
+        }
+        return this.value.toString();
+    };
+    
+    /**
+     * Returns the BigInteger representation of the value.
+     * @throws {NumberFormatException} If the value cannot be parsed as an int.
+     */
+    DatatypeAware.prototype.integerValue = function () {
+        var ret = parseInt(this.value, 10);
+        if (isNaN(ret)) {
+            throw {name: 'NumberFormatException',
+                message: '"' + this.value + '" is not an integer'};
+        }
+        return ret;
+    };
+    
+    /**
+     * Returns the Locator representation of the value.
+     * @throws {ModelConstraintException} If the value is not an Locator
+     * object.
+     */
+    DatatypeAware.prototype.locatorValue = function () {
+        if (!(typeof this.value === 'object' && this.value instanceof Locator)) {
+            throw {name: 'ModelConstraintException',
+                message: '"' + this.value + '" is not a locator'};
+        }
+        return this.value;
+    };
+    
+    /**
+     * Returns the long representation of the value.
+     */
+    DatatypeAware.prototype.longValue = function () {
+        // FIXME Implement!
+    };
+    
+    /**
+     * Sets the value and the datatype.
+     * @throws {ModelConstraintException} If datatype or value is null.
+     */
+    DatatypeAware.prototype.setValue = function (value, datatype) {
+        var tm = this.getTopicMap();
+        if (datatype === null) {
+            throw {name: 'ModelConstraintException', message: 'Invalid datatype'};
+        }
+        if (value === null) {
+            throw {name: 'ModelConstraintException', message: 'Invalid value'};
+        }
+        this.value = value;
+        this.datatype = datatype ||
+            this.getTopicMap().createLocator(XSD.string);
+        if (datatype && datatype.getReference() === XSD.anyURI) {
+            this.value = tm.createLocator(value);
+        }
+        if (!datatype) {
+            if (typeof value === 'number') {
+                // FIXME Could be XSD.float as well
+                this.datatype = tm.createLocator(XSD.integer);
+            }
+        }
+        if (typeof value === 'object' && value instanceof Locator) {
+            this.datatype = tm.createLocator(XSD.anyURI);
+        }
+    };
+    
+    // --------------------------------------------------------------------------
+    /**
+     * Constructs a new Topic Map System Factoy. The constructor should not be
+     * called directly. Use the {TM.TopicMapSystemFactory.newInstance} instead.
+     * @class Represents a Topic Maps construct.
+     * @memberOf TM
+     */
+    TopicMapSystemFactory = function () {
+        this.properties = {};
+        this.features = {};
+    };
+    
+    /**
+     * Returns the particular feature requested for in the underlying implementation
+     * of TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.getFeature = function (featureName) {
+        return this.features;
+    };
+    
+    /**
+     * Gets the value of a property in the underlying implementation of
+     * TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.getProperty = function (propertyName) {
+        return this.properties[propertyName];
+    };
+    
+    /**
+     * Returns if the particular feature is supported by the TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.hasFeature = function (featureName) {
+        return false;
+    };
+    
+    /**
+     * Obtain a new instance of a TopicMapSystemFactory.
+     * @static
+     * @returns {TopicMapSystemFactory}
+     */
+    TopicMapSystemFactory.newInstance = function () {
+        return new TopicMapSystemFactory();
+    };
+    
+    /**
+     * Creates a new TopicMapSystem instance using the currently configured
+     * factory parameters.
+     */
+    TopicMapSystemFactory.prototype.newTopicMapSystem = function () {
+        var backend = this.properties['com.semanticheadache.tmjs.backend'] || 'memory'; 
+        if (backend === 'memory') {
+            return new TopicMapSystemMemImpl();
+        }
+    };
+    
+    /**
+     * Sets a particular feature in the underlying implementation of TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.setFeature = function (featureName, enable) {
+        this.features[featureName] = enable;
+    };
+    
+    /**
+     * Sets a property in the underlying implementation of TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.setProperty = function (propertyName, value) {
+        this.properties[propertyName] = value;
+    };
+    
+    /**
+     * Creates a new instance of TopicMamSystem.
+     * @class Implementation of the TopicMapSystem interface.
+     */
+    TopicMapSystemMemImpl = function () {
+        this.topicmaps = {};
+    };
+    
+    /**
+     * @throws {TopicMapExistsException} If a topic map with the given locator
+     * already exists.
+     */
+    TopicMapSystemMemImpl.prototype.createTopicMap = function (locator) {
+        if (this.topicmaps[locator.getReference()]) {
+            throw {name: 'TopicMapExistsException',
+                message: 'A topic map under the same IRI already exists'};
+        }
+        var tm = new TopicMap(this, locator);
+        this.topicmaps[locator.getReference()] = tm;
+        return tm;
+    };
+    
+    TopicMapSystemMemImpl.prototype.getLocators = function () {
+        var locators = [], key;
+        for (key in this.topicmaps) {
+            if (this.topicmaps.hasOwnProperty(key)) {
+                locators.push(this.createLocator(key));
+            }
+        }
+        return locators;
+    };
+    
+    TopicMapSystemMemImpl.prototype.getTopicMap = function (locator) {
+        var tm;
+        if (locator instanceof Locator) {
+            tm = this.topicmaps[locator.getReference()];
+        } else {
+            tm = this.topicmaps[locator];
+        }
+        if (!tm) {
+            return null;
+        }
+        return tm;
+    };
+    
+    /**
+     * @param {String} iri
+     */
+    TopicMapSystemMemImpl.prototype.createLocator = function (iri) {
+        return new Locator(this, iri);
+    };
+    
+    TopicMapSystemMemImpl.prototype.getFeature = function (featureName) {
+        return false;
+    };
+    
+    TopicMapSystemMemImpl.prototype._removeTopicMap = function (tm) {
+        var key;
+        for (key in this.topicmaps) {
+            if (this.topicmaps.hasOwnProperty(key) &&
+                key === tm.locator.getReference()) {
+                delete this.topicmaps[key];
+            }
+        }
+    };
+    
+    TopicMapSystemMemImpl.prototype.close = function () {
+        this.topicmaps = null; // release references
+    };
+    
+    TopicMap = function (tms, locator) {
+        this.topicmapsystem = tms;
+        this.itemIdentifiers = [];
+        this.locator = locator;
+        this.topics = [];
+        this.associations = [];
+        this._constructId = 1;
+        this._si2topic = new Hash(); // Index for subject identifiers
+        this._sl2topic = new Hash(); // Index for subject locators
+        this._ii2construct = new Hash(); // Index for item identifiers
+        this._id2construct = new Hash(); // Index for object ids
+
+        // The topic map object always get the id 0
+        this.id = 0;
+        this._id2construct.put(this.id, this);
+
+        this.reifier = null;
+        this.handlers = [];
+
+        // Our own event handling mechanism
+        var EventHandler = function (eventtype) {
+            this.eventtype = eventtype;
+            this.handlers = [];
+        };
+        EventHandler.prototype = {
+            registerHandler: function (handler) {
+                this.handlers.push(handler);
+            },
+            removeHandler: function (handler) {
+                for (var i = 0; i < this.handlers.length; i += 1) {
+                    if (handler.toString() ===
+                        this.handlers[i].toString()) {
+                        this.handlers.splice(i, 1);
+                    }
+                }
+            },
+            fire: function (source, obj) {
+                obj = obj || {};
+                for (var i = 0; i < this.handlers.length; i += 1) {
+                    this.handlers[i](this.eventtype, source, obj);
+                }
+            }
+        };
+        this.addAssociationEvent = new EventHandler(EventType.ADD_ASSOCIATION); 
+        this.addNameEvent = new EventHandler(EventType.ADD_NAME); 
+        this.addOccurrenceEvent = new EventHandler(EventType.ADD_OCCURRENCE); 
+        this.addRoleEvent = new EventHandler(EventType.ADD_ROLE); 
+        this.addThemeEvent = new EventHandler(EventType.ADD_THEME); 
+        this.addTopicEvent = new EventHandler(EventType.ADD_TOPIC); 
+        this.addTypeEvent = new EventHandler(EventType.ADD_TYPE); 
+        this.removeAssociationEvent = new EventHandler(EventType.REMOVE_ASSOCIATION);
+        this.removeNameEvent = new EventHandler(EventType.REMOVE_NAME);
+        this.removeOccurrenceEvent = new EventHandler(EventType.REMOVE_OCCURRENCE);
+        this.removeRoleEvent = new EventHandler(EventType.REMOVE_ROLE);
+        this.removeThemeEvent = new EventHandler(EventType.REMOVE_THEME);
+        this.removeTopicEvent = new EventHandler(EventType.REMOVE_TOPIC);
+        this.removeTypeEvent = new EventHandler(EventType.REMOVE_TYPE); 
+        this.setTypeEvent = new EventHandler(EventType.SET_TYPE);
+        this.typeInstanceIndex = new TypeInstanceIndex(this);
+        this.scopedIndex = new ScopedIndex(this);
+    };
+
+    /**
+     * @returns {TopicMap} The topic map object itself (for chaining support)
+     */
+    TopicMap.prototype.register_event_handler = function (type, handler) {
+        switch (type) {
+        case EventType.ADD_ASSOCIATION:
+            this.addAssociationEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_NAME:
+            this.addNameEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_OCCURRENCE:
+            this.addOccurrenceEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_ROLE:
+            this.addRoleEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_THEME:
+            this.addThemeEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_TOPIC:
+            this.addTopicEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_TYPE:
+            this.addTypeEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_ASSOCIATION:
+            this.removeAssociationEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_NAME:
+            this.removeNameEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_OCCURRENCE:
+            this.removeOccurrenceEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_ROLE:
+            this.removeRoleEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_THEME:
+            this.removeThemeEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_TOPIC:
+            this.removeTopicEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_TYPE:
+            this.removeTypeEvent.registerHandler(handler);
+            break;
+        case EventType.SET_TYPE:
+            this.setTypeEvent.registerHandler(handler);
+            break;
+        }
+        return this;
+    };
+
+    TopicMap.swiss(Reifiable, 'getReifier', 'setReifier');
+    TopicMap.swiss(Construct, 'addItemIdentifier', 'getItemIdentifiers',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    /**
+     * Removes duplicate topic map objects. This function is quite expensive,
+     * so it should not be called too often. It is meant to remove duplicates
+     * after imports of topic maps.
+     * @returns {TopicMap} The topic map object itself (for chaining support)
+     */
+    TopicMap.prototype.sanitize = function () {
+        DuplicateRemover.removeTopicMapDuplicates(this);
+        TypeInstanceHelper.convertAssociationsToType(this);
+        return this;
+    };
+    
+    TopicMap.prototype.isTopicMap = function () {
+        return true;
+    };
+    
+    TopicMap.prototype._getConstructId = function () {
+        this._constructId = this._constructId + 1;
+        return this._constructId;
+    };
+    
+    TopicMap.prototype.remove = function () {
+        if (this.topicmapsystem === null) {
+            return null;
+        }
+        this.topicmapsystem._removeTopicMap(this);
+        this.topicmapsystem = null;
+        this.itemIdentifiers = null;
+        this.locator = null;
+        this.topics = null;
+        this.associations = null;
+        this._si2topic = null;
+        this._sl2topic = null;
+        this._ii2construct = null;
+        this._id2construct = null;
+        this.reifier = null;
+        this.id = null;
+        this.typeInstanceIndex = null;
+        return null;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If type or scope is null.
+     */
+    TopicMap.prototype.createAssociation = function (type, scope) {
+        var a;
+        if (type === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Creating an association with type == null is not allowed'};
+        } 
+        if (scope === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Creating an association with scope == null is not allowed'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this, type);
+        SameTopicMapHelper.assertBelongsTo(this, scope);
+    
+        a = new Association(this);
+        this.associations.push(a);
+        if (type) {
+            a.setType(type);
+        }
+        addScope(a, scope);
+        this.addAssociationEvent.fire(a);
+        return a;
+    };
+    
+    TopicMap.prototype.createLocator = function (iri) {
+        return new Locator(this, iri);
+    };
+    
+    TopicMap.prototype._createEmptyTopic = function () {
+        var t = new Topic(this);
+        this.addTopicEvent.fire(t);
+        this.topics.push(t);
+        return t;
+    };
+    
+    TopicMap.prototype.createTopic = function () {
+        var t = this._createEmptyTopic();
+        t.addItemIdentifier(this.createLocator('urn:x-tmjs:' + t.getId()));
+        return t;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If no itemIdentifier is given.
+     * @throws {IdentityConstraintException} If another construct with the
+     * specified item identifier exists which is not a Topic.
+     */
+    TopicMap.prototype.createTopicByItemIdentifier = function (itemIdentifier) {
+        if (!itemIdentifier) {
+            throw {name: 'ModelConstraintException',
+            message: 'createTopicByItemIdentifier() needs an item identifier'};
+        }
+        var t = this.getConstructByItemIdentifier(itemIdentifier);
+        if (t) {
+            if (!t.isTopic()) {
+                throw {name: 'IdentityConstraintException',
+                message: 'Another construct with the specified item identifier ' +
+                    'exists which is not a Topic.'};
+            }
+            return t;
+        }
+        t = this._createEmptyTopic();
+        t.addItemIdentifier(itemIdentifier);
+        return t;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If no subjectIdentifier is given.
+     */
+    TopicMap.prototype.createTopicBySubjectIdentifier = function (subjectIdentifier) {
+        if (!subjectIdentifier) {
+            throw {name: 'ModelConstraintException',
+            message: 'createTopicBySubjectIdentifier() needs a subject identifier'};
+        }
+        var t = this.getTopicBySubjectIdentifier(subjectIdentifier);
+        if (t) {
+            return t;
+        }
+        t = this._createEmptyTopic();
+        t.addSubjectIdentifier(subjectIdentifier);
+        return t;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If no subjectLocator is given.
+     */
+    TopicMap.prototype.createTopicBySubjectLocator = function (subjectLocator) {
+        if (!subjectLocator) {
+            throw {name: 'ModelConstraintException',
+            message: 'createTopicBySubjectLocator() needs a subject locator'};
+        }
+        var t = this.getTopicBySubjectLocator(subjectLocator);
+        if (t) {
+            return t;
+        }
+        t = this._createEmptyTopic();
+        t.addSubjectLocator(subjectLocator);
+        return t;
+    };
+    
+    TopicMap.prototype.getAssociations = function () {
+        return this.associations;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If id is null.
+     */
+    TopicMap.prototype.getConstructById = function (id) {
+        if (id === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'getConstructById(null) is illegal'};
+        }
+        var ret = this._id2construct.get(id);
+        if (!ret) {
+            return null;
+        }
+        return ret;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If itemIdentifier is null.
+     */
+    TopicMap.prototype.getConstructByItemIdentifier = function (itemIdentifier) {
+        if (itemIdentifier === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'getConstructByItemIdentifier(null) is illegal'};
+        }
+        var ret = this._ii2construct.get(itemIdentifier.getReference());
+        if (!ret) {
+            return null;
+        }
+        return ret;
+    };
+    
+    /**
+     * @throws {UnsupportedOperationException} If the index type is not
+     * supported.
+     */
+    TopicMap.prototype.getIndex = function (className) {
+        var index;
+        if (className === 'TypeInstanceIndex') {
+            index = this.typeInstanceIndex;
+            return index;
+        } else if (className === 'ScopedIndex') {
+            index = new ScopedIndex(this);
+            return index;
+        }
+        // TODO: Should we throw an exception that indicates that the 
+        // index is not known? Check the TMAPI docs!
+        throw {name: 'UnsupportedOperationException', 
+            message: 'getIndex ist not (yet) supported'};
+    };
+    
+    TopicMap.prototype.getParent = function () {
+        return null;
+    };
+    
+    TopicMap.prototype.getTopicBySubjectIdentifier = function (subjectIdentifier) {
+        var res = this._si2topic.get(subjectIdentifier.getReference());
+        if (res) {
+            return res;
+        }
+        return null; // Make sure that the result is not undefined
+    };
+    
+    TopicMap.prototype.getTopicBySubjectLocator = function (subjectLocator) {
+        var res = this._sl2topic.get(subjectLocator.getReference());
+        if (res) {
+            return res;
+        }
+        return null; // Make sure that the result is not undefined
+    };
+    
+    TopicMap.prototype.getLocator = function () {
+        return this.locator;
+    };
+    
+    TopicMap.prototype.getTopics = function () {
+        return this.topics;
+    };
+    
+    TopicMap.prototype.mergeIn = function (topicmap) {
+        // TODO implement!
+        throw {name: 'NotImplemented', message: 'TopicMap.mergeIn() not implemented'};
+    };
+    
+    TopicMap.prototype.equals = function (topicmap) {
+        return this.locator.equals(topicmap.locator);
+    };
+    
+    TopicMap.prototype.getId = function () {
+        return this.id;
+    };
+    
+    TopicMap.prototype.getTopicMap = function () {
+        return this;
+    };
+    
+    // Remove item identifiers
+    TopicMap.prototype._removeConstruct = function (construct) {
+        var iis = construct.getItemIdentifiers(), i;
+        for (i = 0; i < iis.length; i += 1) {
+            this._ii2construct.remove(iis[i].getReference());
+        }
+        this._id2construct.remove(construct.getId());
+    };
+    
+    TopicMap.prototype._removeTopic = function (topic) {
+        var i, sis = topic.getSubjectIdentifiers(),
+            slos = topic.getSubjectLocators();
+        // remove subject identifiers from TopicMap._si2topic
+        for (i = 0; i < sis.length; i += 1) {
+            this._si2topic.remove(sis[i].getReference());
+        }
+        // remove subject locators from TopicMap._sl2topic
+        for (i = 0; i < slos.length; i += 1) {
+            this._sl2topic.remove(slos[i].getReference());
+        }
+        this._removeConstruct(topic);
+        // remove topic from TopicMap.topics
+        for (i = 0; i < this.topics.length; i += 1) {
+            if (topic.id === this.topics[i].id) {
+                this.topics.splice(i, 1);
+                break;
+            }
+        }
+    };
+    
+    TopicMap.prototype._removeAssociation = function (association) {
+        var i;
+        // remove association from TopicMap.associations
+        for (i = 0; i < this.associations.length; i += 1) {
+            if (association.id === this.associations[i].id) {
+                this.associations.splice(i, 1);
+                break;
+            }
+        }
+        this._removeConstruct(association);
+        // remove association from TopicMap.associations
+        for (i = 0; i < this.associations.length; i += 1) {
+            if (association.id === this.associations[i].id) {
+                this.associations.splice(i, 1);
+                break;
+            }
+        }
+    };
+    
+    TopicMap.prototype._removeRole = function (role) {
+        this._removeConstruct(role);
+    };
+    
+    TopicMap.prototype._removeOccurrence = function (occ) {
+        this._removeConstruct(occ);
+    };
+    
+    TopicMap.prototype._removeName = function (name) {
+        this._removeConstruct(name);
+    };
+    
+    TopicMap.prototype._removeVariant = function (variant) {
+        this._removeConstruct(variant);
+    };
+    
+    // hashCode, remove
+    
+    // --------------------------------------------------------------------------
+    
+    Topic = function (parnt) {
+        this.subjectIdentifiers = [];
+        this.subjectLocators = [];
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.id = parnt._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+        this.types = [];
+        this.rolesPlayed = [];
+        this.occurrences = [];
+        this.names = [];
+        this.reified = null;
+    };
+    
+    Topic.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Topic.prototype.isTopic = function () {
+        return true;
+    };
+    
+    Topic.prototype.getTopicMap = function () {
+        return this.parnt;
+    };
+    
+    /**
+     * Adds a subject identifier to this topic.
+     * @throws {ModelConstraintException} If subjectIdentifier is null or
+     * not defined.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.addSubjectIdentifier = function (subjectIdentifier) {
+        if (!subjectIdentifier) {
+            throw {name: 'ModelConstraintException',
+            message: 'addSubjectIdentifier() needs subject identifier'};
+        }
+        // Ignore if the identifier already exists
+        for (var i = 0; i < this.subjectIdentifiers.length; i += 1) {
+            if (this.subjectIdentifiers[i].getReference() ===
+                subjectIdentifier.getReference()) {
+                return;
+            }
+        }
+        this.subjectIdentifiers.push(subjectIdentifier);
+        this.parnt._si2topic.put(subjectIdentifier.getReference(), this);
+        return this;
+    };
+    
+    /**
+     * Adds a subject locator to this topic.
+     * @throws {ModelConstraintException} If subjectLocator is null or
+     * not defined.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.addSubjectLocator = function (subjectLocator) {
+        if (!subjectLocator) {
+            throw {name: 'ModelConstraintException',
+            message: 'addSubjectLocator() needs subject locator'};
+        }
+        // Ignore if the identifier already exists
+        for (var i = 0; i < this.subjectLocators.length; i += 1) {
+            if (this.subjectLocators[i].getReference() ===
+                subjectLocator.getReference()) {
+                return;
+            }
+        }
+        this.subjectLocators.push(subjectLocator);
+        this.parnt._sl2topic.put(subjectLocator.getReference(), this);
+        return this;
+    };
+    
+    /**
+     * Adds a type to this topic.
+     * @throws {ModelConstraintException} If type is null or not defined.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.addType = function (type) {
+        if (!type) {
+            throw {name: 'ModelConstraintException',
+            message: 'addType() needs type'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        this.parnt.addTypeEvent.fire(this, {type: type});
+        this.types.push(type);
+        return this;
+    };
+    
+    // TODO: @type is optional In TMAPI 2.0
+    // Creates a Name for this topic with the specified value, and scope.
+    // Creates a Name for this topic with the specified type, value, and scope.
+    Topic.prototype.createName = function (value, type, scope) {
+        var name;
+        if (type) {
+            SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        }
+        if (scope) {
+            SameTopicMapHelper.assertBelongsTo(this.parnt, scope);
+        }
+        if (typeof scope === 'undefined') {
+            scope = null;
+        }
+    
+        name = new Name(this, value, type);
+        addScope(name, scope);
+        this.names.push(name);
+        return name;
+    };
+    
+    // TODO: @datatype is optional in TMAPI, value may be string or locator.
+    // Creates an Occurrence for this topic with the specified type, IRI value, and
+    // scope.
+    // createOccurrence(Topic type, java.lang.String value, Locator datatype,
+    // java.util.Collection<Topic> scope) 
+    // Creates an Occurrence for this topic with the specified type, string value,
+    // and scope.
+    Topic.prototype.createOccurrence = function (type, value, datatype, scope) {
+        var occ;
+        SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        SameTopicMapHelper.assertBelongsTo(this.parnt, scope);
+    
+        occ = new Occurrence(this, type, value, datatype);
+        this.parnt.addOccurrenceEvent.fire(occ, {type: type, value: value});
+        addScope(occ, scope);
+        this.occurrences.push(occ);
+        return occ;
+    };
+    
+    /**
+     * Returns the Names of this topic where the name type is type.
+     *type is optional.
+     */
+    Topic.prototype.getNames = function (type) {
+        var ret = [], i;
+
+        for (i = 0; i < this.names.length; i += 1) {
+            if (type && this.names[i].getType().equals(type)) {
+                ret.push(this.names[i]);
+            } else if (!type) {
+                ret.push(this.names[i]);
+            }
+        }
+        return ret;
+    };
+    
+    /**
+     * Returns the Occurrences of this topic where the occurrence type is type. type
+     * is optional.
+     * @throws {IllegalArgumentException} If type is null.
+     */
+    Topic.prototype.getOccurrences = function (type) {
+        var ret = [], i;
+        if (type === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getOccurrences cannot be called without type'};
+        }
+        for (i = 0; i < this.occurrences.length; i += 1) {
+            if (type && this.occurrences[i].getType().equals(type)) {
+                ret.push(this.occurrences[i]);
+            } else if (!type) {
+                ret.push(this.occurrences[i]);
+            }
+        }
+        return ret;
+    };
+    
+    Topic.prototype._removeOccurrence = function (occ) {
+        // remove this from TopicMap.topics
+        for (var i = 0; i < this.occurrences.length; i += 1) {
+            if (this.occurrences[i].equals(occ)) {
+                this.occurrences.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._removeOccurrence(occ);
+    };
+    
+    // Returns the Construct which is reified by this topic.
+    Topic.prototype.getReified = function (type) {
+        return this.reified;
+    };
+    
+    Topic.prototype._setReified = function (reified) {
+        this.reified = reified;
+    };
+    
+    /**
+     * Returns the roles played by this topic.
+     * Returns the roles played by this topic where the role type is type.
+     * assocType is optional
+     * @throws {IllegalArgumentException} If type or assocType is null.
+     */
+    Topic.prototype.getRolesPlayed = function (type, assocType) {
+        if (type === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getRolesPlayed cannot be called without type'};
+        }
+        if (assocType === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getRolesPlayed cannot be called with assocType===null'};
+        }
+        var ret = [], i;
+        for (i = 0; i < this.rolesPlayed.length; i += 1) {
+            if (!type) {
+                ret.push(this.rolesPlayed[i]);
+            } else if (this.rolesPlayed[i].getType().equals(type)) {
+                if (assocType &&
+                    this.rolesPlayed[i].getParent().getType().equals(assocType) ||
+                    !assocType) {
+                    ret.push(this.rolesPlayed[i]);
+                }
+            }
+        }
+        return ret;
+    };
+    
+    // @private Registers role as a role played
+    // TODO: Rename to _addRolePlayed
+    Topic.prototype.addRolePlayed = function (role) {
+        this.rolesPlayed.push(role);
+    };
+    
+    // TODO: Rename to _removeRolePlayed
+    Topic.prototype.removeRolePlayed = function (role) {
+        for (var i = 0; i < this.rolesPlayed.length; i += 1) {
+            if (this.rolesPlayed[i].id === role.id) {
+                this.rolesPlayed.splice(i, 1);
+            }
+        }
+    };
+    
+    /**
+     * Returns the subject identifiers assigned to this topic.
+     */
+    Topic.prototype.getSubjectIdentifiers = function () {
+        return this.subjectIdentifiers;
+    };
+    
+    /**
+     * Returns the subject locators assigned to this topic.
+     */
+    Topic.prototype.getSubjectLocators = function () {
+        return this.subjectLocators;
+    };
+    
+    /**
+     * Returns the types of which this topic is an instance of.
+     */
+    Topic.prototype.getTypes = function () {
+        return this.types;
+    };
+    
+    /**
+     * Merges another topic into this topic.
+     * @throws {ModelConstraintException} If the topics reify different
+     * information items.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.mergeIn = function (other) {
+        var arr, i, tmp, tmp2, signatures, tiidx, sidx;
+        if (this.equals(other)) {
+            return true;
+        }
+
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), other);
+        if (this.getReified() && other.getReified() &&
+            !this.getReified().equals(other.getReified())) {
+            throw {name: 'ModelConstraintException',
+                message: 'The topics reify different Topic Maps constructs and cannot be merged!'
+            };
+        }
+
+        if (!this.getReified() && other.getReified()) {
+            tmp = other.getReified();
+            tmp.setReifier(this);
+        }
+
+        // Change all constructs that use other as type
+        tiidx = this.parnt.typeInstanceIndex;
+        MergeHelper.moveTypes(tiidx.getOccurrences(other), this);
+        MergeHelper.moveTypes(tiidx.getNames(other), this);
+        MergeHelper.moveTypes(tiidx.getAssociations(other), this);
+        MergeHelper.moveTypes(tiidx.getRoles(other), this);
+
+        // Change all topics that have other as type
+        arr = tiidx.getTopics(other);
+        for (i = 0; i < arr.length; i += 1) {
+            arr[i].removeType(other);
+            arr[i].addType(this);
+        }
+
+        // Change all constructs that use other as theme
+        sidx = this.parnt.scopedIndex;
+        MergeHelper.moveThemes(sidx.getAssociations(other), other, this);
+        MergeHelper.moveThemes(sidx.getOccurrences(other), other, this);
+        MergeHelper.moveThemes(sidx.getNames(other), other, this);
+        MergeHelper.moveThemes(sidx.getVariants(other), other, this);
+
+        MergeHelper.moveItemIdentifiers(other, this);
+
+        arr = other.getSubjectLocators();
+        while (arr.length) {
+            tmp = arr[arr.length - 1];
+            other.removeSubjectLocator(tmp);
+            this.addSubjectLocator(tmp);
+        }
+
+        arr = other.getSubjectIdentifiers();
+        while (arr.length) {
+            tmp = arr[arr.length - 1];
+            other.removeSubjectIdentifier(tmp);
+            this.addSubjectIdentifier(tmp);
+        }
+
+        arr = other.getTypes();
+        while (arr.length) {
+            tmp = arr[arr.length - 1];
+            other.removeType(tmp);
+            this.addType(tmp);
+        }
+
+        // merge roles played
+        arr = this.getRolesPlayed();
+        signatures = {};
+        for (i = 0; i < arr.length; i += 1) {
+            tmp2 = arr[i].getParent();
+            signatures[SignatureGenerator.makeAssociationSignature(tmp2)] = tmp2;
+        }
+        arr = other.getRolesPlayed();
+        for (i = 0; i < arr.length; i += 1) {
+            tmp = arr[i];
+            tmp.setPlayer(this);
+            if ((tmp2 = signatures[SignatureGenerator.makeAssociationSignature(tmp.getParent())])) {
+                MergeHelper.moveItemIdentifiers(tmp.getParent(), tmp2);
+                MergeHelper.moveReifier(tmp.getParent(), tmp2);
+                tmp.getParent().remove();
+            }
+        }
+
+        // merge names
+        arr = this.getNames();
+        signatures = {};
+        for (i = 0; i < arr.length; i += 1) {
+            signatures[SignatureGenerator.makeNameSignature(arr[i])] = arr[i];
+        }
+        arr = other.getNames();
+        for (i = 0; i < arr.length; i += 1) {
+            tmp = arr[i];
+            if ((tmp2 = signatures[SignatureGenerator.makeNameSignature(arr[i])])) {
+                MergeHelper.moveItemIdentifiers(tmp, tmp2);
+                MergeHelper.moveReifier(tmp, tmp2);
+                MergeHelper.moveVariants(tmp, tmp2);
+                tmp.remove();
+            } else {
+                tmp2 = this.createName(tmp.getValue(), tmp.getType(), tmp.getScope());
+                MergeHelper.moveVariants(tmp, tmp2);
+            }
+        }
+
+        // merge occurrences
+        arr = this.getOccurrences();
+        signatures = {};
+        for (i = 0; i < arr.length; i += 1) {
+            signatures[SignatureGenerator.makeOccurrenceSignature(arr[i])] = arr[i];
+        }
+        arr = other.getOccurrences();
+        for (i = 0; i < arr.length; i += 1) {
+            tmp = arr[i];
+            if ((tmp2 = signatures[SignatureGenerator.makeOccurrenceSignature(arr[i])])) {
+                MergeHelper.moveItemIdentifiers(tmp, tmp2);
+                MergeHelper.moveReifier(tmp, tmp2);
+                tmp.remove();
+            } else {
+                tmp2 = this.createOccurrence(tmp.getType(), tmp.getValue(),
+                    tmp.getDatatype(), tmp.getScope());
+                MergeHelper.moveReifier(tmp, tmp2);
+            }
+        }
+
+        other.remove();
+        return this;
+    };
+    
+    /**
+     * Removes this topic from the containing TopicMap instance.
+     * @throws {TopicInUseException} If the topics is used as reifier,
+     * occurrence type, name type, association type, role type, topic type,
+     * association theme, occurrence theme, name theme, variant theme,
+     * or if it is used as a role player.
+     */
+    Topic.prototype.remove = function () {
+        var tiidx = this.parnt.typeInstanceIndex,
+            sidx = this.parnt.scopedIndex;
+        if (this.getReified() ||
+            tiidx.getOccurrences(this).length ||
+            tiidx.getNames(this).length ||
+            tiidx.getAssociations(this).length ||
+            tiidx.getRoles(this).length ||
+            tiidx.getTopics(this).length ||
+            sidx.getAssociations(this).length ||
+            sidx.getOccurrences(this).length ||
+            sidx.getNames(this).length ||
+            sidx.getVariants(this).length ||
+            this.getRolesPlayed().length) {
+            throw {name: 'TopicInUseException',
+                message: '', reporter: this};
+        }
+        this.parnt._removeTopic(this);
+        this.parnt._id2construct.remove(this.id);
+        this.parnt.removeTopicEvent.fire(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+    /**
+     * Removes a subject identifier from this topic.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.removeSubjectIdentifier = function (subjectIdentifier) {
+        for (var i = 0; i < this.subjectIdentifiers.length; i += 1) {
+            if (this.subjectIdentifiers[i].getReference() ===
+                subjectIdentifier.getReference()) {
+                this.subjectIdentifiers.splice(i, 1);
+                break;
+            }
+        }
+        this.parnt._sl2topic.remove(subjectIdentifier.getReference());
+        return this;
+    };
+    
+    /**
+     * Removes a subject locator from this topic.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.removeSubjectLocator = function (subjectLocator) {
+        for (var i = 0; i < this.subjectLocators.length; i += 1) {
+            if (this.subjectLocators[i].getReference() ===
+                subjectLocator.getReference()) {
+                this.subjectLocators.splice(i, 1);
+                break;
+            }
+        }
+        this.parnt._sl2topic.remove(subjectLocator.getReference());
+        return this;
+    };
+    
+    /**
+     * Removes a type from this topic.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.removeType = function (type) {
+        for (var i = 0; i < this.types.length; i += 1) {
+            if (this.types[i].equals(type)) {
+                this.types.splice(i, 1);
+                this.parnt.removeTypeEvent.fire(this, {type: type});
+                break;
+            }
+        }
+    };
+    
+    Topic.prototype._removeName = function (name) {
+        for (var i = 0; i < this.names.length; i += 1) {
+            if (this.names[i].equals(name)) {
+                this.names.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._removeName(name);
+    };
+    
+    // --------------------------------------------------------------------------
+    Occurrence = function (parnt, type, value, datatype) {
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.type = type;
+        this.value = value;
+        this.datatype = datatype ? datatype : this.getTopicMap().createLocator(XSD.string);
+        this.scope = [];
+        this.reifier = null;
+        this.id = this.getTopicMap()._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+    };
+    
+    // mergein Typed, DatatypeAware, Reifiable, Scoped, Construct
+    Occurrence.swiss(Typed, 'getType', 'setType');
+    Occurrence.swiss(DatatypeAware, 'decimalValue', 'floatValue',
+        'getDatatype', 'getValue', 'integerValue', 'locatorValue', 'longValue',
+        'setValue');
+    Occurrence.swiss(Reifiable, 'getReifier', 'setReifier');
+    Occurrence.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Occurrence.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Occurrence.prototype.isOccurrence = function () {
+        return true;
+    };
+    
+    Occurrence.prototype.getTopicMap = function () {
+        return this.parnt.getParent();
+    };
+    
+    Occurrence.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.parnt.parnt.removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.parnt.parnt.removeOccurrenceEvent.fire(this);
+        this.parnt._removeOccurrence(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+    Name = function (parnt, value, type) {
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.value = value;
+        this.scope = [];
+        this.id = this.getTopicMap()._getConstructId();
+        this.type = type ||
+            parnt.parnt.createTopicBySubjectIdentifier(
+                parnt.parnt.createLocator('http://psi.topicmaps.org/iso13250/model/topic-name'));
+        this.reifier = null;
+        this.variants = [];
+        this.getTopicMap()._id2construct.put(this.id, this);
+        this.parnt.parnt.addNameEvent.fire(this, {type: this.type, value: value});
+    };
+    
+    // mergein Typed, DatatypeAware, Reifiable, Scoped, Construct
+    Name.swiss(Typed, 'getType', 'setType');
+    Name.swiss(Reifiable, 'getReifier', 'setReifier');
+    Name.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Name.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Name.prototype.isName = function () {
+        return true;
+    };
+    
+    Name.prototype.getTopicMap = function () {
+        return this.parnt.parnt;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If scope is null.
+     */
+    Name.prototype.createVariant = function (value, datatype, scope) {
+        var scope_length = 0, i, variant;
+        if (typeof scope === 'undefined' || scope === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'Creation of a variant with a null scope is not allowed'};
+        }
+        if (scope && typeof scope === 'object') {
+            if (scope instanceof Array) {
+                scope_length = scope.length;
+            } else if (scope instanceof Topic) {
+                scope_length = 1;
+            }
+        }
+       /* 
+        TODO: Compare scope of Name and Variant
+        if (scope_length <= this.getScope().length) {
+            // check if the variants scope contains more scoping topics
+            throw {name: 'ModelConstraintException',
+            message: 'The variant would be in the same scope as the parent'};
+        }*/
+        variant = new Variant(this, value, datatype);
+        addScope(variant, scope);
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.getTopicMap().addThemeEvent.fire(variant,
+                {theme: this.scope[i]});
+        }
+        this.variants.push(variant);
+        return variant;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If value is null.
+     * @returns {Name} The name itself (for chaining support)
+     */
+    Name.prototype.setValue = function (value) {
+        if (!value) {
+            throw {name: 'ModelConstraintException',
+            message: 'Name.setValue(null) is not allowed'};
+        }
+        this.value = value;
+        return this;
+    };
+    
+    Name.prototype.getValue = function (value) {
+        return this.value;
+    };
+    
+    Name.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.parnt.parnt.removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.parnt.parnt.removeNameEvent.fire(this);
+        this.parnt._removeName(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+    Name.prototype._removeVariant = function (variant) {
+        for (var i = 0; i < this.variants.length; i += 1) {
+            if (this.variants[i].equals(variant)) {
+                this.variants.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._removeVariant(variant);
+    };
+
+    Name.prototype.getVariants = function () {
+        return this.variants;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If value or datatype is null.
+     */
+    Variant = function (parnt, value, datatype) {
+        if (value === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Creation of a variant with null value is not allowed'};
+        }
+        if (datatype === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'Creation of a variant with datatype == null is not allowed'};
+        }
+        this.itemIdentifiers = [];
+        this.scope = [];
+        this.parnt = parnt;
+        if (typeof value === 'object' && value instanceof Locator) {
+            this.datatype = this.getTopicMap().createLocator('http://www.w3.org/2001/XMLSchema#anyURI');
+        } else {
+            this.datatype = 
+                this.getTopicMap().createLocator(XSD.string);
+        }
+        this.datatype = datatype;
+        this.reifier = null;
+        this.value = value;
+        this.id = this.getTopicMap()._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+    };
+    
+    Variant.swiss(Reifiable, 'getReifier', 'setReifier');
+    Variant.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Variant.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    Variant.swiss(DatatypeAware, 'decimalValue', 'floatValue', 'getDatatype',
+        'getValue', 'integerValue', 'locatorValue', 'longValue', 'setValue');
+    
+    Variant.prototype.isVariant = function () {
+        return true;
+    };
+    
+    Variant.prototype.getTopicMap = function () {
+        return this.getParent().getParent().getParent();
+    };
+    
+    Variant.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.getTopicMap().removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.getParent()._removeVariant(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+
+    Role = function (parnt, type, player) {
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.type = type;
+        this.player = player;
+        this.id = this.getTopicMap()._getConstructId();
+        this.reifier = null;
+        this.getTopicMap()._id2construct.put(this.id, this);
+    };
+    
+    Role.swiss(Typed, 'getType', 'setType');
+    Role.swiss(Reifiable, 'getReifier', 'setReifier');
+    Role.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Role.prototype.isRole = function () {
+        return true;
+    };
+    
+    Role.prototype.getTopicMap = function () {
+        return this.getParent().getParent();
+    };
+    
+    Role.prototype.remove = function () {
+        var parnt = this.parnt;
+        this.parnt.parnt.removeRoleEvent.fire(this);
+        this.parnt._removeRole(this);
+        this.itemIdentifiers = null;
+        this.parnt = null;
+        this.type = null;
+        this.player = null;
+        this.reifier = null;
+        this.id = null;
+        return parnt;
+    };
+    
+    Role.prototype.getPlayer = function () {
+        return this.player;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If player is null.
+     * @returns {Role} The role itself (for chaining support)
+     */
+    Role.prototype.setPlayer = function (player) {
+        if (!player) {
+            throw {name: 'ModelConstraintException',
+            message: 'player i Role.setPlayer cannot be null'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.parnt.parnt, player);
+        if (this.player.equals(player)) {
+            return;
+        }
+        this.player.removeRolePlayed(this);
+        player.addRolePlayed(this);
+        this.player = player;
+        return this;
+    };
+    
+    Association = function (par) {
+        this.itemIdentifiers = [];
+        this.parnt = par;
+        this.id = this.getTopicMap()._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+        this.roles = [];
+        this.scope = [];
+        this.type = null;
+        this.reifier = null;
+    };
+    
+    Association.swiss(Typed, 'getType', 'setType');
+    Association.swiss(Reifiable, 'getReifier', 'setReifier');
+    Association.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Association.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Association.prototype.isAssociation = function () {
+        return true;
+    };
+    
+    Association.prototype.getTopicMap = function () {
+        return this.parnt;
+    };
+    
+    /**
+     * Creates a new Role representing a role in this association.
+     * @throws {ModelConstraintException} If type or player is null.
+     */
+    Association.prototype.createRole = function (type, player) {
+        if (!type) {
+            throw {name: 'ModelConstraintException',
+                message: 'type i Role.createPlayer cannot be null'};
+        }
+        if (!player) {
+            throw {name: 'ModelConstraintException',
+                message: 'player i Role.createRole cannot be null'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        SameTopicMapHelper.assertBelongsTo(this.parnt, player);
+        var role = new Role(this, type, player);
+        player.addRolePlayed(role);
+        this.roles.push(role);
+        this.parnt.addRoleEvent.fire(role, {type: type, player: player});
+        return role;
+    };
+    
+    Association.prototype._removeRole = function (role) {
+        for (var i = 0; i < this.roles.length; i += 1) {
+            if (role.id === this.roles[i].id) {
+                this.roles.splice(i, 1);
+                break;
+            }
+        }
+        role.getPlayer().removeRolePlayed(role);
+        this.getTopicMap()._removeRole(role);
+    };
+    
+    Association.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.parnt.removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.parnt.removeAssociationEvent.fire(this);
+        while (this.roles.length) {
+            this.roles[0].remove();
+        }
+        this.id = null;
+        this.roles = null;
+        this.parnt._removeAssociation(this);
+        this.getTopicMap()._ii2construct.remove(this.id);
+        this.item_identifiers = null;
+        this.scope = null;
+        this.type = null;
+        this.reifier = null;
+        return this.parnt;
+    };
+    
+    /**
+     * Returns the roles participating in this association, or, if type
+     * is given, all roles with the specified type.
+     * @throws {IllegalArgumentException} If type is null.
+     */
+    Association.prototype.getRoles = function (type) {
+        if (type === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getRoles cannot be called with type null'};
+        }
+        if (!type) {
+            return this.roles;
+        }
+        var ret = [], i; 
+        for (i = 0; i < this.roles.length; i += 1) {
+            if (this.roles[i].getType().equals(type)) {
+                ret.push(this.roles[i]);
+            }
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the role types participating in this association.
+     */
+    Association.prototype.getRoleTypes = function () {
+        // Create a hash with the object ids as keys to avoid duplicates
+        var types = {}, typearr = [], i, t;
+        for (i = 0; i < this.roles.length; i += 1) {
+            types[this.roles[i].getType().getId()] =
+                this.roles[i].getType();
+        }
+        for (t in types) {
+            if (types.hasOwnProperty(t)) {
+                typearr.push(types[t]);
+            }
+        }
+        return typearr;
+    };
+
+    // ------ ----------------------------------------------------------------
+    /** @class */
+    Index = function () {
+        this.opened = false;
+    };
+
+    /**
+     * Close the index.
+     */
+    Index.prototype.close = function () {
+        return;
+    };
+
+    /** 
+     * Indicates whether the index is updated automatically. 
+     * @returns {boolean}
+     */
+    Index.prototype.isAutoUpdated = function () {
+        return true;
+    };
+
+    /** Indicates if the index is open.
+     * @returns {boolean} true if index is already opened, false otherwise.
+     */
+    Index.prototype.isOpen = function () {
+        return this.opened;
+    };
+
+    /**
+     * Opens the index. This method must be invoked before using any other
+     * method (aside from isOpen()) exported by this interface or derived
+     * interfaces.
+     */
+    Index.prototype.open = function () {
+        this.opened = true;
+    };
+
+    /**
+     * Synchronizes the index with data in the topic map.
+     */
+    Index.prototype.reindex = function () {
+        return;
+    };
+
+    /**
+     * Creates a new instance of TypeInstanceIndex.
+     * @class Implementation of the TypeInstanceIndex interface.
+     */
+    TypeInstanceIndex = function (tm) {
+        var eventHandler, that = this;
+        this.tm = tm;
+        // we use hash tables of hash tables for our index
+        this.type2topics = new Hash();
+        this.type2associations = new Hash();
+        this.type2roles = new Hash();
+        this.type2occurrences = new Hash();
+        this.type2names = new Hash();
+        this.type2variants = new Hash();
+        this.opened = false;
+
+        eventHandler = function (eventtype, source, obj) {
+            var existing, untyped, types, type, i;
+            switch (eventtype) {
+            case EventType.ADD_ASSOCIATION:
+                break;
+            case EventType.ADD_NAME:
+                existing = that.type2names.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2names.put(obj.type.getId(), existing);
+                break;
+            case EventType.ADD_OCCURRENCE:
+                existing = that.type2occurrences.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2occurrences.put(obj.type.getId(), existing);
+                break;
+            case EventType.ADD_ROLE:
+                existing = that.type2roles.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2roles.put(obj.type.getId(), existing);
+                break;
+            case EventType.ADD_TOPIC:
+                existing = that.type2topics.get('null');
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2topics.put('null', existing);
+                break;
+            case EventType.ADD_TYPE:
+                // check if source exists with type null, remove it there
+                untyped = that.type2topics.get('null');
+                if (untyped && untyped.get(source.getId())) {
+                    untyped.remove(source.getId());
+                    that.type2topics.put('null', untyped);
+                }
+                    
+                existing = that.type2topics.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2topics.put(obj.type.getId(), existing);
+                break;
+            case EventType.REMOVE_ASSOCIATION:
+                type = source.getType();
+                if (!type) {
+                    break;
+                }
+                existing = that.type2associations.get(type.getId());
+                for (i = 0; i < existing.length; i += 1) {
+                    if (existing[i].equals(source)) {
+                        existing.splice(i, 1);
+                        break;
+                    }    
+                }
+                if (existing.length > 0) {
+                    that.type2associations.put(type.getId(),
+                            existing);
+                } else {
+                    that.type2associations.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_NAME:
+                type = source.getType();
+                existing = that.type2names.get(type.getId());
+                existing.remove(source.getId());
+                if (existing.length > 0) {
+                    that.type2names.put(type.getId(), existing);
+                } else {
+                    that.type2names.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_OCCURRENCE:
+                type = source.getType();
+                existing = that.type2occurrences.get(type.getId());
+                existing.remove(source.getId());
+                if (existing.length > 0) {
+                    that.type2occurrences.put(type.getId(), existing);
+                } else {
+                    that.type2occurrences.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_ROLE:
+                type = source.getType();
+                existing = that.type2roles.get(type.getId());
+                existing.remove(source.getId());
+                if (existing.length > 0) {
+                    that.type2roles.put(type.getId(), existing);
+                } else {
+                    that.type2roles.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_TOPIC:
+                // two cases:
+                //  topic has types
+                types = source.getTypes();
+                for (i = 0; i < types.length; i += 1) {
+                    existing = that.type2topics.get(types[i].getId());
+                    existing.remove(source.getId());
+                    if (!existing.size()) {
+                        that.type2topics.remove(types[i].getId());
+                    }
+                }
+                // topic used as type 
+                that.type2topics.remove(source.getId());
+                that.type2associations.remove(source.getId());
+                that.type2roles.remove(source.getId());
+                that.type2occurrences.remove(source.getId());
+                that.type2variants.remove(source.getId());
+                break;
+            case EventType.REMOVE_TYPE:
+                existing = that.type2topics.get(obj.type.getId());
+                existing.remove(source.getId());
+                if (!existing.size()) {
+                    that.type2topics.remove(obj.type.getId());
+                }
+                if (source.getTypes().length === 0) {
+                    untyped = that.type2topics.get('null');
+                    if (typeof untyped === 'undefined') {
+                        untyped = new Hash();
+                    }
+                    untyped.put(source.getId(), source);
+                }
+                break;
+            case EventType.SET_TYPE:
+                if (source.isAssociation()) {
+                    // remove source from type2associations(obj.old.getId());
+                    if (obj.old) {
+                        existing = that.type2associations.get(obj.old.getId());
+                        for (i = 0; i < existing.length; i += 1) {
+                            if (existing[i].equals(source)) {
+                                existing.splice(i, 1);
+                                break;
+                            }    
+                        }
+                        if (existing.length > 0) {
+                            that.type2associations.put(obj.old.getId(),
+                                    existing);
+                        } else {
+                            that.type2associations.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2associations.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = [];
+                    }
+                    existing.push(source);
+                    that.type2associations.put(obj.type.getId(), existing);
+                } else if (source.isName()) {
+                    existing = that.type2names.get(obj.old.getId());
+                    if (existing) {
+                        existing.remove(source.getId());
+                        if (existing.length > 0) {
+                            that.type2names.put(obj.old.getId(), existing);
+                        } else {
+                            that.type2names.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2names.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = new Hash();
+                    }
+                    existing.put(source.getId(), source);
+                    that.type2names.put(obj.type.getId(), existing);
+                } else if (source.isOccurrence()) {
+                    existing = that.type2occurrences.get(obj.old.getId());
+                    if (existing) {
+                        existing.remove(source.getId());
+                        if (existing.length > 0) {
+                            that.type2occurrences.put(obj.old.getId(), existing);
+                        } else {
+                            that.type2occurrences.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2occurrences.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = new Hash();
+                    }
+                    existing.put(source.getId(), source);
+                    that.type2occurrences.put(obj.type.getId(), existing);
+                } else if (source.isRole()) {
+                    existing = that.type2roles.get(obj.old.getId());
+                    if (existing) {
+                        existing.remove(source.getId());
+                        if (existing.length > 0) {
+                            that.type2roles.put(obj.old.getId(), existing);
+                        } else {
+                            that.type2roles.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2roles.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = new Hash();
+                    }
+                    existing.put(source.getId(), source);
+                    that.type2roles.put(obj.type.getId(), existing);
+                }
+                break;
+            }
+        };
+        tm.addAssociationEvent.registerHandler(eventHandler);
+        tm.addNameEvent.registerHandler(eventHandler);
+        tm.addOccurrenceEvent.registerHandler(eventHandler);
+        tm.addRoleEvent.registerHandler(eventHandler);
+        tm.addTopicEvent.registerHandler(eventHandler);
+        tm.addTypeEvent.registerHandler(eventHandler);
+        tm.removeAssociationEvent.registerHandler(eventHandler);
+        tm.removeNameEvent.registerHandler(eventHandler);
+        tm.removeOccurrenceEvent.registerHandler(eventHandler);
+        tm.removeRoleEvent.registerHandler(eventHandler);
+        tm.removeTopicEvent.registerHandler(eventHandler);
+        tm.removeTypeEvent.registerHandler(eventHandler);
+        tm.setTypeEvent.registerHandler(eventHandler);
+    };
+
+    TypeInstanceIndex.swiss(Index, 'close', 'isAutoUpdated',
+        'isOpen', 'open', 'reindex');
+          
+    /**
+     * Returns the associations in the topic map whose type property equals type.
+     *
+     * @param {Topic} type
+     * @returns {Array} A list of all associations in the topic map with the given type.
+     */
+    TypeInstanceIndex.prototype.getAssociations = function (type) {
+        var ret = this.type2associations.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of Associations.
+     *
+     * @returns {Array} A list of all topics that are used as an association type.
+     */
+    TypeInstanceIndex.prototype.getAssociationTypes = function () {
+        var ret = [], keys = this.type2associations.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the topic names in the topic map whose type property equals type.
+     *
+     * @param {Topic} type
+     * @returns {Array}
+     */
+    TypeInstanceIndex.prototype.getNames = function (type) {
+        var ret = this.type2names.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of Names.
+     *
+     * @returns {Array} An array of topic types. Note that the array contains
+     * a reference to the actual topics, not copies of them.
+     */
+    TypeInstanceIndex.prototype.getNameTypes = function () {
+        var ret = [], keys = this.type2names.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the occurrences in the topic map whose type property equals type.
+     *
+     * @returns {Array}
+     */
+    TypeInstanceIndex.prototype.getOccurrences = function (type) {
+        var ret = this.type2occurrences.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of
+     * Occurrences.
+     *
+     * @returns {Array} An array of topic types. Note that the array contains
+     * a reference to the actual topics, not copies of them.
+     */
+    TypeInstanceIndex.prototype.getOccurrenceTypes = function () {
+        var ret = [], keys = this.type2occurrences.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+
+    /**
+     * Returns the roles in the topic map whose type property equals type.
+     *
+     * @returns {Array}
+     */
+    TypeInstanceIndex.prototype.getRoles = function (type) {
+        var ret = this.type2roles.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of Roles.
+     *
+     * @returns {Array} An array of topic types. Note that the array contains
+     * a reference to the actual topics, not copies of them.
+     */
+    TypeInstanceIndex.prototype.getRoleTypes = function () {
+        var ret = [], keys = this.type2roles.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the topics which are an instance of the specified type.
+     */
+    TypeInstanceIndex.prototype.getTopics = function (type) {
+        var ret = this.type2topics.get((type ? type.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics which are an instance of the specified types.
+     * If matchall is true only topics that have all of the listed types
+     * are returned.
+     * @returns {Array} A list of Topic objects
+     */
+    TypeInstanceIndex.prototype.getTopicsByTypes = function (types, matchall) {
+        var instances, i, j;
+        instances = IndexHelper.getForKeys(this.type2topics, types);
+        if (!matchall) {
+            return instances;
+        }
+        // If matchall is true, we check all values for all types in {types}
+        // It's a hack, but will do for now
+        for (i = 0; i < instances.length; i += 1) {
+            for (j = 0; j < types.length; j += 1) {
+                if (!ArrayHelper.contains(instances[i].getTypes(), types[j])) {
+                    instances.splice(i, 1);
+                    i -= 1;
+                    break;
+                }
+            }
+        }
+        return instances;
+    };
+
+    /**
+     * Returns the topics in topic map which are used as type in an
+     * "type-instance"-relationship.
+     */
+    TypeInstanceIndex.prototype.getTopicTypes = function () {
+        var ret = [], keys = this.type2topics.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            if (keys[i] !== 'null') {
+                ret.push(this.tm.getConstructById(keys[i]));
+            }
+        }
+        return ret;
+    };
+
+    TypeInstanceIndex.prototype.close = function () {
+        return;
+    };
+
+
+    /**
+     * Index for Scoped statements and their scope. This index provides access
+     * to Associations, Occurrences, Names, and Variants by their scope
+     * property and to Topics which are used as theme in a scope. 
+     */
+    ScopedIndex = function (tm) {
+        var that = this, eventHandler;
+        this.tm = tm;
+        this.theme2associations = new Hash();
+        this.theme2names = new Hash();
+        this.theme2occurrences = new Hash();
+        this.theme2variants = new Hash();
+        eventHandler = function (eventtype, source, obj) {
+            var existing, key, unscoped, remove_from_index, add_to_index;
+            add_to_index = function (hash, source, obj) {
+                key = (obj.theme ? obj.theme.getId() : 'null');
+
+                // check if source exists with theme null, remove it there
+                // this is the case iff source now has one scoping topic
+                if (source.getScope().length === 1) {
+                    unscoped = hash.get('null');
+                    if (unscoped && unscoped.get(source.getId())) {
+                        unscoped.remove(source.getId());
+                        hash.put('null', unscoped);
+                    }
+                }
+                existing = hash.get(key);
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);  
+                hash.put(key, existing);
+            };
+            remove_from_index = function (hash, source, obj) {
+                key = obj.theme.getId();
+                existing = hash.get(key);
+                if (typeof existing !== 'undefined') {
+                    existing.remove(source.getId());  
+                    if (!existing.size()) {
+                        hash.remove(key);
+                    }
+                }
+            };
+            switch (eventtype) {
+            case EventType.ADD_THEME:
+                if (source.isAssociation()) {
+                    add_to_index(that.theme2associations, source, obj);
+                } else if (source.isName()) {
+                    add_to_index(that.theme2names, source, obj);
+                } else if (source.isOccurrence()) {
+                    add_to_index(that.theme2occurrences, source, obj);
+                } else if (source.isVariant()) {
+                    add_to_index(that.theme2variants, source, obj);
+                }
+                break;
+            case EventType.REMOVE_THEME:
+                if (source.isAssociation()) {
+                    remove_from_index(that.theme2associations, source, obj);
+                } else if (source.isName()) {
+                    remove_from_index(that.theme2names, source, obj);
+                } else if (source.isOccurrence()) {
+                    remove_from_index(that.theme2occurrences, source, obj);
+                } else if (source.isVariant()) {
+                    remove_from_index(that.theme2variants, source, obj);
+                }
+                break;
+            }
+        };
+        tm.addThemeEvent.registerHandler(eventHandler);
+        tm.removeThemeEvent.registerHandler(eventHandler);
+    };
+
+    ScopedIndex.swiss(Index, 'close', 'isAutoUpdated',
+        'isOpen', 'open', 'reindex');
+
+    ScopedIndex.prototype.close = function () {
+        return;
+    };
+
+    /**
+     * Returns the Associations in the topic map whose scope property contains
+     * the specified theme. The return value may be empty but must never be null. 
+     * @param theme can be array or {Topic}
+     * @param [matchall] boolean
+     */
+    ScopedIndex.prototype.getAssociations = function (theme) {
+        var ret = this.theme2associations.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Associations in the topic map whose scope property contains
+     * the specified theme. The return value may be empty but must never be null. 
+     * @param theme can be array or {Topic}
+     * @param [matchall] boolean
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getAssociationsByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getAssociationsByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2associations,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of
+     * Associations.
+     */
+    ScopedIndex.prototype.getAssociationThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2associations);
+    };
+
+    /**
+     * Returns the Names in the topic map whose scope property contains the
+     * specified theme.
+     */
+    ScopedIndex.prototype.getNames = function (theme) {
+        var ret = this.theme2names.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Names in the topic map whose scope property equals one of
+     * those themes at least.
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getNamesByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getNamesByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2names,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of Names.
+     */
+    ScopedIndex.prototype.getNameThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2names);
+    };
+
+    /**
+     * Returns the Occurrences in the topic map whose scope property contains the
+     * specified theme.
+     */
+    ScopedIndex.prototype.getOccurrences = function (theme) {
+        var ret = this.theme2occurrences.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Occurrences in the topic map whose scope property equals one
+     * of those themes at least.
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getOccurrencesByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getOccurrencesByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2occurrences,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of
+     * Occurrences.
+     */
+    ScopedIndex.prototype.getOccurrenceThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2occurrences);
+    };
+
+    /**
+     * Returns the Variants in the topic map whose scope property contains the
+     * specified theme. The return value may be empty but must never be null. 
+     * @param {Topic} The Topic which must be part of the scope. This must not be
+     * null. 
+     * @returns {Array} An array of Variants.
+     * @throws {IllegalArgumentException} If theme is null.
+     */
+    ScopedIndex.prototype.getVariants = function (theme) {
+        if (theme === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getVariants cannot be called without themes'};
+        }
+        var ret = this.theme2variants.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Variants in the topic map whose scope property equals one of
+     * those themes at least.
+     * @param {Array} themes Scope of the Variants to be returned.
+     * @param {boolean} If true the scope property of a variant must match all
+     * themes, if false one theme must be matched at least.
+     * @returns {Array} An array of variants
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getVariantsByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getVariantsByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2variants,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of Variants.
+     * The return value may be empty but must never be null.
+     * @returns {Array} An array of Topics.
+     */
+    ScopedIndex.prototype.getVariantThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2variants);
+    };
+
+
+
+
+    /**
+     * @class Helper class that is used to check if constructs belong to
+     * a given topic map.
+     */
+    SameTopicMapHelper = {
+        /**
+         * Checks if topic belongs to the topicmap 'topicmap'.
+         * topic can be instance of Topic or an Array with topics.
+         * topic map be null.
+         * @static
+         * @throws ModelConstraintException if the topic(s) don't
+         * belong to the same topic map.
+         * @returns false if the topic was null or true otherwise.
+         */
+        assertBelongsTo: function (topicmap, topic) {
+            var i;
+            if (!topic) {
+                return false;
+            }
+            if (topic && topic instanceof Topic &&
+                    !topicmap.equals(topic.getTopicMap())) {
+                throw {name: 'ModelConstraintException',
+                    message: 'scope topic belongs to different topic map'};
+            }
+            if (topic && topic instanceof Array) {
+                for (i = 0; i < topic.length; i += 1) {
+                    if (!topicmap.equals(topic[i].getTopicMap())) {
+                        throw {name: 'ModelConstraintException',
+                            message: 'scope topic belong to different topic maps'};
+                    }
+                }
+            }
+            return true;
+        }
+    };
+
+    /**
+     * Helper functions for hashes of hashes
+     * @ignore
+     */
+    IndexHelper = {
+        getForKeys: function (hash, keys) {
+            var i, j, tmp = new Hash(), value_hash, value_keys;
+            for (i = 0; i < keys.length; i += 1) {
+                value_hash = hash.get(keys[i].getId());
+                if (value_hash) {
+                    value_keys = value_hash.keys();
+                    // we use a hash to store instances to avoid duplicates
+                    for (j = 0; j < value_keys.length; j += 1) {
+                        tmp.put(value_hash.get(value_keys[j]).getId(),
+                                value_hash.get(value_keys[j]));
+                    }
+                }
+            }
+            return tmp.values();
+        },
+
+        getConstructThemes: function (tm, hash) {
+            var ret = [], keys = hash.keys(), i;
+            for (i = 0; i < keys.length; i += 1) {
+                if (keys[i] !== 'null') {
+                    ret.push(tm.getConstructById(keys[i]));
+                }
+            }
+            return ret;
+        },
+
+        getConstructsByThemes: function (hash, themes, matchall) {
+            var constructs, i, j;
+            constructs = IndexHelper.getForKeys(hash, themes);
+            if (!matchall) {
+                return constructs;
+            }
+            // If matchall is true, we check all values for all types in {types}
+            // It's a hack, but will do for now
+            for (i = 0; i < constructs.length; i += 1) {
+                for (j = 0; j < themes.length; j += 1) {
+                    if (!ArrayHelper.contains(constructs[i].getScope(), themes[j])) {
+                        constructs.splice(i, 1);
+                        i -= 1;
+                        break;
+                    }
+                }
+            }
+            return constructs;
+        }
+    };
+
+    /** 
+     * Helper functions for arrays. We don't modify the global array
+     * object to avoid conflicts with other libraries.
+     * @ignore
+     */
+    ArrayHelper = {
+        /** Checks if arr contains elem */
+        contains: function (arr, elem) {
+            for (var key in arr) {
+                if (arr.hasOwnProperty(key)) {
+                    if (arr[key].equals(elem)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    };
+
+    /** 
+     * Internal function to add scope. scope may be Array, Topic or null.
+     * @ignore
+     * FIXME: Move to a class
+     */
+    addScope = function (construct, scope) {
+        var i;
+        if (scope && typeof scope === 'object') {
+            if (scope instanceof Array) {
+                for (i = 0; i < scope.length; i += 1) {
+                    construct.addTheme(scope[i]);
+                }
+            } else if (scope instanceof Topic) {
+                construct.addTheme(scope);
+            }
+        } else {
+            construct.getTopicMap().addThemeEvent.fire(construct, {theme: null});
+        }
+    };
+
+    /**
+     * Helper class for generating signatures of Topic Maps constructs.
+     */
+    SignatureGenerator = {
+        makeNameValueSignature: function (name) {
+            return name.getValue();
+        },
+
+        makeNameSignature: function (name) {
+            return SignatureGenerator.makeNameValueSignature(name) +
+                '#' + SignatureGenerator.makeTypeSignature(name) +
+                '#' + SignatureGenerator.makeScopeSignature(name);
+        },
+
+        makeOccurrenceSignature: function (occ) {
+            return SignatureGenerator.makeOccurrenceValueSignature(occ) +
+                '#' + SignatureGenerator.makeTypeSignature(occ) +
+                '#' + SignatureGenerator.makeScopeSignature(occ);
+        },
+
+        makeOccurrenceValueSignature: function (occ) {
+            return '#' + occ.getValue() + '#' +
+                (occ.getDatatype() ? occ.getDatatype().getReference() : 'null');
+        },
+
+        makeTypeSignature: function (obj) {
+            var type = obj.getType();
+            if (type) {
+                return type.getId();
+            } else {
+                return '';
+            }
+        },
+
+        makeScopeSignature: function (scope) {
+            var i, arr = [];
+            for (i = 0; i < scope.length; i += 1) {
+                arr.push(scope[i].getId());
+            }
+            arr.sort();
+            return arr.join('#');
+        },
+
+        makeAssociationSignature: function (ass) {
+            var roles, i, tmp = [];
+            roles = ass.getRoles();
+            for (i = 0; i < roles.length; i += 1) {
+                tmp.push(SignatureGenerator.makeRoleSignature(roles[i]));
+            }
+            tmp.sort();
+        
+            return '#' + SignatureGenerator.makeTypeSignature(ass) + '#' + tmp.join('#') +
+                SignatureGenerator.makeScopeSignature(ass);
+        },
+
+        makeRoleSignature: function (role) {
+            return SignatureGenerator.makeTypeSignature(role) + '#' +
+                role.getPlayer().getId();
+        },
+
+        makeVariantValueSignature: function (variant) {
+            return '#' + variant.getValue() + '#' + variant.getDatatype().getReference();
+        },
+
+        makeVariantSignature: function (variant) {
+            return SignatureGenerator.makeVariantValueSignature(variant) +
+                '#' + SignatureGenerator.makeScopeSignature(variant);
+        }
+    };
+
+    /**
+     * Utility class that removes duplicates according to the TMDM.
+     */
+    DuplicateRemover = {
+        removeTopicMapDuplicates: function (tm) {
+            var i, topics, associations, sig2ass = new Hash(), sig, existing;
+            topics = tm.getTopics();
+            for (i = 0; i < topics.length; i += 1) {
+                DuplicateRemover.removeOccurrencesDuplicates(topics[i].getOccurrences());
+                DuplicateRemover.removeNamesDuplicates(topics[i].getNames());
+            }
+            associations = tm.getAssociations();
+            for (i = 0; i < associations.length; i += 1) {
+                DuplicateRemover.removeAssociationDuplicates(associations[i]);
+                sig = SignatureGenerator.makeAssociationSignature(associations[i]);
+                if ((existing = sig2ass.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(associations[i], existing);
+                    MergeHelper.moveRoleCharacteristics(associations[i], existing);
+                    associations[i].remove();
+                } else {
+                    sig2ass.put(sig, associations[i]);
+                }
+            }
+            sig2ass.empty();
+        },
+
+        removeOccurrencesDuplicates: function (occurrences) {
+            var i, sig2occ = new Hash(), occ, sig, existing;
+            for (i = 0; i < occurrences.length; i += 1) {
+                occ = occurrences[i];
+                sig = SignatureGenerator.makeOccurrenceSignature(occ);
+                if ((existing = sig2occ.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(occ, existing);
+                    occ.remove();
+                } else {
+                    sig2occ.put(sig, occ);
+                }
+            }
+            sig2occ.empty();
+        },
+
+        removeNamesDuplicates: function (names) {
+            var i, sig2names = new Hash(), name, sig, existing;
+            for (i = 0; i < names.length; i += 1) {
+                name = names[i];
+                DuplicateRemover.removeVariantsDuplicates(name.getVariants());
+                sig = SignatureGenerator.makeNameSignature(name);
+                if ((existing = sig2names.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(name, existing);
+                    MergeHelper.moveVariants(name, existing);
+                    name.remove();
+                } else {
+                    sig2names.put(sig, name);
+                }
+            }
+            sig2names.empty();
+        },
+
+        removeVariantsDuplicates: function (variants) {
+            var i, sig2variants = new Hash(), variant, sig, existing;
+            for (i = 0; i < variants.length; i += 1) {
+                variant = variants[i];
+                sig = SignatureGenerator.makeVariantSignature(variant);
+                if ((existing = sig2variants.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(variant, existing);
+                    variant.remove();
+                } else {
+                    sig2variants.put(sig, variant);
+                }
+            }
+            sig2variants.empty();
+        },
+
+        removeAssociationDuplicates: function (assoc) {
+            var i, roles = assoc.getRoles(), sig2role = new Hash(), sig, existing;
+            for (i = 0; i < roles.length; i += 1) {
+                sig = SignatureGenerator.makeRoleSignature(roles[i]);
+                if ((existing = sig2role.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(roles[i], existing);
+                    roles[i].remove();
+                } else {
+                    sig2role.put(sig, roles[i]);
+                }
+            }
+        }
+    };
+
+    MergeHelper = {
+        moveTypes: function (arr, target) {
+            var i;
+            for (i = 0; i < arr.length; i += 1) {
+                arr[i].setType(target);
+            }
+        },
+
+        moveThemes: function (arr, source, target) {
+            for (var i = 0; i < arr.length; i += 1) {
+                arr[i].removeTheme(source);
+                arr[i].addTheme(target);
+            }
+        },
+
+        moveItemIdentifiers: function (source, target) {
+            var iis, ii;
+            iis = source.getItemIdentifiers();
+            while (iis.length) {
+                ii = iis[iis.length - 1];
+                source.removeItemIdentifier(ii);
+                target.addItemIdentifier(ii);
+            }
+        },
+
+        /**
+         * Moves variants from the name source to the name target
+         */
+        moveVariants: function (source, target) {
+            var arr, i, tmp, tmp2, signatures;
+            arr = target.getVariants();
+            signatures = {};
+            for (i = 0; i < arr.length; i += 1) {
+                signatures[SignatureGenerator.makeVariantSignature(arr[i])] = arr[i];
+            }
+            arr = source.getVariants();
+            for (i = 0; i < arr.length; i += 1) {
+                tmp = arr[i];
+                if ((tmp2 = signatures[SignatureGenerator.makeVariantSignature(arr[i])])) {
+                    MergeHelper.moveItemIdentifiers(tmp, tmp2);
+                    MergeHelper.moveReifier(tmp, tmp2);
+                    tmp.remove();
+                } else {
+                    target.createVariant(tmp.getValue(), tmp.getDatatype(), tmp.getScope());
+                }
+            }
+        },
+
+        moveReifier: function (source, target) {
+            var r1, r2;
+            if (source.getReifier() === null) {
+                return;
+            } else if (target.getReifier() === null) {
+                target.setReifier(source.getReifier());
+            } else {
+                r1 = source.getReifier();
+                r2 = target.getReifier();
+                source.setReifier(null);
+                r1.mergeIn(r2);
+            }
+        },
+
+        moveRoleCharacteristics: function (source, target) {
+            var i, roles, sigs = new Hash();
+            roles = target.getRoles();
+            for (i = 0; i < roles.length; i += 1) {
+                sigs.put(roles[i], SignatureGenerator.makeRoleSignature(roles[i]));
+            }
+            roles = source.getRoles();
+            for (i = 0; i < roles.length; i += 1) {
+                MergeHelper.moveItemIdentifiers(roles[i],
+                    sigs.get(SignatureGenerator.makeRoleSignature(roles[i])));
+                roles[i].remove();
+            }
+        },
+
+        moveConstructCharacteristics: function (source, target) {
+            MergeHelper.moveReifier(source, target);
+            MergeHelper.moveItemIdentifiers(source, target);
+        }
+    };
+
+    CopyHelper = {
+        copyAssociations: function (source, target, mergeMap) {
+        },
+        copyItemIdentifiers: function (source, target) {
+        },
+        copyReifier: function (source, target, mergeMap) {
+        },
+        copyScope: function (source, target, mergeMap) {
+        },
+        copyTopicMap: function (source, target) {
+        },
+        copyTopic: function (sourcetm, targettm, mergeMap) {
+        },
+        copyType: function (source, target, mergeMap) {
+        }
+    };
+
+    TypeInstanceHelper = {
+        convertAssociationsToType: function (tm) {
+            var typeInstance, type, instance, associations, index, i, ass, roles;
+            typeInstance = tm.getTopicBySubjectIdentifier(
+                tm.createLocator(TMDM.TYPE_INSTANCE));
+            type = tm.getTopicBySubjectIdentifier(
+                tm.createLocator(TMDM.TYPE));
+            instance = tm.getTopicBySubjectIdentifier(
+                tm.createLocator(TMDM.INSTANCE));
+            if (!typeInstance || !type || !instance) {
+                return;
+            }
+            index = tm.getIndex('TypeInstanceIndex');
+            if (!index) {
+                return;
+            }
+            if (!index.isAutoUpdated()) {
+                index.reindex();
+            }
+            associations = index.getAssociations(typeInstance);
+            for (i = 0; i < associations.length; i += 1) {
+                ass = associations[i];
+                if (ass.getScope().length > 0 ||
+                    ass.getReifier() !== null ||
+                    ass.getItemIdentifiers().length > 0) {
+                    continue;
+                }
+                roles = ass.getRoles();
+                if (roles.length !== 2) {
+                    continue;
+                }
+                if (roles[0].getType().equals(type) && roles[1].getType().equals(instance)) {
+                    roles[1].getPlayer().addType(roles[0].getPlayer());
+                } else
+                if (roles[1].getType().equals(type) && roles[0].getType().equals(instance)) {
+                    roles[0].getPlayer().addType(roles[1].getPlayer());
+                } else {
+                    continue;
+                }
+                ass.remove();
+            }
+        }
+    };
+
+    // Export objects into the TM namespace
+    return {
+        TopicMapSystemFactory: TopicMapSystemFactory,
+        XSD: XSD,
+        TMDM: TMDM,
+        Hash: Hash, // needed by CXTM export
+        Version: Version
+    };
+}());
+
+// Pollute the global namespace
+TopicMapSystemFactory = TM.TopicMapSystemFactory; 
+
+// Check if we are in a CommonJS environment (e.g. node.js)
+if (typeof exports === 'object' && exports !== null) {
+    exports.TopicMapSystemFactory = TopicMapSystemFactory;
+    exports.TM = TM;
+}
+
+/*jslint browser: true, devel: true, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: true, bitwise: true,
+  regexp: true, newcap: true, immed: true, indent: 4 */
+/*global TM, window, DOMParser, ActiveXObject*/ 
+
+TM.JTM = (function () {
+    var ReaderImpl, WriterImpl;
+
+    ReaderImpl = function (tm) {
+        var that = this;
+        this.tm = tm;
+        this.version = null; // Keep the JTM version number
+        this.prefixes = {};
+        this.defaultDatatype = this.tm.createLocator(TM.XSD.string);
+
+        this.curieToLocator = function (loc) {
+            var curie, prefix, pos;
+            if (that.version === '1.1' &&
+                loc.substr(0, 1) === '[') {
+                if (loc.substr(loc.length - 1, 1) !== ']') {
+                    throw {name: 'InvalidFormat',
+                        message: 'Invaild CURIE: missing tailing bracket'};
+                }
+                curie = loc.substr(1, loc.length - 2);
+                pos = curie.indexOf(':');
+                if (pos !== -1) {
+                    // Lookup prefix and replace with URL
+                    prefix = curie.substr(0, pos);
+                    if (that.prefixes[prefix]) {
+                        loc = that.prefixes[prefix] +
+                            curie.substr(pos + 1, curie.length - 1);
+                        return loc;
+                    } else {
+                        throw {name: 'InvalidFormat',
+                            message: 'Missing prefix declaration: ' + prefix};
+                    }
+                } else {
+                    throw {name: 'InvalidFormat',
+                        message: 'Invaild CURIE: missing colon'};
+                }
+            }
+            return loc;
+        };
+
+        /**
+        * Internal function that takes a JTM-identifier string as a parameter
+        * and returns a topic object - either an existing topic or a new topic
+        * if the requested topic did not exist
+        * @param {String} locator JTM-identifier
+        * @throws {InvalidFormat} If the locator could not be parsed.
+        */
+        this.getTopicByReference = function (locator) {
+            if (typeof locator === 'undefined' || locator === null) {
+                return null;
+            }
+            switch (locator.substr(0, 3)) {
+            case 'si:' :
+                return this.tm.createTopicBySubjectIdentifier(
+                    this.tm.createLocator(this.curieToLocator(locator.substr(3))));
+            case 'sl:' :
+                return this.tm.createTopicBySubjectLocator(
+                    this.tm.createLocator(this.curieToLocator(locator.substr(3))));
+            case 'ii:' :
+                return this.tm.createTopicByItemIdentifier(
+                    this.tm.createLocator(this.curieToLocator(locator.substr(3))));
+            }
+            throw {name: 'InvalidFormat',
+                message: 'Invaild topic reference \'' + locator + '\''};
+        };
+    };
+
+    /**
+    * Imports a JTM topic map or JTM fragment from a JSON-string.
+    * name, variant, occurrence and role fragments need the optional parent
+    * construct as a parameter.
+    * TODO: Decide if this should be part of tmjs. Add functions for decoding/
+    * encoding JSON if so.
+    *
+    * @param {String} str JSON encoded JTM
+    * @param {Construct} [parent] Parent construct if the JTM fragment contains
+    *        a name, variant, occurrence or role.
+    */
+    ReaderImpl.prototype.fromString = function (str, parent) {
+        var obj = JSON.parse(str);
+        return this.fromObject(obj);
+    };
+
+    /**
+    * Imports a JTM topic map or JTM fragment.
+    * name, variant, occurrence and role fragments need the parent construct
+    * as a parameter.
+    *
+    * @param {object} obj with JTM properties
+    * @param {Construct} [parent] Parent construct if the JTM fragment contains
+    *        a name, variant, occurrence or role.
+    */
+    ReaderImpl.prototype.fromObject = function (obj, parent) {
+        var ret;
+        parent = parent || null;
+        if (obj.version !== '1.0' && obj.version !== '1.1') {
+            throw {name: 'InvalidFormat',
+                message: 'Unknown version of JTM: ' + obj.version};
+        }
+        this.version = obj.version;
+        if (obj.version === '1.1' && obj.prefixes) {
+            this.prefixes = obj.prefixes;
+            // Check if xsd is defined and if it is valid:
+            if (obj.prefixes && obj.prefixes.xsd &&
+                obj.prefixes.xsd !== 'http://www.w3.org/2001/XMLSchema#') {
+                throw {name: 'InvalidFormat',
+                    message: 'The XSD prefix MUST have the value "http://www.w3.org/2001/XMLSchema#"'};
+            }
+        } else if (obj.prefixes) {
+            throw {name: 'InvalidFormat',
+                message: 'Prefixes are invalid in JTM 1.0: ' + obj.version};
+        }
+        if (!this.prefixes.xsd) {
+            this.prefixes.xsd = 'http://www.w3.org/2001/XMLSchema#';
+        }
+        if (!obj.item_type) {
+            throw {name: 'InvalidFormat',
+                message: 'Missing item_type'};
+        }
+        switch (obj.item_type.toLowerCase()) {
+        case "topicmap":
+            ret = this.parseTopicMap(obj);
+            break;
+        case "topic":
+            ret = this.parseTopic(obj);
+            break;
+        case "name":
+            ret = this.parseName(parent, obj);
+            break;
+        case "variant":
+            ret = this.parseVariant(parent, obj);
+            break;
+        case "occurrence":
+            ret = this.parseOccurrence(parent, obj);
+            break;
+        case "association":
+            ret = this.parseAssociation(obj);
+            break;
+        case "role":
+            ret = this.parseRole(parent, obj);
+            break;
+        default:
+            throw {name: 'InvalidFormat',
+                message: 'Unknown item_type property'};
+        }
+        return ret;
+    };
+
+    /**
+     * FIXME: Work in progress. We have to specify *how* the information
+     * item can be created.
+     *
+     * Internal function that parses a parent field. From the JTM spec:
+     * "The value of the parent member is an array of item identifiers,
+     * each prefixed by "ii:". For occurrences and names the parent array
+     * may as well contain subject identifiers prefixed by "si:" and
+     * subject locators prefixed by "sl:".
+     */
+    ReaderImpl.prototype.parseParentAsTopic = function (obj, allowTopic) {
+        var parent = null, tmp, i;
+        if (!obj.parent) {
+            parent = this.tm.createTopic();
+        } else if (!(obj.parent instanceof Array) || obj.parent.length === 0) {
+            throw {name: 'InvalidFormat',
+                message: 'Missing parent topic reference in occurrence'};
+        }
+        if (obj.parent) {
+            for (i = 0; i < obj.parent.length; i += 1) {
+                tmp = this.getTopicByReference(obj.parent[i]);
+                if (!parent) {
+                    parent = tmp;
+                } else {
+                    parent.mergeIn(tmp);
+                }
+            }
+        }
+        return parent;
+    };
+
+    ReaderImpl.prototype.parseTopicMap = function (obj) {
+        var i, len, arr;
+        this.parseItemIdentifiers(this.tm, obj.item_identifiers);
+        this.parseReifier(this.tm, obj.reifier);
+        if (obj.topics && typeof obj.topics === 'object' && obj.topics instanceof Array) {
+            arr = obj.topics;
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                this.parseTopic(arr[i]);
+            }
+            arr = null;
+        }
+        if (obj.associations && typeof obj.associations === 'object' &&
+            obj.associations instanceof Array) {
+            arr = obj.associations;
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                this.parseAssociation(arr[i]);
+            }
+            arr = null;
+        }
+        this.tm.sanitize(); // remove duplicates and convert type-instance associations to types
+        return true;
+    };
+
+    ReaderImpl.prototype.parseTopic = function (obj) {
+        var that = this, topic = null, parseIdentifier, arr, i, identifier, type;
+        parseIdentifier = function (tm, topic, arr, getFunc, createFunc, addFunc) {
+            var i, len, tmp;
+            if (arr && typeof arr === 'object' && arr instanceof Array) {
+                len = arr.length;
+                for (i = 0; i < len; i += 1) {
+                    identifier = decodeURI(that.curieToLocator(arr[i]));
+                    if (!topic) {
+                        topic = createFunc.apply(tm, [tm.createLocator(identifier)]);
+                    } else {
+                        tmp = getFunc.apply(tm, [tm.createLocator(identifier)]);
+                        if (tmp && tmp.isTopic() && !topic.equals(tmp)) {
+                            topic.mergeIn(tmp);
+                        } else if (!(tmp && tmp.isTopic() && topic.equals(tmp))) {
+                            topic[addFunc](tm.createLocator(identifier));
+                        }
+                    }
+                }
+            }
+            return topic;
+        };
+        topic = parseIdentifier(this.tm, topic, obj.subject_identifiers,
+            this.tm.getTopicBySubjectIdentifier,
+            this.tm.createTopicBySubjectIdentifier, 'addSubjectIdentifier');
+        topic = parseIdentifier(this.tm, topic, obj.subject_locators,
+            this.tm.getTopicBySubjectLocator,
+            this.tm.createTopicBySubjectLocator, 'addSubjectLocator');
+        topic = parseIdentifier(this.tm, topic, obj.item_identifiers,
+            this.tm.getConstructByItemIdentifier,
+            this.tm.createTopicByItemIdentifier, 'addItemIdentifier');
+
+        if ((arr = obj.instance_of) && this.version === '1.1') {
+            for (i = 0; i < arr.length; i += 1) {
+                type = this.getTopicByReference(arr[i]);
+                topic.addType(type);
+            }
+        } else if (obj.instance_of && this.version === '1.0') {
+            throw {name: 'InvalidFormat',
+                message: 'instance_of is invalid in JTM 1.0'};
+        }
+
+        arr = obj.names;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseName(topic, arr[i]);
+            }
+        }
+        arr = obj.occurrences;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseOccurrence(topic, arr[i]);
+            }
+        }
+    };
+
+    ReaderImpl.prototype.parseName = function (parent, obj) {
+        var name, type, scope, arr, i;
+        if (!parent) {
+            parent = this.parseParentAsTopic(obj);
+        }
+        scope = this.parseScope(obj.scope);
+        type = this.getTopicByReference(obj.type);
+        name = parent.createName(obj.value, type, scope);
+        arr = obj.variants;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseVariant(name, arr[i]);
+            }
+        }
+        this.parseItemIdentifiers(name, obj.item_identifiers);
+        this.parseReifier(name, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseVariant = function (parent, obj) {
+        var variant, scope;
+        scope = this.parseScope(obj.scope);
+        variant = parent.createVariant(obj.value, 
+            obj.datatype ?
+                this.tm.createLocator(this.curieToLocator(obj.datatype)) :
+                    this.defaultDatatype, scope);
+        this.parseItemIdentifiers(variant, obj.item_identifiers);
+        this.parseReifier(variant, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseOccurrence = function (parent, obj) {
+        var occurrence, type, scope;
+        if (!parent) {
+            parent = this.parseParentAsTopic(obj);
+        }
+        scope = this.parseScope(obj.scope);
+        type = this.getTopicByReference(obj.type);
+        occurrence = parent.createOccurrence(type, obj.value,
+            obj.datatype ?
+                this.tm.createLocator(this.curieToLocator(obj.datatype)) :
+                    this.defaultDatatype, scope);
+        this.parseItemIdentifiers(occurrence, obj.item_identifiers);
+        this.parseReifier(occurrence, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseAssociation = function (obj) {
+        var association, type, scope, arr, i;
+        scope = this.parseScope(obj.scope);
+        type = this.getTopicByReference(obj.type);
+        association = this.tm.createAssociation(type, scope);
+        arr = obj.roles;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            if (arr.length === 0) {
+                throw {name: 'InvalidFormat',
+                    message: 'Association needs roles'};
+            }
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseRole(association, arr[i]);
+            }
+        } else {
+            throw {name: 'InvalidFormat',
+                message: 'Association needs roles'};
+        }
+        this.parseItemIdentifiers(association, obj.item_identifiers);
+        this.parseReifier(association, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseRole = function (parent, obj) {
+        var role, type, player;
+        type = this.getTopicByReference(obj.type);
+        player = this.getTopicByReference(obj.player);
+        role = parent.createRole(type, player);
+        this.parseItemIdentifiers(role, obj.item_identifiers);
+        this.parseReifier(role, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseScope = function (arr) {
+        var i, scope = [];
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                scope.push(this.getTopicByReference(arr[i]));
+            }
+        }
+        return scope;
+    };
+
+
+    ReaderImpl.prototype.parseItemIdentifiers = function (construct, arr) {
+        var i, tm, identifier;
+        tm = construct.getTopicMap();
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                identifier = this.curieToLocator(arr[i]);
+                if (!tm.getConstructByItemIdentifier(tm.createLocator(identifier))) {
+                    construct.addItemIdentifier(tm.createLocator(identifier));
+                }
+            }
+        }
+    };
+
+    ReaderImpl.prototype.parseReifier = function (construct, reifier) {
+        var reifierTopic = this.getTopicByReference(reifier);
+        if (reifierTopic && reifierTopic.getReified() === null || !reifierTopic) {
+            construct.setReifier(reifierTopic);
+        } // else: Ignore the case that reifierTopic reifies another item
+    };
+
+    /**
+    * @class Exports topic maps constructs as JTM 1.0 JavaScript objects.
+    * See http://www.cerny-online.com/jtm/1.0/ for the JSON Topic Maps specification.
+    * JSON 1.1 is described at http://www.cerny-online.com/jtm/1.1/
+    * @param {String} version Version number of the JTM export. Valid values are '1.0'
+    *                 and '1.1'. Version 1.1 produces more compact files. The default
+    *                 value is '1.0', but this may change in the future.
+    */
+    WriterImpl = function (version) {
+        var that = this, referenceToCURIEorURI;
+        this.defaultDatatype = TM.XSD.string;
+        this.prefixes = new TM.Hash();
+        this.version = version || '1.0';
+
+        referenceToCURIEorURI = function (reference) {
+            var key, keys, i, value;
+            if (that.version === '1.0') {
+                return reference;
+            }
+            // TODO Sort keys after descending value length - longest first
+            // to find the best prefix
+            keys = that.prefixes.keys();
+            for (i = 0; i < keys.length; i += 1) {
+                key = keys[i];
+                value = that.prefixes.get(key);
+                if (reference.substring(0, value.length) ===  value) {
+                    return '[' + key + ':' +
+                        reference.substr(value.length) + ']';
+                }
+            }
+            return reference;
+        };  
+
+        /**
+        * Sets prefixes for JTM 1.1 export. prefixes is an object with the
+        * prefix as key and its corresponding reference as value.
+        */
+        this.setPrefixes = function (prefixes) {
+            var key;
+            for (key in prefixes) {
+                if (prefixes.hasOwnProperty(key)) {
+                    this.prefixes.put(key, prefixes[key]);
+                }
+            }
+        };
+
+        /**
+         * Generates a JTM reference based on the topics subject identifier,
+         * subject locator or item identifier (whatever is set, tested in this
+         * order).
+         * @returns {string} Representing the topic t, e.g.
+         *     "si:http://psi.topicmaps.org/iso13250/model/type
+         */
+        this.getTopicReference = function (t) {
+            var arr;
+            arr = t.getSubjectIdentifiers();
+            if (arr.length > 0) {
+                return 'si:' + referenceToCURIEorURI(arr[0].getReference());
+            }
+            arr = t.getSubjectLocators();
+            if (arr.length > 0) {
+                return 'sl:' + referenceToCURIEorURI(arr[0].getReference());
+            }
+            arr = t.getItemIdentifiers();
+            if (arr.length > 0) {
+                return 'ii:' + referenceToCURIEorURI(arr[0].getReference());
+            }
+            // ModelConstraintExeption: TMDM says that t MUST have on of these
+        };
+
+        this.exportIdentifiers = function (obj, arr, attr) {
+            var i, len = arr.length;
+            if (len > 0) {
+                obj[attr] = [];
+                for (i = 0; i < len; i += 1) {
+                    obj[attr].push(referenceToCURIEorURI(arr[i].getReference()));
+                }
+            }
+        
+        }; 
+
+        this.exportScope = function (obj, construct) {
+            var i, arr = construct.getScope();
+            if (arr.length > 0) {
+                obj.scope = [];
+                for (i = 0; i < arr.length; i += 1) {
+                    obj.scope.push(that.getTopicReference(arr[i]));
+                }
+            }
+        };
+
+        this.exportParent = function (obj, construct) {
+            var parent = construct.getParent();
+            that.exportIdentifiers(obj, parent.getItemIdentifiers(), 'parent');
+        };
+
+        this.exportTopicMap = function (m) {
+            var arr, i, len, obj;
+            obj = {
+                topics: [],
+                associations: []
+            };
+            arr = m.getTopics();
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                obj.topics.push(that.exportTopic(arr[i]));
+            }
+            arr = m.getAssociations();
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                obj.associations.push(that.exportAssociation(arr[i]));
+            }
+            return obj;
+        };
+
+        this.exportTopic = function (t) {
+            var arr, i, len, obj;
+            obj = {};
+            that.exportIdentifiers(obj, t.getSubjectIdentifiers(), 'subject_identifiers');
+            that.exportIdentifiers(obj, t.getSubjectLocators(), 'subject_locators');
+            that.exportIdentifiers(obj, t.getItemIdentifiers(), 'item_identifiers');
+            arr = t.getNames();
+            len = arr.length;
+            if (len > 0) {
+                obj.names = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.names.push(that.exportName(arr[i]));
+                }
+            }
+            arr = t.getOccurrences();
+            len = arr.length;
+            if (len > 0) {
+                obj.occurrences = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.occurrences.push(that.exportOccurrence(arr[i]));
+                }
+            }
+            arr = t.getTypes();
+            len = arr.length;
+            if (len > 0) {
+                obj.instance_of = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.instance_of.push(that.getTopicReference(arr[i]));
+                }
+            }
+            return obj;
+        };
+
+        this.exportName = function (name) {
+            var arr, i, len, obj, tmp;
+            obj = {
+                'value': name.getValue()
+            };
+            tmp = name.getType();
+            if (tmp) {
+                obj.type = that.getTopicReference(tmp);
+            }
+            tmp = name.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            
+            that.exportIdentifiers(obj, name.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, name);
+            arr = name.getVariants();
+            len = arr.length;
+            if (len > 0) {
+                obj.variants = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.variants.push(that.exportVariant(arr[i]));
+                }
+            }
+            return obj;
+        };
+
+        this.exportVariant = function (variant) {
+            var obj, tmp;
+            obj = {
+                'value': variant.getValue()
+            };
+            tmp = variant.getDatatype();
+            if (tmp && tmp !== variant.getTopicMap().createLocator(that.defaultDatatype)) {
+                obj.datatype = referenceToCURIEorURI(tmp.getReference());
+            }
+            tmp = variant.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            
+            that.exportIdentifiers(obj, variant.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, variant);
+        };
+
+        this.exportOccurrence = function (occ) {
+            var obj, tmp;
+            obj = {
+                value: occ.getValue(),
+                type: that.getTopicReference(occ.getType())
+            };
+            tmp = occ.getDatatype();
+            if (tmp && tmp !== occ.getTopicMap().createLocator(that.defaultDatatype)) {
+                obj.datatype = referenceToCURIEorURI(tmp.getReference());
+            }
+            tmp = occ.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            
+            that.exportIdentifiers(obj, occ.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, occ);
+            return obj;
+        };
+
+        this.exportAssociation = function (association) {
+            var arr, i, obj, tmp;
+            obj = {
+                type: that.getTopicReference(association.getType()),
+                roles: []
+            };
+            tmp = association.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            that.exportIdentifiers(obj, association.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, association);
+            arr = association.getRoles();
+            for (i = 0; i < arr.length; i += 1) {
+                obj.roles.push(that.exportRole(arr[i]));
+            }
+            return obj;
+        };
+
+        this.exportRole = function (role) {
+            var obj, tmp;
+            obj = {
+                player: that.getTopicReference(role.getPlayer()),
+                type: that.getTopicReference(role.getType())
+            };
+            tmp = role.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            that.exportIdentifiers(obj, role.getItemIdentifiers(), 'item_identifiers');
+            return obj;
+        };
+    };
+
+    /**
+    * Returns a JTM JavaScript object representation of construct.
+    * @param {Construct} construct The topic map construct to be exported. Can be
+    * TopicMap, Topic, Occurrence, Name, Variant, Association or Role.
+    * @param {boolean} [includeParent] If true the optional JTM element 'parent' is
+    * included. Refers to the parent via its item identifier.  If undefined or false,
+    * the parent element is dropped.
+    */
+    WriterImpl.prototype.toObject = function (construct, includeParent) {
+        var obj, tm, keys, i;
+        includeParent = includeParent || false;
+        tm = construct.getTopicMap();
+
+        if (construct.isTopicMap()) {
+            obj = this.exportTopicMap(construct);
+            obj.item_type = 'topicmap';
+        } else if (construct.isRole()) {
+            obj = this.exportRole(construct);
+            obj.item_type = 'role';
+        } else if (construct.isTopic()) {
+            obj = this.exportTopic(construct);
+            obj.item_type = 'topic';
+        } else if (construct.isAssociation()) {
+            obj = this.exportAssociation(construct);
+            obj.item_type = 'association';
+        } else if (construct.isOccurrence()) {
+            obj = this.exportOccurrence(construct);
+            obj.item_type = 'occurrence';
+        } else if (construct.isName()) {
+            obj = this.exportName(construct);
+            obj.item_type = 'name';
+        } else if (construct.isVariant()) {
+            obj = this.exportVariant(construct);
+            obj.item_type = 'variant';
+        }
+        obj.version = this.version;
+        if (this.version === '1.1' && this.prefixes) {
+            if (this.prefixes.size()) {
+                keys = this.prefixes.keys();
+                obj.prefixes = {};
+                for (i = 0; i < keys.length; i += 1) {
+                    obj.prefixes[keys[i]] = this.prefixes.get(keys[i]);
+                }
+            }
+        }
+        if (!construct.isTopic() && construct.getReifier()) {
+            obj.reifier = this.getTopicReference(construct.getReifier());
+        }
+        if (includeParent && !construct.isTopicMap()) {
+            this.exportParent(obj, construct);
+        }
+        return obj;
+    };
+
+    return {
+        Reader: ReaderImpl,
+        Writer: WriterImpl
+    };
+}());

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/tm.min.js
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/lib/tm.min.js	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,115 @@
+// tmjs, version 0.4.0
+// http://github.com/jansc/tmjs
+// Copyright (c) 2010 Jan Schreiber <jans at ravn.no>
+// Licensed under the MIT-License.
+var TM,TopicMapSystemFactory;
+TM=function(){var n,C,h,g,e,f,i,l,m,o,t,u,p,D,x,A,B,v,y,w,z,O,E,J,H,s,q,P;Function.prototype.swiss=function(a){var b,c;for(b=1;b<arguments.length;b+=1){c=arguments[b];this.prototype[c]=a.prototype[c]}return this};n=function(){this.hash={};this.length=0};n.prototype={get:function(a){return this.hash[a]},contains:function(a){return this.get(a)!==undefined},put:function(a,b){this.hash[a]||(this.length+=1);return this.hash[a]=b},remove:function(a){delete this.hash[a];this.length-=1;return this},keys:function(){var a=
+[],b;for(b in this.hash)this.hash.hasOwnProperty(b)&&a.push(b);return a},values:function(){var a=[],b;for(b in this.hash)this.hash.hasOwnProperty(b)&&a.push(this.hash[b]);return a},empty:function(){this.hash={};this.length=0},size:function(){return this.length}};e={};e.ADD_ASSOCIATION=1;e.ADD_NAME=2;e.ADD_OCCURRENCE=3;e.ADD_ROLE=4;e.ADD_THEME=5;e.ADD_TOPIC=6;e.ADD_TYPE=7;e.REMOVE_ASSOCIATION=8;e.REMOVE_NAME=9;e.REMOVE_OCCURRENCE=10;e.REMOVE_ROLE=11;e.REMOVE_THEME=12;e.REMOVE_TOPIC=13;e.REMOVE_TYPE=
+14;e.SET_TYPE=15;C={string:"http://www.w3.org/2001/XMLSchema#string",integer:"http://www.w3.org/2001/XMLSchema#integer",anyURI:"http://www.w3.org/2001/XMLSchema#anyURI"};h={TYPE_INSTANCE:"http://psi.topicmaps.org/iso13250/model/type-instance",TYPE:"http://psi.topicmaps.org/iso13250/model/type",INSTANCE:"http://psi.topicmaps.org/iso13250/model/instance",TOPIC_NAME:"http://psi.topicmaps.org/iso13250/model/topic-name"};g=function(a,b){this.parnt=a;this.iri=b};g.prototype.getReference=function(){return this.iri};
+g.prototype.equals=function(a){return this.iri===a.getReference()};g.prototype.toExternalForm=function(){throw{name:"NotImplemented",message:"Locator.toExternalForm() not implemented"};};m=function(){};m.prototype.addItemIdentifier=function(a){var b;if(a===null)throw{name:"ModelConstraintException",message:"addItemIdentifier(null) is illegal"};if(b=this.getTopicMap()._ii2construct.get(a.getReference()))throw{name:"IdentityConstraintException",message:"Topic Maps constructs with the same item identifier are not allowed",
+reporter:this,existing:b,locator:a};this.itemIdentifiers.push(a);this.getTopicMap()._ii2construct.put(a.getReference(),this);return this};m.prototype.equals=function(a){return this.id===a.id};m.prototype.getId=function(){return this.id};m.prototype.getItemIdentifiers=function(){return this.itemIdentifiers};m.prototype.getParent=function(){return this.parnt};m.prototype.getTopicMap=function(){throw{name:"NotImplemented",message:"getTopicMap() not implemented"};};m.prototype.hashCode=function(){throw{name:"NotImplemented",
+message:"hashCode() not implemented"};};m.prototype.remove=function(){throw{name:"NotImplemented",message:"remove() not implemented"};};m.prototype.removeItemIdentifier=function(a){if(a!==null){for(var b=0;b<this.itemIdentifiers.length;b+=1)if(this.itemIdentifiers[b].getReference()===a.getReference()){this.itemIdentifiers.splice(b,1);break}this.getTopicMap()._ii2construct.remove(a.getReference());return this}};m.prototype.isTopicMap=function(){return false};m.prototype.isTopic=function(){return false};
+m.prototype.isAssociation=function(){return false};m.prototype.isRole=function(){return false};m.prototype.isName=function(){return false};m.prototype.isOccurrence=function(){return false};m.prototype.isVariant=function(){return false};o=function(){};o.prototype.getType=function(){return this.type};o.prototype.setType=function(a){if(a===null)throw{name:"ModelConstraintException",message:"Topic.setType cannot be called without type"};z.assertBelongsTo(this.getTopicMap(),a);this.getTopicMap().setTypeEvent.fire(this,
+{old:this.type,type:a});this.type=a;return this};l=function(){};l.prototype.addTheme=function(a){if(a===null)throw{name:"ModelConstraintException",message:"addTheme(null) is illegal"};for(var b=0;b<this.scope.length;b+=1)if(this.scope[b]===a)return false;z.assertBelongsTo(this.getTopicMap(),a);this.scope.push(a);this.getTopicMap().addThemeEvent.fire(this,{theme:a});if(this.isName())for(b=0;b<this.variants.length;b+=1)this.getTopicMap().addThemeEvent.fire(this.variants[b],{theme:a});return this};l.prototype.getScope=
+function(){if(this.isVariant()){var a,b=new n,c=this.parnt.getScope();for(a=0;a<c.length;a+=1)b.put(c[a].getId(),c[a]);for(a=0;a<this.scope.length;a+=1)b.put(this.scope[a].getId(),this.scope[a]);return b.values()}return this.scope};l.prototype.removeTheme=function(a){var b,c,d,j;for(b=0;b<this.scope.length;b+=1)if(this.scope[b]===a){this.getTopicMap().removeThemeEvent.fire(this,{theme:this.scope[b]});this.scope.splice(b,1);break}if(this.isName())for(b=0;b<this.variants.length;b+=1){d=this.variants[b].scope;
+j=false;for(c=0;c<d.length;c+=1)if(a.equals(d[c]))j=true;j||this.getTopicMap().removeThemeEvent.fire(this.variants[b],{theme:a})}return this};t=function(){};t.prototype.getReifier=function(){return this.reifier};t.prototype.setReifier=function(a){if(a&&a.getReified()!==null)throw{name:"ModelConstraintException",message:"Reifies already another construct"};z.assertBelongsTo(this.getTopicMap(),a);this.reifier&&this.reifier._setReified(null);a&&a._setReified(this);this.reifier=a;return this};u=function(){};
+u.prototype.decimalValue=function(){};u.prototype.floatValue=function(){var a=parseFloat(this.value);if(isNaN(a))throw{name:"NumberFormatException",message:'"'+this.value+'" is not a float'};return a};u.prototype.getDatatype=function(){return this.datatype};u.prototype.getValue=function(){if(typeof this.value==="object"&&this.value instanceof g)return this.value.getReference();return this.value.toString()};u.prototype.integerValue=function(){var a=parseInt(this.value,10);if(isNaN(a))throw{name:"NumberFormatException",
+message:'"'+this.value+'" is not an integer'};return a};u.prototype.locatorValue=function(){if(!(typeof this.value==="object"&&this.value instanceof g))throw{name:"ModelConstraintException",message:'"'+this.value+'" is not a locator'};return this.value};u.prototype.longValue=function(){};u.prototype.setValue=function(a,b){var c=this.getTopicMap();if(b===null)throw{name:"ModelConstraintException",message:"Invalid datatype"};if(a===null)throw{name:"ModelConstraintException",message:"Invalid value"};
+this.value=a;this.datatype=b||this.getTopicMap().createLocator(C.string);if(b&&b.getReference()===C.anyURI)this.value=c.createLocator(a);if(!b)if(typeof a==="number")this.datatype=c.createLocator(C.integer);if(typeof a==="object"&&a instanceof g)this.datatype=c.createLocator(C.anyURI)};TopicMapSystemFactory=function(){this.properties={};this.features={}};TopicMapSystemFactory.prototype.getFeature=function(){return this.features};TopicMapSystemFactory.prototype.getProperty=function(a){return this.properties[a]};
+TopicMapSystemFactory.prototype.hasFeature=function(){return false};TopicMapSystemFactory.newInstance=function(){return new TopicMapSystemFactory};TopicMapSystemFactory.prototype.newTopicMapSystem=function(){if((this.properties["com.semanticheadache.tmjs.backend"]||"memory")==="memory")return new v};TopicMapSystemFactory.prototype.setFeature=function(a,b){this.features[a]=b};TopicMapSystemFactory.prototype.setProperty=function(a,b){this.properties[a]=b};v=function(){this.topicmaps={}};v.prototype.createTopicMap=
+function(a){if(this.topicmaps[a.getReference()])throw{name:"TopicMapExistsException",message:"A topic map under the same IRI already exists"};var b=new p(this,a);return this.topicmaps[a.getReference()]=b};v.prototype.getLocators=function(){var a=[],b;for(b in this.topicmaps)this.topicmaps.hasOwnProperty(b)&&a.push(this.createLocator(b));return a};v.prototype.getTopicMap=function(a){a=a instanceof g?this.topicmaps[a.getReference()]:this.topicmaps[a];if(!a)return null;return a};v.prototype.createLocator=
+function(a){return new g(this,a)};v.prototype.getFeature=function(){return false};v.prototype._removeTopicMap=function(a){var b;for(b in this.topicmaps)this.topicmaps.hasOwnProperty(b)&&b===a.locator.getReference()&&delete this.topicmaps[b]};v.prototype.close=function(){this.topicmaps=null};p=function(a,b){this.topicmapsystem=a;this.itemIdentifiers=[];this.locator=b;this.topics=[];this.associations=[];this._constructId=1;this._si2topic=new n;this._sl2topic=new n;this._ii2construct=new n;this._id2construct=
+new n;this.id=0;this._id2construct.put(this.id,this);this.reifier=null;this.handlers=[];a=function(c){this.eventtype=c;this.handlers=[]};a.prototype={registerHandler:function(c){this.handlers.push(c)},removeHandler:function(c){for(var d=0;d<this.handlers.length;d+=1)c.toString()===this.handlers[d].toString()&&this.handlers.splice(d,1)},fire:function(c,d){d=d||{};for(var j=0;j<this.handlers.length;j+=1)this.handlers[j](this.eventtype,c,d)}};this.addAssociationEvent=new a(e.ADD_ASSOCIATION);this.addNameEvent=
+new a(e.ADD_NAME);this.addOccurrenceEvent=new a(e.ADD_OCCURRENCE);this.addRoleEvent=new a(e.ADD_ROLE);this.addThemeEvent=new a(e.ADD_THEME);this.addTopicEvent=new a(e.ADD_TOPIC);this.addTypeEvent=new a(e.ADD_TYPE);this.removeAssociationEvent=new a(e.REMOVE_ASSOCIATION);this.removeNameEvent=new a(e.REMOVE_NAME);this.removeOccurrenceEvent=new a(e.REMOVE_OCCURRENCE);this.removeRoleEvent=new a(e.REMOVE_ROLE);this.removeThemeEvent=new a(e.REMOVE_THEME);this.removeTopicEvent=new a(e.REMOVE_TOPIC);this.removeTypeEvent=
+new a(e.REMOVE_TYPE);this.setTypeEvent=new a(e.SET_TYPE);this.typeInstanceIndex=new y(this);this.scopedIndex=new w(this)};p.prototype.register_event_handler=function(a,b){switch(a){case e.ADD_ASSOCIATION:this.addAssociationEvent.registerHandler(b);break;case e.ADD_NAME:this.addNameEvent.registerHandler(b);break;case e.ADD_OCCURRENCE:this.addOccurrenceEvent.registerHandler(b);break;case e.ADD_ROLE:this.addRoleEvent.registerHandler(b);break;case e.ADD_THEME:this.addThemeEvent.registerHandler(b);break;
+case e.ADD_TOPIC:this.addTopicEvent.registerHandler(b);break;case e.ADD_TYPE:this.addTypeEvent.registerHandler(b);break;case e.REMOVE_ASSOCIATION:this.removeAssociationEvent.registerHandler(b);break;case e.REMOVE_NAME:this.removeNameEvent.registerHandler(b);break;case e.REMOVE_OCCURRENCE:this.removeOccurrenceEvent.registerHandler(b);break;case e.REMOVE_ROLE:this.removeRoleEvent.registerHandler(b);break;case e.REMOVE_THEME:this.removeThemeEvent.registerHandler(b);break;case e.REMOVE_TOPIC:this.removeTopicEvent.registerHandler(b);
+break;case e.REMOVE_TYPE:this.removeTypeEvent.registerHandler(b);break;case e.SET_TYPE:this.setTypeEvent.registerHandler(b);break}return this};p.swiss(t,"getReifier","setReifier");p.swiss(m,"addItemIdentifier","getItemIdentifiers","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");p.prototype.sanitize=function(){H.removeTopicMapDuplicates(this);P.convertAssociationsToType(this);return this};p.prototype.isTopicMap=function(){return true};p.prototype._getConstructId=
+function(){this._constructId+=1;return this._constructId};p.prototype.remove=function(){if(this.topicmapsystem===null)return null;this.topicmapsystem._removeTopicMap(this);return this.typeInstanceIndex=this.id=this.reifier=this._id2construct=this._ii2construct=this._sl2topic=this._si2topic=this.associations=this.topics=this.locator=this.itemIdentifiers=this.topicmapsystem=null};p.prototype.createAssociation=function(a,b){var c;if(a===null)throw{name:"ModelConstraintException",message:"Creating an association with type == null is not allowed"};
+if(b===null)throw{name:"ModelConstraintException",message:"Creating an association with scope == null is not allowed"};z.assertBelongsTo(this,a);z.assertBelongsTo(this,b);c=new i(this);this.associations.push(c);a&&c.setType(a);J(c,b);this.addAssociationEvent.fire(c);return c};p.prototype.createLocator=function(a){return new g(this,a)};p.prototype._createEmptyTopic=function(){var a=new f(this);this.addTopicEvent.fire(a);this.topics.push(a);return a};p.prototype.createTopic=function(){var a=this._createEmptyTopic();
+a.addItemIdentifier(this.createLocator("urn:x-tmjs:"+a.getId()));return a};p.prototype.createTopicByItemIdentifier=function(a){if(!a)throw{name:"ModelConstraintException",message:"createTopicByItemIdentifier() needs an item identifier"};var b=this.getConstructByItemIdentifier(a);if(b){if(!b.isTopic())throw{name:"IdentityConstraintException",message:"Another construct with the specified item identifier exists which is not a Topic."};return b}b=this._createEmptyTopic();b.addItemIdentifier(a);return b};
+p.prototype.createTopicBySubjectIdentifier=function(a){if(!a)throw{name:"ModelConstraintException",message:"createTopicBySubjectIdentifier() needs a subject identifier"};var b=this.getTopicBySubjectIdentifier(a);if(b)return b;b=this._createEmptyTopic();b.addSubjectIdentifier(a);return b};p.prototype.createTopicBySubjectLocator=function(a){if(!a)throw{name:"ModelConstraintException",message:"createTopicBySubjectLocator() needs a subject locator"};var b=this.getTopicBySubjectLocator(a);if(b)return b;
+b=this._createEmptyTopic();b.addSubjectLocator(a);return b};p.prototype.getAssociations=function(){return this.associations};p.prototype.getConstructById=function(a){if(a===null)throw{name:"ModelConstraintException",message:"getConstructById(null) is illegal"};a=this._id2construct.get(a);if(!a)return null;return a};p.prototype.getConstructByItemIdentifier=function(a){if(a===null)throw{name:"ModelConstraintException",message:"getConstructByItemIdentifier(null) is illegal"};a=this._ii2construct.get(a.getReference());
+if(!a)return null;return a};p.prototype.getIndex=function(a){if(a==="TypeInstanceIndex")return a=this.typeInstanceIndex;else if(a==="ScopedIndex")return a=new w(this);throw{name:"UnsupportedOperationException",message:"getIndex ist not (yet) supported"};};p.prototype.getParent=function(){return null};p.prototype.getTopicBySubjectIdentifier=function(a){if(a=this._si2topic.get(a.getReference()))return a;return null};p.prototype.getTopicBySubjectLocator=function(a){if(a=this._sl2topic.get(a.getReference()))return a;
+return null};p.prototype.getLocator=function(){return this.locator};p.prototype.getTopics=function(){return this.topics};p.prototype.mergeIn=function(){throw{name:"NotImplemented",message:"TopicMap.mergeIn() not implemented"};};p.prototype.equals=function(a){return this.locator.equals(a.locator)};p.prototype.getId=function(){return this.id};p.prototype.getTopicMap=function(){return this};p.prototype._removeConstruct=function(a){var b=a.getItemIdentifiers(),c;for(c=0;c<b.length;c+=1)this._ii2construct.remove(b[c].getReference());
+this._id2construct.remove(a.getId())};p.prototype._removeTopic=function(a){var b,c=a.getSubjectIdentifiers(),d=a.getSubjectLocators();for(b=0;b<c.length;b+=1)this._si2topic.remove(c[b].getReference());for(b=0;b<d.length;b+=1)this._sl2topic.remove(d[b].getReference());this._removeConstruct(a);for(b=0;b<this.topics.length;b+=1)if(a.id===this.topics[b].id){this.topics.splice(b,1);break}};p.prototype._removeAssociation=function(a){var b;for(b=0;b<this.associations.length;b+=1)if(a.id===this.associations[b].id){this.associations.splice(b,
+1);break}this._removeConstruct(a);for(b=0;b<this.associations.length;b+=1)if(a.id===this.associations[b].id){this.associations.splice(b,1);break}};p.prototype._removeRole=function(a){this._removeConstruct(a)};p.prototype._removeOccurrence=function(a){this._removeConstruct(a)};p.prototype._removeName=function(a){this._removeConstruct(a)};p.prototype._removeVariant=function(a){this._removeConstruct(a)};f=function(a){this.subjectIdentifiers=[];this.subjectLocators=[];this.itemIdentifiers=[];this.parnt=
+a;this.id=a._getConstructId();this.getTopicMap()._id2construct.put(this.id,this);this.types=[];this.rolesPlayed=[];this.occurrences=[];this.names=[];this.reified=null};f.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");f.prototype.isTopic=function(){return true};f.prototype.getTopicMap=function(){return this.parnt};f.prototype.addSubjectIdentifier=
+function(a){if(!a)throw{name:"ModelConstraintException",message:"addSubjectIdentifier() needs subject identifier"};for(var b=0;b<this.subjectIdentifiers.length;b+=1)if(this.subjectIdentifiers[b].getReference()===a.getReference())return;this.subjectIdentifiers.push(a);this.parnt._si2topic.put(a.getReference(),this);return this};f.prototype.addSubjectLocator=function(a){if(!a)throw{name:"ModelConstraintException",message:"addSubjectLocator() needs subject locator"};for(var b=0;b<this.subjectLocators.length;b+=
+1)if(this.subjectLocators[b].getReference()===a.getReference())return;this.subjectLocators.push(a);this.parnt._sl2topic.put(a.getReference(),this);return this};f.prototype.addType=function(a){if(!a)throw{name:"ModelConstraintException",message:"addType() needs type"};z.assertBelongsTo(this.parnt,a);this.parnt.addTypeEvent.fire(this,{type:a});this.types.push(a);return this};f.prototype.createName=function(a,b,c){b&&z.assertBelongsTo(this.parnt,b);c&&z.assertBelongsTo(this.parnt,c);if(typeof c==="undefined")c=
+null;a=new x(this,a,b);J(a,c);this.names.push(a);return a};f.prototype.createOccurrence=function(a,b,c,d){z.assertBelongsTo(this.parnt,a);z.assertBelongsTo(this.parnt,d);c=new B(this,a,b,c);this.parnt.addOccurrenceEvent.fire(c,{type:a,value:b});J(c,d);this.occurrences.push(c);return c};f.prototype.getNames=function(a){var b=[],c;for(c=0;c<this.names.length;c+=1)if(a&&this.names[c].getType().equals(a))b.push(this.names[c]);else a||b.push(this.names[c]);return b};f.prototype.getOccurrences=function(a){var b=
+[],c;if(a===null)throw{name:"IllegalArgumentException",message:"Topic.getOccurrences cannot be called without type"};for(c=0;c<this.occurrences.length;c+=1)if(a&&this.occurrences[c].getType().equals(a))b.push(this.occurrences[c]);else a||b.push(this.occurrences[c]);return b};f.prototype._removeOccurrence=function(a){for(var b=0;b<this.occurrences.length;b+=1)if(this.occurrences[b].equals(a)){this.occurrences.splice(b,1);break}this.getTopicMap()._removeOccurrence(a)};f.prototype.getReified=function(){return this.reified};
+f.prototype._setReified=function(a){this.reified=a};f.prototype.getRolesPlayed=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"Topic.getRolesPlayed cannot be called without type"};if(b===null)throw{name:"IllegalArgumentException",message:"Topic.getRolesPlayed cannot be called with assocType===null"};var c=[],d;for(d=0;d<this.rolesPlayed.length;d+=1)if(a){if(this.rolesPlayed[d].getType().equals(a))if(b&&this.rolesPlayed[d].getParent().getType().equals(b)||!b)c.push(this.rolesPlayed[d])}else c.push(this.rolesPlayed[d]);
+return c};f.prototype.addRolePlayed=function(a){this.rolesPlayed.push(a)};f.prototype.removeRolePlayed=function(a){for(var b=0;b<this.rolesPlayed.length;b+=1)this.rolesPlayed[b].id===a.id&&this.rolesPlayed.splice(b,1)};f.prototype.getSubjectIdentifiers=function(){return this.subjectIdentifiers};f.prototype.getSubjectLocators=function(){return this.subjectLocators};f.prototype.getTypes=function(){return this.types};f.prototype.mergeIn=function(a){var b,c,d,j,k;if(this.equals(a))return true;z.assertBelongsTo(this.getTopicMap(),
+a);if(this.getReified()&&a.getReified()&&!this.getReified().equals(a.getReified()))throw{name:"ModelConstraintException",message:"The topics reify different Topic Maps constructs and cannot be merged!"};if(!this.getReified()&&a.getReified()){d=a.getReified();d.setReifier(this)}b=this.parnt.typeInstanceIndex;q.moveTypes(b.getOccurrences(a),this);q.moveTypes(b.getNames(a),this);q.moveTypes(b.getAssociations(a),this);q.moveTypes(b.getRoles(a),this);b=b.getTopics(a);for(c=0;c<b.length;c+=1){b[c].removeType(a);
+b[c].addType(this)}b=this.parnt.scopedIndex;q.moveThemes(b.getAssociations(a),a,this);q.moveThemes(b.getOccurrences(a),a,this);q.moveThemes(b.getNames(a),a,this);q.moveThemes(b.getVariants(a),a,this);q.moveItemIdentifiers(a,this);for(b=a.getSubjectLocators();b.length;){d=b[b.length-1];a.removeSubjectLocator(d);this.addSubjectLocator(d)}for(b=a.getSubjectIdentifiers();b.length;){d=b[b.length-1];a.removeSubjectIdentifier(d);this.addSubjectIdentifier(d)}for(b=a.getTypes();b.length;){d=b[b.length-1];
+a.removeType(d);this.addType(d)}b=this.getRolesPlayed();k={};for(c=0;c<b.length;c+=1){j=b[c].getParent();k[s.makeAssociationSignature(j)]=j}b=a.getRolesPlayed();for(c=0;c<b.length;c+=1){d=b[c];d.setPlayer(this);if(j=k[s.makeAssociationSignature(d.getParent())]){q.moveItemIdentifiers(d.getParent(),j);q.moveReifier(d.getParent(),j);d.getParent().remove()}}b=this.getNames();k={};for(c=0;c<b.length;c+=1)k[s.makeNameSignature(b[c])]=b[c];b=a.getNames();for(c=0;c<b.length;c+=1){d=b[c];if(j=k[s.makeNameSignature(b[c])]){q.moveItemIdentifiers(d,
+j);q.moveReifier(d,j);q.moveVariants(d,j);d.remove()}else{j=this.createName(d.getValue(),d.getType(),d.getScope());q.moveVariants(d,j)}}b=this.getOccurrences();k={};for(c=0;c<b.length;c+=1)k[s.makeOccurrenceSignature(b[c])]=b[c];b=a.getOccurrences();for(c=0;c<b.length;c+=1){d=b[c];if(j=k[s.makeOccurrenceSignature(b[c])]){q.moveItemIdentifiers(d,j);q.moveReifier(d,j);d.remove()}else{j=this.createOccurrence(d.getType(),d.getValue(),d.getDatatype(),d.getScope());q.moveReifier(d,j)}}a.remove();return this};
+f.prototype.remove=function(){var a=this.parnt.typeInstanceIndex,b=this.parnt.scopedIndex;if(this.getReified()||a.getOccurrences(this).length||a.getNames(this).length||a.getAssociations(this).length||a.getRoles(this).length||a.getTopics(this).length||b.getAssociations(this).length||b.getOccurrences(this).length||b.getNames(this).length||b.getVariants(this).length||this.getRolesPlayed().length)throw{name:"TopicInUseException",message:"",reporter:this};this.parnt._removeTopic(this);this.parnt._id2construct.remove(this.id);
+this.parnt.removeTopicEvent.fire(this);this.id=null;return this.parnt};f.prototype.removeSubjectIdentifier=function(a){for(var b=0;b<this.subjectIdentifiers.length;b+=1)if(this.subjectIdentifiers[b].getReference()===a.getReference()){this.subjectIdentifiers.splice(b,1);break}this.parnt._sl2topic.remove(a.getReference());return this};f.prototype.removeSubjectLocator=function(a){for(var b=0;b<this.subjectLocators.length;b+=1)if(this.subjectLocators[b].getReference()===a.getReference()){this.subjectLocators.splice(b,
+1);break}this.parnt._sl2topic.remove(a.getReference());return this};f.prototype.removeType=function(a){for(var b=0;b<this.types.length;b+=1)if(this.types[b].equals(a)){this.types.splice(b,1);this.parnt.removeTypeEvent.fire(this,{type:a});break}};f.prototype._removeName=function(a){for(var b=0;b<this.names.length;b+=1)if(this.names[b].equals(a)){this.names.splice(b,1);break}this.getTopicMap()._removeName(a)};B=function(a,b,c,d){this.itemIdentifiers=[];this.parnt=a;this.type=b;this.value=c;this.datatype=
+d?d:this.getTopicMap().createLocator(C.string);this.scope=[];this.reifier=null;this.id=this.getTopicMap()._getConstructId();this.getTopicMap()._id2construct.put(this.id,this)};B.swiss(o,"getType","setType");B.swiss(u,"decimalValue","floatValue","getDatatype","getValue","integerValue","locatorValue","longValue","setValue");B.swiss(t,"getReifier","setReifier");B.swiss(l,"addTheme","getScope","removeTheme");B.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap",
+"hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");B.prototype.isOccurrence=function(){return true};B.prototype.getTopicMap=function(){return this.parnt.getParent()};B.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=1)this.parnt.parnt.removeThemeEvent.fire(this,{theme:this.scope[a]});this.parnt.parnt.removeOccurrenceEvent.fire(this);this.parnt._removeOccurrence(this);this.id=null;return this.parnt};x=function(a,
+b,c){this.itemIdentifiers=[];this.parnt=a;this.value=b;this.scope=[];this.id=this.getTopicMap()._getConstructId();this.type=c||a.parnt.createTopicBySubjectIdentifier(a.parnt.createLocator("http://psi.topicmaps.org/iso13250/model/topic-name"));this.reifier=null;this.variants=[];this.getTopicMap()._id2construct.put(this.id,this);this.parnt.parnt.addNameEvent.fire(this,{type:this.type,value:b})};x.swiss(o,"getType","setType");x.swiss(t,"getReifier","setReifier");x.swiss(l,"addTheme","getScope","removeTheme");
+x.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");x.prototype.isName=function(){return true};x.prototype.getTopicMap=function(){return this.parnt.parnt};x.prototype.createVariant=function(a,b,c){if(typeof c==="undefined"||c===null)throw{name:"ModelConstraintException",message:"Creation of a variant with a null scope is not allowed"};
+a=new A(this,a,b);J(a,c);for(c=0;c<this.scope.length;c+=1)this.getTopicMap().addThemeEvent.fire(a,{theme:this.scope[c]});this.variants.push(a);return a};x.prototype.setValue=function(a){if(!a)throw{name:"ModelConstraintException",message:"Name.setValue(null) is not allowed"};this.value=a;return this};x.prototype.getValue=function(){return this.value};x.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=1)this.parnt.parnt.removeThemeEvent.fire(this,{theme:this.scope[a]});this.parnt.parnt.removeNameEvent.fire(this);
+this.parnt._removeName(this);this.id=null;return this.parnt};x.prototype._removeVariant=function(a){for(var b=0;b<this.variants.length;b+=1)if(this.variants[b].equals(a)){this.variants.splice(b,1);break}this.getTopicMap()._removeVariant(a)};x.prototype.getVariants=function(){return this.variants};A=function(a,b,c){if(b===null)throw{name:"ModelConstraintException",message:"Creation of a variant with null value is not allowed"};if(c===null)throw{name:"ModelConstraintException",message:"Creation of a variant with datatype == null is not allowed"};
+this.itemIdentifiers=[];this.scope=[];this.parnt=a;this.datatype=typeof b==="object"&&b instanceof g?this.getTopicMap().createLocator("http://www.w3.org/2001/XMLSchema#anyURI"):this.getTopicMap().createLocator(C.string);this.datatype=c;this.reifier=null;this.value=b;this.id=this.getTopicMap()._getConstructId();this.getTopicMap()._id2construct.put(this.id,this)};A.swiss(t,"getReifier","setReifier");A.swiss(l,"addTheme","getScope","removeTheme");A.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers",
+"getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");A.swiss(u,"decimalValue","floatValue","getDatatype","getValue","integerValue","locatorValue","longValue","setValue");A.prototype.isVariant=function(){return true};A.prototype.getTopicMap=function(){return this.getParent().getParent().getParent()};A.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=1)this.getTopicMap().removeThemeEvent.fire(this,
+{theme:this.scope[a]});this.getParent()._removeVariant(this);this.id=null;return this.parnt};D=function(a,b,c){this.itemIdentifiers=[];this.parnt=a;this.type=b;this.player=c;this.id=this.getTopicMap()._getConstructId();this.reifier=null;this.getTopicMap()._id2construct.put(this.id,this)};D.swiss(o,"getType","setType");D.swiss(t,"getReifier","setReifier");D.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic",
+"isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");D.prototype.isRole=function(){return true};D.prototype.getTopicMap=function(){return this.getParent().getParent()};D.prototype.remove=function(){var a=this.parnt;this.parnt.parnt.removeRoleEvent.fire(this);this.parnt._removeRole(this);this.id=this.reifier=this.player=this.type=this.parnt=this.itemIdentifiers=null;return a};D.prototype.getPlayer=function(){return this.player};D.prototype.setPlayer=function(a){if(!a)throw{name:"ModelConstraintException",
+message:"player i Role.setPlayer cannot be null"};z.assertBelongsTo(this.parnt.parnt,a);if(!this.player.equals(a)){this.player.removeRolePlayed(this);a.addRolePlayed(this);this.player=a;return this}};i=function(a){this.itemIdentifiers=[];this.parnt=a;this.id=this.getTopicMap()._getConstructId();this.getTopicMap()._id2construct.put(this.id,this);this.roles=[];this.scope=[];this.reifier=this.type=null};i.swiss(o,"getType","setType");i.swiss(t,"getReifier","setReifier");i.swiss(l,"addTheme","getScope",
+"removeTheme");i.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");i.prototype.isAssociation=function(){return true};i.prototype.getTopicMap=function(){return this.parnt};i.prototype.createRole=function(a,b){if(!a)throw{name:"ModelConstraintException",message:"type i Role.createPlayer cannot be null"};if(!b)throw{name:"ModelConstraintException",
+message:"player i Role.createRole cannot be null"};z.assertBelongsTo(this.parnt,a);z.assertBelongsTo(this.parnt,b);var c=new D(this,a,b);b.addRolePlayed(c);this.roles.push(c);this.parnt.addRoleEvent.fire(c,{type:a,player:b});return c};i.prototype._removeRole=function(a){for(var b=0;b<this.roles.length;b+=1)if(a.id===this.roles[b].id){this.roles.splice(b,1);break}a.getPlayer().removeRolePlayed(a);this.getTopicMap()._removeRole(a)};i.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=
+1)this.parnt.removeThemeEvent.fire(this,{theme:this.scope[a]});for(this.parnt.removeAssociationEvent.fire(this);this.roles.length;)this.roles[0].remove();this.roles=this.id=null;this.parnt._removeAssociation(this);this.getTopicMap()._ii2construct.remove(this.id);this.reifier=this.type=this.scope=this.item_identifiers=null;return this.parnt};i.prototype.getRoles=function(a){if(a===null)throw{name:"IllegalArgumentException",message:"Topic.getRoles cannot be called with type null"};if(!a)return this.roles;
+var b=[],c;for(c=0;c<this.roles.length;c+=1)this.roles[c].getType().equals(a)&&b.push(this.roles[c]);return b};i.prototype.getRoleTypes=function(){var a={},b=[],c,d;for(c=0;c<this.roles.length;c+=1)a[this.roles[c].getType().getId()]=this.roles[c].getType();for(d in a)a.hasOwnProperty(d)&&b.push(a[d]);return b};l=function(){this.opened=false};l.prototype.close=function(){};l.prototype.isAutoUpdated=function(){return true};l.prototype.isOpen=function(){return this.opened};l.prototype.open=function(){this.opened=
+true};l.prototype.reindex=function(){};y=function(a){var b,c=this;this.tm=a;this.type2topics=new n;this.type2associations=new n;this.type2roles=new n;this.type2occurrences=new n;this.type2names=new n;this.type2variants=new n;this.opened=false;b=function(d,j,k){var r;switch(d){case e.ADD_ASSOCIATION:break;case e.ADD_NAME:d=c.type2names.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2names.put(k.type.getId(),d);break;case e.ADD_OCCURRENCE:d=c.type2occurrences.get(k.type.getId());
+if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2occurrences.put(k.type.getId(),d);break;case e.ADD_ROLE:d=c.type2roles.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2roles.put(k.type.getId(),d);break;case e.ADD_TOPIC:d=c.type2topics.get("null");if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2topics.put("null",d);break;case e.ADD_TYPE:if((d=c.type2topics.get("null"))&&d.get(j.getId())){d.remove(j.getId());c.type2topics.put("null",d)}d=c.type2topics.get(k.type.getId());
+if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2topics.put(k.type.getId(),d);break;case e.REMOVE_ASSOCIATION:k=j.getType();if(!k)break;d=c.type2associations.get(k.getId());for(r=0;r<d.length;r+=1)if(d[r].equals(j)){d.splice(r,1);break}d.length>0?c.type2associations.put(k.getId(),d):c.type2associations.remove(k.getId());break;case e.REMOVE_NAME:k=j.getType();d=c.type2names.get(k.getId());d.remove(j.getId());d.length>0?c.type2names.put(k.getId(),d):c.type2names.remove(k.getId());break;case e.REMOVE_OCCURRENCE:k=
+j.getType();d=c.type2occurrences.get(k.getId());d.remove(j.getId());d.length>0?c.type2occurrences.put(k.getId(),d):c.type2occurrences.remove(k.getId());break;case e.REMOVE_ROLE:k=j.getType();d=c.type2roles.get(k.getId());d.remove(j.getId());d.length>0?c.type2roles.put(k.getId(),d):c.type2roles.remove(k.getId());break;case e.REMOVE_TOPIC:k=j.getTypes();for(r=0;r<k.length;r+=1){d=c.type2topics.get(k[r].getId());d.remove(j.getId());d.size()||c.type2topics.remove(k[r].getId())}c.type2topics.remove(j.getId());
+c.type2associations.remove(j.getId());c.type2roles.remove(j.getId());c.type2occurrences.remove(j.getId());c.type2variants.remove(j.getId());break;case e.REMOVE_TYPE:d=c.type2topics.get(k.type.getId());d.remove(j.getId());d.size()||c.type2topics.remove(k.type.getId());if(j.getTypes().length===0){d=c.type2topics.get("null");if(typeof d==="undefined")d=new n;d.put(j.getId(),j)}break;case e.SET_TYPE:if(j.isAssociation()){if(k.old){d=c.type2associations.get(k.old.getId());for(r=0;r<d.length;r+=1)if(d[r].equals(j)){d.splice(r,
+1);break}d.length>0?c.type2associations.put(k.old.getId(),d):c.type2associations.remove(k.old.getId())}d=c.type2associations.get(k.type.getId());if(typeof d==="undefined")d=[];d.push(j);c.type2associations.put(k.type.getId(),d)}else if(j.isName()){if(d=c.type2names.get(k.old.getId())){d.remove(j.getId());d.length>0?c.type2names.put(k.old.getId(),d):c.type2names.remove(k.old.getId())}d=c.type2names.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2names.put(k.type.getId(),
+d)}else if(j.isOccurrence()){if(d=c.type2occurrences.get(k.old.getId())){d.remove(j.getId());d.length>0?c.type2occurrences.put(k.old.getId(),d):c.type2occurrences.remove(k.old.getId())}d=c.type2occurrences.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2occurrences.put(k.type.getId(),d)}else if(j.isRole()){if(d=c.type2roles.get(k.old.getId())){d.remove(j.getId());d.length>0?c.type2roles.put(k.old.getId(),d):c.type2roles.remove(k.old.getId())}d=c.type2roles.get(k.type.getId());
+if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2roles.put(k.type.getId(),d)}break}};a.addAssociationEvent.registerHandler(b);a.addNameEvent.registerHandler(b);a.addOccurrenceEvent.registerHandler(b);a.addRoleEvent.registerHandler(b);a.addTopicEvent.registerHandler(b);a.addTypeEvent.registerHandler(b);a.removeAssociationEvent.registerHandler(b);a.removeNameEvent.registerHandler(b);a.removeOccurrenceEvent.registerHandler(b);a.removeRoleEvent.registerHandler(b);a.removeTopicEvent.registerHandler(b);
+a.removeTypeEvent.registerHandler(b);a.setTypeEvent.registerHandler(b)};y.swiss(l,"close","isAutoUpdated","isOpen","open","reindex");y.prototype.getAssociations=function(a){a=this.type2associations.get(a.getId());if(!a)return[];return a};y.prototype.getAssociationTypes=function(){var a=[],b=this.type2associations.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getNames=function(a){a=this.type2names.get(a.getId());if(!a)return[];return a.values()};y.prototype.getNameTypes=
+function(){var a=[],b=this.type2names.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getOccurrences=function(a){a=this.type2occurrences.get(a.getId());if(!a)return[];return a.values()};y.prototype.getOccurrenceTypes=function(){var a=[],b=this.type2occurrences.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getRoles=function(a){a=this.type2roles.get(a.getId());if(!a)return[];return a.values()};y.prototype.getRoleTypes=
+function(){var a=[],b=this.type2roles.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getTopics=function(a){a=this.type2topics.get(a?a.getId():"null");if(!a)return[];return a.values()};y.prototype.getTopicsByTypes=function(a,b){var c,d;c=E.getForKeys(this.type2topics,a);if(!b)return c;for(b=0;b<c.length;b+=1)for(d=0;d<a.length;d+=1)if(!O.contains(c[b].getTypes(),a[d])){c.splice(b,1);b-=1;break}return c};y.prototype.getTopicTypes=function(){var a=[],b=
+this.type2topics.keys(),c;for(c=0;c<b.length;c+=1)b[c]!=="null"&&a.push(this.tm.getConstructById(b[c]));return a};y.prototype.close=function(){};w=function(a){var b=this,c;this.tm=a;this.theme2associations=new n;this.theme2names=new n;this.theme2occurrences=new n;this.theme2variants=new n;c=function(d,j,k){var r,I,M,K,L;L=function(F,G,N){I=N.theme?N.theme.getId():"null";if(G.getScope().length===1)if((M=F.get("null"))&&M.get(G.getId())){M.remove(G.getId());F.put("null",M)}r=F.get(I);if(typeof r===
+"undefined")r=new n;r.put(G.getId(),G);F.put(I,r)};K=function(F,G,N){I=N.theme.getId();r=F.get(I);if(typeof r!=="undefined"){r.remove(G.getId());r.size()||F.remove(I)}};switch(d){case e.ADD_THEME:if(j.isAssociation())L(b.theme2associations,j,k);else if(j.isName())L(b.theme2names,j,k);else if(j.isOccurrence())L(b.theme2occurrences,j,k);else j.isVariant()&&L(b.theme2variants,j,k);break;case e.REMOVE_THEME:if(j.isAssociation())K(b.theme2associations,j,k);else if(j.isName())K(b.theme2names,j,k);else if(j.isOccurrence())K(b.theme2occurrences,
+j,k);else j.isVariant()&&K(b.theme2variants,j,k);break}};a.addThemeEvent.registerHandler(c);a.removeThemeEvent.registerHandler(c)};w.swiss(l,"close","isAutoUpdated","isOpen","open","reindex");w.prototype.close=function(){};w.prototype.getAssociations=function(a){a=this.theme2associations.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getAssociationsByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getAssociationsByThemes cannot be called without themes"};
+return E.getConstructsByThemes(this.theme2associations,a,b)};w.prototype.getAssociationThemes=function(){return E.getConstructThemes(this.tm,this.theme2associations)};w.prototype.getNames=function(a){a=this.theme2names.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getNamesByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getNamesByThemes cannot be called without themes"};return E.getConstructsByThemes(this.theme2names,a,b)};w.prototype.getNameThemes=
+function(){return E.getConstructThemes(this.tm,this.theme2names)};w.prototype.getOccurrences=function(a){a=this.theme2occurrences.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getOccurrencesByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getOccurrencesByThemes cannot be called without themes"};return E.getConstructsByThemes(this.theme2occurrences,a,b)};w.prototype.getOccurrenceThemes=function(){return E.getConstructThemes(this.tm,
+this.theme2occurrences)};w.prototype.getVariants=function(a){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getVariants cannot be called without themes"};a=this.theme2variants.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getVariantsByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getVariantsByThemes cannot be called without themes"};return E.getConstructsByThemes(this.theme2variants,a,b)};w.prototype.getVariantThemes=
+function(){return E.getConstructThemes(this.tm,this.theme2variants)};z={assertBelongsTo:function(a,b){var c;if(!b)return false;if(b&&b instanceof f&&!a.equals(b.getTopicMap()))throw{name:"ModelConstraintException",message:"scope topic belongs to different topic map"};if(b&&b instanceof Array)for(c=0;c<b.length;c+=1)if(!a.equals(b[c].getTopicMap()))throw{name:"ModelConstraintException",message:"scope topic belong to different topic maps"};return true}};E={getForKeys:function(a,b){var c,d,j=new n,k,
+r;for(c=0;c<b.length;c+=1)if(k=a.get(b[c].getId())){r=k.keys();for(d=0;d<r.length;d+=1)j.put(k.get(r[d]).getId(),k.get(r[d]))}return j.values()},getConstructThemes:function(a,b){var c=[];b=b.keys();var d;for(d=0;d<b.length;d+=1)b[d]!=="null"&&c.push(a.getConstructById(b[d]));return c},getConstructsByThemes:function(a,b,c){var d;a=E.getForKeys(a,b);if(!c)return a;for(c=0;c<a.length;c+=1)for(d=0;d<b.length;d+=1)if(!O.contains(a[c].getScope(),b[d])){a.splice(c,1);c-=1;break}return a}};O={contains:function(a,
+b){for(var c in a)if(a.hasOwnProperty(c))if(a[c].equals(b))return true;return false}};J=function(a,b){var c;if(b&&typeof b==="object")if(b instanceof Array)for(c=0;c<b.length;c+=1)a.addTheme(b[c]);else b instanceof f&&a.addTheme(b);else a.getTopicMap().addThemeEvent.fire(a,{theme:null})};s={makeNameValueSignature:function(a){return a.getValue()},makeNameSignature:function(a){return s.makeNameValueSignature(a)+"#"+s.makeTypeSignature(a)+"#"+s.makeScopeSignature(a)},makeOccurrenceSignature:function(a){return s.makeOccurrenceValueSignature(a)+
+"#"+s.makeTypeSignature(a)+"#"+s.makeScopeSignature(a)},makeOccurrenceValueSignature:function(a){return"#"+a.getValue()+"#"+(a.getDatatype()?a.getDatatype().getReference():"null")},makeTypeSignature:function(a){return(a=a.getType())?a.getId():""},makeScopeSignature:function(a){var b,c=[];for(b=0;b<a.length;b+=1)c.push(a[b].getId());c.sort();return c.join("#")},makeAssociationSignature:function(a){var b,c,d=[];b=a.getRoles();for(c=0;c<b.length;c+=1)d.push(s.makeRoleSignature(b[c]));d.sort();return"#"+
+s.makeTypeSignature(a)+"#"+d.join("#")+s.makeScopeSignature(a)},makeRoleSignature:function(a){return s.makeTypeSignature(a)+"#"+a.getPlayer().getId()},makeVariantValueSignature:function(a){return"#"+a.getValue()+"#"+a.getDatatype().getReference()},makeVariantSignature:function(a){return s.makeVariantValueSignature(a)+"#"+s.makeScopeSignature(a)}};H={removeTopicMapDuplicates:function(a){var b,c,d=new n,j;c=a.getTopics();for(b=0;b<c.length;b+=1){H.removeOccurrencesDuplicates(c[b].getOccurrences());
+H.removeNamesDuplicates(c[b].getNames())}a=a.getAssociations();for(b=0;b<a.length;b+=1){H.removeAssociationDuplicates(a[b]);c=s.makeAssociationSignature(a[b]);if(j=d.get(c)){q.moveConstructCharacteristics(a[b],j);q.moveRoleCharacteristics(a[b],j);a[b].remove()}else d.put(c,a[b])}d.empty()},removeOccurrencesDuplicates:function(a){var b,c=new n,d,j,k;for(b=0;b<a.length;b+=1){d=a[b];j=s.makeOccurrenceSignature(d);if(k=c.get(j)){q.moveConstructCharacteristics(d,k);d.remove()}else c.put(j,d)}c.empty()},
+removeNamesDuplicates:function(a){var b,c=new n,d,j,k;for(b=0;b<a.length;b+=1){d=a[b];H.removeVariantsDuplicates(d.getVariants());j=s.makeNameSignature(d);if(k=c.get(j)){q.moveConstructCharacteristics(d,k);q.moveVariants(d,k);d.remove()}else c.put(j,d)}c.empty()},removeVariantsDuplicates:function(a){var b,c=new n,d,j,k;for(b=0;b<a.length;b+=1){d=a[b];j=s.makeVariantSignature(d);if(k=c.get(j)){q.moveConstructCharacteristics(d,k);d.remove()}else c.put(j,d)}c.empty()},removeAssociationDuplicates:function(a){var b=
+a.getRoles(),c=new n,d,j;for(a=0;a<b.length;a+=1){d=s.makeRoleSignature(b[a]);if(j=c.get(d)){q.moveConstructCharacteristics(b[a],j);b[a].remove()}else c.put(d,b[a])}}};q={moveTypes:function(a,b){var c;for(c=0;c<a.length;c+=1)a[c].setType(b)},moveThemes:function(a,b,c){for(var d=0;d<a.length;d+=1){a[d].removeTheme(b);a[d].addTheme(c)}},moveItemIdentifiers:function(a,b){var c,d;for(c=a.getItemIdentifiers();c.length;){d=c[c.length-1];a.removeItemIdentifier(d);b.addItemIdentifier(d)}},moveVariants:function(a,
+b){var c,d,j,k;c=b.getVariants();k={};for(d=0;d<c.length;d+=1)k[s.makeVariantSignature(c[d])]=c[d];c=a.getVariants();for(d=0;d<c.length;d+=1){a=c[d];if(j=k[s.makeVariantSignature(c[d])]){q.moveItemIdentifiers(a,j);q.moveReifier(a,j);a.remove()}else b.createVariant(a.getValue(),a.getDatatype(),a.getScope())}},moveReifier:function(a,b){var c;if(a.getReifier()!==null)if(b.getReifier()===null)b.setReifier(a.getReifier());else{c=a.getReifier();b=b.getReifier();a.setReifier(null);c.mergeIn(b)}},moveRoleCharacteristics:function(a,
+b){var c,d=new n;c=b.getRoles();for(b=0;b<c.length;b+=1)d.put(c[b],s.makeRoleSignature(c[b]));c=a.getRoles();for(b=0;b<c.length;b+=1){q.moveItemIdentifiers(c[b],d.get(s.makeRoleSignature(c[b])));c[b].remove()}},moveConstructCharacteristics:function(a,b){q.moveReifier(a,b);q.moveItemIdentifiers(a,b)}};P={convertAssociationsToType:function(a){var b,c,d,j,k;b=a.getTopicBySubjectIdentifier(a.createLocator(h.TYPE_INSTANCE));c=a.getTopicBySubjectIdentifier(a.createLocator(h.TYPE));d=a.getTopicBySubjectIdentifier(a.createLocator(h.INSTANCE));
+if(!(!b||!c||!d))if(a=a.getIndex("TypeInstanceIndex")){a.isAutoUpdated()||a.reindex();b=a.getAssociations(b);for(a=0;a<b.length;a+=1){j=b[a];if(!(j.getScope().length>0||j.getReifier()!==null||j.getItemIdentifiers().length>0)){k=j.getRoles();if(k.length===2){if(k[0].getType().equals(c)&&k[1].getType().equals(d))k[1].getPlayer().addType(k[0].getPlayer());else if(k[1].getType().equals(c)&&k[0].getType().equals(d))k[0].getPlayer().addType(k[1].getPlayer());else continue;j.remove()}}}}}};return{TopicMapSystemFactory:TopicMapSystemFactory,
+XSD:C,TMDM:h,Hash:n,Version:"0.4.0"}}();TopicMapSystemFactory=TM.TopicMapSystemFactory;if(typeof exports==="object"&&exports!==null){exports.TopicMapSystemFactory=TopicMapSystemFactory;exports.TM=TM}
+TM.JTM=function(){var n,C;n=function(h){var g=this;this.tm=h;this.version=null;this.prefixes={};this.defaultDatatype=this.tm.createLocator(TM.XSD.string);this.curieToLocator=function(e){var f,i;if(g.version==="1.1"&&e.substr(0,1)==="["){if(e.substr(e.length-1,1)!=="]")throw{name:"InvalidFormat",message:"Invaild CURIE: missing tailing bracket"};e=e.substr(1,e.length-2);i=e.indexOf(":");if(i!==-1){f=e.substr(0,i);if(g.prefixes[f])return e=g.prefixes[f]+e.substr(i+1,e.length-1);else throw{name:"InvalidFormat",
+message:"Missing prefix declaration: "+f};}else throw{name:"InvalidFormat",message:"Invaild CURIE: missing colon"};}return e};this.getTopicByReference=function(e){if(typeof e==="undefined"||e===null)return null;switch(e.substr(0,3)){case "si:":return this.tm.createTopicBySubjectIdentifier(this.tm.createLocator(this.curieToLocator(e.substr(3))));case "sl:":return this.tm.createTopicBySubjectLocator(this.tm.createLocator(this.curieToLocator(e.substr(3))));case "ii:":return this.tm.createTopicByItemIdentifier(this.tm.createLocator(this.curieToLocator(e.substr(3))))}throw{name:"InvalidFormat",
+message:"Invaild topic reference '"+e+"'"};}};n.prototype.fromString=function(h){return this.fromObject(JSON.parse(h))};n.prototype.fromObject=function(h,g){g=g||null;if(h.version!=="1.0"&&h.version!=="1.1")throw{name:"InvalidFormat",message:"Unknown version of JTM: "+h.version};this.version=h.version;if(h.version==="1.1"&&h.prefixes){if((this.prefixes=h.prefixes)&&h.prefixes.xsd&&h.prefixes.xsd!=="http://www.w3.org/2001/XMLSchema#")throw{name:"InvalidFormat",message:'The XSD prefix MUST have the value "http://www.w3.org/2001/XMLSchema#"'};
+}else if(h.prefixes)throw{name:"InvalidFormat",message:"Prefixes are invalid in JTM 1.0: "+h.version};if(!this.prefixes.xsd)this.prefixes.xsd="http://www.w3.org/2001/XMLSchema#";if(!h.item_type)throw{name:"InvalidFormat",message:"Missing item_type"};switch(h.item_type.toLowerCase()){case "topicmap":h=this.parseTopicMap(h);break;case "topic":h=this.parseTopic(h);break;case "name":h=this.parseName(g,h);break;case "variant":h=this.parseVariant(g,h);break;case "occurrence":h=this.parseOccurrence(g,h);
+break;case "association":h=this.parseAssociation(h);break;case "role":h=this.parseRole(g,h);break;default:throw{name:"InvalidFormat",message:"Unknown item_type property"};}return h};n.prototype.parseParentAsTopic=function(h){var g=null,e,f;if(h.parent){if(!(h.parent instanceof Array)||h.parent.length===0)throw{name:"InvalidFormat",message:"Missing parent topic reference in occurrence"};}else g=this.tm.createTopic();if(h.parent)for(f=0;f<h.parent.length;f+=1){e=this.getTopicByReference(h.parent[f]);
+if(g)g.mergeIn(e);else g=e}return g};n.prototype.parseTopicMap=function(h){var g,e,f;this.parseItemIdentifiers(this.tm,h.item_identifiers);this.parseReifier(this.tm,h.reifier);if(h.topics&&typeof h.topics==="object"&&h.topics instanceof Array){f=h.topics;e=f.length;for(g=0;g<e;g+=1)this.parseTopic(f[g])}if(h.associations&&typeof h.associations==="object"&&h.associations instanceof Array){f=h.associations;e=f.length;for(g=0;g<e;g+=1)this.parseAssociation(f[g])}this.tm.sanitize();return true};n.prototype.parseTopic=
+function(h){var g=this,e=null,f,i,l,m;f=function(o,t,u,p,D,x){var A,B,v;if(u&&typeof u==="object"&&u instanceof Array){B=u.length;for(A=0;A<B;A+=1){l=decodeURI(g.curieToLocator(u[A]));if(t)if((v=p.apply(o,[o.createLocator(l)]))&&v.isTopic()&&!t.equals(v))t.mergeIn(v);else v&&v.isTopic()&&t.equals(v)||t[x](o.createLocator(l));else t=D.apply(o,[o.createLocator(l)])}}return t};e=f(this.tm,e,h.subject_identifiers,this.tm.getTopicBySubjectIdentifier,this.tm.createTopicBySubjectIdentifier,"addSubjectIdentifier");
+e=f(this.tm,e,h.subject_locators,this.tm.getTopicBySubjectLocator,this.tm.createTopicBySubjectLocator,"addSubjectLocator");e=f(this.tm,e,h.item_identifiers,this.tm.getConstructByItemIdentifier,this.tm.createTopicByItemIdentifier,"addItemIdentifier");if((f=h.instance_of)&&this.version==="1.1")for(i=0;i<f.length;i+=1){m=this.getTopicByReference(f[i]);e.addType(m)}else if(h.instance_of&&this.version==="1.0")throw{name:"InvalidFormat",message:"instance_of is invalid in JTM 1.0"};if((f=h.names)&&typeof f===
+"object"&&f instanceof Array)for(i=0;i<f.length;i+=1)this.parseName(e,f[i]);if((f=h.occurrences)&&typeof f==="object"&&f instanceof Array)for(i=0;i<f.length;i+=1)this.parseOccurrence(e,f[i])};n.prototype.parseName=function(h,g){var e,f;h||(h=this.parseParentAsTopic(g));f=this.parseScope(g.scope);e=this.getTopicByReference(g.type);h=h.createName(g.value,e,f);if((e=g.variants)&&typeof e==="object"&&e instanceof Array)for(f=0;f<e.length;f+=1)this.parseVariant(h,e[f]);this.parseItemIdentifiers(h,g.item_identifiers);
+this.parseReifier(h,g.reifier)};n.prototype.parseVariant=function(h,g){var e;e=this.parseScope(g.scope);h=h.createVariant(g.value,g.datatype?this.tm.createLocator(this.curieToLocator(g.datatype)):this.defaultDatatype,e);this.parseItemIdentifiers(h,g.item_identifiers);this.parseReifier(h,g.reifier)};n.prototype.parseOccurrence=function(h,g){var e,f;h||(h=this.parseParentAsTopic(g));f=this.parseScope(g.scope);e=this.getTopicByReference(g.type);h=h.createOccurrence(e,g.value,g.datatype?this.tm.createLocator(this.curieToLocator(g.datatype)):
+this.defaultDatatype,f);this.parseItemIdentifiers(h,g.item_identifiers);this.parseReifier(h,g.reifier)};n.prototype.parseAssociation=function(h){var g,e,f;g=this.parseScope(h.scope);g=this.tm.createAssociation(this.getTopicByReference(h.type),g);if((e=h.roles)&&typeof e==="object"&&e instanceof Array){if(e.length===0)throw{name:"InvalidFormat",message:"Association needs roles"};for(f=0;f<e.length;f+=1)this.parseRole(g,e[f])}else throw{name:"InvalidFormat",message:"Association needs roles"};this.parseItemIdentifiers(g,
+h.item_identifiers);this.parseReifier(g,h.reifier)};n.prototype.parseRole=function(h,g){var e,f;e=this.getTopicByReference(g.type);f=this.getTopicByReference(g.player);h=h.createRole(e,f);this.parseItemIdentifiers(h,g.item_identifiers);this.parseReifier(h,g.reifier)};n.prototype.parseScope=function(h){var g,e=[];if(h&&typeof h==="object"&&h instanceof Array)for(g=0;g<h.length;g+=1)e.push(this.getTopicByReference(h[g]));return e};n.prototype.parseItemIdentifiers=function(h,g){var e,f,i;f=h.getTopicMap();
+if(g&&typeof g==="object"&&g instanceof Array)for(e=0;e<g.length;e+=1){i=this.curieToLocator(g[e]);f.getConstructByItemIdentifier(f.createLocator(i))||h.addItemIdentifier(f.createLocator(i))}};n.prototype.parseReifier=function(h,g){if((g=this.getTopicByReference(g))&&g.getReified()===null||!g)h.setReifier(g)};C=function(h){var g=this,e;this.defaultDatatype=TM.XSD.string;this.prefixes=new TM.Hash;this.version=h||"1.0";e=function(f){var i,l,m,o;if(g.version==="1.0")return f;l=g.prefixes.keys();for(m=
+0;m<l.length;m+=1){i=l[m];o=g.prefixes.get(i);if(f.substring(0,o.length)===o)return"["+i+":"+f.substr(o.length)+"]"}return f};this.setPrefixes=function(f){var i;for(i in f)f.hasOwnProperty(i)&&this.prefixes.put(i,f[i])};this.getTopicReference=function(f){var i;i=f.getSubjectIdentifiers();if(i.length>0)return"si:"+e(i[0].getReference());i=f.getSubjectLocators();if(i.length>0)return"sl:"+e(i[0].getReference());i=f.getItemIdentifiers();if(i.length>0)return"ii:"+e(i[0].getReference())};this.exportIdentifiers=
+function(f,i,l){var m,o=i.length;if(o>0){f[l]=[];for(m=0;m<o;m+=1)f[l].push(e(i[m].getReference()))}};this.exportScope=function(f,i){var l=i.getScope();if(l.length>0){f.scope=[];for(i=0;i<l.length;i+=1)f.scope.push(g.getTopicReference(l[i]))}};this.exportParent=function(f,i){i=i.getParent();g.exportIdentifiers(f,i.getItemIdentifiers(),"parent")};this.exportTopicMap=function(f){var i,l,m,o;o={topics:[],associations:[]};i=f.getTopics();m=i.length;for(l=0;l<m;l+=1)o.topics.push(g.exportTopic(i[l]));
+i=f.getAssociations();m=i.length;for(l=0;l<m;l+=1)o.associations.push(g.exportAssociation(i[l]));return o};this.exportTopic=function(f){var i,l,m,o;o={};g.exportIdentifiers(o,f.getSubjectIdentifiers(),"subject_identifiers");g.exportIdentifiers(o,f.getSubjectLocators(),"subject_locators");g.exportIdentifiers(o,f.getItemIdentifiers(),"item_identifiers");i=f.getNames();m=i.length;if(m>0){o.names=[];for(l=0;l<m;l+=1)o.names.push(g.exportName(i[l]))}i=f.getOccurrences();m=i.length;if(m>0){o.occurrences=
+[];for(l=0;l<m;l+=1)o.occurrences.push(g.exportOccurrence(i[l]))}i=f.getTypes();m=i.length;if(m>0){o.instance_of=[];for(l=0;l<m;l+=1)o.instance_of.push(g.getTopicReference(i[l]))}return o};this.exportName=function(f){var i,l,m;m={value:f.getValue()};if(i=f.getType())m.type=g.getTopicReference(i);if(i=f.getReifier())m.reifier=g.getTopicReference(i);g.exportIdentifiers(m,f.getItemIdentifiers(),"item_identifiers");g.exportScope(m,f);f=f.getVariants();l=f.length;if(l>0){m.variants=[];for(i=0;i<l;i+=1)m.variants.push(g.exportVariant(f[i]))}return m};
+this.exportVariant=function(f){var i,l;i={value:f.getValue()};if((l=f.getDatatype())&&l!==f.getTopicMap().createLocator(g.defaultDatatype))i.datatype=e(l.getReference());if(l=f.getReifier())i.reifier=g.getTopicReference(l);g.exportIdentifiers(i,f.getItemIdentifiers(),"item_identifiers");g.exportScope(i,f)};this.exportOccurrence=function(f){var i,l;i={value:f.getValue(),type:g.getTopicReference(f.getType())};if((l=f.getDatatype())&&l!==f.getTopicMap().createLocator(g.defaultDatatype))i.datatype=e(l.getReference());
+if(l=f.getReifier())i.reifier=g.getTopicReference(l);g.exportIdentifiers(i,f.getItemIdentifiers(),"item_identifiers");g.exportScope(i,f);return i};this.exportAssociation=function(f){var i,l;l={type:g.getTopicReference(f.getType()),roles:[]};if(i=f.getReifier())l.reifier=g.getTopicReference(i);g.exportIdentifiers(l,f.getItemIdentifiers(),"item_identifiers");g.exportScope(l,f);f=f.getRoles();for(i=0;i<f.length;i+=1)l.roles.push(g.exportRole(f[i]));return l};this.exportRole=function(f){var i,l;i={player:g.getTopicReference(f.getPlayer()),
+type:g.getTopicReference(f.getType())};if(l=f.getReifier())i.reifier=g.getTopicReference(l);g.exportIdentifiers(i,f.getItemIdentifiers(),"item_identifiers");return i}};C.prototype.toObject=function(h,g){var e,f,i;g=g||false;h.getTopicMap();if(h.isTopicMap()){e=this.exportTopicMap(h);e.item_type="topicmap"}else if(h.isRole()){e=this.exportRole(h);e.item_type="role"}else if(h.isTopic()){e=this.exportTopic(h);e.item_type="topic"}else if(h.isAssociation()){e=this.exportAssociation(h);e.item_type="association"}else if(h.isOccurrence()){e=
+this.exportOccurrence(h);e.item_type="occurrence"}else if(h.isName()){e=this.exportName(h);e.item_type="name"}else if(h.isVariant()){e=this.exportVariant(h);e.item_type="variant"}e.version=this.version;if(this.version==="1.1"&&this.prefixes)if(this.prefixes.size()){f=this.prefixes.keys();e.prefixes={};for(i=0;i<f.length;i+=1)e.prefixes[f[i]]=this.prefixes.get(f[i])}if(!h.isTopic()&&h.getReifier())e.reifier=this.getTopicReference(h.getReifier());g&&!h.isTopicMap()&&this.exportParent(e,h);return e};
+return{Reader:n,Writer:C}}();

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/GDL_TmEngine.gwt.xml
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/GDL_TmEngine.gwt.xml	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module rename-to='gdl_tmengine'>
+  <!-- Inherit the core Web Toolkit stuff.                        -->
+  <inherits name='com.google.gwt.user.User'/>
+
+  <!-- Inherit the default GWT style sheet.  You can change       -->
+  <!-- the theme of your GWT application by uncommenting          -->
+  <!-- any one of the following lines.                            -->
+  <inherits name='com.google.gwt.user.theme.clean.Clean'/>
+  <!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/> -->
+  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
+  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->
+
+  <!-- Other module inherits                                      -->
+
+  <!-- Specify the app entry point class.                         -->
+  <entry-point class='us.isidor.gdl.anaToMia.TmEngine.jtmsBasedEngine.TestClass'/> 
+  
+  <!-- Specify the paths for translatable code                    -->
+  <source path='jtmsBasedEngine'/>
+
+  <!-- Reference the javascript file that is necessary for tmjs -->
+  <script src="lib/tm.min.js" />
+</module>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/GDL_TmEngine.java
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/GDL_TmEngine.java	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,4 @@
+package us.isidor.gdl.anaToMia.TmEngine.jtmsBasedEngine;
+
+public class GDL_TmEngine {
+}

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/TestClass.java
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/src/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/TestClass.java	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,13 @@
+package us.isidor.gdl.anaToMia.TmEngine.jtmsBasedEngine;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.user.client.Window;
+
+public class TestClass implements EntryPoint{
+
+	@Override
+	public void onModuleLoad() {
+		Window.alert("TEST !!!");
+	}
+
+}

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/GDL_TmEngine.css
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/GDL_TmEngine.css	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,34 @@
+/** Add css rules here for your application. */
+
+
+/** Example rules used by the template application (remove for your app) */
+h1 {
+  font-size: 2em;
+  font-weight: bold;
+  color: #777777;
+  margin: 40px 0px 70px;
+  text-align: center;
+}
+
+.sendButton {
+  display: block;
+  font-size: 16pt;
+}
+
+/** Most GWT widgets already have a style name defined */
+.gwt-DialogBox {
+  width: 400px;
+}
+
+.dialogVPanel {
+  margin: 5px;
+}
+
+.serverResponseLabelError {
+  color: red;
+}
+
+/** Set ids using widget.getElement().setId("idOfElement") */
+#closeButton {
+  margin: 15px 6px 6px;
+}

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/GDL_TmEngine.html
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/GDL_TmEngine.html	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,63 @@
+<!doctype html>
+<!-- The DOCTYPE declaration above will set the    -->
+<!-- browser's rendering engine into               -->
+<!-- "Standards Mode". Replacing this declaration  -->
+<!-- with a "Quirks Mode" doctype may lead to some -->
+<!-- differences in layout.                        -->
+
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+    <!--                                                               -->
+    <!-- Consider inlining CSS to reduce the number of requested files -->
+    <!--                                                               -->
+    <link type="text/css" rel="stylesheet" href="GDL_TmEngine.css">
+
+    <!--                                           -->
+    <!-- Any title is fine                         -->
+    <!--                                           -->
+    <title>Web Application Starter Project</title>
+    
+    <!--                                           -->
+    <!-- This script loads your compiled module.   -->
+    <!-- If you add any GWT meta tags, they must   -->
+    <!-- be added before this line.                -->
+    <!--                                           -->
+    <script type="text/javascript" language="javascript" src="gdl_tmengine/gdl_tmengine.nocache.js"></script>
+  </head>
+
+  <!--                                           -->
+  <!-- The body can have arbitrary html, or      -->
+  <!-- you can leave the body empty if you want  -->
+  <!-- to create a completely dynamic UI.        -->
+  <!--                                           -->
+  <body>
+
+    <!-- OPTIONAL: include this if you want history support -->
+    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
+    
+    <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
+    <noscript>
+      <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
+        Your web browser must have JavaScript enabled
+        in order for this application to display correctly.
+      </div>
+    </noscript>
+
+    <h1>Web Application Starter Project</h1>
+
+    <table align="center">
+      <tr>
+        <td colspan="2" style="font-weight:bold;">Please enter your name:</td>        
+      </tr>
+      <tr>
+        <td id="nameFieldContainer"></td>
+        <td id="sendButtonContainer"></td>
+      </tr>
+      <tr>
+        <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
+      </tr>
+    </table>
+  </body>
+</html>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/GDL_TmEngine.gwt.xml
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/GDL_TmEngine.gwt.xml	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module rename-to='gdl_tmengine'>
+  <!-- Inherit the core Web Toolkit stuff.                        -->
+  <inherits name='com.google.gwt.user.User'/>
+
+  <!-- Inherit the default GWT style sheet.  You can change       -->
+  <!-- the theme of your GWT application by uncommenting          -->
+  <!-- any one of the following lines.                            -->
+  <inherits name='com.google.gwt.user.theme.clean.Clean'/>
+  <!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/> -->
+  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
+  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->
+
+  <!-- Other module inherits                                      -->
+
+  <!-- Specify the app entry point class.                         -->
+  <entry-point class='us.isidor.gdl.anaToMia.TmEngine.jtmsBasedEngine.TestClass'/> 
+  
+  <!-- Specify the paths for translatable code                    -->
+  <source path='jtmsBasedEngine'/>
+
+  <!-- Reference the javascript file that is necessary for tmjs -->
+  <script src="lib/tm.min.js" />
+</module>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/GDL_TmEngine.class
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/classes/us/isidor/gdl/anaToMia/TmEngine/jtmsBasedEngine/TestClass.class
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine/rpcPolicyManifest/manifest.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/deploy/gdl_tmengine/rpcPolicyManifest/manifest.txt	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,2 @@
+# Module gdl_tmengine
+# RPC service class, partial path of RPC policy file

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/lib/gwt-servlet.jar
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/web.xml
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/WEB-INF/web.xml	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+  
+  <!-- Servlets -->
+
+  
+  <!-- Default page to serve -->
+  <welcome-file-list>
+    <welcome-file>GDL_TmEngine.html</welcome-file>
+  </welcome-file-list>
+
+</web-app>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/clear.cache.gif
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gdl_tmengine.nocache.js
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gdl_tmengine.nocache.js	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,16 @@
+function gdl_tmengine(){var N='',ub='" for "gwt:onLoadErrorFn"',sb='" for "gwt:onPropertyErrorFn"',gb='"><\/script>',X='#',Pb='.cache.html',Z='/',Ob=':',mb='::',$b='<script defer="defer">gdl_tmengine.onInjectionDone(\'gdl_tmengine\')<\/script>',fb='<script id="',Yb='<script language="javascript" src="',pb='=',Y='?',rb='Bad handler "',Wb='DOMContentLoaded',Nb="GWT module 'gdl_tmengine' may need to be (re)compiled",hb='SCRIPT',eb='__gwt_marker_gdl_tmengine',ib='base',ab='baseUrl',R='begin',Q='bootstrap',_='clear.cache.gif',ob='content',W='end',O='gdl_tmengine',cb='gdl_tmengine.nocache.js',lb='gdl_tmengine::',Hb='gecko',Ib='gecko1_8',S='gwt.codesvr=',T='gwt.hosted=',U='gwt.hybrid',Qb='gwt/clean/clean.css',tb='gwt:onLoadErrorFn',qb='gwt:onPropertyErrorFn',nb='gwt:property',Vb='head',Lb='hosted.html?gdl_tmengine',Ub='href',Gb='ie6',Fb='ie8',Eb='ie9',vb='iframe',$='img',wb="javascript:''",Xb='lib/tm.min.js',Zb='lib/tm.min.js"><\/script>',Rb='link',Kb='loadExternalRefs',jb='meta',yb='moduleRequested',V='moduleStartup',Db='msie',kb='name',Ab='opera',xb='position:absolute;width:0;height:0;border:none',Sb='rel',Cb='safari',bb='script',Mb='selectingPermutation',P='startup',Tb='stylesheet',db='undefined',Jb='unknown',zb='user.agent',Bb='webkit';var l=window,m=document,n=l.__gwtStatsEvent?function(a){return l.__gwtStatsEvent(a)}:null,o=l.__gwtStatsSessionId?l.__gwtStatsSessionId:null,p,q,r,s=N,t={},u=[],v=[],w=[],x=0,y,z;n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:Q,millis:(new Date).getTime(),type:R});if(!l.__gwt_stylesLoaded){l.__gwt_stylesLoaded={}}if(!l.__gwt_scriptsLoaded){l.__gwt_scriptsLoaded={}}function A(){var b=false;try{var c=l.location.search;return (c.indexOf(S)!=-1||(c.indexOf(T)!=-1||l.external&&l.external.gwtOnLoad))&&c.indexOf(U)==-1}catch(a){}A=function(){return b};return b}
+function B(){if(p&&q){var b=m.getElementById(O);var c=b.contentWindow;if(A()){c.__gwt_getProperty=function(a){return F(a)}}gdl_tmengine=null;c.gwtOnLoad(y,O,s,x);n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:V,millis:(new Date).getTime(),type:W})}}
+function C(){function e(a){var b=a.lastIndexOf(X);if(b==-1){b=a.length}var c=a.indexOf(Y);if(c==-1){c=a.length}var d=a.lastIndexOf(Z,Math.min(c,b));return d>=0?a.substring(0,d+1):N}
+function f(a){if(a.match(/^\w+:\/\//)){}else{var b=m.createElement($);b.src=a+_;a=e(b.src)}return a}
+function g(){var a=E(ab);if(a!=null){return a}return N}
+function h(){var a=m.getElementsByTagName(bb);for(var b=0;b<a.length;++b){if(a[b].src.indexOf(cb)!=-1){return e(a[b].src)}}return N}
+function i(){var a;if(typeof isBodyLoaded==db||!isBodyLoaded()){var b=eb;var c;m.write(fb+b+gb);c=m.getElementById(b);a=c&&c.previousSibling;while(a&&a.tagName!=hb){a=a.previousSibling}if(c){c.parentNode.removeChild(c)}if(a&&a.src){return e(a.src)}}return N}
+function j(){var a=m.getElementsByTagName(ib);if(a.length>0){return a[a.length-1].href}return N}
+var k=g();if(k==N){k=h()}if(k==N){k=i()}if(k==N){k=j()}if(k==N){k=e(m.location.href)}k=f(k);s=k;return k}
+function D(){var b=document.getElementsByTagName(jb);for(var c=0,d=b.length;c<d;++c){var e=b[c],f=e.getAttribute(kb),g;if(f){f=f.replace(lb,N);if(f.indexOf(mb)>=0){continue}if(f==nb){g=e.getAttribute(ob);if(g){var h,i=g.indexOf(pb);if(i>=0){f=g.substring(0,i);h=g.substring(i+1)}else{f=g;h=N}t[f]=h}}else if(f==qb){g=e.getAttribute(ob);if(g){try{z=eval(g)}catch(a){alert(rb+g+sb)}}}else if(f==tb){g=e.getAttribute(ob);if(g){try{y=eval(g)}catch(a){alert(rb+g+ub)}}}}}}
+function E(a){var b=t[a];return b==null?null:b}
+function F(a){var b=v[a](),c=u[a];if(b in c){return b}var d=[];for(var e in c){d[c[e]]=e}if(z){z(a,d,b)}throw null}
+var G;function H(){if(!G){G=true;var a=m.createElement(vb);a.src=wb;a.id=O;a.style.cssText=xb;a.tabIndex=-1;m.body.appendChild(a);n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:V,millis:(new Date).getTime(),type:yb});a.contentWindow.location.replace(s+J)}}
+v[zb]=function(){var b=navigator.userAgent.toLowerCase();var c=function(a){return parseInt(a[1])*1000+parseInt(a[2])};if(function(){return b.indexOf(Ab)!=-1}())return Ab;if(function(){return b.indexOf(Bb)!=-1}())return Cb;if(function(){return b.indexOf(Db)!=-1&&m.documentMode>=9}())return Eb;if(function(){return b.indexOf(Db)!=-1&&m.documentMode>=8}())return Fb;if(function(){var a=/msie ([0-9]+)\.([0-9]+)/.exec(b);if(a&&a.length==3)return c(a)>=6000}())return Gb;if(function(){return b.indexOf(Hb)!=-1}())return Ib;return Jb};u[zb]={gecko1_8:0,ie6:1,ie8:2,ie9:3,opera:4,safari:5};gdl_tmengine.onScriptLoad=function(){if(G){q=true;B()}};gdl_tmengine.onInjectionDone=function(){p=true;n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:Kb,millis:(new Date).getTime(),type:W});B()};D();C();var I;var J;if(A()){if(l.external&&(l.external.initModule&&l.external.initModule(O))){l.location.reload();return}J=Lb;I=N}n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:Q,millis:(new Date).getTime(),type:Mb});if(!A()){try{alert(Nb);return;var K=I.indexOf(Ob);if(K!=-1){x=Number(I.substring(K+1));I=I.substring(0,K)}J=I+Pb}catch(a){return}}var L;function M(){if(!r){r=true;if(!__gwt_stylesLoaded[Qb]){var a=m.createElement(Rb);__gwt_stylesLoaded[Qb]=a;a.setAttribute(Sb,Tb);a.setAttribute(Ub,s+Qb);m.getElementsByTagName(Vb)[0].appendChild(a)}B();if(m.removeEventListener){m.removeEventListener(Wb,M,false)}if(L){clearInterval(L)}}}
+if(m.addEventListener){m.addEventListener(Wb,function(){H();M()},false)}var L=setInterval(function(){if(/loaded|complete/.test(m.readyState)){H();M()}},50);n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:Q,millis:(new Date).getTime(),type:W});n&&n({moduleName:O,sessionId:o,subSystem:P,evtGroup:Kb,millis:(new Date).getTime(),type:R});if(!__gwt_scriptsLoaded[Xb]){__gwt_scriptsLoaded[Xb]=true;document.write(Yb+s+Zb)}m.write($b)}
+gdl_tmengine();
\ No newline at end of file

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/clean.css
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/clean.css	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,1263 @@
+/**
+ * The file contains styles for GWT widgets in the Clean theme.
+ *
+ * In order to maintain cross-browser compatibility, the following syntax is
+ * used to create IE6 specific style rules:
+ *    .gwt-Widget {
+ *      property: rule applies to all browsers
+ *      -property: rule applies only to IE6 (overrides previous rule)
+ *    }
+ *    * html .gwt-Widget {
+ *      property: rule applies to all versions of IE
+ *    }
+ */
+
+body, table td, select, button {
+  font-family: Arial Unicode MS, Arial, sans-serif;
+  font-size: small;
+}
+pre {
+  font-family: "courier new", courier;
+  font-size: small;
+}
+body {
+  color: black;
+  margin: 10px;
+  border: 0px;
+  padding: 0px;
+  background: #fff;
+  direction: ltr;
+}
+a, a:visited {
+  color: #0066cc;
+  text-decoration:none;
+}
+
+a:hover {
+  color: #0066cc;
+  text-decoration:underline;
+}
+
+select {
+  background: white;
+}
+
+/**
+ * The reference theme can be used to determine when this style sheet has
+ * loaded.  Create a hidden div element with absolute position, assign the style
+ * name below, and attach it to the DOM.  Use a timer to detect when the
+ * element's height and width are set to 5px.
+ */
+.gwt-Reference-clean {
+  height: 5px;
+  width: 5px;
+  zoom: 1;
+}
+
+.gwt-Button {
+  margin: 0;
+  padding: 5px 7px;
+  text-decoration: none;
+  cursor: pointer;
+  cursor: hand;
+  font-size:small;
+  background: url("images/hborder.png") repeat-x 0px -2077px;
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;
+  border-radius: 3px;
+ -moz-border-radius: 3px;
+}
+.gwt-Button:active {
+  border: 1px inset #ccc;
+}
+.gwt-Button:hover {
+  border-color: #939393;
+}
+.gwt-Button[disabled] {
+  cursor: default;
+  color: #888;
+}
+.gwt-Button[disabled]:hover {
+  border: 1px outset #ccc;
+}
+
+.gwt-CheckBox {
+}
+.gwt-CheckBox-disabled {
+  color: #888;
+}
+
+.gwt-DecoratorPanel {
+}
+.gwt-DecoratorPanel .topCenter {
+  border-top: 1px solid #bbb;
+  line-height: 0px;
+}
+.gwt-DecoratorPanel .bottomCenter {
+  border-bottom: 1px solid #bbb;
+  line-height: 0px;
+}
+.gwt-DecoratorPanel .topCenterInner,
+.gwt-DecoratorPanel .bottomCenterInner {
+  height: 1px;
+  line-height: 0px;
+  font-size: 1px;
+}
+.gwt-DecoratorPanel .middleLeft {
+  border-left: 1px solid #bbb;
+}
+.gwt-DecoratorPanel .middleRight {
+  border-right: 1px solid #bbb;
+}
+.gwt-DecoratorPanel .middleLeftInner,
+.gwt-DecoratorPanel .middleRightInner {
+  width: 1px;
+  line-height: 1px;
+}
+.gwt-DecoratorPanel .topLeftInner,
+.gwt-DecoratorPanel .topRightInner,
+.gwt-DecoratorPanel .bottomLeftInner,
+.gwt-DecoratorPanel .bottomRightInner {
+  width: 5px;
+  height: 5px;
+  zoom: 1;
+  font-size: 1px;
+  overflow: hidden;
+}
+.gwt-DecoratorPanel .topLeft {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat 0px -6px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -6px;
+}
+.gwt-DecoratorPanel .topRight {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat -5px -6px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -6px;
+}
+.gwt-DecoratorPanel .bottomLeft {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat 0px -11px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -11px;
+}
+.gwt-DecoratorPanel .bottomRight {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat -5px -11px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -11px;
+}
+* html .gwt-DecoratorPanel .topLeftInner,
+* html .gwt-DecoratorPanel .topRightInner,
+* html .gwt-DecoratorPanel .bottomLeftInner,
+* html .gwt-DecoratorPanel .bottomRightInner {
+  width: 5px;
+  height: 5px;
+  overflow: hidden;
+}
+
+.gwt-DialogBox .Caption {
+  background: #F1F1F1;
+  padding: 4px 8px 4px 4px;
+  cursor: default;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+  font-weight: bold;
+  border-bottom: 1px solid #bbbbbb;
+  border-top: 1px solid #D2D2D2;
+}
+.gwt-DialogBox .dialogContent {
+}
+.gwt-DialogBox .dialogMiddleCenter {
+  padding: 3px;
+  background: white;
+}
+.gwt-DialogBox .dialogBottomCenter {
+  background: url(images/hborder.png) repeat-x 0px -2945px;
+  -background: url(images/hborder_ie6.png) repeat-x 0px -2144px;
+}
+.gwt-DialogBox .dialogMiddleLeft {
+  background: url(images/vborder.png) repeat-y -31px 0px;
+}
+.gwt-DialogBox .dialogMiddleRight {
+  background: url(images/vborder.png) repeat-y -32px 0px;
+  -background: url(images/vborder_ie6.png) repeat-y -32px 0px;
+}
+.gwt-DialogBox .dialogTopLeftInner {
+  width: 10px;
+  height: 8px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogTopRightInner {
+  width: 12px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogBottomLeftInner {
+  width: 10px;
+  height: 12px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogBottomRightInner {
+  width: 12px;
+  height: 12px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogTopLeft {
+  background: url(images/circles.png) no-repeat -20px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -20px 0px;
+}
+.gwt-DialogBox .dialogTopRight {
+  background: url(images/circles.png) no-repeat -28px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -28px 0px;
+}
+.gwt-DialogBox .dialogBottomLeft {
+  background: url(images/circles.png) no-repeat 0px -36px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -36px;
+}
+.gwt-DialogBox .dialogBottomRight {
+  background: url(images/circles.png) no-repeat -8px -36px;
+  -background: url(images/circles_ie6.png) no-repeat -8px -36px;
+}
+* html .gwt-DialogBox .dialogTopLeftInner {
+  width: 10px;
+  overflow: hidden;
+}
+* html .gwt-DialogBox .dialogTopRightInner {
+  width: 12px;
+  overflow: hidden;
+}
+* html .gwt-DialogBox .dialogBottomLeftInner {
+  width: 10px;
+  height: 12px;
+  overflow: hidden;
+}
+* html .gwt-DialogBox .dialogBottomRightInner {
+  width: 12px;
+  height: 12px;
+  overflow: hidden;
+}
+
+.gwt-DisclosurePanel {
+}
+.gwt-DisclosurePanel-open {
+}
+.gwt-DisclosurePanel-closed {
+}
+.gwt-DisclosurePanel .header,
+.gwt-DisclosurePanel .header a,
+.gwt-DisclosurePanel .header td {
+  text-decoration: none;  /* Remove underline from header */
+  color: black; 
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-DisclosurePanel .content {
+  border-left: 3px solid #e7e7e7;
+  padding: 4px 0px 4px 8px;
+  margin-left: 6px;
+}
+
+.gwt-FileUpload {
+}
+
+.gwt-Frame {
+  border-top: 2px solid #666;
+  border-left: 2px solid #666;
+  border-right: 2px solid #bbb;
+  border-bottom: 2px solid #bbb;
+}
+
+.gwt-HorizontalSplitPanel {
+}
+.gwt-HorizontalSplitPanel .hsplitter {
+  cursor: move;
+  border: 0px; 
+  background: #e7e7e7;
+  line-height: 0px;
+}
+.gwt-VerticalSplitPanel {
+}
+.gwt-VerticalSplitPanel .vsplitter {
+  cursor: move;
+  border: 0px; 
+  background: #e7e7e7;
+  line-height: 0px;
+}
+
+.gwt-HTML {
+  padding: 0 0px;
+}
+
+.gwt-Hyperlink {
+}
+
+.gwt-Image {
+}
+
+.gwt-Label {
+}
+
+.gwt-ListBox {
+}
+
+.gwt-MenuBar {
+  cursor: default;
+}
+.gwt-MenuBar .gwt-MenuItem {
+  cursor: default;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+.gwt-MenuBar .gwt-MenuItem-selected {
+  background: #E3E8F3;
+}
+.gwt-MenuBar-horizontal {
+  background: #e3e8f3 url(images/hborder.png) repeat-x 0px -2003px;
+  border: 1px solid #e0e0e0;
+}
+.gwt-MenuBar-horizontal .gwt-MenuItem {
+  padding: 5px 10px;
+  vertical-align: bottom;
+  color: #000;
+  font-weight: bold;
+}
+.gwt-MenuBar-horizontal .gwt-MenuItemSeparator {
+  width: 1px;
+  padding: 0px;
+  margin: 0px;
+  border: 0px;
+  border-left: 1px solid #ccc;
+  background: white;
+}
+.gwt-MenuBar-horizontal .gwt-MenuItemSeparator .menuSeparatorInner {
+  width: 1px;
+  height: 1px;
+  background: white; 
+}
+.gwt-MenuBar-vertical {
+  margin-top: 0px;
+  margin-left: 0px;
+  background: white;
+}
+.gwt-MenuBar-vertical table {
+  border-collapse: collapse;
+}
+.gwt-MenuBar-vertical .gwt-MenuItem {
+  padding: 2px 40px 2px 1px;
+}
+.gwt-MenuBar-vertical .gwt-MenuItemSeparator {
+  padding: 2px 0px;
+}
+.gwt-MenuBar-vertical .gwt-MenuItemSeparator .menuSeparatorInner {
+  height: 1px;
+  padding: 0px;
+  border: 0px;
+  border-top: 1px solid #ccc;
+  overflow: hidden;
+}
+.gwt-MenuBar-vertical .subMenuIcon {
+  padding-right: 4px;
+}
+.gwt-MenuBar-vertical .subMenuIcon-selected {
+  background: #E3E8F3;
+}
+.gwt-MenuBarPopup {
+  margin: 0px 0px 0px 3px;
+}
+.gwt-MenuBarPopup .menuPopupTopCenter {
+  background: url(images/hborder.png) 0px -12px repeat-x;
+}
+.gwt-MenuBarPopup .menuPopupBottomCenter {
+  background: url(images/hborder.png) 0px -13px repeat-x;
+  -background: url(images/hborder_ie6.png) 0px -13px repeat-x;
+}
+.gwt-MenuBarPopup .menuPopupMiddleLeft {
+  background: url(images/vborder.png) -12px 0px repeat-y;
+  -background: url(images/vborder_ie6.png) -12px 0px repeat-y;
+}
+.gwt-MenuBarPopup .menuPopupMiddleRight {
+  background: url(images/vborder.png) -13px 0px repeat-y;
+  -background: url(images/vborder_ie6.png) -13px 0px repeat-y;
+}
+.gwt-MenuBarPopup .menuPopupTopLeftInner {
+  width: 5px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupTopRightInner {
+  width: 8px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupBottomLeftInner {
+  width: 5px;
+  height: 8px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupBottomRightInner {
+  width: 8px;
+  height: 8px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupTopLeft {
+  background: url(images/corner.png) no-repeat 0px -36px;
+  -background: url(images/corner_ie6.png) no-repeat 0px -36px;
+}
+.gwt-MenuBarPopup .menuPopupTopRight {
+  background: url(images/corner.png) no-repeat -5px -36px;
+  -background: url(images/corner_ie6.png) no-repeat -5px -36px;
+}
+.gwt-MenuBarPopup .menuPopupBottomLeft {
+  background: url(images/corner.png) no-repeat 0px -41px;
+  -background: url(images/corner_ie6.png) no-repeat 0px -41px;
+}
+.gwt-MenuBarPopup .menuPopupBottomRight {
+  background: url(images/corner.png) no-repeat -5px -41px;
+  -background: url(images/corner_ie6.png) no-repeat -5px -41px;
+}
+* html .gwt-MenuBarPopup .menuPopupTopLeftInner {
+  width: 5px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-MenuBarPopup .menuPopupTopRightInner {
+  width: 8px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-MenuBarPopup .menuPopupBottomLeftInner {
+  width: 5px;
+  height: 8px;
+  overflow: hidden;
+}
+* html .gwt-MenuBarPopup .menuPopupBottomRightInner {
+  width: 8px;
+  height: 8px;
+  overflow: hidden;
+}
+
+.gwt-PasswordTextBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: 100%;
+}
+.gwt-PasswordTextBox-readonly {
+  color: #888;
+}
+
+.gwt-PopupPanel {
+  border: 3px solid #e7e7e7;
+  padding: 3px;
+  background: white;
+}
+
+.gwt-DecoratedPopupPanel .popupContent {
+}
+.gwt-DecoratedPopupPanel .popupMiddleCenter {
+  padding: 3px;
+  background: #f1f1f1;
+}
+.gwt-DecoratedPopupPanel .popupTopCenter {
+  background: url(images/hborder.png) 0px -2937px repeat-x;
+}
+.gwt-DecoratedPopupPanel .popupBottomCenter {
+  background:  url(images/hborder.png) repeat-x 0px -2938px;
+  -background: url(images/hborder_ie6.png) repeat-x 0px -2138px;
+}
+.gwt-DecoratedPopupPanel .popupMiddleLeft {
+  background: url(images/vborder.png) -21px 0px repeat-y;
+}
+.gwt-DecoratedPopupPanel .popupMiddleRight {
+  background: url(images/vborder.png) repeat-y -24px 0px;
+  -background: url(images/vborder_ie6.png) repeat-y -24px 0px;
+}
+.gwt-DecoratedPopupPanel .popupTopLeftInner {
+  width: 6px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupTopRightInner {
+  width: 6px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupBottomLeftInner {
+  width: 6px;
+  height: 6px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupBottomRightInner {
+  width: 6px;
+  height: 6px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupTopLeft {
+  background: url(images/circles.png) no-repeat 0px -16px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -16px;
+}
+.gwt-DecoratedPopupPanel .popupTopRight {
+  background: url(images/circles.png) no-repeat -6px -16px;
+  -background: url(images/circles_ie6.png) no-repeat -6px -16px;
+}
+.gwt-DecoratedPopupPanel .popupBottomLeft {
+  background: url(images/circles.png) no-repeat 0px -21px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -21px;
+}
+.gwt-DecoratedPopupPanel .popupBottomRight {
+  background: url(images/circles.png) no-repeat -6px -21px;
+  -background: url(images/circles_ie6.png) no-repeat -6px -21px;
+}
+* html .gwt-DecoratedPopupPanel .popupTopLeftInner {
+  width: 6px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-DecoratedPopupPanel .popupTopRightInner {
+  width: 6px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-DecoratedPopupPanel .popupBottomLeftInner {
+  width: 6px;
+  height: 6px;
+  overflow: hidden;
+}
+* html .gwt-DecoratedPopupPanel .popupBottomRightInner {
+  width: 6px;
+  height: 6px;
+  overflow: hidden;
+}
+
+.gwt-PopupPanelGlass {
+  background-color: #000;
+  opacity: 0.3;
+  filter: alpha(opacity=30);
+}
+
+.gwt-PushButton-up,
+.gwt-PushButton-up-hovering,
+.gwt-PushButton-up-disabled,
+.gwt-PushButton-down,
+.gwt-PushButton-down-hovering,
+.gwt-PushButton-down-disabled {
+  margin: 0;
+  text-decoration: none;
+  background: url("images/hborder.png") repeat-x 0px -27px;
+  border-radius: 2px;
+  -moz-border-radius: 2px;
+}
+.gwt-PushButton-up,
+.gwt-PushButton-up-hovering,
+.gwt-PushButton-up-disabled {
+  padding: 3px 5px 3px 5px;
+}
+.gwt-PushButton-up {
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-up-hovering {
+  border: 1px solid;
+  border-color: #939393;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-up-disabled {
+  border: 1px solid #bbb;
+  cursor: default;
+  opacity: .5;
+  filter: alpha(opacity=45);
+  zoom: 1;
+}
+.gwt-PushButton-down,
+.gwt-PushButton-down-hovering,
+.gwt-PushButton-down-disabled {
+  padding: 4px 4px 2px 6px;
+  outline:none;
+}
+.gwt-PushButton-down {
+  border: 1px inset #666;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-down-hovering {
+  border: 1px solid #939393;
+  border-top: 1px solid #333333;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-down-disabled {
+  border: 1px outset #ccc;
+  cursor: default;
+  opacity: 0.5;
+  filter: alpha(opacity=45);
+  zoom: 1;
+}
+
+.gwt-RadioButton {
+}
+.gwt-RadioButton-disabled {
+  color: #888;
+}
+
+.gwt-RichTextArea {
+}
+.hasRichTextToolbar {
+  border: 0px;
+}
+.gwt-RichTextToolbar {
+  background: #e3e8f3 url(images/hborder.png) repeat-x 0px -2003px;
+  border-bottom: 1px solid #BBBBBB;
+  padding: 3px;
+  margin: 0px;
+}
+.gwt-RichTextToolbar .gwt-PushButton-up {
+  padding: 0px 1px 0px 0px;
+  margin-right: 4px;
+  margin-bottom: 4px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-PushButton-up-hovering {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-PushButton-down {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-PushButton-down-hovering {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-up {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-up-hovering {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border-width: 1px;
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-down {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border-width: 1px;
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-down-hovering {
+  margin-right: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border-width: 1px;
+}
+
+.gwt-StackPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackPanel .gwt-StackPanelItem {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-StackPanel .gwt-StackPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 2px 10px 5px;
+}
+
+.gwt-DecoratedStackPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 2px 10px 5px;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelItem {
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-DecoratedStackPanel .stackItemTopLeft,
+.gwt-DecoratedStackPanel .stackItemTopRight {
+  height: 6px;
+  width: 6px;
+  zoom: 1;
+}
+.gwt-DecoratedStackPanel .stackItemTopLeft {
+  border-left: 1px solid #bbbbbb;
+  background: #d3def6 url(images/corner.png) no-repeat 0px -49px;
+  -background: #d3def6 url(images/corner_ie6.png) no-repeat 0px -49px;
+}
+.gwt-DecoratedStackPanel .stackItemTopRight {
+  border-right: 1px solid #bbbbbb;
+  background: #d3def6 url(images/corner.png) no-repeat -6px -49px;
+  -background: #d3def6 url(images/corner_ie6.png) no-repeat -6px -49px;
+}
+.gwt-DecoratedStackPanel .stackItemTopLeftInner,
+.gwt-DecoratedStackPanel .stackItemTopRightInner {
+  width: 1px;
+  height: 1px;
+}
+* html .gwt-DecoratedStackPanel .stackItemTopLeftInner,
+* html .gwt-DecoratedStackPanel .stackItemTopRightInner {
+  width: 6px;
+  height: 6px;
+  overflow: hidden;
+}
+.gwt-DecoratedStackPanel .stackItemTopCenter {
+  background: url(images/hborder.png) 0px -21px repeat-x;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleLeft {
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+  border-left: 1px solid #bbbbbb;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleLeftInner,
+.gwt-DecoratedStackPanel .stackItemMiddleRightInner {
+  width: 1px;
+  height: 1px;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleRight {
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+  border-right: 1px solid #bbbbbb;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleCenter {
+  font-weight: bold;
+  font-size: 1.3em;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-first .stackItemTopRight,
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-first .stackItemTopLeft {
+  border: 0px;
+  background-color: white;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-below-selected .stackItemTopLeft,
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-below-selected .stackItemTopRight {
+  background-color: white;
+}
+
+.gwt-SuggestBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: 100%;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+
+.gwt-SuggestBoxPopup {
+}
+
+.gwt-SuggestBoxPopup .item {
+  padding: 2px 6px;
+  color: #000;
+  cursor: default;
+  font-size: 110%;
+}
+.gwt-SuggestBoxPopup .item-selected {
+  background: #D5E2FF;
+}
+.gwt-SuggestBoxPopup .suggestPopupContent {
+  background: white;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopCenter {
+  border-top: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomCenter {
+  border-bottom: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopCenterInner,
+.gwt-SuggestBoxPopup .suggestPopupBottomCenterInner {
+  height: 1px;
+  line-height: 1px;
+}
+.gwt-SuggestBoxPopup .suggestPopupMiddleLeft {
+  border-left: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupMiddleRight {
+  border-right: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupMiddleLeftInner,
+.gwt-SuggestBoxPopup .suggestPopupMiddleRightInner {
+  width: 1px;
+  line-height: 1px;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopLeftInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;  
+}
+.gwt-SuggestBoxPopup .suggestPopupTopRightInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomLeftInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomRightInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopLeft {
+  background: url(images/circles.png) no-repeat 0px -6px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -6px;
+  width:5px;
+  height:5px;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopRight {
+  background: url(images/circles.png) no-repeat -5px -6px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -6px;
+  width:5px;
+  height:5px;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomLeft {
+  background: url(images/circles.png) no-repeat 0px -11px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -11px;
+  width:5px;
+  height:5px;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomRight {
+  background: url(images/circles.png) no-repeat -5px -11px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -11px;
+  width:5px;
+  height:5px;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupTopLeftInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupTopRightInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupBottomLeftInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupBottomRightInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+
+.gwt-TabBar {
+  background: #ccc;
+  padding-top: 6px;
+}
+.gwt-TabBar .gwt-TabBarFirst {
+  width: 5px;  /* first tab distance from the left */
+}
+.gwt-TabBar .gwt-TabBarRest {
+}
+.gwt-TabBar .gwt-TabBarItem {
+  margin-left: 4px;
+  padding: 4px 8px 4px 8px;
+  cursor: pointer;
+  cursor: hand;
+  color: white;
+  font-weight: normal;
+  text-align: center;
+  background: #8E8E8E;
+  -moz-border-radius: 3px 3px 0px 0px;
+  border-radius: 3px 3px 0px 0px;
+}
+.gwt-TabBar .gwt-TabBarItem-selected {
+  cursor: default;
+  background: white;
+  color: #333;
+  font-weight: bold;
+} 
+.gwt-TabBar .gwt-TabBarItem-disabled {
+  cursor: default;
+  color: #999999;
+}
+.gwt-TabPanel {
+}
+.gwt-TabPanelBottom {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 0px 1px 1px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-DecoratedTabBar {
+  background: #ccc;
+  padding-top: 6px;
+}
+.gwt-DecoratedTabBar .gwt-TabBarFirst {
+  width: 5px;  /* first tab distance from the left */
+}
+.gwt-DecoratedTabBar .gwt-TabBarRest {
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem {
+  border-collapse: collapse;
+  margin-left: 4px;
+}
+.gwt-DecoratedTabBar .tabTopCenter {
+  padding: 0px;
+  background: #8E8E8E;
+}
+.gwt-DecoratedTabBar .tabTopLeft,
+.gwt-DecoratedTabBar .tabTopRight {
+  padding: 0px;
+  zoom: 1;
+}
+.gwt-DecoratedTabBar .tabTopLeftInner,
+.gwt-DecoratedTabBar .tabTopRightInner {
+  width: 3px;
+  height: 3px;
+}
+.gwt-DecoratedTabBar .tabTopLeft {
+  background: url(images/circles.png) no-repeat 0px 0px;
+  -background: url(images/circles_ie6.png) no-repeat 0px 0px;
+}
+.gwt-DecoratedTabBar .tabTopRight {
+  background: url(images/circles.png) no-repeat -3px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -3px 0px;
+}
+* html .gwt-DecoratedTabBar .tabTopLeftInner,
+* html .gwt-DecoratedTabBar .tabTopRightInner {
+  width: 3px;
+  height: 3px;
+  overflow: hidden;
+}
+.gwt-DecoratedTabBar .tabMiddleLeft,
+.gwt-DecoratedTabBar .tabMiddleRight {
+  width: 3px;
+  padding: 0px;
+  background: #8E8E8E;
+}
+.gwt-DecoratedTabBar .tabMiddleLeftInner,
+.gwt-DecoratedTabBar .tabMiddleRightInner {
+  width: 1px;
+  height: 1px;
+}
+.gwt-DecoratedTabBar .tabMiddleCenter {
+  padding: 0px 5px 4px 5px;
+  cursor: pointer;
+  cursor: hand;
+  color: #fff;
+  font-weight: normal;
+  text-align: center;
+  background: #8E8E8E;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabTopCenter {
+  background:#fff;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabTopLeft {
+  background: url(images/circles.png) no-repeat -6px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -6px 0px;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabTopRight {
+  background: url(images/circles.png) no-repeat -9px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -9px 0px;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabMiddleLeft,
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabMiddleRight {
+  background: #fff;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabMiddleCenter {
+  cursor: default;
+  background: #fff;
+  color:#333;
+  font-weight:bold;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-disabled .tabMiddleCenter {
+  cursor: default;
+  color: #999999;
+}
+
+.gwt-TextArea {
+  padding: 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #666;
+  font-size: 100%;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+.gwt-TextArea-readonly {
+  color: #888;
+}
+
+.gwt-TextBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: small;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+.gwt-TextBox-readonly {
+  color: #888;
+}
+.gwt-ToggleButton-up,
+.gwt-ToggleButton-up-hovering,
+.gwt-ToggleButton-up-disabled,
+.gwt-ToggleButton-down,
+.gwt-ToggleButton-down-hovering,
+.gwt-ToggleButton-down-disabled {
+  margin: 0;
+  text-decoration: none;
+  background: url("images/hborder.png") repeat-x 0px -27px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+}
+.gwt-ToggleButton-up,
+.gwt-ToggleButton-up-hovering,
+.gwt-ToggleButton-up-disabled {
+  padding: 3px 5px 3px 5px;
+}
+.gwt-ToggleButton-up {
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;  
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-up-hovering {
+  border: 1px solid;
+  border-color: #939393;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-up-disabled {
+  border: 1px solid #bbb;
+  cursor: default;
+  opacity: .5;
+  zoom: 1;
+  filter: alpha(opacity=45);
+}
+.gwt-ToggleButton-down,
+.gwt-ToggleButton-down-hovering,
+.gwt-ToggleButton-down-disabled {
+  padding: 4px 4px 2px 6px;
+}
+.gwt-ToggleButton-down {
+  background-position: 0 -513px;
+  border: 1px inset #666;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-down-hovering {
+  background-position: 0 -513px;
+  border: 1px inset;
+  border-color: #9cf #69e #69e #7af;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-down-disabled {
+  background-position: 0 -513px;
+  border: 1px inset #ccc;
+  cursor: default;
+  opacity: .5;
+  zoom: 1;
+  filter: alpha(opacity=45);
+}
+
+.gwt-Tree .gwt-TreeItem {
+  padding: 1px 0px;
+  margin: 0px;
+  white-space: nowrap;
+  cursor: hand;
+  cursor: pointer;
+}
+.gwt-Tree .gwt-TreeItem-selected {
+  background: #ebeff9;
+}
+.gwt-TreeItem .gwt-RadioButton input,
+.gwt-TreeItem .gwt-CheckBox input {
+  margin-left: 0px;
+}
+* html .gwt-TreeItem .gwt-RadioButton input,
+* html .gwt-TreeItem .gwt-CheckBox input {
+  margin-left: -4px;
+}
+
+.gwt-DateBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: 100%;
+}
+.gwt-DateBox input {
+  width: 8em;
+}
+.dateBoxFormatError {
+  background: #ffcccc;
+}
+.dateBoxPopup {
+}
+
+.gwt-DatePicker {
+  border: 1px solid #ccc;
+  border-top:1px solid #999;
+  cursor: default;
+}
+.gwt-DatePicker td,
+.datePickerMonthSelector td:focus {
+  outline: none;
+}
+.datePickerDays {
+  width: 100%;
+  background: white;
+}
+.datePickerDay,
+.datePickerWeekdayLabel,
+.datePickerWeekendLabel {
+  font-size: 85%;
+  text-align: center;
+  padding: 4px;
+  outline: none;
+  font-weight:bold;
+  color:#333;
+  border-right: 1px solid #EDEDED;
+  border-bottom: 1px solid #EDEDED;
+}
+.datePickerWeekdayLabel,
+.datePickerWeekendLabel {
+  background: #fff;
+  padding: 0px 4px 2px;
+  cursor: default;
+  color:#666;
+  font-size:70%;
+  font-weight:normal;
+}
+.datePickerDay {
+  padding: 4px 7px;
+  cursor: hand;
+  cursor: pointer;
+}
+.datePickerDayIsWeekend {
+  background: #f7f7f7;
+}
+.datePickerDayIsFiller {
+  color: #999;
+  font-weight:normal;
+}
+.datePickerDayIsValue {
+  background: #d7dfe8;
+}
+.datePickerDayIsDisabled {
+  color: #AAAAAA;
+  font-style: italic;
+}
+.datePickerDayIsHighlighted {
+  background: #F0E68C;
+}
+.datePickerDayIsValueAndHighlighted {
+  background: #d7dfe8;
+}
+.datePickerDayIsToday {
+  padding: 3px;
+  color: #fff;
+  background: url(images/hborder.png) repeat-x 0px -2607px;
+}
+
+.datePickerMonthSelector {
+  width: 100%;
+  padding: 1px 0 5px 0;
+  background: #fff;
+}
+td.datePickerMonth {
+  text-align: center;
+  vertical-align: middle;
+  white-space: nowrap;
+  font-size: 100%;
+  font-weight: bold;
+  color: #333;
+}
+.datePickerPreviousButton,
+.datePickerNextButton {
+  font-size: 120%;
+  line-height: 1em;
+  color: #3a6aad;
+  cursor: hand;
+  cursor: pointer;
+  font-weight: bold;
+  padding: 0px 4px;
+  outline: none;
+}
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader-hovering {
+  background: #d3def6;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 2px 10px 5px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+  background: #ccc;
+  padding-top: 6px;
+  padding-left: 5px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContentContainer {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 0px 1px 1px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 4px;
+  padding: 4px 8px 4px 8px;
+  cursor: pointer;
+  cursor: hand;
+  color: white;
+  font-weight: normal;
+  text-align: center;
+  background: #8E8E8E;
+  -moz-border-radius: 3px 3px 0px 0px;
+  border-radius: 3px 3px 0px 0px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  background: white;
+  color: #333;
+  font-weight: bold;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+  background: #e7e7e7 url(images/thumb_vertical.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+  background: #e7e7e7 url(images/thumb_horz.png) center center no-repeat;
+  cursor: row-resize;
+}
\ No newline at end of file

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/clean_rtl.css
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/clean_rtl.css	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,1264 @@
+/**
+ * The file contains styles for GWT widgets in the Clean theme, in RTL mode.
+ *
+ * In order to maintain cross-browser compatibility, the following syntax is
+ * used to create IE6 specific style rules:
+ *    .gwt-Widget {
+ *      property: rule applies to all browsers
+ *      -property: rule applies only to IE6 (overrides previous rule)
+ *    }
+ *    * html .gwt-Widget {
+ *      property: rule applies to all versions of IE
+ *    }
+ */
+
+body, table td, select, button {
+  font-family: Arial Unicode MS, Arial, sans-serif;
+  font-size: small;
+}
+pre {
+  font-family: "courier new", courier;
+  font-size: small;
+}
+body {
+  color: black;
+  margin: 10px;
+  border: 0px;
+  padding: 0px;
+  background: #fff;
+  direction: rtl;
+}
+a, a:visited {
+  color: #0066cc;
+  text-decoration:none;
+}
+
+a:hover {
+  color: #0066cc;
+  text-decoration:underline;
+}
+
+select {
+  background: white;
+}
+
+/**
+ * The reference theme can be used to determine when this style sheet has
+ * loaded.  Create a hidden div element with absolute position, assign the style
+ * name below, and attach it to the DOM.  Use a timer to detect when the
+ * element's height and width are set to 5px.
+ */
+.gwt-Reference-clean-rtl {
+  height: 5px;
+  width: 5px;
+  zoom: 1;
+}
+
+.gwt-Button {
+  margin: 0;
+  padding: 5px 7px;
+  text-decoration: none;
+  cursor: pointer;
+  cursor: hand;
+  font-size:small;
+  background: url("images/hborder.png") repeat-x 0px -2077px;
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;
+  border-radius: 3px;
+ -moz-border-radius: 3px;
+}
+.gwt-Button:active {
+  border: 1px inset #ccc;
+}
+.gwt-Button:hover {
+  border-color: #939393;
+}
+.gwt-Button[disabled] {
+  cursor: default;
+  color: #888;
+}
+.gwt-Button[disabled]:hover {
+  border: 1px outset #ccc;
+}
+
+.gwt-CheckBox {
+}
+.gwt-CheckBox-disabled {
+  color: #888;
+}
+
+.gwt-DecoratorPanel {
+}
+.gwt-DecoratorPanel .topCenter {
+  border-top: 1px solid #bbb;
+  line-height: 0px;
+}
+.gwt-DecoratorPanel .bottomCenter {
+  border-bottom: 1px solid #bbb;
+  line-height: 0px;
+}
+.gwt-DecoratorPanel .topCenterInner,
+.gwt-DecoratorPanel .bottomCenterInner {
+  height: 1px;
+  line-height: 0px;
+  font-size: 1px;
+}
+.gwt-DecoratorPanel .middleLeft {
+  border-left: 1px solid #bbb;
+}
+.gwt-DecoratorPanel .middleRight {
+  border-right: 1px solid #bbb;
+}
+.gwt-DecoratorPanel .middleLeftInner,
+.gwt-DecoratorPanel .middleRightInner {
+  width: 1px;
+  line-height: 1px;
+}
+.gwt-DecoratorPanel .topLeftInner,
+.gwt-DecoratorPanel .topRightInner,
+.gwt-DecoratorPanel .bottomLeftInner,
+.gwt-DecoratorPanel .bottomRightInner {
+  width: 5px;
+  height: 5px;
+  zoom: 1;
+  font-size: 1px;
+  overflow: hidden;
+}
+.gwt-DecoratorPanel .topLeft {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat 0px -6px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -6px;
+}
+.gwt-DecoratorPanel .topRight {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat -5px -6px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -6px;
+}
+.gwt-DecoratorPanel .bottomLeft {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat 0px -11px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -11px;
+}
+.gwt-DecoratorPanel .bottomRight {
+  line-height: 0px;
+  background: url(images/circles.png) no-repeat -5px -11px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -11px;
+}
+* html .gwt-DecoratorPanel .topLeftInner,
+* html .gwt-DecoratorPanel .topRightInner,
+* html .gwt-DecoratorPanel .bottomLeftInner,
+* html .gwt-DecoratorPanel .bottomRightInner {
+  width: 5px;
+  height: 5px;
+  overflow: hidden;
+}
+
+.gwt-DialogBox .Caption {
+  background: #F1F1F1;
+  padding: 4px 4px 4px 8px;
+  cursor: default;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+  font-weight: bold;
+  border-bottom: 1px solid #bbbbbb;
+  border-top: 1px solid #D2D2D2;
+}
+.gwt-DialogBox .dialogContent {
+}
+.gwt-DialogBox .dialogMiddleCenter {
+  padding: 3px;
+  background: white;
+}
+.gwt-DialogBox .dialogBottomCenter {
+  background: url(images/hborder.png) repeat-x 0px -2945px;
+  -background: url(images/hborder_ie6.png) repeat-x 0px -2144px;
+}
+.gwt-DialogBox .dialogMiddleLeft {
+  background: url(images/vborder.png) repeat-y -31px 0px;
+}
+.gwt-DialogBox .dialogMiddleRight {
+  background: url(images/vborder.png) repeat-y -32px 0px;
+  -background: url(images/vborder_ie6.png) repeat-y -32px 0px;
+}
+.gwt-DialogBox .dialogTopLeftInner {
+  width: 10px;
+  height: 8px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogTopRightInner {
+  width: 12px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogBottomLeftInner {
+  width: 10px;
+  height: 12px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogBottomRightInner {
+  width: 12px;
+  height: 12px;
+  zoom: 1;
+}
+.gwt-DialogBox .dialogTopLeft {
+  background: url(images/circles.png) no-repeat -20px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -20px 0px;
+}
+.gwt-DialogBox .dialogTopRight {
+  background: url(images/circles.png) no-repeat -28px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -28px 0px;
+}
+.gwt-DialogBox .dialogBottomLeft {
+  background: url(images/circles.png) no-repeat 0px -36px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -36px;
+}
+.gwt-DialogBox .dialogBottomRight {
+  background: url(images/circles.png) no-repeat -8px -36px;
+  -background: url(images/circles_ie6.png) no-repeat -8px -36px;
+}
+* html .gwt-DialogBox .dialogTopLeftInner {
+  width: 10px;
+  overflow: hidden;
+}
+* html .gwt-DialogBox .dialogTopRightInner {
+  width: 12px;
+  overflow: hidden;
+}
+* html .gwt-DialogBox .dialogBottomLeftInner {
+  width: 10px;
+  height: 12px;
+  overflow: hidden;
+}
+* html .gwt-DialogBox .dialogBottomRightInner {
+  width: 12px;
+  height: 12px;
+  overflow: hidden;
+}
+
+.gwt-DisclosurePanel {
+}
+.gwt-DisclosurePanel-open {
+}
+.gwt-DisclosurePanel-closed {
+}
+.gwt-DisclosurePanel .header,
+.gwt-DisclosurePanel .header a,
+.gwt-DisclosurePanel .header td {
+  text-decoration: none;  /* Remove underline from header */
+  color: black; 
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-DisclosurePanel .content {
+  border-right: 3px solid #e7e7e7;
+  padding: 4px 8px 4px 0px;
+  margin-right: 6px;
+}
+
+.gwt-FileUpload {
+}
+
+.gwt-Frame {
+  border-top: 2px solid #666;
+  border-left: 2px solid #666;
+  border-right: 2px solid #bbb;
+  border-bottom: 2px solid #bbb;
+}
+
+.gwt-HorizontalSplitPanel {
+}
+.gwt-HorizontalSplitPanel .hsplitter {
+  cursor: move;
+  border: 0px; 
+  background: #e7e7e7;
+  line-height: 0px;
+}
+.gwt-VerticalSplitPanel {
+}
+.gwt-VerticalSplitPanel .vsplitter {
+  cursor: move;
+  border: 0px; 
+  background: #e7e7e7;
+  line-height: 0px;
+}
+
+.gwt-HTML {
+  padding: 0 0px;
+}
+
+.gwt-Hyperlink {
+}
+
+.gwt-Image {
+}
+
+.gwt-Label {
+}
+
+.gwt-ListBox {
+}
+
+.gwt-MenuBar {
+  cursor: default;
+}
+.gwt-MenuBar .gwt-MenuItem {
+  cursor: default;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+.gwt-MenuBar .gwt-MenuItem-selected {
+  background: #E3E8F3;
+}
+.gwt-MenuBar-horizontal {
+  background: #e3e8f3 url(images/hborder.png) repeat-x 0px -2003px;
+  border: 1px solid #e0e0e0;
+}
+.gwt-MenuBar-horizontal .gwt-MenuItem {
+  padding: 5px 10px;
+  vertical-align: bottom;
+  color: #000;
+  font-weight: bold;
+}
+.gwt-MenuBar-horizontal .gwt-MenuItemSeparator {
+  width: 1px;
+  padding: 0px;
+  margin: 0px;
+  border: 0px;
+  border-right: 1px solid #ccc;
+  background: white;
+}
+.gwt-MenuBar-horizontal .gwt-MenuItemSeparator .menuSeparatorInner {
+  width: 1px;
+  height: 1px;
+  background: white; 
+}
+.gwt-MenuBar-vertical {
+  margin-top: 0px;
+  margin-right: 0px;
+  background: white;
+}
+.gwt-MenuBar-vertical table {
+  border-collapse: collapse;
+}
+.gwt-MenuBar-vertical .gwt-MenuItem {
+  padding: 2px 1px 2px 40px;
+}
+.gwt-MenuBar-vertical .gwt-MenuItemSeparator {
+  padding: 2px 0px;
+}
+.gwt-MenuBar-vertical .gwt-MenuItemSeparator .menuSeparatorInner {
+  height: 1px;
+  padding: 0px;
+  border: 0px;
+  border-top: 1px solid #ccc;
+  overflow: hidden;
+}
+.gwt-MenuBar-vertical .subMenuIcon {
+  padding-left: 4px;
+}
+.gwt-MenuBar-vertical .subMenuIcon-selected {
+  background: #E3E8F3;
+}
+.gwt-MenuBarPopup {
+  margin: 0px 3px 0px 0px;
+}
+.gwt-MenuBarPopup .menuPopupTopCenter {
+  background: url(images/hborder.png) 0px -12px repeat-x;
+}
+.gwt-MenuBarPopup .menuPopupBottomCenter {
+  background: url(images/hborder.png) 0px -13px repeat-x;
+  -background: url(images/hborder_ie6.png) 0px -13px repeat-x;
+}
+.gwt-MenuBarPopup .menuPopupMiddleLeft {
+  background: url(images/vborder.png) -12px 0px repeat-y;
+  -background: url(images/vborder_ie6.png) -12px 0px repeat-y;
+}
+.gwt-MenuBarPopup .menuPopupMiddleRight {
+  background: url(images/vborder.png) -13px 0px repeat-y;
+  -background: url(images/vborder_ie6.png) -13px 0px repeat-y;
+}
+.gwt-MenuBarPopup .menuPopupTopLeftInner {
+  width: 5px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupTopRightInner {
+  width: 8px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupBottomLeftInner {
+  width: 5px;
+  height: 8px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupBottomRightInner {
+  width: 8px;
+  height: 8px;
+  zoom: 1;
+}
+.gwt-MenuBarPopup .menuPopupTopLeft {
+  background: url(images/corner.png) no-repeat 0px -36px;
+  -background: url(images/corner_ie6.png) no-repeat 0px -36px;
+}
+.gwt-MenuBarPopup .menuPopupTopRight {
+  background: url(images/corner.png) no-repeat -5px -36px;
+  -background: url(images/corner_ie6.png) no-repeat -5px -36px;
+}
+.gwt-MenuBarPopup .menuPopupBottomLeft {
+  background: url(images/corner.png) no-repeat 0px -41px;
+  -background: url(images/corner_ie6.png) no-repeat 0px -41px;
+}
+.gwt-MenuBarPopup .menuPopupBottomRight {
+  background: url(images/corner.png) no-repeat -5px -41px;
+  -background: url(images/corner_ie6.png) no-repeat -5px -41px;
+}
+* html .gwt-MenuBarPopup .menuPopupTopLeftInner {
+  width: 5px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-MenuBarPopup .menuPopupTopRightInner {
+  width: 8px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-MenuBarPopup .menuPopupBottomLeftInner {
+  width: 5px;
+  height: 8px;
+  overflow: hidden;
+}
+* html .gwt-MenuBarPopup .menuPopupBottomRightInner {
+  width: 8px;
+  height: 8px;
+  overflow: hidden;
+}
+
+.gwt-PasswordTextBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: 100%;
+}
+.gwt-PasswordTextBox-readonly {
+  color: #888;
+}
+
+.gwt-PopupPanel {
+  border: 3px solid #e7e7e7;
+  padding: 3px;
+  background: white;
+}
+
+.gwt-DecoratedPopupPanel .popupContent {
+}
+.gwt-DecoratedPopupPanel .popupMiddleCenter {
+  padding: 3px;
+  background: #f1f1f1;
+}
+.gwt-DecoratedPopupPanel .popupTopCenter {
+  background: url(images/hborder.png) 0px -2937px repeat-x;
+}
+.gwt-DecoratedPopupPanel .popupBottomCenter {
+  background:  url(images/hborder.png) repeat-x 0px -2938px;
+  -background: url(images/hborder_ie6.png) repeat-x 0px -2138px;
+}
+.gwt-DecoratedPopupPanel .popupMiddleLeft {
+  background: url(images/vborder.png) -21px 0px repeat-y;
+}
+.gwt-DecoratedPopupPanel .popupMiddleRight {
+  background: url(images/vborder.png) repeat-y -24px 0px;
+  -background: url(images/vborder_ie6.png) repeat-y -24px 0px;
+}
+.gwt-DecoratedPopupPanel .popupTopLeftInner {
+  width: 6px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupTopRightInner {
+  width: 6px;
+  height: 5px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupBottomLeftInner {
+  width: 6px;
+  height: 6px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupBottomRightInner {
+  width: 6px;
+  height: 6px;
+  zoom: 1;
+}
+.gwt-DecoratedPopupPanel .popupTopLeft {
+  background: url(images/circles.png) no-repeat 0px -16px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -16px;
+}
+.gwt-DecoratedPopupPanel .popupTopRight {
+  background: url(images/circles.png) no-repeat -6px -16px;
+  -background: url(images/circles_ie6.png) no-repeat -6px -16px;
+}
+.gwt-DecoratedPopupPanel .popupBottomLeft {
+  background: url(images/circles.png) no-repeat 0px -21px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -21px;
+}
+.gwt-DecoratedPopupPanel .popupBottomRight {
+  background: url(images/circles.png) no-repeat -6px -21px;
+  -background: url(images/circles_ie6.png) no-repeat -6px -21px;
+}
+* html .gwt-DecoratedPopupPanel .popupTopLeftInner {
+  width: 6px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-DecoratedPopupPanel .popupTopRightInner {
+  width: 6px;
+  height: 5px;
+  overflow: hidden;
+}
+* html .gwt-DecoratedPopupPanel .popupBottomLeftInner {
+  width: 6px;
+  height: 6px;
+  overflow: hidden;
+}
+* html .gwt-DecoratedPopupPanel .popupBottomRightInner {
+  width: 6px;
+  height: 6px;
+  overflow: hidden;
+}
+
+.gwt-PopupPanelGlass {
+  background-color: #000;
+  opacity: 0.3;
+  filter: alpha(opacity=30);
+}
+
+.gwt-PushButton-up,
+.gwt-PushButton-up-hovering,
+.gwt-PushButton-up-disabled,
+.gwt-PushButton-down,
+.gwt-PushButton-down-hovering,
+.gwt-PushButton-down-disabled {
+  margin: 0;
+  text-decoration: none;
+  background: url("images/hborder.png") repeat-x 0px -27px;
+  border-radius: 2px;
+  -moz-border-radius: 2px;
+}
+.gwt-PushButton-up,
+.gwt-PushButton-up-hovering,
+.gwt-PushButton-up-disabled {
+  padding: 3px 5px 3px 5px;
+}
+.gwt-PushButton-up {
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-up-hovering {
+  border: 1px solid;
+  border-color: #939393;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-up-disabled {
+  border: 1px solid #bbb;
+  cursor: default;
+  opacity: .5;
+  filter: alpha(opacity=45);
+  zoom: 1;
+}
+.gwt-PushButton-down,
+.gwt-PushButton-down-hovering,
+.gwt-PushButton-down-disabled {
+  padding: 4px 6px 2px 4px;
+  outline:none;
+}
+.gwt-PushButton-down {
+  border: 1px inset #666;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-down-hovering {
+  border: 1px solid #939393;
+  border-top: 1px solid #333333;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-PushButton-down-disabled {
+  border: 1px outset #ccc;
+  cursor: default;
+  opacity: 0.5;
+  filter: alpha(opacity=45);
+  zoom: 1;
+}
+
+.gwt-RadioButton {
+}
+.gwt-RadioButton-disabled {
+  color: #888;
+}
+
+.gwt-RichTextArea {
+}
+.hasRichTextToolbar {
+  border: 0px;
+}
+.gwt-RichTextToolbar {
+  background: #e3e8f3 url(images/hborder.png) repeat-x 0px -2003px;
+  border-bottom: 1px solid #BBBBBB;
+  padding: 3px;
+  margin: 0px;
+}
+.gwt-RichTextToolbar .gwt-PushButton-up {
+  padding: 0px 0px 0px 1px;
+  margin-left: 4px;
+  margin-bottom: 4px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-PushButton-up-hovering {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-PushButton-down {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-PushButton-down-hovering {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border-width: 1px; 
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-up {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-up-hovering {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 0px 0px 1px;
+  border-width: 1px;
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-down {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border-width: 1px;
+}
+.gwt-RichTextToolbar .gwt-ToggleButton-down-hovering {
+  margin-left: 4px;
+  margin-bottom: 4px;
+  padding: 0px 1px 0px 0px;
+  border-width: 1px;
+}
+
+.gwt-StackPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackPanel .gwt-StackPanelItem {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-StackPanel .gwt-StackPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 2px 10px 5px;
+}
+
+.gwt-DecoratedStackPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 5px 10px 2px;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelItem {
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-DecoratedStackPanel .stackItemTopLeft,
+.gwt-DecoratedStackPanel .stackItemTopRight {
+  height: 6px;
+  width: 6px;
+  zoom: 1;
+}
+.gwt-DecoratedStackPanel .stackItemTopLeft {
+  border-left: 1px solid #bbbbbb;
+  background: #d3def6 url(images/corner.png) no-repeat 0px -49px;
+  -background: #d3def6 url(images/corner_ie6.png) no-repeat 0px -49px;
+}
+.gwt-DecoratedStackPanel .stackItemTopRight {
+  border-right: 1px solid #bbbbbb;
+  background: #d3def6 url(images/corner.png) no-repeat -6px -49px;
+  -background: #d3def6 url(images/corner_ie6.png) no-repeat -6px -49px;
+}
+.gwt-DecoratedStackPanel .stackItemTopLeftInner,
+.gwt-DecoratedStackPanel .stackItemTopRightInner {
+  width: 1px;
+  height: 1px;
+}
+* html .gwt-DecoratedStackPanel .stackItemTopLeftInner,
+* html .gwt-DecoratedStackPanel .stackItemTopRightInner {
+  width: 6px;
+  height: 6px;
+  overflow: hidden;
+}
+.gwt-DecoratedStackPanel .stackItemTopCenter {
+  background: url(images/hborder.png) 0px -21px repeat-x;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleLeft {
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+  border-left: 1px solid #bbbbbb;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleLeftInner,
+.gwt-DecoratedStackPanel .stackItemMiddleRightInner {
+  width: 1px;
+  height: 1px;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleRight {
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+  border-right: 1px solid #bbbbbb;
+}
+.gwt-DecoratedStackPanel .stackItemMiddleCenter {
+  font-weight: bold;
+  font-size: 1.3em;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-first .stackItemTopRight,
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-first .stackItemTopLeft {
+  border: 0px;
+  background-color: white;
+}
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-below-selected .stackItemTopLeft,
+.gwt-DecoratedStackPanel .gwt-StackPanelItem-below-selected .stackItemTopRight {
+  background-color: white;
+}
+
+.gwt-SuggestBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: 100%;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+
+.gwt-SuggestBoxPopup {
+}
+
+.gwt-SuggestBoxPopup .item {
+  padding: 2px 6px;
+  color: #000;
+  cursor: default;
+  font-size: 110%;
+}
+.gwt-SuggestBoxPopup .item-selected {
+  background: #D5E2FF;
+}
+.gwt-SuggestBoxPopup .suggestPopupContent {
+  background: white;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopCenter {
+  border-top: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomCenter {
+  border-bottom: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopCenterInner,
+.gwt-SuggestBoxPopup .suggestPopupBottomCenterInner {
+  height: 1px;
+  line-height: 1px;
+}
+.gwt-SuggestBoxPopup .suggestPopupMiddleLeft {
+  border-left: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupMiddleRight {
+  border-right: 1px solid #bbb;
+}
+.gwt-SuggestBoxPopup .suggestPopupMiddleLeftInner,
+.gwt-SuggestBoxPopup .suggestPopupMiddleRightInner {
+  width: 1px;
+  line-height: 1px;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopLeftInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;  
+}
+.gwt-SuggestBoxPopup .suggestPopupTopRightInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomLeftInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomRightInner {
+  width: 0px;
+  height: 0px;
+  zoom: 1;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopLeft {
+  background: url(images/circles.png) no-repeat 0px -6px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -6px;
+  width:5px;
+  height:5px;
+}
+.gwt-SuggestBoxPopup .suggestPopupTopRight {
+  background: url(images/circles.png) no-repeat -5px -6px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -6px;
+  width:5px;
+  height:5px;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomLeft {
+  background: url(images/circles.png) no-repeat 0px -11px;
+  -background: url(images/circles_ie6.png) no-repeat 0px -11px;
+  width:5px;
+  height:5px;
+}
+.gwt-SuggestBoxPopup .suggestPopupBottomRight {
+  background: url(images/circles.png) no-repeat -5px -11px;
+  -background: url(images/circles_ie6.png) no-repeat -5px -11px;
+  width:5px;
+  height:5px;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupTopLeftInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupTopRightInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupBottomLeftInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+* html .gwt-SuggestBoxPopup .suggestPopupBottomRightInner {
+  width: 0px;
+  height: 0px;
+  overflow: hidden;
+}
+
+.gwt-TabBar {
+  background: #ccc;
+  padding-top: 6px;
+}
+.gwt-TabBar .gwt-TabBarFirst {
+  width: 5px;  /* first tab distance from the left */
+}
+.gwt-TabBar .gwt-TabBarRest {
+}
+.gwt-TabBar .gwt-TabBarItem {
+  margin-right: 4px;
+  padding: 4px 8px 4px 8px;
+  cursor: pointer;
+  cursor: hand;
+  color: white;
+  font-weight: normal;
+  text-align: center;
+  background: #8E8E8E;
+  -moz-border-radius: 3px 3px 0px 0px;
+  border-radius: 3px 3px 0px 0px;
+}
+.gwt-TabBar .gwt-TabBarItem-selected {
+  cursor: default;
+  background: white;
+  color: #333;
+  font-weight: bold;
+} 
+.gwt-TabBar .gwt-TabBarItem-disabled {
+  cursor: default;
+  color: #999999;
+}
+.gwt-TabPanel {
+}
+.gwt-TabPanelBottom {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 0px 1px 1px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-DecoratedTabBar {
+  background: #ccc;
+  padding-top: 6px;
+}
+.gwt-DecoratedTabBar .gwt-TabBarFirst {
+  width: 5px;  /* first tab distance from the left */
+}
+.gwt-DecoratedTabBar .gwt-TabBarRest {
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem {
+  border-collapse: collapse;
+  margin-right: 4px;
+}
+.gwt-DecoratedTabBar .tabTopCenter {
+  padding: 0px;
+  background: #8E8E8E;
+}
+.gwt-DecoratedTabBar .tabTopLeft,
+.gwt-DecoratedTabBar .tabTopRight {
+  padding: 0px;
+  zoom: 1;
+}
+.gwt-DecoratedTabBar .tabTopLeftInner,
+.gwt-DecoratedTabBar .tabTopRightInner {
+  width: 3px;
+  height: 3px;
+}
+.gwt-DecoratedTabBar .tabTopLeft {
+  background: url(images/circles.png) no-repeat 0px 0px;
+  -background: url(images/circles_ie6.png) no-repeat 0px 0px;
+}
+.gwt-DecoratedTabBar .tabTopRight {
+  background: url(images/circles.png) no-repeat -3px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -3px 0px;
+}
+* html .gwt-DecoratedTabBar .tabTopLeftInner,
+* html .gwt-DecoratedTabBar .tabTopRightInner {
+  width: 3px;
+  height: 3px;
+  overflow: hidden;
+}
+.gwt-DecoratedTabBar .tabMiddleLeft,
+.gwt-DecoratedTabBar .tabMiddleRight {
+  width: 3px;
+  padding: 0px;
+  background: #8E8E8E;
+}
+.gwt-DecoratedTabBar .tabMiddleLeftInner,
+.gwt-DecoratedTabBar .tabMiddleRightInner {
+  width: 1px;
+  height: 1px;
+}
+.gwt-DecoratedTabBar .tabMiddleCenter {
+  padding: 0px 5px 4px 5px;
+  cursor: pointer;
+  cursor: hand;
+  color: #fff;
+  font-weight: normal;
+  text-align: center;
+  background: #8E8E8E;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabTopCenter {
+  background:#fff;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabTopLeft {
+  background: url(images/circles.png) no-repeat -6px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -6px 0px;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabTopRight {
+  background: url(images/circles.png) no-repeat -9px 0px;
+  -background: url(images/circles_ie6.png) no-repeat -9px 0px;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabMiddleLeft,
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabMiddleRight {
+  background: #fff;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-selected .tabMiddleCenter {
+  cursor: default;
+  background: #fff;
+  color:#333;
+  font-weight:bold;
+}
+.gwt-DecoratedTabBar .gwt-TabBarItem-disabled .tabMiddleCenter {
+  cursor: default;
+  color: #999999;
+}
+
+.gwt-TextArea {
+  padding: 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #666;
+  font-size: 100%;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+.gwt-TextArea-readonly {
+  color: #888;
+}
+
+.gwt-TextBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: small;
+  font-family: Arial Unicode MS, Arial, sans-serif;
+}
+.gwt-TextBox-readonly {
+  color: #888;
+}
+.gwt-ToggleButton-up,
+.gwt-ToggleButton-up-hovering,
+.gwt-ToggleButton-up-disabled,
+.gwt-ToggleButton-down,
+.gwt-ToggleButton-down-hovering,
+.gwt-ToggleButton-down-disabled {
+  margin: 0;
+  text-decoration: none;
+  background: url("images/hborder.png") repeat-x 0px -27px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+}
+.gwt-ToggleButton-up,
+.gwt-ToggleButton-up-hovering,
+.gwt-ToggleButton-up-disabled {
+  padding: 3px 5px 3px 5px;
+}
+.gwt-ToggleButton-up {
+  border:1px solid #bbb;
+  border-bottom: 1px solid #a0a0a0;  
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-up-hovering {
+  border: 1px solid;
+  border-color: #939393;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-up-disabled {
+  border: 1px solid #bbb;
+  cursor: default;
+  opacity: .5;
+  zoom: 1;
+  filter: alpha(opacity=45);
+}
+.gwt-ToggleButton-down,
+.gwt-ToggleButton-down-hovering,
+.gwt-ToggleButton-down-disabled {
+  padding: 4px 6px 2px 4px;
+}
+.gwt-ToggleButton-down {
+  background-position: 0 -513px;
+  border: 1px inset #666;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-down-hovering {
+  background-position: 0 -513px;
+  border: 1px inset;
+  border-color: #9cf #69e #69e #7af;
+  cursor: pointer;
+  cursor: hand;
+}
+.gwt-ToggleButton-down-disabled {
+  background-position: 0 -513px;
+  border: 1px inset #ccc;
+  cursor: default;
+  opacity: .5;
+  zoom: 1;
+  filter: alpha(opacity=45);
+}
+
+.gwt-Tree .gwt-TreeItem {
+  padding: 1px 0px;
+  margin: 0px;
+  white-space: nowrap;
+  cursor: hand;
+  cursor: pointer;
+  zoom: 1;
+}
+.gwt-Tree .gwt-TreeItem-selected {
+  background: #ebeff9;
+}
+.gwt-TreeItem .gwt-RadioButton input,
+.gwt-TreeItem .gwt-CheckBox input {
+  margin-right: 0px;
+}
+* html .gwt-TreeItem .gwt-RadioButton input,
+* html .gwt-TreeItem .gwt-CheckBox input {
+  margin-right: -4px;
+}
+
+.gwt-DateBox {
+  padding: 5px 4px;
+  border: 1px solid #ccc;
+  border-top: 1px solid #999;
+  font-size: 100%;
+}
+.gwt-DateBox input {
+  width: 8em;
+}
+.dateBoxFormatError {
+  background: #ffcccc;
+}
+.dateBoxPopup {
+}
+
+.gwt-DatePicker {
+  border: 1px solid #ccc;
+  border-top:1px solid #999;
+  cursor: default;
+}
+.gwt-DatePicker td,
+.datePickerMonthSelector td:focus {
+  outline: none;
+}
+.datePickerDays {
+  width: 100%;
+  background: white;
+}
+.datePickerDay,
+.datePickerWeekdayLabel,
+.datePickerWeekendLabel {
+  font-size: 85%;
+  text-align: center;
+  padding: 4px;
+  outline: none;
+  font-weight:bold;
+  color:#333;
+  border-right: 1px solid #EDEDED;
+  border-bottom: 1px solid #EDEDED;
+}
+.datePickerWeekdayLabel,
+.datePickerWeekendLabel {
+  background: #fff;
+  padding: 0px 4px 2px;
+  cursor: default;
+  color:#666;
+  font-size:70%;
+  font-weight:normal;
+}
+.datePickerDay {
+  padding: 4px 7px;
+  cursor: hand;
+  cursor: pointer;
+}
+.datePickerDayIsWeekend {
+  background: #f7f7f7;
+}
+.datePickerDayIsFiller {
+  color: #999;
+  font-weight:normal;
+}
+.datePickerDayIsValue {
+  background: #d7dfe8;
+}
+.datePickerDayIsDisabled {
+  color: #AAAAAA;
+  font-style: italic;
+}
+.datePickerDayIsHighlighted {
+  background: #F0E68C;
+}
+.datePickerDayIsValueAndHighlighted {
+  background: #d7dfe8;
+}
+.datePickerDayIsToday {
+  padding: 3px;
+  color: #fff;
+  background: url(images/hborder.png) repeat-x 0px -2607px;
+}
+
+.datePickerMonthSelector {
+  width: 100%;
+  padding: 1px 0 5px 0;
+  background: #fff;
+}
+td.datePickerMonth {
+  text-align: center;
+  vertical-align: middle;
+  white-space: nowrap;
+  font-size: 100%;
+  font-weight: bold;
+  color: #333;
+}
+.datePickerPreviousButton,
+.datePickerNextButton {
+  font-size: 120%;
+  line-height: 1em;
+  color: #3a6aad;
+  cursor: hand;
+  cursor: pointer;
+  font-weight: bold;
+  padding: 0px 4px;
+  outline: none;
+}
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader-hovering {
+  background: #d3def6;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 5px 10px 2px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+  background: #ccc;
+  padding-top: 6px;
+  padding-right: 5px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContentContainer {
+  border-color: #ccc;
+  border-style: solid;
+  border-width: 0px 1px 1px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-right: 4px;
+  padding: 4px 8px 4px 8px;
+  cursor: pointer;
+  cursor: hand;
+  color: white;
+  font-weight: normal;
+  text-align: center;
+  background: #8E8E8E;
+  -moz-border-radius: 3px 3px 0px 0px;
+  border-radius: 3px 3px 0px 0px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  background: white;
+  color: #333;
+  font-weight: bold;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+  background: #e7e7e7 url(images/thumb_vertical.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+  background: #e7e7e7 url(images/thumb_horz.png) center center no-repeat;
+  cursor: row-resize;
+}
\ No newline at end of file

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/circles.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/circles_ie6.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/corner.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/corner_ie6.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/hborder.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/hborder_ie6.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/thumb_horz.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/thumb_vertical.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/vborder.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/gwt/clean/images/vborder_ie6.png
==============================================================================
Binary file. No diff available.

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/hosted.html
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/hosted.html	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,355 @@
+<html>
+<head><script>
+var $wnd = parent;
+var $doc = $wnd.document;
+var $moduleName, $moduleBase, $entry
+,$stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null
+,$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;
+// Lightweight metrics
+if ($stats) {
+  var moduleFuncName = location.search.substr(1);
+  var moduleFunc = $wnd[moduleFuncName];
+  var moduleName = moduleFunc ? moduleFunc.moduleName : "unknown";
+  $stats({moduleName:moduleName,sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'});
+}
+var $hostedHtmlVersion="2.1";
+
+var gwtOnLoad;
+var $hosted = "localhost:9997";
+
+function loadIframe(url) {
+  var topDoc = window.top.document;
+
+  // create an iframe
+  var iframeDiv = topDoc.createElement("div");
+  iframeDiv.innerHTML = "<iframe scrolling=no frameborder=0 src='" + url + "'>";
+  var iframe = iframeDiv.firstChild;
+  
+  // mess with the iframe style a little
+  var iframeStyle = iframe.style;
+  iframeStyle.position = "absolute";
+  iframeStyle.borderWidth = "0";
+  iframeStyle.left = "0";
+  iframeStyle.top = "0";
+  iframeStyle.width = "100%";
+  iframeStyle.backgroundColor = "#ffffff";
+  iframeStyle.zIndex = "1";
+  iframeStyle.height = "100%";
+
+  // update the top window's document's body's style
+  var hostBodyStyle = window.top.document.body.style; 
+  hostBodyStyle.margin = "0";
+  hostBodyStyle.height = iframeStyle.height;
+  hostBodyStyle.overflow = "hidden";
+
+  // insert the iframe
+  topDoc.body.insertBefore(iframe, topDoc.body.firstChild);
+}
+
+var ua = navigator.userAgent.toLowerCase();
+if (ua.indexOf("gecko") != -1) {
+  // install eval wrapper on FF to avoid EvalError problem
+  var __eval = window.eval;
+  window.eval = function(s) {
+    return __eval(s);
+  }
+}
+if (ua.indexOf("chrome") != -1) {
+  // work around __gwt_ObjectId appearing in JS objects
+  var hop = Object.prototype.hasOwnProperty;
+  Object.prototype.hasOwnProperty = function(prop) {
+    return prop != "__gwt_ObjectId" && hop.call(this, prop);
+  };
+  // do the same in our parent as well -- see issue 4486
+  // NOTE: this will have to be changed when we support non-iframe-based DevMode 
+  var hop2 = parent.Object.prototype.hasOwnProperty;
+  parent.Object.prototype.hasOwnProperty = function(prop) {
+    return prop != "__gwt_ObjectId" && hop2.call(this, prop);
+  };
+}
+
+// wrapper to call JS methods, which we need both to be able to supply a
+// different this for method lookup and to get the exception back
+function __gwt_jsInvoke(thisObj, methodName) {
+  try {
+    var args = Array.prototype.slice.call(arguments, 2);
+    return [0, window[methodName].apply(thisObj, args)];
+  } catch (e) {
+    return [1, e];
+  }
+}
+
+var __gwt_javaInvokes = [];
+function __gwt_makeJavaInvoke(argCount) {
+  return __gwt_javaInvokes[argCount] || __gwt_doMakeJavaInvoke(argCount);
+}
+
+function __gwt_doMakeJavaInvoke(argCount) {
+  // IE6 won't eval() anonymous functions except as r-values
+  var argList = "";
+  for (var i = 0; i < argCount; i++) {
+    argList += ",p" + i;
+  }
+  var argListNoComma = argList.substring(1);
+
+  return eval(
+    "__gwt_javaInvokes[" + argCount + "] =\n" +
+    "  function(thisObj, dispId" + argList + ") {\n" +
+    "    var result = __static(dispId, thisObj" + argList + ");\n" +
+    "    if (result[0]) {\n" +
+    "      throw result[1];\n" +
+    "    } else {\n" +
+    "      return result[1];\n" +
+    "    }\n" +
+    "  }\n"
+  ); 
+}
+
+/*
+ * This is used to create tear-offs of Java methods.  Each function corresponds
+ * to exactly one dispId, and also embeds the argument count.  We get the "this"
+ * value from the context in which the function is being executed.
+ * Function-object identity is preserved by caching in a sparse array.
+ */
+var __gwt_tearOffs = [];
+var __gwt_tearOffGenerators = [];
+function __gwt_makeTearOff(proxy, dispId, argCount) {
+  return __gwt_tearOffs[dispId] || __gwt_doMakeTearOff(dispId, argCount);
+}
+
+function __gwt_doMakeTearOff(dispId, argCount) {
+  return __gwt_tearOffs[dispId] = 
+      (__gwt_tearOffGenerators[argCount] || __gwt_doMakeTearOffGenerator(argCount))(dispId);
+}
+
+function __gwt_doMakeTearOffGenerator(argCount) {
+  // IE6 won't eval() anonymous functions except as r-values
+  var argList = "";
+  for (var i = 0; i < argCount; i++) {
+    argList += ",p" + i;
+  }
+  var argListNoComma = argList.substring(1);
+
+  return eval(
+    "__gwt_tearOffGenerators[" + argCount + "] =\n" +
+    "  function(dispId) {\n" +
+    "    return function(" + argListNoComma + ") {\n" +
+    "      var result = __static(dispId, this" + argList + ");\n" +
+    "      if (result[0]) {\n" +
+    "        throw result[1];\n" +
+    "      } else {\n" +
+    "        return result[1];\n" +
+    "      }\n" +
+    "    }\n" +
+    "  }\n"
+  ); 
+}
+
+function __gwt_makeResult(isException, result) {
+  return [isException, result];
+}
+
+function __gwt_disconnected() {
+  // Prevent double-invocation.
+  window.__gwt_disconnected = new Function();
+  // Do it in a timeout so we can be sure we have a clean stack.
+  window.setTimeout(__gwt_disconnected_impl, 1);
+}
+
+function __gwt_disconnected_impl() {
+  __gwt_displayGlassMessage('GWT Code Server Disconnected',
+      'Most likely, you closed GWT Development Mode. Or, you might have lost '
+      + 'network connectivity. To fix this, try restarting GWT Development Mode and '
+      + '<a style="color: #FFFFFF; font-weight: bold;" href="javascript:location.reload()">'
+      + 'REFRESH</a> this page.');
+}
+
+// Keep track of z-index to allow layering of multiple glass messages
+var __gwt_glassMessageZIndex = 2147483647;
+
+// Note this method is also used by ModuleSpace.java
+function __gwt_displayGlassMessage(summary, details) {
+  var topWin = window.top;
+  var topDoc = topWin.document;
+  var outer = topDoc.createElement("div");
+  // Do not insert whitespace or outer.firstChild will get a text node.
+  outer.innerHTML = 
+    '<div style="position:absolute;z-index:' + __gwt_glassMessageZIndex-- +
+    ';left:50px;top:50px;width:600px;color:#FFF;font-family:verdana;text-align:left;">' +
+    '<div style="font-size:30px;font-weight:bold;">' + summary + '</div>' +
+    '<div style="font-size:15px;">' + details + '</div>' +
+    '</div>' +
+    '<div style="position:absolute;z-index:' + __gwt_glassMessageZIndex-- +
+    ';left:0px;top:0px;right:0px;bottom:0px;filter:alpha(opacity=60);opacity:0.6;background-color:#000;"></div>'
+  ;
+  topDoc.body.appendChild(outer);
+  var glass = outer.firstChild;
+  var glassStyle = glass.style;
+
+  // Scroll to the top and remove scrollbars.
+  topWin.scrollTo(0, 0);
+  if (topDoc.compatMode == "BackCompat") {
+    topDoc.body.style["overflow"] = "hidden";
+  } else {
+    topDoc.documentElement.style["overflow"] = "hidden";
+  }
+
+  // Steal focus.
+  glass.focus();
+
+  if ((navigator.userAgent.indexOf("MSIE") >= 0) && (topDoc.compatMode == "BackCompat")) {
+    // IE quirks mode doesn't support right/bottom, but does support this.
+    glassStyle.width = "125%";
+    glassStyle.height = "100%";
+  } else if (navigator.userAgent.indexOf("MSIE 6") >= 0) {
+    // IE6 doesn't have a real standards mode, so we have to use hacks.
+    glassStyle.width = "125%"; // Get past scroll bar area.
+    // Nasty CSS; onresize would be better but the outer window won't let us add a listener IE.
+    glassStyle.setExpression("height", "document.documentElement.clientHeight");
+  }
+
+  $doc.title = summary + " [" + $doc.title + "]";
+}
+
+function findPluginObject() {
+  try {
+    return document.getElementById('pluginObject');
+  } catch (e) {
+    return null;
+  }
+}
+
+function findPluginEmbed() {
+  try {
+    return document.getElementById('pluginEmbed')
+  } catch (e) {
+    return null;
+  }
+}
+
+function findPluginXPCOM() {
+  try {
+    return __gwt_HostedModePlugin;
+  } catch (e) {
+    return null;
+  }
+}
+
+gwtOnLoad = function(errFn, modName, modBase){
+  $moduleName = modName;
+  $moduleBase = modBase;
+
+  // Note that the order is important
+  var pluginFinders = [
+    findPluginXPCOM,
+    findPluginObject,
+    findPluginEmbed,
+  ];
+  var topWin = window.top;
+  var url = topWin.location.href;
+  if (!topWin.__gwt_SessionID) {
+    var ASCII_EXCLAMATION = 33;
+    var ASCII_TILDE = 126;
+    var chars = [];
+    for (var i = 0; i < 16; ++i) {
+      chars.push(Math.floor(ASCII_EXCLAMATION
+          + Math.random() * (ASCII_TILDE - ASCII_EXCLAMATION + 1)));
+    }
+    topWin.__gwt_SessionID = String.fromCharCode.apply(null, chars);
+  }
+  var plugin = null;
+  for (var i = 0; i < pluginFinders.length; ++i) {
+    try {
+      var maybePlugin = pluginFinders[i]();
+      if (maybePlugin != null && maybePlugin.init(window)) {
+        plugin = maybePlugin;
+        break;
+      }
+    } catch (e) {
+    }
+  }
+  if (!plugin) {
+    // try searching for a v1 plugin for backwards compatibility
+    var found = false;
+    for (var i = 0; i < pluginFinders.length; ++i) {
+      try {
+        plugin = pluginFinders[i]();
+        if (plugin != null && plugin.connect($hosted, $moduleName, window)) {
+          return;
+        }
+      } catch (e) {
+      }
+    }
+    loadIframe("http://gwt.google.com/missing-plugin");
+  } else {
+    if (plugin.connect(url, topWin.__gwt_SessionID, $hosted, $moduleName,
+        $hostedHtmlVersion)) {
+      window.onUnload = function() {
+        try {
+          // wrap in try/catch since plugins are not required to supply this
+          plugin.disconnect();
+        } catch (e) {
+        }
+      };
+    } else {
+      if (errFn) {
+        errFn(modName);
+      } else {
+        alert("Plugin failed to connect to Development Mode server at " + $hosted);
+        loadIframe("http://code.google.com/p/google-web-toolkit/wiki/TroubleshootingOOPHM");
+      }
+    }
+  }
+}
+
+window.onunload = function() {
+};
+
+// Lightweight metrics
+window.fireOnModuleLoadStart = function(className) {
+  $stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date()).getTime(), type:'onModuleLoadStart', className:className});
+};
+
+window.__gwt_module_id = 0;
+</script></head>
+<body>
+<font face='arial' size='-1'>This html file is for Development Mode support.</font>
+<script><!--
+// Lightweight metrics
+$stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date()).getTime(), type:'moduleEvalEnd'});
+
+// OOPHM currently only supports IFrameLinker
+var query = parent.location.search;
+if (!findPluginXPCOM()) {
+  document.write('<embed id="pluginEmbed" type="application/x-gwt-hosted-mode" width="10" height="10">');
+  document.write('</embed>');
+  document.write('<object id="pluginObject" CLASSID="CLSID:1D6156B6-002B-49E7-B5CA-C138FB843B4E">');
+  document.write('</object>');
+}
+
+// look for the old query parameter if we don't find the new one
+var idx = query.indexOf("gwt.codesvr=");
+if (idx >= 0) {
+  idx += 12;  // "gwt.codesvr=".length() == 12
+} else {
+  idx = query.indexOf("gwt.hosted=");
+  if (idx >= 0) {
+    idx += 11;  // "gwt.hosted=".length() == 11
+  }
+}
+if (idx >= 0) {
+  var amp = query.indexOf("&", idx);
+  if (amp >= 0) {
+    $hosted = query.substring(idx, amp);
+  } else {
+    $hosted = query.substring(idx);
+  }
+
+  // According to RFC 3986, some of this component's characters (e.g., ':')
+  // are reserved and *may* be escaped.
+  $hosted = decodeURIComponent($hosted);
+}
+
+query = window.location.search.substring(1);
+if (query && $wnd[query]) setTimeout($wnd[query].onScriptLoad, 1);
+--></script></body></html>

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/tm.js
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/tm.js	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,3926 @@
+// tmjs, version 0.4.0
+// http://github.com/jansc/tmjs
+// Copyright (c) 2010 Jan Schreiber <jans at ravn.no>
+// Licensed under the MIT-License.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+/*jslint browser: true, devel: true, onevar: true, undef: true,
+  nomen: false, eqeqeq: true, plusplus: true, bitwise: true,
+  regexp: true, newcap: true, immed: true, indent: 4 */
+/*global exports*/ 
+
+var TM, TopicMapSystemFactory;
+
+/**
+ * @namespace Global namespace that holds all Topic Maps related objects.
+ * @author Jan Schreiber <jans at ravn.no>
+ * @copyright 2010 Jan Schreiber <http://purl.org/net/jans>
+ * Date: Wed Dec 1 08:39:28 2010 +0100
+ */
+TM = (function () {
+    var Version, Hash, XSD, TMDM, Locator, EventType, Topic, Association,
+        Scoped, Construct, Typed, Reifiable,
+        DatatypeAware, TopicMap, Role, Name,
+        Variant, Occurrence, TopicMapSystemMemImpl,
+        Index, TypeInstanceIndex, ScopedIndex, 
+        SameTopicMapHelper, ArrayHelper, IndexHelper, addScope,
+        DuplicateRemover,
+        SignatureGenerator, MergeHelper, CopyHelper,
+        TypeInstanceHelper;
+
+    Version = '0.4.0';
+
+    // -----------------------------------------------------------------------
+    // Our swiss army knife for mixin of functions.
+    // See http://javascript.crockford.com/inheritance.html
+    Function.prototype.swiss = function (parnt) {
+        var i, name;
+        for (i = 1; i < arguments.length; i += 1) {
+            name = arguments[i];
+            this.prototype[name] = parnt.prototype[name];
+        }
+        return this;
+    };
+
+    // -----------------------------------------------------------------------
+    // Simple hash table for lookup tables
+    Hash = function () {
+        this.hash = {};
+        this.length = 0;
+    };
+
+    /**
+     * @class Simple hash implementation.
+     */
+    Hash.prototype = {
+        /**
+         * Returns the object belonging to the key key or undefined if the
+         * key does not exist.
+         * @param key {String} The hash key.
+         * @returns {object} The stored object or undefined.
+         */        
+        get: function (key) {
+            return this.hash[key];
+        },
+
+        /**
+         * Checks if the key exists in the hash table.
+         * @param key {String} The hash key.
+         * @returns {boolean} True if key exists in the hash table. False
+         *          otherwise.
+         */
+        contains: function (key) {
+            return this.get(key) !== undefined;
+        },
+
+        /**
+         * Stores an object in the hash table.
+         * @param key {String} The hash key.
+         * @param val {object} The value to be stored in the hash table.
+         * @returns val {object} A reference to the stored object.
+         */
+        put: function (key, val) {
+            if (!this.hash[key]) {
+                this.length += 1;
+            }
+            this.hash[key] = val;
+            return val;
+        },
+
+        /**
+         * Removes the key and the corresponding value from the hash table.
+         * @param key {String} Removes value corresponding to key and the key
+         *             from the hash table
+         * @returns {Hash} The hash table itself.
+         */
+        remove: function (key) {
+            delete this.hash[key];
+            this.length -= 1;
+            return this;
+        },
+
+        /**
+         * Returns an array with keys of the hash table.
+         * @returns {Array} An array with strings.
+         */
+        keys: function () {
+            var ret = [], key;
+            for (key in this.hash) {
+                if (this.hash.hasOwnProperty(key)) {
+                    ret.push(key);
+                }
+            }
+            return ret;
+        },
+
+        /**
+         * Returns an array with all values of the hash table.
+         * @returns {Array} An array with all objects stored as a value in
+         *          the hash table.
+         */
+        values: function () {
+            var ret = [], key;
+            for (key in this.hash) {
+                if (this.hash.hasOwnProperty(key)) {
+                    ret.push(this.hash[key]);
+                }
+            }
+            return ret;
+        },
+
+        /**
+         * Empties the hash table by removing the reference to all objects.
+         * Note that the store objects themselves are not touched.
+         * @returns undefined
+         */
+        empty: function () {
+            this.hash = {};
+            this.length = 0;
+        },
+
+        /**
+         * Returns the size of the hash table, that is the count of all
+         * key/value pairs.
+         * @returns {Number} The count of all key/value pairs stored in the
+         *          hash table.
+         */
+        size: function () {
+            return this.length;
+        }
+    };
+
+    // -----------------------------------------------------------------------
+    // Internal event handling system
+    EventType = {};
+    EventType.ADD_ASSOCIATION = 1;
+    EventType.ADD_NAME = 2;
+    EventType.ADD_OCCURRENCE = 3;
+    EventType.ADD_ROLE = 4;
+    EventType.ADD_THEME = 5;
+    EventType.ADD_TOPIC = 6;
+    EventType.ADD_TYPE = 7;
+    EventType.REMOVE_ASSOCIATION = 8;
+    EventType.REMOVE_NAME = 9;
+    EventType.REMOVE_OCCURRENCE = 10;
+    EventType.REMOVE_ROLE = 11;
+    EventType.REMOVE_THEME = 12;
+    EventType.REMOVE_TOPIC = 13;
+    EventType.REMOVE_TYPE = 14;
+    EventType.SET_TYPE = 15;
+
+    /**
+     * @namespace Namespace for XML Schema URIs. // FIXME!!
+     */
+    XSD = {
+        'string': "http://www.w3.org/2001/XMLSchema#string",
+        'integer': "http://www.w3.org/2001/XMLSchema#integer",
+        'anyURI': "http://www.w3.org/2001/XMLSchema#anyURI"
+
+        // TODO: Add all build-in types
+    };
+
+    TMDM = {
+        'TYPE_INSTANCE': 'http://psi.topicmaps.org/iso13250/model/type-instance',
+        'TYPE': 'http://psi.topicmaps.org/iso13250/model/type',
+        'INSTANCE': 'http://psi.topicmaps.org/iso13250/model/instance',
+        'TOPIC_NAME': 'http://psi.topicmaps.org/iso13250/model/topic-name'
+    };
+
+    // -----------------------------------------------------------------------
+    // TODO: The locator functions need some more work. Implement resolve()
+    // and toExternalForm()
+
+    /**
+     * @class Immutable representation of an IRI.
+     */
+    Locator = function (parnt, iri) {
+        this.parnt = parnt;
+        this.iri = iri;
+    };
+
+    /**
+     * Returns the IRI.
+     * @returns {String} A lexical representation of the IRI.
+     */
+    Locator.prototype.getReference = function () {
+        return this.iri;
+    };
+
+    /**
+     * Returns true if the other object is equal to this one.
+     * @param other The object to compare this object against.
+     * @returns <code>(other instanceof Locator &&
+     *     this.getReference().equals(((Locator)other).getReference()))</code>
+     */
+    Locator.prototype.equals = function (other) {
+        return (this.iri === other.getReference());
+    };
+
+    /**
+     * Returns the external form of the IRI. Any special character will be
+     * escaped using the escaping conventions of RFC 3987.
+     * @returns {String} A string representation of this locator suitable for
+     * output or passing to APIs which will parse the locator anew.
+     */
+    Locator.prototype.toExternalForm = function () {
+        throw {name: 'NotImplemented', message: 'Locator.toExternalForm() not implemented'};
+    };
+
+
+    // -----------------------------------------------------------------------
+    /**
+     * @class Represents a Topic Maps construct.
+     */
+    Construct = function () {};
+
+    /** 
+     * Adds an item identifier.
+     * @param {Locator} itemIdentifier The item identifier to add.
+     * @returns {Construct} The construct itself (for chaining support)
+     * @throws {ModelConstraintException} If the itemidentifier is null.
+     * @throws {IdentityConstraintException} If another Topic Maps construct with
+     *         the same item identifier exists.
+     */
+    Construct.prototype.addItemIdentifier = function (itemIdentifier) {
+        var existing;
+        if (itemIdentifier === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'addItemIdentifier(null) is illegal'};
+        }
+        existing = this.getTopicMap()._ii2construct.get(itemIdentifier.getReference());
+        if (existing) {
+            throw {name: 'IdentityConstraintException',
+                message: 'Topic Maps constructs with the same item identifier ' +
+                        'are not allowed',
+                reporter: this,
+                existing: existing,
+                locator: itemIdentifier};
+        }
+        this.itemIdentifiers.push(itemIdentifier);
+        this.getTopicMap()._ii2construct.put(itemIdentifier.getReference(), this);
+        return this;
+    };
+
+    /**
+     * Returns true if the other object is equal to this one. Equality must be
+     * the result of comparing the identity (<code>this == other</code>) of the
+     * two objects.
+     * Note: This equality test does not reflect any equality rule according to
+     * the Topic Maps - Data Model (TMDM) by intention.
+     * @param {String} other The object to compare this object against.
+     */
+    Construct.prototype.equals = function (other) {
+        return (this.id === other.id);
+    };
+    
+    /**
+     * Returns the identifier of this construct. This property has no
+     * representation in the Topic Maps - Data Model.
+     *
+     * The ID can be anything, so long as no other Construct in the same topic
+     * map has the same ID.
+     * @returns {String} An identifier which identifies this construct uniquely
+     * within a topic map.
+     */
+    Construct.prototype.getId = function () {
+        return this.id;
+    };
+    
+    /**
+     * Returns the item identifiers of this Topic Maps construct. The return
+     * value may be empty but must never be <code>null</code>.
+     * @returns {Array} An array of Locators representing the item identifiers.
+     * The array MUST NOT be modified.
+     */
+    Construct.prototype.getItemIdentifiers = function () {
+        return this.itemIdentifiers;
+    };
+    
+    /**
+     * Returns the parent of this construct. This method returns
+     * <code>null</code> iff this construct is a TopicMap instance.
+     * @returns {Construct} The parent of this construct or <code>null</code>
+     * iff the construct is an instance of TopicMap.
+     */
+    Construct.prototype.getParent = function () {
+        return this.parnt;
+    };
+    
+    /**
+     * Returns the TopicMap instance to which this Topic Maps construct belongs.
+     * A TopicMap instance returns itself.
+     * @returns {Construct} The topic map instance to which this construct belongs.
+     */
+    Construct.prototype.getTopicMap = function () {
+        throw {name: 'NotImplemented', message: 'getTopicMap() not implemented'};
+    };
+    
+    /**
+     * Returns the hash code value.
+     * TODO: Is this needed?
+     */
+    Construct.prototype.hashCode = function () {
+        throw {name: 'NotImplemented', message: 'hashCode() not implemented'};
+    };
+    
+    /**
+     * Returns the parent of this construct. This method returns
+     * <code>null</code> iff this construct is a TopicMap instance.
+     * @returns {Construct} The parent of this construct or <code>null</code>
+     * iff the construct is an instance of {@link TopicMap}.
+     */
+    Construct.prototype.remove = function () {
+        throw {name: 'NotImplemented', message: 'remove() not implemented'};
+    };
+    
+    /**
+     * Removes an item identifier.
+     * @param {Locator} itemIdentifier The item identifier to be removed from
+     * this construct, if present (<code>null</code> is ignored).
+     * @returns {Construct} The construct itself (for chaining support)
+     */
+    Construct.prototype.removeItemIdentifier = function (itemIdentifier) {
+        if (itemIdentifier === null) {
+            return;
+        }
+        for (var i = 0; i < this.itemIdentifiers.length; i += 1) {
+            if (this.itemIdentifiers[i].getReference() ===
+                    itemIdentifier.getReference()) {
+                this.itemIdentifiers.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._ii2construct.remove(itemIdentifier.getReference());
+        return this;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link TopicMap}-object
+     * @returns <code>true</code> if the construct is a {@link TopicMap}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isTopicMap = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Topic}-object
+     * @returns <code>true</code> if the construct is a {@link Topic}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isTopic = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is an {@link Association}-object
+     * @returns <code>true</code> if the construct is an {@link Association}-
+     *     object, <code>false</code> otherwise.
+     */
+    Construct.prototype.isAssociation = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Role}-object
+     * @returns <code>true</code> if the construct is a {@link Role}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isRole = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Name}-object
+     * @returns <code>true</code> if the construct is a {@link Name}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isName = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is an {@link Occurrenct}-object
+     * @returns <code>true</code> if the construct is an {@link Occurrence}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isOccurrence = function () {
+        return false;
+    };
+    
+    /**
+     * Returns true if the construct is a {@link Variant}-object
+     * @returns <code>true</code> if the construct is a {@link Variant}-object,
+     *     <code>false</code> otherwise.
+     */
+    Construct.prototype.isVariant = function () {
+        return false;
+    };
+
+    // --------------------------------------------------------------------------
+    Typed = function () {};
+    
+    // Returns the type of this construct.
+    Typed.prototype.getType = function () {
+        return this.type;
+    };
+    
+    /**
+     * Sets the type of this construct.
+     * @throws {ModelConstraintException} If type is null.
+     * @returns {Typed} The type itself (for chaining support)
+     */
+    Typed.prototype.setType = function (type) {
+        if (type === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'Topic.setType cannot be called without type'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), type);
+        this.getTopicMap().setTypeEvent.fire(this, {old: this.type, type: type});
+        this.type = type;
+        return this;
+    };
+    
+    // --------------------------------------------------------------------------
+    /**
+     * @class Indicates that a statement (Topic Maps construct) has a scope.
+     * Associations, Occurrences, Names, and Variants are scoped.
+     */
+    Scoped = function () {};
+    
+    /**
+     * Adds a topic to the scope.
+     * @throws {ModelConstraintException} If theme is null.
+     * @returns {Typed} The type itself (for chaining support)
+     */
+    Scoped.prototype.addTheme = function (theme) {
+        if (theme === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'addTheme(null) is illegal'}; 
+        }
+        // Check if theme is part of the scope
+        for (var i = 0; i < this.scope.length; i += 1) {
+            if (this.scope[i] === theme) {
+                return false;
+            }
+        }
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), theme);
+        this.scope.push(theme);
+        this.getTopicMap().addThemeEvent.fire(this, {theme: theme});
+        // Special case for names: add the theme to all variants
+        if (this.isName()) {
+            for (i = 0; i < this.variants.length; i += 1) {
+                this.getTopicMap().addThemeEvent.fire(this.variants[i], {theme: theme});
+            }
+        }
+        return this;
+    };
+    
+    /**
+     * Returns the topics which define the scope.
+     * @returns {Array} A possible empty Array with Topic objects.
+     */
+    Scoped.prototype.getScope = function () {
+        if (this.isVariant()) {
+            var i, tmp = new Hash(), parent_scope = this.parnt.getScope();
+            for (i = 0; i < parent_scope.length; i += 1) {
+                tmp.put(parent_scope[i].getId(), parent_scope[i]);
+            }
+            for (i = 0; i < this.scope.length; i += 1) {
+                tmp.put(this.scope[i].getId(), this.scope[i]);
+            }
+            return tmp.values();
+        }
+        return this.scope;
+    };
+    
+    /**
+     * Removes a topic from the scope. 
+     * @returns {Scoped} The scoped object itself (for chaining support)
+     */
+    Scoped.prototype.removeTheme = function (theme) {
+        var i, j, scope, found;
+        for (i = 0; i < this.scope.length; i += 1) {
+            if (this.scope[i] === theme) {
+                this.getTopicMap().removeThemeEvent.fire(this, {theme: this.scope[i]});
+                this.scope.splice(i, 1);
+                break;
+            }
+        }
+        // Special case for names: remove the theme from index for all variants
+        if (this.isName()) {
+            for (i = 0; i < this.variants.length; i += 1) {
+                scope = this.variants[i].scope;
+                // Check if the the variant has theme as scope
+                found = false;
+                for (j = 0; j < scope.length; j += 1) {
+                    if (theme.equals(scope[j])) {
+                        found = true;
+                    }
+                }
+                if (!found) {
+                    this.getTopicMap().removeThemeEvent.fire(this.variants[i], {theme: theme});
+                }
+            }
+        }
+        return this;
+    };
+    
+    
+    // --------------------------------------------------------------------------
+    /**
+     * @class Indicates that a Construct is reifiable. Every Topic Maps
+     * construct that is not a Topic is reifiable.
+     */
+    Reifiable = function () {};
+    
+    /**
+     * Returns the reifier of this construct.
+     */
+    Reifiable.prototype.getReifier = function () {
+        return this.reifier;
+    };
+    
+    /**
+     * Sets the reifier of the construct.
+     * @throws {ModelConstraintException} If reifier already reifies another
+     * construct.
+     * @returns {Reifiable} The reified object itself (for chaining support)
+     */
+    Reifiable.prototype.setReifier = function (reifier) {
+        if (reifier && reifier.getReified() !== null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Reifies already another construct'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), reifier);
+        if (this.reifier) {
+            this.reifier._setReified(null);
+        }
+        if (reifier) {
+            reifier._setReified(this);
+        }
+        this.reifier = reifier;
+        return this;
+    };
+    
+    // --------------------------------------------------------------------------
+    /**
+     * @class Common base interface for Occurrences and Variants.
+     * Inherits Scoped, Reifiable
+     */
+    DatatypeAware = function () {};
+    
+    /**
+     * Returns the BigDecimal representation of the value.
+     */
+    DatatypeAware.prototype.decimalValue = function () {
+        // FIXME Implement!
+    };
+    
+    /**
+     * Returns the float representation of the value.
+     * @throws {NumberFormatException} If the value is not convertable to float.
+     */
+    DatatypeAware.prototype.floatValue = function () {
+        var ret = parseFloat(this.value);
+        if (isNaN(ret)) {
+            throw {name: 'NumberFormatException',
+                message: '"' + this.value + '" is not a float'};
+        }
+        return ret;
+    };
+    
+    /**
+     * Returns the Locator identifying the datatype of the value.
+     */
+    DatatypeAware.prototype.getDatatype = function () {
+        return this.datatype;
+    };
+    
+    /**
+     * Returns the lexical representation of the value.
+     */
+    DatatypeAware.prototype.getValue = function () {
+        if (typeof this.value === 'object' && this.value instanceof Locator) {
+            return this.value.getReference();
+        }
+        return this.value.toString();
+    };
+    
+    /**
+     * Returns the BigInteger representation of the value.
+     * @throws {NumberFormatException} If the value cannot be parsed as an int.
+     */
+    DatatypeAware.prototype.integerValue = function () {
+        var ret = parseInt(this.value, 10);
+        if (isNaN(ret)) {
+            throw {name: 'NumberFormatException',
+                message: '"' + this.value + '" is not an integer'};
+        }
+        return ret;
+    };
+    
+    /**
+     * Returns the Locator representation of the value.
+     * @throws {ModelConstraintException} If the value is not an Locator
+     * object.
+     */
+    DatatypeAware.prototype.locatorValue = function () {
+        if (!(typeof this.value === 'object' && this.value instanceof Locator)) {
+            throw {name: 'ModelConstraintException',
+                message: '"' + this.value + '" is not a locator'};
+        }
+        return this.value;
+    };
+    
+    /**
+     * Returns the long representation of the value.
+     */
+    DatatypeAware.prototype.longValue = function () {
+        // FIXME Implement!
+    };
+    
+    /**
+     * Sets the value and the datatype.
+     * @throws {ModelConstraintException} If datatype or value is null.
+     */
+    DatatypeAware.prototype.setValue = function (value, datatype) {
+        var tm = this.getTopicMap();
+        if (datatype === null) {
+            throw {name: 'ModelConstraintException', message: 'Invalid datatype'};
+        }
+        if (value === null) {
+            throw {name: 'ModelConstraintException', message: 'Invalid value'};
+        }
+        this.value = value;
+        this.datatype = datatype ||
+            this.getTopicMap().createLocator(XSD.string);
+        if (datatype && datatype.getReference() === XSD.anyURI) {
+            this.value = tm.createLocator(value);
+        }
+        if (!datatype) {
+            if (typeof value === 'number') {
+                // FIXME Could be XSD.float as well
+                this.datatype = tm.createLocator(XSD.integer);
+            }
+        }
+        if (typeof value === 'object' && value instanceof Locator) {
+            this.datatype = tm.createLocator(XSD.anyURI);
+        }
+    };
+    
+    // --------------------------------------------------------------------------
+    /**
+     * Constructs a new Topic Map System Factoy. The constructor should not be
+     * called directly. Use the {TM.TopicMapSystemFactory.newInstance} instead.
+     * @class Represents a Topic Maps construct.
+     * @memberOf TM
+     */
+    TopicMapSystemFactory = function () {
+        this.properties = {};
+        this.features = {};
+    };
+    
+    /**
+     * Returns the particular feature requested for in the underlying implementation
+     * of TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.getFeature = function (featureName) {
+        return this.features;
+    };
+    
+    /**
+     * Gets the value of a property in the underlying implementation of
+     * TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.getProperty = function (propertyName) {
+        return this.properties[propertyName];
+    };
+    
+    /**
+     * Returns if the particular feature is supported by the TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.hasFeature = function (featureName) {
+        return false;
+    };
+    
+    /**
+     * Obtain a new instance of a TopicMapSystemFactory.
+     * @static
+     * @returns {TopicMapSystemFactory}
+     */
+    TopicMapSystemFactory.newInstance = function () {
+        return new TopicMapSystemFactory();
+    };
+    
+    /**
+     * Creates a new TopicMapSystem instance using the currently configured
+     * factory parameters.
+     */
+    TopicMapSystemFactory.prototype.newTopicMapSystem = function () {
+        var backend = this.properties['com.semanticheadache.tmjs.backend'] || 'memory'; 
+        if (backend === 'memory') {
+            return new TopicMapSystemMemImpl();
+        }
+    };
+    
+    /**
+     * Sets a particular feature in the underlying implementation of TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.setFeature = function (featureName, enable) {
+        this.features[featureName] = enable;
+    };
+    
+    /**
+     * Sets a property in the underlying implementation of TopicMapSystem.
+     */
+    TopicMapSystemFactory.prototype.setProperty = function (propertyName, value) {
+        this.properties[propertyName] = value;
+    };
+    
+    /**
+     * Creates a new instance of TopicMamSystem.
+     * @class Implementation of the TopicMapSystem interface.
+     */
+    TopicMapSystemMemImpl = function () {
+        this.topicmaps = {};
+    };
+    
+    /**
+     * @throws {TopicMapExistsException} If a topic map with the given locator
+     * already exists.
+     */
+    TopicMapSystemMemImpl.prototype.createTopicMap = function (locator) {
+        if (this.topicmaps[locator.getReference()]) {
+            throw {name: 'TopicMapExistsException',
+                message: 'A topic map under the same IRI already exists'};
+        }
+        var tm = new TopicMap(this, locator);
+        this.topicmaps[locator.getReference()] = tm;
+        return tm;
+    };
+    
+    TopicMapSystemMemImpl.prototype.getLocators = function () {
+        var locators = [], key;
+        for (key in this.topicmaps) {
+            if (this.topicmaps.hasOwnProperty(key)) {
+                locators.push(this.createLocator(key));
+            }
+        }
+        return locators;
+    };
+    
+    TopicMapSystemMemImpl.prototype.getTopicMap = function (locator) {
+        var tm;
+        if (locator instanceof Locator) {
+            tm = this.topicmaps[locator.getReference()];
+        } else {
+            tm = this.topicmaps[locator];
+        }
+        if (!tm) {
+            return null;
+        }
+        return tm;
+    };
+    
+    /**
+     * @param {String} iri
+     */
+    TopicMapSystemMemImpl.prototype.createLocator = function (iri) {
+        return new Locator(this, iri);
+    };
+    
+    TopicMapSystemMemImpl.prototype.getFeature = function (featureName) {
+        return false;
+    };
+    
+    TopicMapSystemMemImpl.prototype._removeTopicMap = function (tm) {
+        var key;
+        for (key in this.topicmaps) {
+            if (this.topicmaps.hasOwnProperty(key) &&
+                key === tm.locator.getReference()) {
+                delete this.topicmaps[key];
+            }
+        }
+    };
+    
+    TopicMapSystemMemImpl.prototype.close = function () {
+        this.topicmaps = null; // release references
+    };
+    
+    TopicMap = function (tms, locator) {
+        this.topicmapsystem = tms;
+        this.itemIdentifiers = [];
+        this.locator = locator;
+        this.topics = [];
+        this.associations = [];
+        this._constructId = 1;
+        this._si2topic = new Hash(); // Index for subject identifiers
+        this._sl2topic = new Hash(); // Index for subject locators
+        this._ii2construct = new Hash(); // Index for item identifiers
+        this._id2construct = new Hash(); // Index for object ids
+
+        // The topic map object always get the id 0
+        this.id = 0;
+        this._id2construct.put(this.id, this);
+
+        this.reifier = null;
+        this.handlers = [];
+
+        // Our own event handling mechanism
+        var EventHandler = function (eventtype) {
+            this.eventtype = eventtype;
+            this.handlers = [];
+        };
+        EventHandler.prototype = {
+            registerHandler: function (handler) {
+                this.handlers.push(handler);
+            },
+            removeHandler: function (handler) {
+                for (var i = 0; i < this.handlers.length; i += 1) {
+                    if (handler.toString() ===
+                        this.handlers[i].toString()) {
+                        this.handlers.splice(i, 1);
+                    }
+                }
+            },
+            fire: function (source, obj) {
+                obj = obj || {};
+                for (var i = 0; i < this.handlers.length; i += 1) {
+                    this.handlers[i](this.eventtype, source, obj);
+                }
+            }
+        };
+        this.addAssociationEvent = new EventHandler(EventType.ADD_ASSOCIATION); 
+        this.addNameEvent = new EventHandler(EventType.ADD_NAME); 
+        this.addOccurrenceEvent = new EventHandler(EventType.ADD_OCCURRENCE); 
+        this.addRoleEvent = new EventHandler(EventType.ADD_ROLE); 
+        this.addThemeEvent = new EventHandler(EventType.ADD_THEME); 
+        this.addTopicEvent = new EventHandler(EventType.ADD_TOPIC); 
+        this.addTypeEvent = new EventHandler(EventType.ADD_TYPE); 
+        this.removeAssociationEvent = new EventHandler(EventType.REMOVE_ASSOCIATION);
+        this.removeNameEvent = new EventHandler(EventType.REMOVE_NAME);
+        this.removeOccurrenceEvent = new EventHandler(EventType.REMOVE_OCCURRENCE);
+        this.removeRoleEvent = new EventHandler(EventType.REMOVE_ROLE);
+        this.removeThemeEvent = new EventHandler(EventType.REMOVE_THEME);
+        this.removeTopicEvent = new EventHandler(EventType.REMOVE_TOPIC);
+        this.removeTypeEvent = new EventHandler(EventType.REMOVE_TYPE); 
+        this.setTypeEvent = new EventHandler(EventType.SET_TYPE);
+        this.typeInstanceIndex = new TypeInstanceIndex(this);
+        this.scopedIndex = new ScopedIndex(this);
+    };
+
+    /**
+     * @returns {TopicMap} The topic map object itself (for chaining support)
+     */
+    TopicMap.prototype.register_event_handler = function (type, handler) {
+        switch (type) {
+        case EventType.ADD_ASSOCIATION:
+            this.addAssociationEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_NAME:
+            this.addNameEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_OCCURRENCE:
+            this.addOccurrenceEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_ROLE:
+            this.addRoleEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_THEME:
+            this.addThemeEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_TOPIC:
+            this.addTopicEvent.registerHandler(handler);
+            break;
+        case EventType.ADD_TYPE:
+            this.addTypeEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_ASSOCIATION:
+            this.removeAssociationEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_NAME:
+            this.removeNameEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_OCCURRENCE:
+            this.removeOccurrenceEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_ROLE:
+            this.removeRoleEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_THEME:
+            this.removeThemeEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_TOPIC:
+            this.removeTopicEvent.registerHandler(handler);
+            break;
+        case EventType.REMOVE_TYPE:
+            this.removeTypeEvent.registerHandler(handler);
+            break;
+        case EventType.SET_TYPE:
+            this.setTypeEvent.registerHandler(handler);
+            break;
+        }
+        return this;
+    };
+
+    TopicMap.swiss(Reifiable, 'getReifier', 'setReifier');
+    TopicMap.swiss(Construct, 'addItemIdentifier', 'getItemIdentifiers',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    /**
+     * Removes duplicate topic map objects. This function is quite expensive,
+     * so it should not be called too often. It is meant to remove duplicates
+     * after imports of topic maps.
+     * @returns {TopicMap} The topic map object itself (for chaining support)
+     */
+    TopicMap.prototype.sanitize = function () {
+        DuplicateRemover.removeTopicMapDuplicates(this);
+        TypeInstanceHelper.convertAssociationsToType(this);
+        return this;
+    };
+    
+    TopicMap.prototype.isTopicMap = function () {
+        return true;
+    };
+    
+    TopicMap.prototype._getConstructId = function () {
+        this._constructId = this._constructId + 1;
+        return this._constructId;
+    };
+    
+    TopicMap.prototype.remove = function () {
+        if (this.topicmapsystem === null) {
+            return null;
+        }
+        this.topicmapsystem._removeTopicMap(this);
+        this.topicmapsystem = null;
+        this.itemIdentifiers = null;
+        this.locator = null;
+        this.topics = null;
+        this.associations = null;
+        this._si2topic = null;
+        this._sl2topic = null;
+        this._ii2construct = null;
+        this._id2construct = null;
+        this.reifier = null;
+        this.id = null;
+        this.typeInstanceIndex = null;
+        return null;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If type or scope is null.
+     */
+    TopicMap.prototype.createAssociation = function (type, scope) {
+        var a;
+        if (type === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Creating an association with type == null is not allowed'};
+        } 
+        if (scope === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Creating an association with scope == null is not allowed'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this, type);
+        SameTopicMapHelper.assertBelongsTo(this, scope);
+    
+        a = new Association(this);
+        this.associations.push(a);
+        if (type) {
+            a.setType(type);
+        }
+        addScope(a, scope);
+        this.addAssociationEvent.fire(a);
+        return a;
+    };
+    
+    TopicMap.prototype.createLocator = function (iri) {
+        return new Locator(this, iri);
+    };
+    
+    TopicMap.prototype._createEmptyTopic = function () {
+        var t = new Topic(this);
+        this.addTopicEvent.fire(t);
+        this.topics.push(t);
+        return t;
+    };
+    
+    TopicMap.prototype.createTopic = function () {
+        var t = this._createEmptyTopic();
+        t.addItemIdentifier(this.createLocator('urn:x-tmjs:' + t.getId()));
+        return t;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If no itemIdentifier is given.
+     * @throws {IdentityConstraintException} If another construct with the
+     * specified item identifier exists which is not a Topic.
+     */
+    TopicMap.prototype.createTopicByItemIdentifier = function (itemIdentifier) {
+        if (!itemIdentifier) {
+            throw {name: 'ModelConstraintException',
+            message: 'createTopicByItemIdentifier() needs an item identifier'};
+        }
+        var t = this.getConstructByItemIdentifier(itemIdentifier);
+        if (t) {
+            if (!t.isTopic()) {
+                throw {name: 'IdentityConstraintException',
+                message: 'Another construct with the specified item identifier ' +
+                    'exists which is not a Topic.'};
+            }
+            return t;
+        }
+        t = this._createEmptyTopic();
+        t.addItemIdentifier(itemIdentifier);
+        return t;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If no subjectIdentifier is given.
+     */
+    TopicMap.prototype.createTopicBySubjectIdentifier = function (subjectIdentifier) {
+        if (!subjectIdentifier) {
+            throw {name: 'ModelConstraintException',
+            message: 'createTopicBySubjectIdentifier() needs a subject identifier'};
+        }
+        var t = this.getTopicBySubjectIdentifier(subjectIdentifier);
+        if (t) {
+            return t;
+        }
+        t = this._createEmptyTopic();
+        t.addSubjectIdentifier(subjectIdentifier);
+        return t;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If no subjectLocator is given.
+     */
+    TopicMap.prototype.createTopicBySubjectLocator = function (subjectLocator) {
+        if (!subjectLocator) {
+            throw {name: 'ModelConstraintException',
+            message: 'createTopicBySubjectLocator() needs a subject locator'};
+        }
+        var t = this.getTopicBySubjectLocator(subjectLocator);
+        if (t) {
+            return t;
+        }
+        t = this._createEmptyTopic();
+        t.addSubjectLocator(subjectLocator);
+        return t;
+    };
+    
+    TopicMap.prototype.getAssociations = function () {
+        return this.associations;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If id is null.
+     */
+    TopicMap.prototype.getConstructById = function (id) {
+        if (id === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'getConstructById(null) is illegal'};
+        }
+        var ret = this._id2construct.get(id);
+        if (!ret) {
+            return null;
+        }
+        return ret;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If itemIdentifier is null.
+     */
+    TopicMap.prototype.getConstructByItemIdentifier = function (itemIdentifier) {
+        if (itemIdentifier === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'getConstructByItemIdentifier(null) is illegal'};
+        }
+        var ret = this._ii2construct.get(itemIdentifier.getReference());
+        if (!ret) {
+            return null;
+        }
+        return ret;
+    };
+    
+    /**
+     * @throws {UnsupportedOperationException} If the index type is not
+     * supported.
+     */
+    TopicMap.prototype.getIndex = function (className) {
+        var index;
+        if (className === 'TypeInstanceIndex') {
+            index = this.typeInstanceIndex;
+            return index;
+        } else if (className === 'ScopedIndex') {
+            index = new ScopedIndex(this);
+            return index;
+        }
+        // TODO: Should we throw an exception that indicates that the 
+        // index is not known? Check the TMAPI docs!
+        throw {name: 'UnsupportedOperationException', 
+            message: 'getIndex ist not (yet) supported'};
+    };
+    
+    TopicMap.prototype.getParent = function () {
+        return null;
+    };
+    
+    TopicMap.prototype.getTopicBySubjectIdentifier = function (subjectIdentifier) {
+        var res = this._si2topic.get(subjectIdentifier.getReference());
+        if (res) {
+            return res;
+        }
+        return null; // Make sure that the result is not undefined
+    };
+    
+    TopicMap.prototype.getTopicBySubjectLocator = function (subjectLocator) {
+        var res = this._sl2topic.get(subjectLocator.getReference());
+        if (res) {
+            return res;
+        }
+        return null; // Make sure that the result is not undefined
+    };
+    
+    TopicMap.prototype.getLocator = function () {
+        return this.locator;
+    };
+    
+    TopicMap.prototype.getTopics = function () {
+        return this.topics;
+    };
+    
+    TopicMap.prototype.mergeIn = function (topicmap) {
+        // TODO implement!
+        throw {name: 'NotImplemented', message: 'TopicMap.mergeIn() not implemented'};
+    };
+    
+    TopicMap.prototype.equals = function (topicmap) {
+        return this.locator.equals(topicmap.locator);
+    };
+    
+    TopicMap.prototype.getId = function () {
+        return this.id;
+    };
+    
+    TopicMap.prototype.getTopicMap = function () {
+        return this;
+    };
+    
+    // Remove item identifiers
+    TopicMap.prototype._removeConstruct = function (construct) {
+        var iis = construct.getItemIdentifiers(), i;
+        for (i = 0; i < iis.length; i += 1) {
+            this._ii2construct.remove(iis[i].getReference());
+        }
+        this._id2construct.remove(construct.getId());
+    };
+    
+    TopicMap.prototype._removeTopic = function (topic) {
+        var i, sis = topic.getSubjectIdentifiers(),
+            slos = topic.getSubjectLocators();
+        // remove subject identifiers from TopicMap._si2topic
+        for (i = 0; i < sis.length; i += 1) {
+            this._si2topic.remove(sis[i].getReference());
+        }
+        // remove subject locators from TopicMap._sl2topic
+        for (i = 0; i < slos.length; i += 1) {
+            this._sl2topic.remove(slos[i].getReference());
+        }
+        this._removeConstruct(topic);
+        // remove topic from TopicMap.topics
+        for (i = 0; i < this.topics.length; i += 1) {
+            if (topic.id === this.topics[i].id) {
+                this.topics.splice(i, 1);
+                break;
+            }
+        }
+    };
+    
+    TopicMap.prototype._removeAssociation = function (association) {
+        var i;
+        // remove association from TopicMap.associations
+        for (i = 0; i < this.associations.length; i += 1) {
+            if (association.id === this.associations[i].id) {
+                this.associations.splice(i, 1);
+                break;
+            }
+        }
+        this._removeConstruct(association);
+        // remove association from TopicMap.associations
+        for (i = 0; i < this.associations.length; i += 1) {
+            if (association.id === this.associations[i].id) {
+                this.associations.splice(i, 1);
+                break;
+            }
+        }
+    };
+    
+    TopicMap.prototype._removeRole = function (role) {
+        this._removeConstruct(role);
+    };
+    
+    TopicMap.prototype._removeOccurrence = function (occ) {
+        this._removeConstruct(occ);
+    };
+    
+    TopicMap.prototype._removeName = function (name) {
+        this._removeConstruct(name);
+    };
+    
+    TopicMap.prototype._removeVariant = function (variant) {
+        this._removeConstruct(variant);
+    };
+    
+    // hashCode, remove
+    
+    // --------------------------------------------------------------------------
+    
+    Topic = function (parnt) {
+        this.subjectIdentifiers = [];
+        this.subjectLocators = [];
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.id = parnt._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+        this.types = [];
+        this.rolesPlayed = [];
+        this.occurrences = [];
+        this.names = [];
+        this.reified = null;
+    };
+    
+    Topic.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Topic.prototype.isTopic = function () {
+        return true;
+    };
+    
+    Topic.prototype.getTopicMap = function () {
+        return this.parnt;
+    };
+    
+    /**
+     * Adds a subject identifier to this topic.
+     * @throws {ModelConstraintException} If subjectIdentifier is null or
+     * not defined.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.addSubjectIdentifier = function (subjectIdentifier) {
+        if (!subjectIdentifier) {
+            throw {name: 'ModelConstraintException',
+            message: 'addSubjectIdentifier() needs subject identifier'};
+        }
+        // Ignore if the identifier already exists
+        for (var i = 0; i < this.subjectIdentifiers.length; i += 1) {
+            if (this.subjectIdentifiers[i].getReference() ===
+                subjectIdentifier.getReference()) {
+                return;
+            }
+        }
+        this.subjectIdentifiers.push(subjectIdentifier);
+        this.parnt._si2topic.put(subjectIdentifier.getReference(), this);
+        return this;
+    };
+    
+    /**
+     * Adds a subject locator to this topic.
+     * @throws {ModelConstraintException} If subjectLocator is null or
+     * not defined.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.addSubjectLocator = function (subjectLocator) {
+        if (!subjectLocator) {
+            throw {name: 'ModelConstraintException',
+            message: 'addSubjectLocator() needs subject locator'};
+        }
+        // Ignore if the identifier already exists
+        for (var i = 0; i < this.subjectLocators.length; i += 1) {
+            if (this.subjectLocators[i].getReference() ===
+                subjectLocator.getReference()) {
+                return;
+            }
+        }
+        this.subjectLocators.push(subjectLocator);
+        this.parnt._sl2topic.put(subjectLocator.getReference(), this);
+        return this;
+    };
+    
+    /**
+     * Adds a type to this topic.
+     * @throws {ModelConstraintException} If type is null or not defined.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.addType = function (type) {
+        if (!type) {
+            throw {name: 'ModelConstraintException',
+            message: 'addType() needs type'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        this.parnt.addTypeEvent.fire(this, {type: type});
+        this.types.push(type);
+        return this;
+    };
+    
+    // TODO: @type is optional In TMAPI 2.0
+    // Creates a Name for this topic with the specified value, and scope.
+    // Creates a Name for this topic with the specified type, value, and scope.
+    Topic.prototype.createName = function (value, type, scope) {
+        var name;
+        if (type) {
+            SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        }
+        if (scope) {
+            SameTopicMapHelper.assertBelongsTo(this.parnt, scope);
+        }
+        if (typeof scope === 'undefined') {
+            scope = null;
+        }
+    
+        name = new Name(this, value, type);
+        addScope(name, scope);
+        this.names.push(name);
+        return name;
+    };
+    
+    // TODO: @datatype is optional in TMAPI, value may be string or locator.
+    // Creates an Occurrence for this topic with the specified type, IRI value, and
+    // scope.
+    // createOccurrence(Topic type, java.lang.String value, Locator datatype,
+    // java.util.Collection<Topic> scope) 
+    // Creates an Occurrence for this topic with the specified type, string value,
+    // and scope.
+    Topic.prototype.createOccurrence = function (type, value, datatype, scope) {
+        var occ;
+        SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        SameTopicMapHelper.assertBelongsTo(this.parnt, scope);
+    
+        occ = new Occurrence(this, type, value, datatype);
+        this.parnt.addOccurrenceEvent.fire(occ, {type: type, value: value});
+        addScope(occ, scope);
+        this.occurrences.push(occ);
+        return occ;
+    };
+    
+    /**
+     * Returns the Names of this topic where the name type is type.
+     *type is optional.
+     */
+    Topic.prototype.getNames = function (type) {
+        var ret = [], i;
+
+        for (i = 0; i < this.names.length; i += 1) {
+            if (type && this.names[i].getType().equals(type)) {
+                ret.push(this.names[i]);
+            } else if (!type) {
+                ret.push(this.names[i]);
+            }
+        }
+        return ret;
+    };
+    
+    /**
+     * Returns the Occurrences of this topic where the occurrence type is type. type
+     * is optional.
+     * @throws {IllegalArgumentException} If type is null.
+     */
+    Topic.prototype.getOccurrences = function (type) {
+        var ret = [], i;
+        if (type === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getOccurrences cannot be called without type'};
+        }
+        for (i = 0; i < this.occurrences.length; i += 1) {
+            if (type && this.occurrences[i].getType().equals(type)) {
+                ret.push(this.occurrences[i]);
+            } else if (!type) {
+                ret.push(this.occurrences[i]);
+            }
+        }
+        return ret;
+    };
+    
+    Topic.prototype._removeOccurrence = function (occ) {
+        // remove this from TopicMap.topics
+        for (var i = 0; i < this.occurrences.length; i += 1) {
+            if (this.occurrences[i].equals(occ)) {
+                this.occurrences.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._removeOccurrence(occ);
+    };
+    
+    // Returns the Construct which is reified by this topic.
+    Topic.prototype.getReified = function (type) {
+        return this.reified;
+    };
+    
+    Topic.prototype._setReified = function (reified) {
+        this.reified = reified;
+    };
+    
+    /**
+     * Returns the roles played by this topic.
+     * Returns the roles played by this topic where the role type is type.
+     * assocType is optional
+     * @throws {IllegalArgumentException} If type or assocType is null.
+     */
+    Topic.prototype.getRolesPlayed = function (type, assocType) {
+        if (type === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getRolesPlayed cannot be called without type'};
+        }
+        if (assocType === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getRolesPlayed cannot be called with assocType===null'};
+        }
+        var ret = [], i;
+        for (i = 0; i < this.rolesPlayed.length; i += 1) {
+            if (!type) {
+                ret.push(this.rolesPlayed[i]);
+            } else if (this.rolesPlayed[i].getType().equals(type)) {
+                if (assocType &&
+                    this.rolesPlayed[i].getParent().getType().equals(assocType) ||
+                    !assocType) {
+                    ret.push(this.rolesPlayed[i]);
+                }
+            }
+        }
+        return ret;
+    };
+    
+    // @private Registers role as a role played
+    // TODO: Rename to _addRolePlayed
+    Topic.prototype.addRolePlayed = function (role) {
+        this.rolesPlayed.push(role);
+    };
+    
+    // TODO: Rename to _removeRolePlayed
+    Topic.prototype.removeRolePlayed = function (role) {
+        for (var i = 0; i < this.rolesPlayed.length; i += 1) {
+            if (this.rolesPlayed[i].id === role.id) {
+                this.rolesPlayed.splice(i, 1);
+            }
+        }
+    };
+    
+    /**
+     * Returns the subject identifiers assigned to this topic.
+     */
+    Topic.prototype.getSubjectIdentifiers = function () {
+        return this.subjectIdentifiers;
+    };
+    
+    /**
+     * Returns the subject locators assigned to this topic.
+     */
+    Topic.prototype.getSubjectLocators = function () {
+        return this.subjectLocators;
+    };
+    
+    /**
+     * Returns the types of which this topic is an instance of.
+     */
+    Topic.prototype.getTypes = function () {
+        return this.types;
+    };
+    
+    /**
+     * Merges another topic into this topic.
+     * @throws {ModelConstraintException} If the topics reify different
+     * information items.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.mergeIn = function (other) {
+        var arr, i, tmp, tmp2, signatures, tiidx, sidx;
+        if (this.equals(other)) {
+            return true;
+        }
+
+        SameTopicMapHelper.assertBelongsTo(this.getTopicMap(), other);
+        if (this.getReified() && other.getReified() &&
+            !this.getReified().equals(other.getReified())) {
+            throw {name: 'ModelConstraintException',
+                message: 'The topics reify different Topic Maps constructs and cannot be merged!'
+            };
+        }
+
+        if (!this.getReified() && other.getReified()) {
+            tmp = other.getReified();
+            tmp.setReifier(this);
+        }
+
+        // Change all constructs that use other as type
+        tiidx = this.parnt.typeInstanceIndex;
+        MergeHelper.moveTypes(tiidx.getOccurrences(other), this);
+        MergeHelper.moveTypes(tiidx.getNames(other), this);
+        MergeHelper.moveTypes(tiidx.getAssociations(other), this);
+        MergeHelper.moveTypes(tiidx.getRoles(other), this);
+
+        // Change all topics that have other as type
+        arr = tiidx.getTopics(other);
+        for (i = 0; i < arr.length; i += 1) {
+            arr[i].removeType(other);
+            arr[i].addType(this);
+        }
+
+        // Change all constructs that use other as theme
+        sidx = this.parnt.scopedIndex;
+        MergeHelper.moveThemes(sidx.getAssociations(other), other, this);
+        MergeHelper.moveThemes(sidx.getOccurrences(other), other, this);
+        MergeHelper.moveThemes(sidx.getNames(other), other, this);
+        MergeHelper.moveThemes(sidx.getVariants(other), other, this);
+
+        MergeHelper.moveItemIdentifiers(other, this);
+
+        arr = other.getSubjectLocators();
+        while (arr.length) {
+            tmp = arr[arr.length - 1];
+            other.removeSubjectLocator(tmp);
+            this.addSubjectLocator(tmp);
+        }
+
+        arr = other.getSubjectIdentifiers();
+        while (arr.length) {
+            tmp = arr[arr.length - 1];
+            other.removeSubjectIdentifier(tmp);
+            this.addSubjectIdentifier(tmp);
+        }
+
+        arr = other.getTypes();
+        while (arr.length) {
+            tmp = arr[arr.length - 1];
+            other.removeType(tmp);
+            this.addType(tmp);
+        }
+
+        // merge roles played
+        arr = this.getRolesPlayed();
+        signatures = {};
+        for (i = 0; i < arr.length; i += 1) {
+            tmp2 = arr[i].getParent();
+            signatures[SignatureGenerator.makeAssociationSignature(tmp2)] = tmp2;
+        }
+        arr = other.getRolesPlayed();
+        for (i = 0; i < arr.length; i += 1) {
+            tmp = arr[i];
+            tmp.setPlayer(this);
+            if ((tmp2 = signatures[SignatureGenerator.makeAssociationSignature(tmp.getParent())])) {
+                MergeHelper.moveItemIdentifiers(tmp.getParent(), tmp2);
+                MergeHelper.moveReifier(tmp.getParent(), tmp2);
+                tmp.getParent().remove();
+            }
+        }
+
+        // merge names
+        arr = this.getNames();
+        signatures = {};
+        for (i = 0; i < arr.length; i += 1) {
+            signatures[SignatureGenerator.makeNameSignature(arr[i])] = arr[i];
+        }
+        arr = other.getNames();
+        for (i = 0; i < arr.length; i += 1) {
+            tmp = arr[i];
+            if ((tmp2 = signatures[SignatureGenerator.makeNameSignature(arr[i])])) {
+                MergeHelper.moveItemIdentifiers(tmp, tmp2);
+                MergeHelper.moveReifier(tmp, tmp2);
+                MergeHelper.moveVariants(tmp, tmp2);
+                tmp.remove();
+            } else {
+                tmp2 = this.createName(tmp.getValue(), tmp.getType(), tmp.getScope());
+                MergeHelper.moveVariants(tmp, tmp2);
+            }
+        }
+
+        // merge occurrences
+        arr = this.getOccurrences();
+        signatures = {};
+        for (i = 0; i < arr.length; i += 1) {
+            signatures[SignatureGenerator.makeOccurrenceSignature(arr[i])] = arr[i];
+        }
+        arr = other.getOccurrences();
+        for (i = 0; i < arr.length; i += 1) {
+            tmp = arr[i];
+            if ((tmp2 = signatures[SignatureGenerator.makeOccurrenceSignature(arr[i])])) {
+                MergeHelper.moveItemIdentifiers(tmp, tmp2);
+                MergeHelper.moveReifier(tmp, tmp2);
+                tmp.remove();
+            } else {
+                tmp2 = this.createOccurrence(tmp.getType(), tmp.getValue(),
+                    tmp.getDatatype(), tmp.getScope());
+                MergeHelper.moveReifier(tmp, tmp2);
+            }
+        }
+
+        other.remove();
+        return this;
+    };
+    
+    /**
+     * Removes this topic from the containing TopicMap instance.
+     * @throws {TopicInUseException} If the topics is used as reifier,
+     * occurrence type, name type, association type, role type, topic type,
+     * association theme, occurrence theme, name theme, variant theme,
+     * or if it is used as a role player.
+     */
+    Topic.prototype.remove = function () {
+        var tiidx = this.parnt.typeInstanceIndex,
+            sidx = this.parnt.scopedIndex;
+        if (this.getReified() ||
+            tiidx.getOccurrences(this).length ||
+            tiidx.getNames(this).length ||
+            tiidx.getAssociations(this).length ||
+            tiidx.getRoles(this).length ||
+            tiidx.getTopics(this).length ||
+            sidx.getAssociations(this).length ||
+            sidx.getOccurrences(this).length ||
+            sidx.getNames(this).length ||
+            sidx.getVariants(this).length ||
+            this.getRolesPlayed().length) {
+            throw {name: 'TopicInUseException',
+                message: '', reporter: this};
+        }
+        this.parnt._removeTopic(this);
+        this.parnt._id2construct.remove(this.id);
+        this.parnt.removeTopicEvent.fire(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+    /**
+     * Removes a subject identifier from this topic.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.removeSubjectIdentifier = function (subjectIdentifier) {
+        for (var i = 0; i < this.subjectIdentifiers.length; i += 1) {
+            if (this.subjectIdentifiers[i].getReference() ===
+                subjectIdentifier.getReference()) {
+                this.subjectIdentifiers.splice(i, 1);
+                break;
+            }
+        }
+        this.parnt._sl2topic.remove(subjectIdentifier.getReference());
+        return this;
+    };
+    
+    /**
+     * Removes a subject locator from this topic.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.removeSubjectLocator = function (subjectLocator) {
+        for (var i = 0; i < this.subjectLocators.length; i += 1) {
+            if (this.subjectLocators[i].getReference() ===
+                subjectLocator.getReference()) {
+                this.subjectLocators.splice(i, 1);
+                break;
+            }
+        }
+        this.parnt._sl2topic.remove(subjectLocator.getReference());
+        return this;
+    };
+    
+    /**
+     * Removes a type from this topic.
+     * @returns {Topic} The topic itself (for chaining support)
+     */
+    Topic.prototype.removeType = function (type) {
+        for (var i = 0; i < this.types.length; i += 1) {
+            if (this.types[i].equals(type)) {
+                this.types.splice(i, 1);
+                this.parnt.removeTypeEvent.fire(this, {type: type});
+                break;
+            }
+        }
+    };
+    
+    Topic.prototype._removeName = function (name) {
+        for (var i = 0; i < this.names.length; i += 1) {
+            if (this.names[i].equals(name)) {
+                this.names.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._removeName(name);
+    };
+    
+    // --------------------------------------------------------------------------
+    Occurrence = function (parnt, type, value, datatype) {
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.type = type;
+        this.value = value;
+        this.datatype = datatype ? datatype : this.getTopicMap().createLocator(XSD.string);
+        this.scope = [];
+        this.reifier = null;
+        this.id = this.getTopicMap()._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+    };
+    
+    // mergein Typed, DatatypeAware, Reifiable, Scoped, Construct
+    Occurrence.swiss(Typed, 'getType', 'setType');
+    Occurrence.swiss(DatatypeAware, 'decimalValue', 'floatValue',
+        'getDatatype', 'getValue', 'integerValue', 'locatorValue', 'longValue',
+        'setValue');
+    Occurrence.swiss(Reifiable, 'getReifier', 'setReifier');
+    Occurrence.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Occurrence.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Occurrence.prototype.isOccurrence = function () {
+        return true;
+    };
+    
+    Occurrence.prototype.getTopicMap = function () {
+        return this.parnt.getParent();
+    };
+    
+    Occurrence.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.parnt.parnt.removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.parnt.parnt.removeOccurrenceEvent.fire(this);
+        this.parnt._removeOccurrence(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+    Name = function (parnt, value, type) {
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.value = value;
+        this.scope = [];
+        this.id = this.getTopicMap()._getConstructId();
+        this.type = type ||
+            parnt.parnt.createTopicBySubjectIdentifier(
+                parnt.parnt.createLocator('http://psi.topicmaps.org/iso13250/model/topic-name'));
+        this.reifier = null;
+        this.variants = [];
+        this.getTopicMap()._id2construct.put(this.id, this);
+        this.parnt.parnt.addNameEvent.fire(this, {type: this.type, value: value});
+    };
+    
+    // mergein Typed, DatatypeAware, Reifiable, Scoped, Construct
+    Name.swiss(Typed, 'getType', 'setType');
+    Name.swiss(Reifiable, 'getReifier', 'setReifier');
+    Name.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Name.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Name.prototype.isName = function () {
+        return true;
+    };
+    
+    Name.prototype.getTopicMap = function () {
+        return this.parnt.parnt;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If scope is null.
+     */
+    Name.prototype.createVariant = function (value, datatype, scope) {
+        var scope_length = 0, i, variant;
+        if (typeof scope === 'undefined' || scope === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'Creation of a variant with a null scope is not allowed'};
+        }
+        if (scope && typeof scope === 'object') {
+            if (scope instanceof Array) {
+                scope_length = scope.length;
+            } else if (scope instanceof Topic) {
+                scope_length = 1;
+            }
+        }
+       /* 
+        TODO: Compare scope of Name and Variant
+        if (scope_length <= this.getScope().length) {
+            // check if the variants scope contains more scoping topics
+            throw {name: 'ModelConstraintException',
+            message: 'The variant would be in the same scope as the parent'};
+        }*/
+        variant = new Variant(this, value, datatype);
+        addScope(variant, scope);
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.getTopicMap().addThemeEvent.fire(variant,
+                {theme: this.scope[i]});
+        }
+        this.variants.push(variant);
+        return variant;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If value is null.
+     * @returns {Name} The name itself (for chaining support)
+     */
+    Name.prototype.setValue = function (value) {
+        if (!value) {
+            throw {name: 'ModelConstraintException',
+            message: 'Name.setValue(null) is not allowed'};
+        }
+        this.value = value;
+        return this;
+    };
+    
+    Name.prototype.getValue = function (value) {
+        return this.value;
+    };
+    
+    Name.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.parnt.parnt.removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.parnt.parnt.removeNameEvent.fire(this);
+        this.parnt._removeName(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+    Name.prototype._removeVariant = function (variant) {
+        for (var i = 0; i < this.variants.length; i += 1) {
+            if (this.variants[i].equals(variant)) {
+                this.variants.splice(i, 1);
+                break;
+            }
+        }
+        this.getTopicMap()._removeVariant(variant);
+    };
+
+    Name.prototype.getVariants = function () {
+        return this.variants;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If value or datatype is null.
+     */
+    Variant = function (parnt, value, datatype) {
+        if (value === null) {
+            throw {name: 'ModelConstraintException',
+                message: 'Creation of a variant with null value is not allowed'};
+        }
+        if (datatype === null) {
+            throw {name: 'ModelConstraintException',
+            message: 'Creation of a variant with datatype == null is not allowed'};
+        }
+        this.itemIdentifiers = [];
+        this.scope = [];
+        this.parnt = parnt;
+        if (typeof value === 'object' && value instanceof Locator) {
+            this.datatype = this.getTopicMap().createLocator('http://www.w3.org/2001/XMLSchema#anyURI');
+        } else {
+            this.datatype = 
+                this.getTopicMap().createLocator(XSD.string);
+        }
+        this.datatype = datatype;
+        this.reifier = null;
+        this.value = value;
+        this.id = this.getTopicMap()._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+    };
+    
+    Variant.swiss(Reifiable, 'getReifier', 'setReifier');
+    Variant.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Variant.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    Variant.swiss(DatatypeAware, 'decimalValue', 'floatValue', 'getDatatype',
+        'getValue', 'integerValue', 'locatorValue', 'longValue', 'setValue');
+    
+    Variant.prototype.isVariant = function () {
+        return true;
+    };
+    
+    Variant.prototype.getTopicMap = function () {
+        return this.getParent().getParent().getParent();
+    };
+    
+    Variant.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.getTopicMap().removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.getParent()._removeVariant(this);
+        this.id = null;
+        return this.parnt;
+    };
+    
+
+    Role = function (parnt, type, player) {
+        this.itemIdentifiers = [];
+        this.parnt = parnt;
+        this.type = type;
+        this.player = player;
+        this.id = this.getTopicMap()._getConstructId();
+        this.reifier = null;
+        this.getTopicMap()._id2construct.put(this.id, this);
+    };
+    
+    Role.swiss(Typed, 'getType', 'setType');
+    Role.swiss(Reifiable, 'getReifier', 'setReifier');
+    Role.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Role.prototype.isRole = function () {
+        return true;
+    };
+    
+    Role.prototype.getTopicMap = function () {
+        return this.getParent().getParent();
+    };
+    
+    Role.prototype.remove = function () {
+        var parnt = this.parnt;
+        this.parnt.parnt.removeRoleEvent.fire(this);
+        this.parnt._removeRole(this);
+        this.itemIdentifiers = null;
+        this.parnt = null;
+        this.type = null;
+        this.player = null;
+        this.reifier = null;
+        this.id = null;
+        return parnt;
+    };
+    
+    Role.prototype.getPlayer = function () {
+        return this.player;
+    };
+    
+    /**
+     * @throws {ModelConstraintException} If player is null.
+     * @returns {Role} The role itself (for chaining support)
+     */
+    Role.prototype.setPlayer = function (player) {
+        if (!player) {
+            throw {name: 'ModelConstraintException',
+            message: 'player i Role.setPlayer cannot be null'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.parnt.parnt, player);
+        if (this.player.equals(player)) {
+            return;
+        }
+        this.player.removeRolePlayed(this);
+        player.addRolePlayed(this);
+        this.player = player;
+        return this;
+    };
+    
+    Association = function (par) {
+        this.itemIdentifiers = [];
+        this.parnt = par;
+        this.id = this.getTopicMap()._getConstructId();
+        this.getTopicMap()._id2construct.put(this.id, this);
+        this.roles = [];
+        this.scope = [];
+        this.type = null;
+        this.reifier = null;
+    };
+    
+    Association.swiss(Typed, 'getType', 'setType');
+    Association.swiss(Reifiable, 'getReifier', 'setReifier');
+    Association.swiss(Scoped, 'addTheme', 'getScope', 'removeTheme');
+    Association.swiss(Construct, 'addItemIdentifier', 'equals', 'getId',
+        'getItemIdentifiers', 'getParent', 'getTopicMap', 'hashCode', 'remove',
+        'removeItemIdentifier', 'isTopic', 'isAssociation', 'isRole',
+        'isOccurrence', 'isName', 'isVariant', 'isTopicMap');
+    
+    Association.prototype.isAssociation = function () {
+        return true;
+    };
+    
+    Association.prototype.getTopicMap = function () {
+        return this.parnt;
+    };
+    
+    /**
+     * Creates a new Role representing a role in this association.
+     * @throws {ModelConstraintException} If type or player is null.
+     */
+    Association.prototype.createRole = function (type, player) {
+        if (!type) {
+            throw {name: 'ModelConstraintException',
+                message: 'type i Role.createPlayer cannot be null'};
+        }
+        if (!player) {
+            throw {name: 'ModelConstraintException',
+                message: 'player i Role.createRole cannot be null'};
+        }
+        SameTopicMapHelper.assertBelongsTo(this.parnt, type);
+        SameTopicMapHelper.assertBelongsTo(this.parnt, player);
+        var role = new Role(this, type, player);
+        player.addRolePlayed(role);
+        this.roles.push(role);
+        this.parnt.addRoleEvent.fire(role, {type: type, player: player});
+        return role;
+    };
+    
+    Association.prototype._removeRole = function (role) {
+        for (var i = 0; i < this.roles.length; i += 1) {
+            if (role.id === this.roles[i].id) {
+                this.roles.splice(i, 1);
+                break;
+            }
+        }
+        role.getPlayer().removeRolePlayed(role);
+        this.getTopicMap()._removeRole(role);
+    };
+    
+    Association.prototype.remove = function () {
+        var i;
+        for (i = 0; i < this.scope.length; i += 1) {
+            this.parnt.removeThemeEvent.fire(this, {theme: this.scope[i]});
+        }
+        this.parnt.removeAssociationEvent.fire(this);
+        while (this.roles.length) {
+            this.roles[0].remove();
+        }
+        this.id = null;
+        this.roles = null;
+        this.parnt._removeAssociation(this);
+        this.getTopicMap()._ii2construct.remove(this.id);
+        this.item_identifiers = null;
+        this.scope = null;
+        this.type = null;
+        this.reifier = null;
+        return this.parnt;
+    };
+    
+    /**
+     * Returns the roles participating in this association, or, if type
+     * is given, all roles with the specified type.
+     * @throws {IllegalArgumentException} If type is null.
+     */
+    Association.prototype.getRoles = function (type) {
+        if (type === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'Topic.getRoles cannot be called with type null'};
+        }
+        if (!type) {
+            return this.roles;
+        }
+        var ret = [], i; 
+        for (i = 0; i < this.roles.length; i += 1) {
+            if (this.roles[i].getType().equals(type)) {
+                ret.push(this.roles[i]);
+            }
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the role types participating in this association.
+     */
+    Association.prototype.getRoleTypes = function () {
+        // Create a hash with the object ids as keys to avoid duplicates
+        var types = {}, typearr = [], i, t;
+        for (i = 0; i < this.roles.length; i += 1) {
+            types[this.roles[i].getType().getId()] =
+                this.roles[i].getType();
+        }
+        for (t in types) {
+            if (types.hasOwnProperty(t)) {
+                typearr.push(types[t]);
+            }
+        }
+        return typearr;
+    };
+
+    // ------ ----------------------------------------------------------------
+    /** @class */
+    Index = function () {
+        this.opened = false;
+    };
+
+    /**
+     * Close the index.
+     */
+    Index.prototype.close = function () {
+        return;
+    };
+
+    /** 
+     * Indicates whether the index is updated automatically. 
+     * @returns {boolean}
+     */
+    Index.prototype.isAutoUpdated = function () {
+        return true;
+    };
+
+    /** Indicates if the index is open.
+     * @returns {boolean} true if index is already opened, false otherwise.
+     */
+    Index.prototype.isOpen = function () {
+        return this.opened;
+    };
+
+    /**
+     * Opens the index. This method must be invoked before using any other
+     * method (aside from isOpen()) exported by this interface or derived
+     * interfaces.
+     */
+    Index.prototype.open = function () {
+        this.opened = true;
+    };
+
+    /**
+     * Synchronizes the index with data in the topic map.
+     */
+    Index.prototype.reindex = function () {
+        return;
+    };
+
+    /**
+     * Creates a new instance of TypeInstanceIndex.
+     * @class Implementation of the TypeInstanceIndex interface.
+     */
+    TypeInstanceIndex = function (tm) {
+        var eventHandler, that = this;
+        this.tm = tm;
+        // we use hash tables of hash tables for our index
+        this.type2topics = new Hash();
+        this.type2associations = new Hash();
+        this.type2roles = new Hash();
+        this.type2occurrences = new Hash();
+        this.type2names = new Hash();
+        this.type2variants = new Hash();
+        this.opened = false;
+
+        eventHandler = function (eventtype, source, obj) {
+            var existing, untyped, types, type, i;
+            switch (eventtype) {
+            case EventType.ADD_ASSOCIATION:
+                break;
+            case EventType.ADD_NAME:
+                existing = that.type2names.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2names.put(obj.type.getId(), existing);
+                break;
+            case EventType.ADD_OCCURRENCE:
+                existing = that.type2occurrences.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2occurrences.put(obj.type.getId(), existing);
+                break;
+            case EventType.ADD_ROLE:
+                existing = that.type2roles.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2roles.put(obj.type.getId(), existing);
+                break;
+            case EventType.ADD_TOPIC:
+                existing = that.type2topics.get('null');
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2topics.put('null', existing);
+                break;
+            case EventType.ADD_TYPE:
+                // check if source exists with type null, remove it there
+                untyped = that.type2topics.get('null');
+                if (untyped && untyped.get(source.getId())) {
+                    untyped.remove(source.getId());
+                    that.type2topics.put('null', untyped);
+                }
+                    
+                existing = that.type2topics.get(obj.type.getId());
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);
+                that.type2topics.put(obj.type.getId(), existing);
+                break;
+            case EventType.REMOVE_ASSOCIATION:
+                type = source.getType();
+                if (!type) {
+                    break;
+                }
+                existing = that.type2associations.get(type.getId());
+                for (i = 0; i < existing.length; i += 1) {
+                    if (existing[i].equals(source)) {
+                        existing.splice(i, 1);
+                        break;
+                    }    
+                }
+                if (existing.length > 0) {
+                    that.type2associations.put(type.getId(),
+                            existing);
+                } else {
+                    that.type2associations.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_NAME:
+                type = source.getType();
+                existing = that.type2names.get(type.getId());
+                existing.remove(source.getId());
+                if (existing.length > 0) {
+                    that.type2names.put(type.getId(), existing);
+                } else {
+                    that.type2names.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_OCCURRENCE:
+                type = source.getType();
+                existing = that.type2occurrences.get(type.getId());
+                existing.remove(source.getId());
+                if (existing.length > 0) {
+                    that.type2occurrences.put(type.getId(), existing);
+                } else {
+                    that.type2occurrences.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_ROLE:
+                type = source.getType();
+                existing = that.type2roles.get(type.getId());
+                existing.remove(source.getId());
+                if (existing.length > 0) {
+                    that.type2roles.put(type.getId(), existing);
+                } else {
+                    that.type2roles.remove(type.getId());
+                }
+                break;
+            case EventType.REMOVE_TOPIC:
+                // two cases:
+                //  topic has types
+                types = source.getTypes();
+                for (i = 0; i < types.length; i += 1) {
+                    existing = that.type2topics.get(types[i].getId());
+                    existing.remove(source.getId());
+                    if (!existing.size()) {
+                        that.type2topics.remove(types[i].getId());
+                    }
+                }
+                // topic used as type 
+                that.type2topics.remove(source.getId());
+                that.type2associations.remove(source.getId());
+                that.type2roles.remove(source.getId());
+                that.type2occurrences.remove(source.getId());
+                that.type2variants.remove(source.getId());
+                break;
+            case EventType.REMOVE_TYPE:
+                existing = that.type2topics.get(obj.type.getId());
+                existing.remove(source.getId());
+                if (!existing.size()) {
+                    that.type2topics.remove(obj.type.getId());
+                }
+                if (source.getTypes().length === 0) {
+                    untyped = that.type2topics.get('null');
+                    if (typeof untyped === 'undefined') {
+                        untyped = new Hash();
+                    }
+                    untyped.put(source.getId(), source);
+                }
+                break;
+            case EventType.SET_TYPE:
+                if (source.isAssociation()) {
+                    // remove source from type2associations(obj.old.getId());
+                    if (obj.old) {
+                        existing = that.type2associations.get(obj.old.getId());
+                        for (i = 0; i < existing.length; i += 1) {
+                            if (existing[i].equals(source)) {
+                                existing.splice(i, 1);
+                                break;
+                            }    
+                        }
+                        if (existing.length > 0) {
+                            that.type2associations.put(obj.old.getId(),
+                                    existing);
+                        } else {
+                            that.type2associations.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2associations.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = [];
+                    }
+                    existing.push(source);
+                    that.type2associations.put(obj.type.getId(), existing);
+                } else if (source.isName()) {
+                    existing = that.type2names.get(obj.old.getId());
+                    if (existing) {
+                        existing.remove(source.getId());
+                        if (existing.length > 0) {
+                            that.type2names.put(obj.old.getId(), existing);
+                        } else {
+                            that.type2names.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2names.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = new Hash();
+                    }
+                    existing.put(source.getId(), source);
+                    that.type2names.put(obj.type.getId(), existing);
+                } else if (source.isOccurrence()) {
+                    existing = that.type2occurrences.get(obj.old.getId());
+                    if (existing) {
+                        existing.remove(source.getId());
+                        if (existing.length > 0) {
+                            that.type2occurrences.put(obj.old.getId(), existing);
+                        } else {
+                            that.type2occurrences.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2occurrences.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = new Hash();
+                    }
+                    existing.put(source.getId(), source);
+                    that.type2occurrences.put(obj.type.getId(), existing);
+                } else if (source.isRole()) {
+                    existing = that.type2roles.get(obj.old.getId());
+                    if (existing) {
+                        existing.remove(source.getId());
+                        if (existing.length > 0) {
+                            that.type2roles.put(obj.old.getId(), existing);
+                        } else {
+                            that.type2roles.remove(obj.old.getId());
+                        }
+                    }
+                    existing = that.type2roles.get(obj.type.getId());
+                    if (typeof existing === 'undefined') {
+                        existing = new Hash();
+                    }
+                    existing.put(source.getId(), source);
+                    that.type2roles.put(obj.type.getId(), existing);
+                }
+                break;
+            }
+        };
+        tm.addAssociationEvent.registerHandler(eventHandler);
+        tm.addNameEvent.registerHandler(eventHandler);
+        tm.addOccurrenceEvent.registerHandler(eventHandler);
+        tm.addRoleEvent.registerHandler(eventHandler);
+        tm.addTopicEvent.registerHandler(eventHandler);
+        tm.addTypeEvent.registerHandler(eventHandler);
+        tm.removeAssociationEvent.registerHandler(eventHandler);
+        tm.removeNameEvent.registerHandler(eventHandler);
+        tm.removeOccurrenceEvent.registerHandler(eventHandler);
+        tm.removeRoleEvent.registerHandler(eventHandler);
+        tm.removeTopicEvent.registerHandler(eventHandler);
+        tm.removeTypeEvent.registerHandler(eventHandler);
+        tm.setTypeEvent.registerHandler(eventHandler);
+    };
+
+    TypeInstanceIndex.swiss(Index, 'close', 'isAutoUpdated',
+        'isOpen', 'open', 'reindex');
+          
+    /**
+     * Returns the associations in the topic map whose type property equals type.
+     *
+     * @param {Topic} type
+     * @returns {Array} A list of all associations in the topic map with the given type.
+     */
+    TypeInstanceIndex.prototype.getAssociations = function (type) {
+        var ret = this.type2associations.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of Associations.
+     *
+     * @returns {Array} A list of all topics that are used as an association type.
+     */
+    TypeInstanceIndex.prototype.getAssociationTypes = function () {
+        var ret = [], keys = this.type2associations.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the topic names in the topic map whose type property equals type.
+     *
+     * @param {Topic} type
+     * @returns {Array}
+     */
+    TypeInstanceIndex.prototype.getNames = function (type) {
+        var ret = this.type2names.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of Names.
+     *
+     * @returns {Array} An array of topic types. Note that the array contains
+     * a reference to the actual topics, not copies of them.
+     */
+    TypeInstanceIndex.prototype.getNameTypes = function () {
+        var ret = [], keys = this.type2names.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the occurrences in the topic map whose type property equals type.
+     *
+     * @returns {Array}
+     */
+    TypeInstanceIndex.prototype.getOccurrences = function (type) {
+        var ret = this.type2occurrences.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of
+     * Occurrences.
+     *
+     * @returns {Array} An array of topic types. Note that the array contains
+     * a reference to the actual topics, not copies of them.
+     */
+    TypeInstanceIndex.prototype.getOccurrenceTypes = function () {
+        var ret = [], keys = this.type2occurrences.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+
+    /**
+     * Returns the roles in the topic map whose type property equals type.
+     *
+     * @returns {Array}
+     */
+    TypeInstanceIndex.prototype.getRoles = function (type) {
+        var ret = this.type2roles.get(type.getId());
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics in the topic map used in the type property of Roles.
+     *
+     * @returns {Array} An array of topic types. Note that the array contains
+     * a reference to the actual topics, not copies of them.
+     */
+    TypeInstanceIndex.prototype.getRoleTypes = function () {
+        var ret = [], keys = this.type2roles.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            ret.push(this.tm.getConstructById(keys[i]));
+        }
+        return ret;
+    };
+
+    /**
+     * Returns the topics which are an instance of the specified type.
+     */
+    TypeInstanceIndex.prototype.getTopics = function (type) {
+        var ret = this.type2topics.get((type ? type.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the topics which are an instance of the specified types.
+     * If matchall is true only topics that have all of the listed types
+     * are returned.
+     * @returns {Array} A list of Topic objects
+     */
+    TypeInstanceIndex.prototype.getTopicsByTypes = function (types, matchall) {
+        var instances, i, j;
+        instances = IndexHelper.getForKeys(this.type2topics, types);
+        if (!matchall) {
+            return instances;
+        }
+        // If matchall is true, we check all values for all types in {types}
+        // It's a hack, but will do for now
+        for (i = 0; i < instances.length; i += 1) {
+            for (j = 0; j < types.length; j += 1) {
+                if (!ArrayHelper.contains(instances[i].getTypes(), types[j])) {
+                    instances.splice(i, 1);
+                    i -= 1;
+                    break;
+                }
+            }
+        }
+        return instances;
+    };
+
+    /**
+     * Returns the topics in topic map which are used as type in an
+     * "type-instance"-relationship.
+     */
+    TypeInstanceIndex.prototype.getTopicTypes = function () {
+        var ret = [], keys = this.type2topics.keys(), i;
+        for (i = 0; i < keys.length; i += 1) {
+            if (keys[i] !== 'null') {
+                ret.push(this.tm.getConstructById(keys[i]));
+            }
+        }
+        return ret;
+    };
+
+    TypeInstanceIndex.prototype.close = function () {
+        return;
+    };
+
+
+    /**
+     * Index for Scoped statements and their scope. This index provides access
+     * to Associations, Occurrences, Names, and Variants by their scope
+     * property and to Topics which are used as theme in a scope. 
+     */
+    ScopedIndex = function (tm) {
+        var that = this, eventHandler;
+        this.tm = tm;
+        this.theme2associations = new Hash();
+        this.theme2names = new Hash();
+        this.theme2occurrences = new Hash();
+        this.theme2variants = new Hash();
+        eventHandler = function (eventtype, source, obj) {
+            var existing, key, unscoped, remove_from_index, add_to_index;
+            add_to_index = function (hash, source, obj) {
+                key = (obj.theme ? obj.theme.getId() : 'null');
+
+                // check if source exists with theme null, remove it there
+                // this is the case iff source now has one scoping topic
+                if (source.getScope().length === 1) {
+                    unscoped = hash.get('null');
+                    if (unscoped && unscoped.get(source.getId())) {
+                        unscoped.remove(source.getId());
+                        hash.put('null', unscoped);
+                    }
+                }
+                existing = hash.get(key);
+                if (typeof existing === 'undefined') {
+                    existing = new Hash();
+                }
+                existing.put(source.getId(), source);  
+                hash.put(key, existing);
+            };
+            remove_from_index = function (hash, source, obj) {
+                key = obj.theme.getId();
+                existing = hash.get(key);
+                if (typeof existing !== 'undefined') {
+                    existing.remove(source.getId());  
+                    if (!existing.size()) {
+                        hash.remove(key);
+                    }
+                }
+            };
+            switch (eventtype) {
+            case EventType.ADD_THEME:
+                if (source.isAssociation()) {
+                    add_to_index(that.theme2associations, source, obj);
+                } else if (source.isName()) {
+                    add_to_index(that.theme2names, source, obj);
+                } else if (source.isOccurrence()) {
+                    add_to_index(that.theme2occurrences, source, obj);
+                } else if (source.isVariant()) {
+                    add_to_index(that.theme2variants, source, obj);
+                }
+                break;
+            case EventType.REMOVE_THEME:
+                if (source.isAssociation()) {
+                    remove_from_index(that.theme2associations, source, obj);
+                } else if (source.isName()) {
+                    remove_from_index(that.theme2names, source, obj);
+                } else if (source.isOccurrence()) {
+                    remove_from_index(that.theme2occurrences, source, obj);
+                } else if (source.isVariant()) {
+                    remove_from_index(that.theme2variants, source, obj);
+                }
+                break;
+            }
+        };
+        tm.addThemeEvent.registerHandler(eventHandler);
+        tm.removeThemeEvent.registerHandler(eventHandler);
+    };
+
+    ScopedIndex.swiss(Index, 'close', 'isAutoUpdated',
+        'isOpen', 'open', 'reindex');
+
+    ScopedIndex.prototype.close = function () {
+        return;
+    };
+
+    /**
+     * Returns the Associations in the topic map whose scope property contains
+     * the specified theme. The return value may be empty but must never be null. 
+     * @param theme can be array or {Topic}
+     * @param [matchall] boolean
+     */
+    ScopedIndex.prototype.getAssociations = function (theme) {
+        var ret = this.theme2associations.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Associations in the topic map whose scope property contains
+     * the specified theme. The return value may be empty but must never be null. 
+     * @param theme can be array or {Topic}
+     * @param [matchall] boolean
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getAssociationsByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getAssociationsByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2associations,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of
+     * Associations.
+     */
+    ScopedIndex.prototype.getAssociationThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2associations);
+    };
+
+    /**
+     * Returns the Names in the topic map whose scope property contains the
+     * specified theme.
+     */
+    ScopedIndex.prototype.getNames = function (theme) {
+        var ret = this.theme2names.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Names in the topic map whose scope property equals one of
+     * those themes at least.
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getNamesByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getNamesByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2names,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of Names.
+     */
+    ScopedIndex.prototype.getNameThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2names);
+    };
+
+    /**
+     * Returns the Occurrences in the topic map whose scope property contains the
+     * specified theme.
+     */
+    ScopedIndex.prototype.getOccurrences = function (theme) {
+        var ret = this.theme2occurrences.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Occurrences in the topic map whose scope property equals one
+     * of those themes at least.
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getOccurrencesByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getOccurrencesByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2occurrences,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of
+     * Occurrences.
+     */
+    ScopedIndex.prototype.getOccurrenceThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2occurrences);
+    };
+
+    /**
+     * Returns the Variants in the topic map whose scope property contains the
+     * specified theme. The return value may be empty but must never be null. 
+     * @param {Topic} The Topic which must be part of the scope. This must not be
+     * null. 
+     * @returns {Array} An array of Variants.
+     * @throws {IllegalArgumentException} If theme is null.
+     */
+    ScopedIndex.prototype.getVariants = function (theme) {
+        if (theme === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getVariants cannot be called without themes'};
+        }
+        var ret = this.theme2variants.get((theme ? theme.getId() : 'null'));
+        if (!ret) {
+            return [];
+        }
+        return ret.values();
+    };
+
+    /**
+     * Returns the Variants in the topic map whose scope property equals one of
+     * those themes at least.
+     * @param {Array} themes Scope of the Variants to be returned.
+     * @param {boolean} If true the scope property of a variant must match all
+     * themes, if false one theme must be matched at least.
+     * @returns {Array} An array of variants
+     * @throws {IllegalArgumentException} If themes is null.
+     */
+    ScopedIndex.prototype.getVariantsByThemes = function (themes, matchall) {
+        if (themes === null) {
+            throw {name: 'IllegalArgumentException',
+                message: 'ScopedIndex.getVariantsByThemes cannot be called without themes'};
+        }
+        return IndexHelper.getConstructsByThemes(this.theme2variants,
+            themes, matchall);
+    };
+
+    /**
+     * Returns the topics in the topic map used in the scope property of Variants.
+     * The return value may be empty but must never be null.
+     * @returns {Array} An array of Topics.
+     */
+    ScopedIndex.prototype.getVariantThemes = function () {
+        return IndexHelper.getConstructThemes(this.tm, this.theme2variants);
+    };
+
+
+
+
+    /**
+     * @class Helper class that is used to check if constructs belong to
+     * a given topic map.
+     */
+    SameTopicMapHelper = {
+        /**
+         * Checks if topic belongs to the topicmap 'topicmap'.
+         * topic can be instance of Topic or an Array with topics.
+         * topic map be null.
+         * @static
+         * @throws ModelConstraintException if the topic(s) don't
+         * belong to the same topic map.
+         * @returns false if the topic was null or true otherwise.
+         */
+        assertBelongsTo: function (topicmap, topic) {
+            var i;
+            if (!topic) {
+                return false;
+            }
+            if (topic && topic instanceof Topic &&
+                    !topicmap.equals(topic.getTopicMap())) {
+                throw {name: 'ModelConstraintException',
+                    message: 'scope topic belongs to different topic map'};
+            }
+            if (topic && topic instanceof Array) {
+                for (i = 0; i < topic.length; i += 1) {
+                    if (!topicmap.equals(topic[i].getTopicMap())) {
+                        throw {name: 'ModelConstraintException',
+                            message: 'scope topic belong to different topic maps'};
+                    }
+                }
+            }
+            return true;
+        }
+    };
+
+    /**
+     * Helper functions for hashes of hashes
+     * @ignore
+     */
+    IndexHelper = {
+        getForKeys: function (hash, keys) {
+            var i, j, tmp = new Hash(), value_hash, value_keys;
+            for (i = 0; i < keys.length; i += 1) {
+                value_hash = hash.get(keys[i].getId());
+                if (value_hash) {
+                    value_keys = value_hash.keys();
+                    // we use a hash to store instances to avoid duplicates
+                    for (j = 0; j < value_keys.length; j += 1) {
+                        tmp.put(value_hash.get(value_keys[j]).getId(),
+                                value_hash.get(value_keys[j]));
+                    }
+                }
+            }
+            return tmp.values();
+        },
+
+        getConstructThemes: function (tm, hash) {
+            var ret = [], keys = hash.keys(), i;
+            for (i = 0; i < keys.length; i += 1) {
+                if (keys[i] !== 'null') {
+                    ret.push(tm.getConstructById(keys[i]));
+                }
+            }
+            return ret;
+        },
+
+        getConstructsByThemes: function (hash, themes, matchall) {
+            var constructs, i, j;
+            constructs = IndexHelper.getForKeys(hash, themes);
+            if (!matchall) {
+                return constructs;
+            }
+            // If matchall is true, we check all values for all types in {types}
+            // It's a hack, but will do for now
+            for (i = 0; i < constructs.length; i += 1) {
+                for (j = 0; j < themes.length; j += 1) {
+                    if (!ArrayHelper.contains(constructs[i].getScope(), themes[j])) {
+                        constructs.splice(i, 1);
+                        i -= 1;
+                        break;
+                    }
+                }
+            }
+            return constructs;
+        }
+    };
+
+    /** 
+     * Helper functions for arrays. We don't modify the global array
+     * object to avoid conflicts with other libraries.
+     * @ignore
+     */
+    ArrayHelper = {
+        /** Checks if arr contains elem */
+        contains: function (arr, elem) {
+            for (var key in arr) {
+                if (arr.hasOwnProperty(key)) {
+                    if (arr[key].equals(elem)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    };
+
+    /** 
+     * Internal function to add scope. scope may be Array, Topic or null.
+     * @ignore
+     * FIXME: Move to a class
+     */
+    addScope = function (construct, scope) {
+        var i;
+        if (scope && typeof scope === 'object') {
+            if (scope instanceof Array) {
+                for (i = 0; i < scope.length; i += 1) {
+                    construct.addTheme(scope[i]);
+                }
+            } else if (scope instanceof Topic) {
+                construct.addTheme(scope);
+            }
+        } else {
+            construct.getTopicMap().addThemeEvent.fire(construct, {theme: null});
+        }
+    };
+
+    /**
+     * Helper class for generating signatures of Topic Maps constructs.
+     */
+    SignatureGenerator = {
+        makeNameValueSignature: function (name) {
+            return name.getValue();
+        },
+
+        makeNameSignature: function (name) {
+            return SignatureGenerator.makeNameValueSignature(name) +
+                '#' + SignatureGenerator.makeTypeSignature(name) +
+                '#' + SignatureGenerator.makeScopeSignature(name);
+        },
+
+        makeOccurrenceSignature: function (occ) {
+            return SignatureGenerator.makeOccurrenceValueSignature(occ) +
+                '#' + SignatureGenerator.makeTypeSignature(occ) +
+                '#' + SignatureGenerator.makeScopeSignature(occ);
+        },
+
+        makeOccurrenceValueSignature: function (occ) {
+            return '#' + occ.getValue() + '#' +
+                (occ.getDatatype() ? occ.getDatatype().getReference() : 'null');
+        },
+
+        makeTypeSignature: function (obj) {
+            var type = obj.getType();
+            if (type) {
+                return type.getId();
+            } else {
+                return '';
+            }
+        },
+
+        makeScopeSignature: function (scope) {
+            var i, arr = [];
+            for (i = 0; i < scope.length; i += 1) {
+                arr.push(scope[i].getId());
+            }
+            arr.sort();
+            return arr.join('#');
+        },
+
+        makeAssociationSignature: function (ass) {
+            var roles, i, tmp = [];
+            roles = ass.getRoles();
+            for (i = 0; i < roles.length; i += 1) {
+                tmp.push(SignatureGenerator.makeRoleSignature(roles[i]));
+            }
+            tmp.sort();
+        
+            return '#' + SignatureGenerator.makeTypeSignature(ass) + '#' + tmp.join('#') +
+                SignatureGenerator.makeScopeSignature(ass);
+        },
+
+        makeRoleSignature: function (role) {
+            return SignatureGenerator.makeTypeSignature(role) + '#' +
+                role.getPlayer().getId();
+        },
+
+        makeVariantValueSignature: function (variant) {
+            return '#' + variant.getValue() + '#' + variant.getDatatype().getReference();
+        },
+
+        makeVariantSignature: function (variant) {
+            return SignatureGenerator.makeVariantValueSignature(variant) +
+                '#' + SignatureGenerator.makeScopeSignature(variant);
+        }
+    };
+
+    /**
+     * Utility class that removes duplicates according to the TMDM.
+     */
+    DuplicateRemover = {
+        removeTopicMapDuplicates: function (tm) {
+            var i, topics, associations, sig2ass = new Hash(), sig, existing;
+            topics = tm.getTopics();
+            for (i = 0; i < topics.length; i += 1) {
+                DuplicateRemover.removeOccurrencesDuplicates(topics[i].getOccurrences());
+                DuplicateRemover.removeNamesDuplicates(topics[i].getNames());
+            }
+            associations = tm.getAssociations();
+            for (i = 0; i < associations.length; i += 1) {
+                DuplicateRemover.removeAssociationDuplicates(associations[i]);
+                sig = SignatureGenerator.makeAssociationSignature(associations[i]);
+                if ((existing = sig2ass.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(associations[i], existing);
+                    MergeHelper.moveRoleCharacteristics(associations[i], existing);
+                    associations[i].remove();
+                } else {
+                    sig2ass.put(sig, associations[i]);
+                }
+            }
+            sig2ass.empty();
+        },
+
+        removeOccurrencesDuplicates: function (occurrences) {
+            var i, sig2occ = new Hash(), occ, sig, existing;
+            for (i = 0; i < occurrences.length; i += 1) {
+                occ = occurrences[i];
+                sig = SignatureGenerator.makeOccurrenceSignature(occ);
+                if ((existing = sig2occ.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(occ, existing);
+                    occ.remove();
+                } else {
+                    sig2occ.put(sig, occ);
+                }
+            }
+            sig2occ.empty();
+        },
+
+        removeNamesDuplicates: function (names) {
+            var i, sig2names = new Hash(), name, sig, existing;
+            for (i = 0; i < names.length; i += 1) {
+                name = names[i];
+                DuplicateRemover.removeVariantsDuplicates(name.getVariants());
+                sig = SignatureGenerator.makeNameSignature(name);
+                if ((existing = sig2names.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(name, existing);
+                    MergeHelper.moveVariants(name, existing);
+                    name.remove();
+                } else {
+                    sig2names.put(sig, name);
+                }
+            }
+            sig2names.empty();
+        },
+
+        removeVariantsDuplicates: function (variants) {
+            var i, sig2variants = new Hash(), variant, sig, existing;
+            for (i = 0; i < variants.length; i += 1) {
+                variant = variants[i];
+                sig = SignatureGenerator.makeVariantSignature(variant);
+                if ((existing = sig2variants.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(variant, existing);
+                    variant.remove();
+                } else {
+                    sig2variants.put(sig, variant);
+                }
+            }
+            sig2variants.empty();
+        },
+
+        removeAssociationDuplicates: function (assoc) {
+            var i, roles = assoc.getRoles(), sig2role = new Hash(), sig, existing;
+            for (i = 0; i < roles.length; i += 1) {
+                sig = SignatureGenerator.makeRoleSignature(roles[i]);
+                if ((existing = sig2role.get(sig))) {
+                    MergeHelper.moveConstructCharacteristics(roles[i], existing);
+                    roles[i].remove();
+                } else {
+                    sig2role.put(sig, roles[i]);
+                }
+            }
+        }
+    };
+
+    MergeHelper = {
+        moveTypes: function (arr, target) {
+            var i;
+            for (i = 0; i < arr.length; i += 1) {
+                arr[i].setType(target);
+            }
+        },
+
+        moveThemes: function (arr, source, target) {
+            for (var i = 0; i < arr.length; i += 1) {
+                arr[i].removeTheme(source);
+                arr[i].addTheme(target);
+            }
+        },
+
+        moveItemIdentifiers: function (source, target) {
+            var iis, ii;
+            iis = source.getItemIdentifiers();
+            while (iis.length) {
+                ii = iis[iis.length - 1];
+                source.removeItemIdentifier(ii);
+                target.addItemIdentifier(ii);
+            }
+        },
+
+        /**
+         * Moves variants from the name source to the name target
+         */
+        moveVariants: function (source, target) {
+            var arr, i, tmp, tmp2, signatures;
+            arr = target.getVariants();
+            signatures = {};
+            for (i = 0; i < arr.length; i += 1) {
+                signatures[SignatureGenerator.makeVariantSignature(arr[i])] = arr[i];
+            }
+            arr = source.getVariants();
+            for (i = 0; i < arr.length; i += 1) {
+                tmp = arr[i];
+                if ((tmp2 = signatures[SignatureGenerator.makeVariantSignature(arr[i])])) {
+                    MergeHelper.moveItemIdentifiers(tmp, tmp2);
+                    MergeHelper.moveReifier(tmp, tmp2);
+                    tmp.remove();
+                } else {
+                    target.createVariant(tmp.getValue(), tmp.getDatatype(), tmp.getScope());
+                }
+            }
+        },
+
+        moveReifier: function (source, target) {
+            var r1, r2;
+            if (source.getReifier() === null) {
+                return;
+            } else if (target.getReifier() === null) {
+                target.setReifier(source.getReifier());
+            } else {
+                r1 = source.getReifier();
+                r2 = target.getReifier();
+                source.setReifier(null);
+                r1.mergeIn(r2);
+            }
+        },
+
+        moveRoleCharacteristics: function (source, target) {
+            var i, roles, sigs = new Hash();
+            roles = target.getRoles();
+            for (i = 0; i < roles.length; i += 1) {
+                sigs.put(roles[i], SignatureGenerator.makeRoleSignature(roles[i]));
+            }
+            roles = source.getRoles();
+            for (i = 0; i < roles.length; i += 1) {
+                MergeHelper.moveItemIdentifiers(roles[i],
+                    sigs.get(SignatureGenerator.makeRoleSignature(roles[i])));
+                roles[i].remove();
+            }
+        },
+
+        moveConstructCharacteristics: function (source, target) {
+            MergeHelper.moveReifier(source, target);
+            MergeHelper.moveItemIdentifiers(source, target);
+        }
+    };
+
+    CopyHelper = {
+        copyAssociations: function (source, target, mergeMap) {
+        },
+        copyItemIdentifiers: function (source, target) {
+        },
+        copyReifier: function (source, target, mergeMap) {
+        },
+        copyScope: function (source, target, mergeMap) {
+        },
+        copyTopicMap: function (source, target) {
+        },
+        copyTopic: function (sourcetm, targettm, mergeMap) {
+        },
+        copyType: function (source, target, mergeMap) {
+        }
+    };
+
+    TypeInstanceHelper = {
+        convertAssociationsToType: function (tm) {
+            var typeInstance, type, instance, associations, index, i, ass, roles;
+            typeInstance = tm.getTopicBySubjectIdentifier(
+                tm.createLocator(TMDM.TYPE_INSTANCE));
+            type = tm.getTopicBySubjectIdentifier(
+                tm.createLocator(TMDM.TYPE));
+            instance = tm.getTopicBySubjectIdentifier(
+                tm.createLocator(TMDM.INSTANCE));
+            if (!typeInstance || !type || !instance) {
+                return;
+            }
+            index = tm.getIndex('TypeInstanceIndex');
+            if (!index) {
+                return;
+            }
+            if (!index.isAutoUpdated()) {
+                index.reindex();
+            }
+            associations = index.getAssociations(typeInstance);
+            for (i = 0; i < associations.length; i += 1) {
+                ass = associations[i];
+                if (ass.getScope().length > 0 ||
+                    ass.getReifier() !== null ||
+                    ass.getItemIdentifiers().length > 0) {
+                    continue;
+                }
+                roles = ass.getRoles();
+                if (roles.length !== 2) {
+                    continue;
+                }
+                if (roles[0].getType().equals(type) && roles[1].getType().equals(instance)) {
+                    roles[1].getPlayer().addType(roles[0].getPlayer());
+                } else
+                if (roles[1].getType().equals(type) && roles[0].getType().equals(instance)) {
+                    roles[0].getPlayer().addType(roles[1].getPlayer());
+                } else {
+                    continue;
+                }
+                ass.remove();
+            }
+        }
+    };
+
+    // Export objects into the TM namespace
+    return {
+        TopicMapSystemFactory: TopicMapSystemFactory,
+        XSD: XSD,
+        TMDM: TMDM,
+        Hash: Hash, // needed by CXTM export
+        Version: Version
+    };
+}());
+
+// Pollute the global namespace
+TopicMapSystemFactory = TM.TopicMapSystemFactory; 
+
+// Check if we are in a CommonJS environment (e.g. node.js)
+if (typeof exports === 'object' && exports !== null) {
+    exports.TopicMapSystemFactory = TopicMapSystemFactory;
+    exports.TM = TM;
+}
+
+/*jslint browser: true, devel: true, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: true, bitwise: true,
+  regexp: true, newcap: true, immed: true, indent: 4 */
+/*global TM, window, DOMParser, ActiveXObject*/ 
+
+TM.JTM = (function () {
+    var ReaderImpl, WriterImpl;
+
+    ReaderImpl = function (tm) {
+        var that = this;
+        this.tm = tm;
+        this.version = null; // Keep the JTM version number
+        this.prefixes = {};
+        this.defaultDatatype = this.tm.createLocator(TM.XSD.string);
+
+        this.curieToLocator = function (loc) {
+            var curie, prefix, pos;
+            if (that.version === '1.1' &&
+                loc.substr(0, 1) === '[') {
+                if (loc.substr(loc.length - 1, 1) !== ']') {
+                    throw {name: 'InvalidFormat',
+                        message: 'Invaild CURIE: missing tailing bracket'};
+                }
+                curie = loc.substr(1, loc.length - 2);
+                pos = curie.indexOf(':');
+                if (pos !== -1) {
+                    // Lookup prefix and replace with URL
+                    prefix = curie.substr(0, pos);
+                    if (that.prefixes[prefix]) {
+                        loc = that.prefixes[prefix] +
+                            curie.substr(pos + 1, curie.length - 1);
+                        return loc;
+                    } else {
+                        throw {name: 'InvalidFormat',
+                            message: 'Missing prefix declaration: ' + prefix};
+                    }
+                } else {
+                    throw {name: 'InvalidFormat',
+                        message: 'Invaild CURIE: missing colon'};
+                }
+            }
+            return loc;
+        };
+
+        /**
+        * Internal function that takes a JTM-identifier string as a parameter
+        * and returns a topic object - either an existing topic or a new topic
+        * if the requested topic did not exist
+        * @param {String} locator JTM-identifier
+        * @throws {InvalidFormat} If the locator could not be parsed.
+        */
+        this.getTopicByReference = function (locator) {
+            if (typeof locator === 'undefined' || locator === null) {
+                return null;
+            }
+            switch (locator.substr(0, 3)) {
+            case 'si:' :
+                return this.tm.createTopicBySubjectIdentifier(
+                    this.tm.createLocator(this.curieToLocator(locator.substr(3))));
+            case 'sl:' :
+                return this.tm.createTopicBySubjectLocator(
+                    this.tm.createLocator(this.curieToLocator(locator.substr(3))));
+            case 'ii:' :
+                return this.tm.createTopicByItemIdentifier(
+                    this.tm.createLocator(this.curieToLocator(locator.substr(3))));
+            }
+            throw {name: 'InvalidFormat',
+                message: 'Invaild topic reference \'' + locator + '\''};
+        };
+    };
+
+    /**
+    * Imports a JTM topic map or JTM fragment from a JSON-string.
+    * name, variant, occurrence and role fragments need the optional parent
+    * construct as a parameter.
+    * TODO: Decide if this should be part of tmjs. Add functions for decoding/
+    * encoding JSON if so.
+    *
+    * @param {String} str JSON encoded JTM
+    * @param {Construct} [parent] Parent construct if the JTM fragment contains
+    *        a name, variant, occurrence or role.
+    */
+    ReaderImpl.prototype.fromString = function (str, parent) {
+        var obj = JSON.parse(str);
+        return this.fromObject(obj);
+    };
+
+    /**
+    * Imports a JTM topic map or JTM fragment.
+    * name, variant, occurrence and role fragments need the parent construct
+    * as a parameter.
+    *
+    * @param {object} obj with JTM properties
+    * @param {Construct} [parent] Parent construct if the JTM fragment contains
+    *        a name, variant, occurrence or role.
+    */
+    ReaderImpl.prototype.fromObject = function (obj, parent) {
+        var ret;
+        parent = parent || null;
+        if (obj.version !== '1.0' && obj.version !== '1.1') {
+            throw {name: 'InvalidFormat',
+                message: 'Unknown version of JTM: ' + obj.version};
+        }
+        this.version = obj.version;
+        if (obj.version === '1.1' && obj.prefixes) {
+            this.prefixes = obj.prefixes;
+            // Check if xsd is defined and if it is valid:
+            if (obj.prefixes && obj.prefixes.xsd &&
+                obj.prefixes.xsd !== 'http://www.w3.org/2001/XMLSchema#') {
+                throw {name: 'InvalidFormat',
+                    message: 'The XSD prefix MUST have the value "http://www.w3.org/2001/XMLSchema#"'};
+            }
+        } else if (obj.prefixes) {
+            throw {name: 'InvalidFormat',
+                message: 'Prefixes are invalid in JTM 1.0: ' + obj.version};
+        }
+        if (!this.prefixes.xsd) {
+            this.prefixes.xsd = 'http://www.w3.org/2001/XMLSchema#';
+        }
+        if (!obj.item_type) {
+            throw {name: 'InvalidFormat',
+                message: 'Missing item_type'};
+        }
+        switch (obj.item_type.toLowerCase()) {
+        case "topicmap":
+            ret = this.parseTopicMap(obj);
+            break;
+        case "topic":
+            ret = this.parseTopic(obj);
+            break;
+        case "name":
+            ret = this.parseName(parent, obj);
+            break;
+        case "variant":
+            ret = this.parseVariant(parent, obj);
+            break;
+        case "occurrence":
+            ret = this.parseOccurrence(parent, obj);
+            break;
+        case "association":
+            ret = this.parseAssociation(obj);
+            break;
+        case "role":
+            ret = this.parseRole(parent, obj);
+            break;
+        default:
+            throw {name: 'InvalidFormat',
+                message: 'Unknown item_type property'};
+        }
+        return ret;
+    };
+
+    /**
+     * FIXME: Work in progress. We have to specify *how* the information
+     * item can be created.
+     *
+     * Internal function that parses a parent field. From the JTM spec:
+     * "The value of the parent member is an array of item identifiers,
+     * each prefixed by "ii:". For occurrences and names the parent array
+     * may as well contain subject identifiers prefixed by "si:" and
+     * subject locators prefixed by "sl:".
+     */
+    ReaderImpl.prototype.parseParentAsTopic = function (obj, allowTopic) {
+        var parent = null, tmp, i;
+        if (!obj.parent) {
+            parent = this.tm.createTopic();
+        } else if (!(obj.parent instanceof Array) || obj.parent.length === 0) {
+            throw {name: 'InvalidFormat',
+                message: 'Missing parent topic reference in occurrence'};
+        }
+        if (obj.parent) {
+            for (i = 0; i < obj.parent.length; i += 1) {
+                tmp = this.getTopicByReference(obj.parent[i]);
+                if (!parent) {
+                    parent = tmp;
+                } else {
+                    parent.mergeIn(tmp);
+                }
+            }
+        }
+        return parent;
+    };
+
+    ReaderImpl.prototype.parseTopicMap = function (obj) {
+        var i, len, arr;
+        this.parseItemIdentifiers(this.tm, obj.item_identifiers);
+        this.parseReifier(this.tm, obj.reifier);
+        if (obj.topics && typeof obj.topics === 'object' && obj.topics instanceof Array) {
+            arr = obj.topics;
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                this.parseTopic(arr[i]);
+            }
+            arr = null;
+        }
+        if (obj.associations && typeof obj.associations === 'object' &&
+            obj.associations instanceof Array) {
+            arr = obj.associations;
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                this.parseAssociation(arr[i]);
+            }
+            arr = null;
+        }
+        this.tm.sanitize(); // remove duplicates and convert type-instance associations to types
+        return true;
+    };
+
+    ReaderImpl.prototype.parseTopic = function (obj) {
+        var that = this, topic = null, parseIdentifier, arr, i, identifier, type;
+        parseIdentifier = function (tm, topic, arr, getFunc, createFunc, addFunc) {
+            var i, len, tmp;
+            if (arr && typeof arr === 'object' && arr instanceof Array) {
+                len = arr.length;
+                for (i = 0; i < len; i += 1) {
+                    identifier = decodeURI(that.curieToLocator(arr[i]));
+                    if (!topic) {
+                        topic = createFunc.apply(tm, [tm.createLocator(identifier)]);
+                    } else {
+                        tmp = getFunc.apply(tm, [tm.createLocator(identifier)]);
+                        if (tmp && tmp.isTopic() && !topic.equals(tmp)) {
+                            topic.mergeIn(tmp);
+                        } else if (!(tmp && tmp.isTopic() && topic.equals(tmp))) {
+                            topic[addFunc](tm.createLocator(identifier));
+                        }
+                    }
+                }
+            }
+            return topic;
+        };
+        topic = parseIdentifier(this.tm, topic, obj.subject_identifiers,
+            this.tm.getTopicBySubjectIdentifier,
+            this.tm.createTopicBySubjectIdentifier, 'addSubjectIdentifier');
+        topic = parseIdentifier(this.tm, topic, obj.subject_locators,
+            this.tm.getTopicBySubjectLocator,
+            this.tm.createTopicBySubjectLocator, 'addSubjectLocator');
+        topic = parseIdentifier(this.tm, topic, obj.item_identifiers,
+            this.tm.getConstructByItemIdentifier,
+            this.tm.createTopicByItemIdentifier, 'addItemIdentifier');
+
+        if ((arr = obj.instance_of) && this.version === '1.1') {
+            for (i = 0; i < arr.length; i += 1) {
+                type = this.getTopicByReference(arr[i]);
+                topic.addType(type);
+            }
+        } else if (obj.instance_of && this.version === '1.0') {
+            throw {name: 'InvalidFormat',
+                message: 'instance_of is invalid in JTM 1.0'};
+        }
+
+        arr = obj.names;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseName(topic, arr[i]);
+            }
+        }
+        arr = obj.occurrences;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseOccurrence(topic, arr[i]);
+            }
+        }
+    };
+
+    ReaderImpl.prototype.parseName = function (parent, obj) {
+        var name, type, scope, arr, i;
+        if (!parent) {
+            parent = this.parseParentAsTopic(obj);
+        }
+        scope = this.parseScope(obj.scope);
+        type = this.getTopicByReference(obj.type);
+        name = parent.createName(obj.value, type, scope);
+        arr = obj.variants;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseVariant(name, arr[i]);
+            }
+        }
+        this.parseItemIdentifiers(name, obj.item_identifiers);
+        this.parseReifier(name, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseVariant = function (parent, obj) {
+        var variant, scope;
+        scope = this.parseScope(obj.scope);
+        variant = parent.createVariant(obj.value, 
+            obj.datatype ?
+                this.tm.createLocator(this.curieToLocator(obj.datatype)) :
+                    this.defaultDatatype, scope);
+        this.parseItemIdentifiers(variant, obj.item_identifiers);
+        this.parseReifier(variant, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseOccurrence = function (parent, obj) {
+        var occurrence, type, scope;
+        if (!parent) {
+            parent = this.parseParentAsTopic(obj);
+        }
+        scope = this.parseScope(obj.scope);
+        type = this.getTopicByReference(obj.type);
+        occurrence = parent.createOccurrence(type, obj.value,
+            obj.datatype ?
+                this.tm.createLocator(this.curieToLocator(obj.datatype)) :
+                    this.defaultDatatype, scope);
+        this.parseItemIdentifiers(occurrence, obj.item_identifiers);
+        this.parseReifier(occurrence, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseAssociation = function (obj) {
+        var association, type, scope, arr, i;
+        scope = this.parseScope(obj.scope);
+        type = this.getTopicByReference(obj.type);
+        association = this.tm.createAssociation(type, scope);
+        arr = obj.roles;
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            if (arr.length === 0) {
+                throw {name: 'InvalidFormat',
+                    message: 'Association needs roles'};
+            }
+            for (i = 0; i < arr.length; i += 1) {
+                this.parseRole(association, arr[i]);
+            }
+        } else {
+            throw {name: 'InvalidFormat',
+                message: 'Association needs roles'};
+        }
+        this.parseItemIdentifiers(association, obj.item_identifiers);
+        this.parseReifier(association, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseRole = function (parent, obj) {
+        var role, type, player;
+        type = this.getTopicByReference(obj.type);
+        player = this.getTopicByReference(obj.player);
+        role = parent.createRole(type, player);
+        this.parseItemIdentifiers(role, obj.item_identifiers);
+        this.parseReifier(role, obj.reifier);
+    };
+
+    ReaderImpl.prototype.parseScope = function (arr) {
+        var i, scope = [];
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                scope.push(this.getTopicByReference(arr[i]));
+            }
+        }
+        return scope;
+    };
+
+
+    ReaderImpl.prototype.parseItemIdentifiers = function (construct, arr) {
+        var i, tm, identifier;
+        tm = construct.getTopicMap();
+        if (arr && typeof arr === 'object' && arr instanceof Array) {
+            for (i = 0; i < arr.length; i += 1) {
+                identifier = this.curieToLocator(arr[i]);
+                if (!tm.getConstructByItemIdentifier(tm.createLocator(identifier))) {
+                    construct.addItemIdentifier(tm.createLocator(identifier));
+                }
+            }
+        }
+    };
+
+    ReaderImpl.prototype.parseReifier = function (construct, reifier) {
+        var reifierTopic = this.getTopicByReference(reifier);
+        if (reifierTopic && reifierTopic.getReified() === null || !reifierTopic) {
+            construct.setReifier(reifierTopic);
+        } // else: Ignore the case that reifierTopic reifies another item
+    };
+
+    /**
+    * @class Exports topic maps constructs as JTM 1.0 JavaScript objects.
+    * See http://www.cerny-online.com/jtm/1.0/ for the JSON Topic Maps specification.
+    * JSON 1.1 is described at http://www.cerny-online.com/jtm/1.1/
+    * @param {String} version Version number of the JTM export. Valid values are '1.0'
+    *                 and '1.1'. Version 1.1 produces more compact files. The default
+    *                 value is '1.0', but this may change in the future.
+    */
+    WriterImpl = function (version) {
+        var that = this, referenceToCURIEorURI;
+        this.defaultDatatype = TM.XSD.string;
+        this.prefixes = new TM.Hash();
+        this.version = version || '1.0';
+
+        referenceToCURIEorURI = function (reference) {
+            var key, keys, i, value;
+            if (that.version === '1.0') {
+                return reference;
+            }
+            // TODO Sort keys after descending value length - longest first
+            // to find the best prefix
+            keys = that.prefixes.keys();
+            for (i = 0; i < keys.length; i += 1) {
+                key = keys[i];
+                value = that.prefixes.get(key);
+                if (reference.substring(0, value.length) ===  value) {
+                    return '[' + key + ':' +
+                        reference.substr(value.length) + ']';
+                }
+            }
+            return reference;
+        };  
+
+        /**
+        * Sets prefixes for JTM 1.1 export. prefixes is an object with the
+        * prefix as key and its corresponding reference as value.
+        */
+        this.setPrefixes = function (prefixes) {
+            var key;
+            for (key in prefixes) {
+                if (prefixes.hasOwnProperty(key)) {
+                    this.prefixes.put(key, prefixes[key]);
+                }
+            }
+        };
+
+        /**
+         * Generates a JTM reference based on the topics subject identifier,
+         * subject locator or item identifier (whatever is set, tested in this
+         * order).
+         * @returns {string} Representing the topic t, e.g.
+         *     "si:http://psi.topicmaps.org/iso13250/model/type
+         */
+        this.getTopicReference = function (t) {
+            var arr;
+            arr = t.getSubjectIdentifiers();
+            if (arr.length > 0) {
+                return 'si:' + referenceToCURIEorURI(arr[0].getReference());
+            }
+            arr = t.getSubjectLocators();
+            if (arr.length > 0) {
+                return 'sl:' + referenceToCURIEorURI(arr[0].getReference());
+            }
+            arr = t.getItemIdentifiers();
+            if (arr.length > 0) {
+                return 'ii:' + referenceToCURIEorURI(arr[0].getReference());
+            }
+            // ModelConstraintExeption: TMDM says that t MUST have on of these
+        };
+
+        this.exportIdentifiers = function (obj, arr, attr) {
+            var i, len = arr.length;
+            if (len > 0) {
+                obj[attr] = [];
+                for (i = 0; i < len; i += 1) {
+                    obj[attr].push(referenceToCURIEorURI(arr[i].getReference()));
+                }
+            }
+        
+        }; 
+
+        this.exportScope = function (obj, construct) {
+            var i, arr = construct.getScope();
+            if (arr.length > 0) {
+                obj.scope = [];
+                for (i = 0; i < arr.length; i += 1) {
+                    obj.scope.push(that.getTopicReference(arr[i]));
+                }
+            }
+        };
+
+        this.exportParent = function (obj, construct) {
+            var parent = construct.getParent();
+            that.exportIdentifiers(obj, parent.getItemIdentifiers(), 'parent');
+        };
+
+        this.exportTopicMap = function (m) {
+            var arr, i, len, obj;
+            obj = {
+                topics: [],
+                associations: []
+            };
+            arr = m.getTopics();
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                obj.topics.push(that.exportTopic(arr[i]));
+            }
+            arr = m.getAssociations();
+            len = arr.length;
+            for (i = 0; i < len; i += 1) {
+                obj.associations.push(that.exportAssociation(arr[i]));
+            }
+            return obj;
+        };
+
+        this.exportTopic = function (t) {
+            var arr, i, len, obj;
+            obj = {};
+            that.exportIdentifiers(obj, t.getSubjectIdentifiers(), 'subject_identifiers');
+            that.exportIdentifiers(obj, t.getSubjectLocators(), 'subject_locators');
+            that.exportIdentifiers(obj, t.getItemIdentifiers(), 'item_identifiers');
+            arr = t.getNames();
+            len = arr.length;
+            if (len > 0) {
+                obj.names = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.names.push(that.exportName(arr[i]));
+                }
+            }
+            arr = t.getOccurrences();
+            len = arr.length;
+            if (len > 0) {
+                obj.occurrences = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.occurrences.push(that.exportOccurrence(arr[i]));
+                }
+            }
+            arr = t.getTypes();
+            len = arr.length;
+            if (len > 0) {
+                obj.instance_of = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.instance_of.push(that.getTopicReference(arr[i]));
+                }
+            }
+            return obj;
+        };
+
+        this.exportName = function (name) {
+            var arr, i, len, obj, tmp;
+            obj = {
+                'value': name.getValue()
+            };
+            tmp = name.getType();
+            if (tmp) {
+                obj.type = that.getTopicReference(tmp);
+            }
+            tmp = name.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            
+            that.exportIdentifiers(obj, name.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, name);
+            arr = name.getVariants();
+            len = arr.length;
+            if (len > 0) {
+                obj.variants = [];
+                for (i = 0; i < len; i += 1) {
+                    obj.variants.push(that.exportVariant(arr[i]));
+                }
+            }
+            return obj;
+        };
+
+        this.exportVariant = function (variant) {
+            var obj, tmp;
+            obj = {
+                'value': variant.getValue()
+            };
+            tmp = variant.getDatatype();
+            if (tmp && tmp !== variant.getTopicMap().createLocator(that.defaultDatatype)) {
+                obj.datatype = referenceToCURIEorURI(tmp.getReference());
+            }
+            tmp = variant.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            
+            that.exportIdentifiers(obj, variant.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, variant);
+        };
+
+        this.exportOccurrence = function (occ) {
+            var obj, tmp;
+            obj = {
+                value: occ.getValue(),
+                type: that.getTopicReference(occ.getType())
+            };
+            tmp = occ.getDatatype();
+            if (tmp && tmp !== occ.getTopicMap().createLocator(that.defaultDatatype)) {
+                obj.datatype = referenceToCURIEorURI(tmp.getReference());
+            }
+            tmp = occ.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            
+            that.exportIdentifiers(obj, occ.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, occ);
+            return obj;
+        };
+
+        this.exportAssociation = function (association) {
+            var arr, i, obj, tmp;
+            obj = {
+                type: that.getTopicReference(association.getType()),
+                roles: []
+            };
+            tmp = association.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            that.exportIdentifiers(obj, association.getItemIdentifiers(), 'item_identifiers');
+            that.exportScope(obj, association);
+            arr = association.getRoles();
+            for (i = 0; i < arr.length; i += 1) {
+                obj.roles.push(that.exportRole(arr[i]));
+            }
+            return obj;
+        };
+
+        this.exportRole = function (role) {
+            var obj, tmp;
+            obj = {
+                player: that.getTopicReference(role.getPlayer()),
+                type: that.getTopicReference(role.getType())
+            };
+            tmp = role.getReifier();
+            if (tmp) {
+                obj.reifier = that.getTopicReference(tmp);
+            }
+            that.exportIdentifiers(obj, role.getItemIdentifiers(), 'item_identifiers');
+            return obj;
+        };
+    };
+
+    /**
+    * Returns a JTM JavaScript object representation of construct.
+    * @param {Construct} construct The topic map construct to be exported. Can be
+    * TopicMap, Topic, Occurrence, Name, Variant, Association or Role.
+    * @param {boolean} [includeParent] If true the optional JTM element 'parent' is
+    * included. Refers to the parent via its item identifier.  If undefined or false,
+    * the parent element is dropped.
+    */
+    WriterImpl.prototype.toObject = function (construct, includeParent) {
+        var obj, tm, keys, i;
+        includeParent = includeParent || false;
+        tm = construct.getTopicMap();
+
+        if (construct.isTopicMap()) {
+            obj = this.exportTopicMap(construct);
+            obj.item_type = 'topicmap';
+        } else if (construct.isRole()) {
+            obj = this.exportRole(construct);
+            obj.item_type = 'role';
+        } else if (construct.isTopic()) {
+            obj = this.exportTopic(construct);
+            obj.item_type = 'topic';
+        } else if (construct.isAssociation()) {
+            obj = this.exportAssociation(construct);
+            obj.item_type = 'association';
+        } else if (construct.isOccurrence()) {
+            obj = this.exportOccurrence(construct);
+            obj.item_type = 'occurrence';
+        } else if (construct.isName()) {
+            obj = this.exportName(construct);
+            obj.item_type = 'name';
+        } else if (construct.isVariant()) {
+            obj = this.exportVariant(construct);
+            obj.item_type = 'variant';
+        }
+        obj.version = this.version;
+        if (this.version === '1.1' && this.prefixes) {
+            if (this.prefixes.size()) {
+                keys = this.prefixes.keys();
+                obj.prefixes = {};
+                for (i = 0; i < keys.length; i += 1) {
+                    obj.prefixes[keys[i]] = this.prefixes.get(keys[i]);
+                }
+            }
+        }
+        if (!construct.isTopic() && construct.getReifier()) {
+            obj.reifier = this.getTopicReference(construct.getReifier());
+        }
+        if (includeParent && !construct.isTopicMap()) {
+            this.exportParent(obj, construct);
+        }
+        return obj;
+    };
+
+    return {
+        Reader: ReaderImpl,
+        Writer: WriterImpl
+    };
+}());

Added: branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/tm.min.js
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gdl-frontend/src/GDL_frontend/GDL_TmEngine/war/gdl_tmengine/lib/tm.min.js	Mon Jun 20 02:03:15 2011	(r488)
@@ -0,0 +1,115 @@
+// tmjs, version 0.4.0
+// http://github.com/jansc/tmjs
+// Copyright (c) 2010 Jan Schreiber <jans at ravn.no>
+// Licensed under the MIT-License.
+var TM,TopicMapSystemFactory;
+TM=function(){var n,C,h,g,e,f,i,l,m,o,t,u,p,D,x,A,B,v,y,w,z,O,E,J,H,s,q,P;Function.prototype.swiss=function(a){var b,c;for(b=1;b<arguments.length;b+=1){c=arguments[b];this.prototype[c]=a.prototype[c]}return this};n=function(){this.hash={};this.length=0};n.prototype={get:function(a){return this.hash[a]},contains:function(a){return this.get(a)!==undefined},put:function(a,b){this.hash[a]||(this.length+=1);return this.hash[a]=b},remove:function(a){delete this.hash[a];this.length-=1;return this},keys:function(){var a=
+[],b;for(b in this.hash)this.hash.hasOwnProperty(b)&&a.push(b);return a},values:function(){var a=[],b;for(b in this.hash)this.hash.hasOwnProperty(b)&&a.push(this.hash[b]);return a},empty:function(){this.hash={};this.length=0},size:function(){return this.length}};e={};e.ADD_ASSOCIATION=1;e.ADD_NAME=2;e.ADD_OCCURRENCE=3;e.ADD_ROLE=4;e.ADD_THEME=5;e.ADD_TOPIC=6;e.ADD_TYPE=7;e.REMOVE_ASSOCIATION=8;e.REMOVE_NAME=9;e.REMOVE_OCCURRENCE=10;e.REMOVE_ROLE=11;e.REMOVE_THEME=12;e.REMOVE_TOPIC=13;e.REMOVE_TYPE=
+14;e.SET_TYPE=15;C={string:"http://www.w3.org/2001/XMLSchema#string",integer:"http://www.w3.org/2001/XMLSchema#integer",anyURI:"http://www.w3.org/2001/XMLSchema#anyURI"};h={TYPE_INSTANCE:"http://psi.topicmaps.org/iso13250/model/type-instance",TYPE:"http://psi.topicmaps.org/iso13250/model/type",INSTANCE:"http://psi.topicmaps.org/iso13250/model/instance",TOPIC_NAME:"http://psi.topicmaps.org/iso13250/model/topic-name"};g=function(a,b){this.parnt=a;this.iri=b};g.prototype.getReference=function(){return this.iri};
+g.prototype.equals=function(a){return this.iri===a.getReference()};g.prototype.toExternalForm=function(){throw{name:"NotImplemented",message:"Locator.toExternalForm() not implemented"};};m=function(){};m.prototype.addItemIdentifier=function(a){var b;if(a===null)throw{name:"ModelConstraintException",message:"addItemIdentifier(null) is illegal"};if(b=this.getTopicMap()._ii2construct.get(a.getReference()))throw{name:"IdentityConstraintException",message:"Topic Maps constructs with the same item identifier are not allowed",
+reporter:this,existing:b,locator:a};this.itemIdentifiers.push(a);this.getTopicMap()._ii2construct.put(a.getReference(),this);return this};m.prototype.equals=function(a){return this.id===a.id};m.prototype.getId=function(){return this.id};m.prototype.getItemIdentifiers=function(){return this.itemIdentifiers};m.prototype.getParent=function(){return this.parnt};m.prototype.getTopicMap=function(){throw{name:"NotImplemented",message:"getTopicMap() not implemented"};};m.prototype.hashCode=function(){throw{name:"NotImplemented",
+message:"hashCode() not implemented"};};m.prototype.remove=function(){throw{name:"NotImplemented",message:"remove() not implemented"};};m.prototype.removeItemIdentifier=function(a){if(a!==null){for(var b=0;b<this.itemIdentifiers.length;b+=1)if(this.itemIdentifiers[b].getReference()===a.getReference()){this.itemIdentifiers.splice(b,1);break}this.getTopicMap()._ii2construct.remove(a.getReference());return this}};m.prototype.isTopicMap=function(){return false};m.prototype.isTopic=function(){return false};
+m.prototype.isAssociation=function(){return false};m.prototype.isRole=function(){return false};m.prototype.isName=function(){return false};m.prototype.isOccurrence=function(){return false};m.prototype.isVariant=function(){return false};o=function(){};o.prototype.getType=function(){return this.type};o.prototype.setType=function(a){if(a===null)throw{name:"ModelConstraintException",message:"Topic.setType cannot be called without type"};z.assertBelongsTo(this.getTopicMap(),a);this.getTopicMap().setTypeEvent.fire(this,
+{old:this.type,type:a});this.type=a;return this};l=function(){};l.prototype.addTheme=function(a){if(a===null)throw{name:"ModelConstraintException",message:"addTheme(null) is illegal"};for(var b=0;b<this.scope.length;b+=1)if(this.scope[b]===a)return false;z.assertBelongsTo(this.getTopicMap(),a);this.scope.push(a);this.getTopicMap().addThemeEvent.fire(this,{theme:a});if(this.isName())for(b=0;b<this.variants.length;b+=1)this.getTopicMap().addThemeEvent.fire(this.variants[b],{theme:a});return this};l.prototype.getScope=
+function(){if(this.isVariant()){var a,b=new n,c=this.parnt.getScope();for(a=0;a<c.length;a+=1)b.put(c[a].getId(),c[a]);for(a=0;a<this.scope.length;a+=1)b.put(this.scope[a].getId(),this.scope[a]);return b.values()}return this.scope};l.prototype.removeTheme=function(a){var b,c,d,j;for(b=0;b<this.scope.length;b+=1)if(this.scope[b]===a){this.getTopicMap().removeThemeEvent.fire(this,{theme:this.scope[b]});this.scope.splice(b,1);break}if(this.isName())for(b=0;b<this.variants.length;b+=1){d=this.variants[b].scope;
+j=false;for(c=0;c<d.length;c+=1)if(a.equals(d[c]))j=true;j||this.getTopicMap().removeThemeEvent.fire(this.variants[b],{theme:a})}return this};t=function(){};t.prototype.getReifier=function(){return this.reifier};t.prototype.setReifier=function(a){if(a&&a.getReified()!==null)throw{name:"ModelConstraintException",message:"Reifies already another construct"};z.assertBelongsTo(this.getTopicMap(),a);this.reifier&&this.reifier._setReified(null);a&&a._setReified(this);this.reifier=a;return this};u=function(){};
+u.prototype.decimalValue=function(){};u.prototype.floatValue=function(){var a=parseFloat(this.value);if(isNaN(a))throw{name:"NumberFormatException",message:'"'+this.value+'" is not a float'};return a};u.prototype.getDatatype=function(){return this.datatype};u.prototype.getValue=function(){if(typeof this.value==="object"&&this.value instanceof g)return this.value.getReference();return this.value.toString()};u.prototype.integerValue=function(){var a=parseInt(this.value,10);if(isNaN(a))throw{name:"NumberFormatException",
+message:'"'+this.value+'" is not an integer'};return a};u.prototype.locatorValue=function(){if(!(typeof this.value==="object"&&this.value instanceof g))throw{name:"ModelConstraintException",message:'"'+this.value+'" is not a locator'};return this.value};u.prototype.longValue=function(){};u.prototype.setValue=function(a,b){var c=this.getTopicMap();if(b===null)throw{name:"ModelConstraintException",message:"Invalid datatype"};if(a===null)throw{name:"ModelConstraintException",message:"Invalid value"};
+this.value=a;this.datatype=b||this.getTopicMap().createLocator(C.string);if(b&&b.getReference()===C.anyURI)this.value=c.createLocator(a);if(!b)if(typeof a==="number")this.datatype=c.createLocator(C.integer);if(typeof a==="object"&&a instanceof g)this.datatype=c.createLocator(C.anyURI)};TopicMapSystemFactory=function(){this.properties={};this.features={}};TopicMapSystemFactory.prototype.getFeature=function(){return this.features};TopicMapSystemFactory.prototype.getProperty=function(a){return this.properties[a]};
+TopicMapSystemFactory.prototype.hasFeature=function(){return false};TopicMapSystemFactory.newInstance=function(){return new TopicMapSystemFactory};TopicMapSystemFactory.prototype.newTopicMapSystem=function(){if((this.properties["com.semanticheadache.tmjs.backend"]||"memory")==="memory")return new v};TopicMapSystemFactory.prototype.setFeature=function(a,b){this.features[a]=b};TopicMapSystemFactory.prototype.setProperty=function(a,b){this.properties[a]=b};v=function(){this.topicmaps={}};v.prototype.createTopicMap=
+function(a){if(this.topicmaps[a.getReference()])throw{name:"TopicMapExistsException",message:"A topic map under the same IRI already exists"};var b=new p(this,a);return this.topicmaps[a.getReference()]=b};v.prototype.getLocators=function(){var a=[],b;for(b in this.topicmaps)this.topicmaps.hasOwnProperty(b)&&a.push(this.createLocator(b));return a};v.prototype.getTopicMap=function(a){a=a instanceof g?this.topicmaps[a.getReference()]:this.topicmaps[a];if(!a)return null;return a};v.prototype.createLocator=
+function(a){return new g(this,a)};v.prototype.getFeature=function(){return false};v.prototype._removeTopicMap=function(a){var b;for(b in this.topicmaps)this.topicmaps.hasOwnProperty(b)&&b===a.locator.getReference()&&delete this.topicmaps[b]};v.prototype.close=function(){this.topicmaps=null};p=function(a,b){this.topicmapsystem=a;this.itemIdentifiers=[];this.locator=b;this.topics=[];this.associations=[];this._constructId=1;this._si2topic=new n;this._sl2topic=new n;this._ii2construct=new n;this._id2construct=
+new n;this.id=0;this._id2construct.put(this.id,this);this.reifier=null;this.handlers=[];a=function(c){this.eventtype=c;this.handlers=[]};a.prototype={registerHandler:function(c){this.handlers.push(c)},removeHandler:function(c){for(var d=0;d<this.handlers.length;d+=1)c.toString()===this.handlers[d].toString()&&this.handlers.splice(d,1)},fire:function(c,d){d=d||{};for(var j=0;j<this.handlers.length;j+=1)this.handlers[j](this.eventtype,c,d)}};this.addAssociationEvent=new a(e.ADD_ASSOCIATION);this.addNameEvent=
+new a(e.ADD_NAME);this.addOccurrenceEvent=new a(e.ADD_OCCURRENCE);this.addRoleEvent=new a(e.ADD_ROLE);this.addThemeEvent=new a(e.ADD_THEME);this.addTopicEvent=new a(e.ADD_TOPIC);this.addTypeEvent=new a(e.ADD_TYPE);this.removeAssociationEvent=new a(e.REMOVE_ASSOCIATION);this.removeNameEvent=new a(e.REMOVE_NAME);this.removeOccurrenceEvent=new a(e.REMOVE_OCCURRENCE);this.removeRoleEvent=new a(e.REMOVE_ROLE);this.removeThemeEvent=new a(e.REMOVE_THEME);this.removeTopicEvent=new a(e.REMOVE_TOPIC);this.removeTypeEvent=
+new a(e.REMOVE_TYPE);this.setTypeEvent=new a(e.SET_TYPE);this.typeInstanceIndex=new y(this);this.scopedIndex=new w(this)};p.prototype.register_event_handler=function(a,b){switch(a){case e.ADD_ASSOCIATION:this.addAssociationEvent.registerHandler(b);break;case e.ADD_NAME:this.addNameEvent.registerHandler(b);break;case e.ADD_OCCURRENCE:this.addOccurrenceEvent.registerHandler(b);break;case e.ADD_ROLE:this.addRoleEvent.registerHandler(b);break;case e.ADD_THEME:this.addThemeEvent.registerHandler(b);break;
+case e.ADD_TOPIC:this.addTopicEvent.registerHandler(b);break;case e.ADD_TYPE:this.addTypeEvent.registerHandler(b);break;case e.REMOVE_ASSOCIATION:this.removeAssociationEvent.registerHandler(b);break;case e.REMOVE_NAME:this.removeNameEvent.registerHandler(b);break;case e.REMOVE_OCCURRENCE:this.removeOccurrenceEvent.registerHandler(b);break;case e.REMOVE_ROLE:this.removeRoleEvent.registerHandler(b);break;case e.REMOVE_THEME:this.removeThemeEvent.registerHandler(b);break;case e.REMOVE_TOPIC:this.removeTopicEvent.registerHandler(b);
+break;case e.REMOVE_TYPE:this.removeTypeEvent.registerHandler(b);break;case e.SET_TYPE:this.setTypeEvent.registerHandler(b);break}return this};p.swiss(t,"getReifier","setReifier");p.swiss(m,"addItemIdentifier","getItemIdentifiers","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");p.prototype.sanitize=function(){H.removeTopicMapDuplicates(this);P.convertAssociationsToType(this);return this};p.prototype.isTopicMap=function(){return true};p.prototype._getConstructId=
+function(){this._constructId+=1;return this._constructId};p.prototype.remove=function(){if(this.topicmapsystem===null)return null;this.topicmapsystem._removeTopicMap(this);return this.typeInstanceIndex=this.id=this.reifier=this._id2construct=this._ii2construct=this._sl2topic=this._si2topic=this.associations=this.topics=this.locator=this.itemIdentifiers=this.topicmapsystem=null};p.prototype.createAssociation=function(a,b){var c;if(a===null)throw{name:"ModelConstraintException",message:"Creating an association with type == null is not allowed"};
+if(b===null)throw{name:"ModelConstraintException",message:"Creating an association with scope == null is not allowed"};z.assertBelongsTo(this,a);z.assertBelongsTo(this,b);c=new i(this);this.associations.push(c);a&&c.setType(a);J(c,b);this.addAssociationEvent.fire(c);return c};p.prototype.createLocator=function(a){return new g(this,a)};p.prototype._createEmptyTopic=function(){var a=new f(this);this.addTopicEvent.fire(a);this.topics.push(a);return a};p.prototype.createTopic=function(){var a=this._createEmptyTopic();
+a.addItemIdentifier(this.createLocator("urn:x-tmjs:"+a.getId()));return a};p.prototype.createTopicByItemIdentifier=function(a){if(!a)throw{name:"ModelConstraintException",message:"createTopicByItemIdentifier() needs an item identifier"};var b=this.getConstructByItemIdentifier(a);if(b){if(!b.isTopic())throw{name:"IdentityConstraintException",message:"Another construct with the specified item identifier exists which is not a Topic."};return b}b=this._createEmptyTopic();b.addItemIdentifier(a);return b};
+p.prototype.createTopicBySubjectIdentifier=function(a){if(!a)throw{name:"ModelConstraintException",message:"createTopicBySubjectIdentifier() needs a subject identifier"};var b=this.getTopicBySubjectIdentifier(a);if(b)return b;b=this._createEmptyTopic();b.addSubjectIdentifier(a);return b};p.prototype.createTopicBySubjectLocator=function(a){if(!a)throw{name:"ModelConstraintException",message:"createTopicBySubjectLocator() needs a subject locator"};var b=this.getTopicBySubjectLocator(a);if(b)return b;
+b=this._createEmptyTopic();b.addSubjectLocator(a);return b};p.prototype.getAssociations=function(){return this.associations};p.prototype.getConstructById=function(a){if(a===null)throw{name:"ModelConstraintException",message:"getConstructById(null) is illegal"};a=this._id2construct.get(a);if(!a)return null;return a};p.prototype.getConstructByItemIdentifier=function(a){if(a===null)throw{name:"ModelConstraintException",message:"getConstructByItemIdentifier(null) is illegal"};a=this._ii2construct.get(a.getReference());
+if(!a)return null;return a};p.prototype.getIndex=function(a){if(a==="TypeInstanceIndex")return a=this.typeInstanceIndex;else if(a==="ScopedIndex")return a=new w(this);throw{name:"UnsupportedOperationException",message:"getIndex ist not (yet) supported"};};p.prototype.getParent=function(){return null};p.prototype.getTopicBySubjectIdentifier=function(a){if(a=this._si2topic.get(a.getReference()))return a;return null};p.prototype.getTopicBySubjectLocator=function(a){if(a=this._sl2topic.get(a.getReference()))return a;
+return null};p.prototype.getLocator=function(){return this.locator};p.prototype.getTopics=function(){return this.topics};p.prototype.mergeIn=function(){throw{name:"NotImplemented",message:"TopicMap.mergeIn() not implemented"};};p.prototype.equals=function(a){return this.locator.equals(a.locator)};p.prototype.getId=function(){return this.id};p.prototype.getTopicMap=function(){return this};p.prototype._removeConstruct=function(a){var b=a.getItemIdentifiers(),c;for(c=0;c<b.length;c+=1)this._ii2construct.remove(b[c].getReference());
+this._id2construct.remove(a.getId())};p.prototype._removeTopic=function(a){var b,c=a.getSubjectIdentifiers(),d=a.getSubjectLocators();for(b=0;b<c.length;b+=1)this._si2topic.remove(c[b].getReference());for(b=0;b<d.length;b+=1)this._sl2topic.remove(d[b].getReference());this._removeConstruct(a);for(b=0;b<this.topics.length;b+=1)if(a.id===this.topics[b].id){this.topics.splice(b,1);break}};p.prototype._removeAssociation=function(a){var b;for(b=0;b<this.associations.length;b+=1)if(a.id===this.associations[b].id){this.associations.splice(b,
+1);break}this._removeConstruct(a);for(b=0;b<this.associations.length;b+=1)if(a.id===this.associations[b].id){this.associations.splice(b,1);break}};p.prototype._removeRole=function(a){this._removeConstruct(a)};p.prototype._removeOccurrence=function(a){this._removeConstruct(a)};p.prototype._removeName=function(a){this._removeConstruct(a)};p.prototype._removeVariant=function(a){this._removeConstruct(a)};f=function(a){this.subjectIdentifiers=[];this.subjectLocators=[];this.itemIdentifiers=[];this.parnt=
+a;this.id=a._getConstructId();this.getTopicMap()._id2construct.put(this.id,this);this.types=[];this.rolesPlayed=[];this.occurrences=[];this.names=[];this.reified=null};f.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");f.prototype.isTopic=function(){return true};f.prototype.getTopicMap=function(){return this.parnt};f.prototype.addSubjectIdentifier=
+function(a){if(!a)throw{name:"ModelConstraintException",message:"addSubjectIdentifier() needs subject identifier"};for(var b=0;b<this.subjectIdentifiers.length;b+=1)if(this.subjectIdentifiers[b].getReference()===a.getReference())return;this.subjectIdentifiers.push(a);this.parnt._si2topic.put(a.getReference(),this);return this};f.prototype.addSubjectLocator=function(a){if(!a)throw{name:"ModelConstraintException",message:"addSubjectLocator() needs subject locator"};for(var b=0;b<this.subjectLocators.length;b+=
+1)if(this.subjectLocators[b].getReference()===a.getReference())return;this.subjectLocators.push(a);this.parnt._sl2topic.put(a.getReference(),this);return this};f.prototype.addType=function(a){if(!a)throw{name:"ModelConstraintException",message:"addType() needs type"};z.assertBelongsTo(this.parnt,a);this.parnt.addTypeEvent.fire(this,{type:a});this.types.push(a);return this};f.prototype.createName=function(a,b,c){b&&z.assertBelongsTo(this.parnt,b);c&&z.assertBelongsTo(this.parnt,c);if(typeof c==="undefined")c=
+null;a=new x(this,a,b);J(a,c);this.names.push(a);return a};f.prototype.createOccurrence=function(a,b,c,d){z.assertBelongsTo(this.parnt,a);z.assertBelongsTo(this.parnt,d);c=new B(this,a,b,c);this.parnt.addOccurrenceEvent.fire(c,{type:a,value:b});J(c,d);this.occurrences.push(c);return c};f.prototype.getNames=function(a){var b=[],c;for(c=0;c<this.names.length;c+=1)if(a&&this.names[c].getType().equals(a))b.push(this.names[c]);else a||b.push(this.names[c]);return b};f.prototype.getOccurrences=function(a){var b=
+[],c;if(a===null)throw{name:"IllegalArgumentException",message:"Topic.getOccurrences cannot be called without type"};for(c=0;c<this.occurrences.length;c+=1)if(a&&this.occurrences[c].getType().equals(a))b.push(this.occurrences[c]);else a||b.push(this.occurrences[c]);return b};f.prototype._removeOccurrence=function(a){for(var b=0;b<this.occurrences.length;b+=1)if(this.occurrences[b].equals(a)){this.occurrences.splice(b,1);break}this.getTopicMap()._removeOccurrence(a)};f.prototype.getReified=function(){return this.reified};
+f.prototype._setReified=function(a){this.reified=a};f.prototype.getRolesPlayed=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"Topic.getRolesPlayed cannot be called without type"};if(b===null)throw{name:"IllegalArgumentException",message:"Topic.getRolesPlayed cannot be called with assocType===null"};var c=[],d;for(d=0;d<this.rolesPlayed.length;d+=1)if(a){if(this.rolesPlayed[d].getType().equals(a))if(b&&this.rolesPlayed[d].getParent().getType().equals(b)||!b)c.push(this.rolesPlayed[d])}else c.push(this.rolesPlayed[d]);
+return c};f.prototype.addRolePlayed=function(a){this.rolesPlayed.push(a)};f.prototype.removeRolePlayed=function(a){for(var b=0;b<this.rolesPlayed.length;b+=1)this.rolesPlayed[b].id===a.id&&this.rolesPlayed.splice(b,1)};f.prototype.getSubjectIdentifiers=function(){return this.subjectIdentifiers};f.prototype.getSubjectLocators=function(){return this.subjectLocators};f.prototype.getTypes=function(){return this.types};f.prototype.mergeIn=function(a){var b,c,d,j,k;if(this.equals(a))return true;z.assertBelongsTo(this.getTopicMap(),
+a);if(this.getReified()&&a.getReified()&&!this.getReified().equals(a.getReified()))throw{name:"ModelConstraintException",message:"The topics reify different Topic Maps constructs and cannot be merged!"};if(!this.getReified()&&a.getReified()){d=a.getReified();d.setReifier(this)}b=this.parnt.typeInstanceIndex;q.moveTypes(b.getOccurrences(a),this);q.moveTypes(b.getNames(a),this);q.moveTypes(b.getAssociations(a),this);q.moveTypes(b.getRoles(a),this);b=b.getTopics(a);for(c=0;c<b.length;c+=1){b[c].removeType(a);
+b[c].addType(this)}b=this.parnt.scopedIndex;q.moveThemes(b.getAssociations(a),a,this);q.moveThemes(b.getOccurrences(a),a,this);q.moveThemes(b.getNames(a),a,this);q.moveThemes(b.getVariants(a),a,this);q.moveItemIdentifiers(a,this);for(b=a.getSubjectLocators();b.length;){d=b[b.length-1];a.removeSubjectLocator(d);this.addSubjectLocator(d)}for(b=a.getSubjectIdentifiers();b.length;){d=b[b.length-1];a.removeSubjectIdentifier(d);this.addSubjectIdentifier(d)}for(b=a.getTypes();b.length;){d=b[b.length-1];
+a.removeType(d);this.addType(d)}b=this.getRolesPlayed();k={};for(c=0;c<b.length;c+=1){j=b[c].getParent();k[s.makeAssociationSignature(j)]=j}b=a.getRolesPlayed();for(c=0;c<b.length;c+=1){d=b[c];d.setPlayer(this);if(j=k[s.makeAssociationSignature(d.getParent())]){q.moveItemIdentifiers(d.getParent(),j);q.moveReifier(d.getParent(),j);d.getParent().remove()}}b=this.getNames();k={};for(c=0;c<b.length;c+=1)k[s.makeNameSignature(b[c])]=b[c];b=a.getNames();for(c=0;c<b.length;c+=1){d=b[c];if(j=k[s.makeNameSignature(b[c])]){q.moveItemIdentifiers(d,
+j);q.moveReifier(d,j);q.moveVariants(d,j);d.remove()}else{j=this.createName(d.getValue(),d.getType(),d.getScope());q.moveVariants(d,j)}}b=this.getOccurrences();k={};for(c=0;c<b.length;c+=1)k[s.makeOccurrenceSignature(b[c])]=b[c];b=a.getOccurrences();for(c=0;c<b.length;c+=1){d=b[c];if(j=k[s.makeOccurrenceSignature(b[c])]){q.moveItemIdentifiers(d,j);q.moveReifier(d,j);d.remove()}else{j=this.createOccurrence(d.getType(),d.getValue(),d.getDatatype(),d.getScope());q.moveReifier(d,j)}}a.remove();return this};
+f.prototype.remove=function(){var a=this.parnt.typeInstanceIndex,b=this.parnt.scopedIndex;if(this.getReified()||a.getOccurrences(this).length||a.getNames(this).length||a.getAssociations(this).length||a.getRoles(this).length||a.getTopics(this).length||b.getAssociations(this).length||b.getOccurrences(this).length||b.getNames(this).length||b.getVariants(this).length||this.getRolesPlayed().length)throw{name:"TopicInUseException",message:"",reporter:this};this.parnt._removeTopic(this);this.parnt._id2construct.remove(this.id);
+this.parnt.removeTopicEvent.fire(this);this.id=null;return this.parnt};f.prototype.removeSubjectIdentifier=function(a){for(var b=0;b<this.subjectIdentifiers.length;b+=1)if(this.subjectIdentifiers[b].getReference()===a.getReference()){this.subjectIdentifiers.splice(b,1);break}this.parnt._sl2topic.remove(a.getReference());return this};f.prototype.removeSubjectLocator=function(a){for(var b=0;b<this.subjectLocators.length;b+=1)if(this.subjectLocators[b].getReference()===a.getReference()){this.subjectLocators.splice(b,
+1);break}this.parnt._sl2topic.remove(a.getReference());return this};f.prototype.removeType=function(a){for(var b=0;b<this.types.length;b+=1)if(this.types[b].equals(a)){this.types.splice(b,1);this.parnt.removeTypeEvent.fire(this,{type:a});break}};f.prototype._removeName=function(a){for(var b=0;b<this.names.length;b+=1)if(this.names[b].equals(a)){this.names.splice(b,1);break}this.getTopicMap()._removeName(a)};B=function(a,b,c,d){this.itemIdentifiers=[];this.parnt=a;this.type=b;this.value=c;this.datatype=
+d?d:this.getTopicMap().createLocator(C.string);this.scope=[];this.reifier=null;this.id=this.getTopicMap()._getConstructId();this.getTopicMap()._id2construct.put(this.id,this)};B.swiss(o,"getType","setType");B.swiss(u,"decimalValue","floatValue","getDatatype","getValue","integerValue","locatorValue","longValue","setValue");B.swiss(t,"getReifier","setReifier");B.swiss(l,"addTheme","getScope","removeTheme");B.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap",
+"hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");B.prototype.isOccurrence=function(){return true};B.prototype.getTopicMap=function(){return this.parnt.getParent()};B.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=1)this.parnt.parnt.removeThemeEvent.fire(this,{theme:this.scope[a]});this.parnt.parnt.removeOccurrenceEvent.fire(this);this.parnt._removeOccurrence(this);this.id=null;return this.parnt};x=function(a,
+b,c){this.itemIdentifiers=[];this.parnt=a;this.value=b;this.scope=[];this.id=this.getTopicMap()._getConstructId();this.type=c||a.parnt.createTopicBySubjectIdentifier(a.parnt.createLocator("http://psi.topicmaps.org/iso13250/model/topic-name"));this.reifier=null;this.variants=[];this.getTopicMap()._id2construct.put(this.id,this);this.parnt.parnt.addNameEvent.fire(this,{type:this.type,value:b})};x.swiss(o,"getType","setType");x.swiss(t,"getReifier","setReifier");x.swiss(l,"addTheme","getScope","removeTheme");
+x.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");x.prototype.isName=function(){return true};x.prototype.getTopicMap=function(){return this.parnt.parnt};x.prototype.createVariant=function(a,b,c){if(typeof c==="undefined"||c===null)throw{name:"ModelConstraintException",message:"Creation of a variant with a null scope is not allowed"};
+a=new A(this,a,b);J(a,c);for(c=0;c<this.scope.length;c+=1)this.getTopicMap().addThemeEvent.fire(a,{theme:this.scope[c]});this.variants.push(a);return a};x.prototype.setValue=function(a){if(!a)throw{name:"ModelConstraintException",message:"Name.setValue(null) is not allowed"};this.value=a;return this};x.prototype.getValue=function(){return this.value};x.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=1)this.parnt.parnt.removeThemeEvent.fire(this,{theme:this.scope[a]});this.parnt.parnt.removeNameEvent.fire(this);
+this.parnt._removeName(this);this.id=null;return this.parnt};x.prototype._removeVariant=function(a){for(var b=0;b<this.variants.length;b+=1)if(this.variants[b].equals(a)){this.variants.splice(b,1);break}this.getTopicMap()._removeVariant(a)};x.prototype.getVariants=function(){return this.variants};A=function(a,b,c){if(b===null)throw{name:"ModelConstraintException",message:"Creation of a variant with null value is not allowed"};if(c===null)throw{name:"ModelConstraintException",message:"Creation of a variant with datatype == null is not allowed"};
+this.itemIdentifiers=[];this.scope=[];this.parnt=a;this.datatype=typeof b==="object"&&b instanceof g?this.getTopicMap().createLocator("http://www.w3.org/2001/XMLSchema#anyURI"):this.getTopicMap().createLocator(C.string);this.datatype=c;this.reifier=null;this.value=b;this.id=this.getTopicMap()._getConstructId();this.getTopicMap()._id2construct.put(this.id,this)};A.swiss(t,"getReifier","setReifier");A.swiss(l,"addTheme","getScope","removeTheme");A.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers",
+"getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");A.swiss(u,"decimalValue","floatValue","getDatatype","getValue","integerValue","locatorValue","longValue","setValue");A.prototype.isVariant=function(){return true};A.prototype.getTopicMap=function(){return this.getParent().getParent().getParent()};A.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=1)this.getTopicMap().removeThemeEvent.fire(this,
+{theme:this.scope[a]});this.getParent()._removeVariant(this);this.id=null;return this.parnt};D=function(a,b,c){this.itemIdentifiers=[];this.parnt=a;this.type=b;this.player=c;this.id=this.getTopicMap()._getConstructId();this.reifier=null;this.getTopicMap()._id2construct.put(this.id,this)};D.swiss(o,"getType","setType");D.swiss(t,"getReifier","setReifier");D.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic",
+"isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");D.prototype.isRole=function(){return true};D.prototype.getTopicMap=function(){return this.getParent().getParent()};D.prototype.remove=function(){var a=this.parnt;this.parnt.parnt.removeRoleEvent.fire(this);this.parnt._removeRole(this);this.id=this.reifier=this.player=this.type=this.parnt=this.itemIdentifiers=null;return a};D.prototype.getPlayer=function(){return this.player};D.prototype.setPlayer=function(a){if(!a)throw{name:"ModelConstraintException",
+message:"player i Role.setPlayer cannot be null"};z.assertBelongsTo(this.parnt.parnt,a);if(!this.player.equals(a)){this.player.removeRolePlayed(this);a.addRolePlayed(this);this.player=a;return this}};i=function(a){this.itemIdentifiers=[];this.parnt=a;this.id=this.getTopicMap()._getConstructId();this.getTopicMap()._id2construct.put(this.id,this);this.roles=[];this.scope=[];this.reifier=this.type=null};i.swiss(o,"getType","setType");i.swiss(t,"getReifier","setReifier");i.swiss(l,"addTheme","getScope",
+"removeTheme");i.swiss(m,"addItemIdentifier","equals","getId","getItemIdentifiers","getParent","getTopicMap","hashCode","remove","removeItemIdentifier","isTopic","isAssociation","isRole","isOccurrence","isName","isVariant","isTopicMap");i.prototype.isAssociation=function(){return true};i.prototype.getTopicMap=function(){return this.parnt};i.prototype.createRole=function(a,b){if(!a)throw{name:"ModelConstraintException",message:"type i Role.createPlayer cannot be null"};if(!b)throw{name:"ModelConstraintException",
+message:"player i Role.createRole cannot be null"};z.assertBelongsTo(this.parnt,a);z.assertBelongsTo(this.parnt,b);var c=new D(this,a,b);b.addRolePlayed(c);this.roles.push(c);this.parnt.addRoleEvent.fire(c,{type:a,player:b});return c};i.prototype._removeRole=function(a){for(var b=0;b<this.roles.length;b+=1)if(a.id===this.roles[b].id){this.roles.splice(b,1);break}a.getPlayer().removeRolePlayed(a);this.getTopicMap()._removeRole(a)};i.prototype.remove=function(){var a;for(a=0;a<this.scope.length;a+=
+1)this.parnt.removeThemeEvent.fire(this,{theme:this.scope[a]});for(this.parnt.removeAssociationEvent.fire(this);this.roles.length;)this.roles[0].remove();this.roles=this.id=null;this.parnt._removeAssociation(this);this.getTopicMap()._ii2construct.remove(this.id);this.reifier=this.type=this.scope=this.item_identifiers=null;return this.parnt};i.prototype.getRoles=function(a){if(a===null)throw{name:"IllegalArgumentException",message:"Topic.getRoles cannot be called with type null"};if(!a)return this.roles;
+var b=[],c;for(c=0;c<this.roles.length;c+=1)this.roles[c].getType().equals(a)&&b.push(this.roles[c]);return b};i.prototype.getRoleTypes=function(){var a={},b=[],c,d;for(c=0;c<this.roles.length;c+=1)a[this.roles[c].getType().getId()]=this.roles[c].getType();for(d in a)a.hasOwnProperty(d)&&b.push(a[d]);return b};l=function(){this.opened=false};l.prototype.close=function(){};l.prototype.isAutoUpdated=function(){return true};l.prototype.isOpen=function(){return this.opened};l.prototype.open=function(){this.opened=
+true};l.prototype.reindex=function(){};y=function(a){var b,c=this;this.tm=a;this.type2topics=new n;this.type2associations=new n;this.type2roles=new n;this.type2occurrences=new n;this.type2names=new n;this.type2variants=new n;this.opened=false;b=function(d,j,k){var r;switch(d){case e.ADD_ASSOCIATION:break;case e.ADD_NAME:d=c.type2names.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2names.put(k.type.getId(),d);break;case e.ADD_OCCURRENCE:d=c.type2occurrences.get(k.type.getId());
+if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2occurrences.put(k.type.getId(),d);break;case e.ADD_ROLE:d=c.type2roles.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2roles.put(k.type.getId(),d);break;case e.ADD_TOPIC:d=c.type2topics.get("null");if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2topics.put("null",d);break;case e.ADD_TYPE:if((d=c.type2topics.get("null"))&&d.get(j.getId())){d.remove(j.getId());c.type2topics.put("null",d)}d=c.type2topics.get(k.type.getId());
+if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2topics.put(k.type.getId(),d);break;case e.REMOVE_ASSOCIATION:k=j.getType();if(!k)break;d=c.type2associations.get(k.getId());for(r=0;r<d.length;r+=1)if(d[r].equals(j)){d.splice(r,1);break}d.length>0?c.type2associations.put(k.getId(),d):c.type2associations.remove(k.getId());break;case e.REMOVE_NAME:k=j.getType();d=c.type2names.get(k.getId());d.remove(j.getId());d.length>0?c.type2names.put(k.getId(),d):c.type2names.remove(k.getId());break;case e.REMOVE_OCCURRENCE:k=
+j.getType();d=c.type2occurrences.get(k.getId());d.remove(j.getId());d.length>0?c.type2occurrences.put(k.getId(),d):c.type2occurrences.remove(k.getId());break;case e.REMOVE_ROLE:k=j.getType();d=c.type2roles.get(k.getId());d.remove(j.getId());d.length>0?c.type2roles.put(k.getId(),d):c.type2roles.remove(k.getId());break;case e.REMOVE_TOPIC:k=j.getTypes();for(r=0;r<k.length;r+=1){d=c.type2topics.get(k[r].getId());d.remove(j.getId());d.size()||c.type2topics.remove(k[r].getId())}c.type2topics.remove(j.getId());
+c.type2associations.remove(j.getId());c.type2roles.remove(j.getId());c.type2occurrences.remove(j.getId());c.type2variants.remove(j.getId());break;case e.REMOVE_TYPE:d=c.type2topics.get(k.type.getId());d.remove(j.getId());d.size()||c.type2topics.remove(k.type.getId());if(j.getTypes().length===0){d=c.type2topics.get("null");if(typeof d==="undefined")d=new n;d.put(j.getId(),j)}break;case e.SET_TYPE:if(j.isAssociation()){if(k.old){d=c.type2associations.get(k.old.getId());for(r=0;r<d.length;r+=1)if(d[r].equals(j)){d.splice(r,
+1);break}d.length>0?c.type2associations.put(k.old.getId(),d):c.type2associations.remove(k.old.getId())}d=c.type2associations.get(k.type.getId());if(typeof d==="undefined")d=[];d.push(j);c.type2associations.put(k.type.getId(),d)}else if(j.isName()){if(d=c.type2names.get(k.old.getId())){d.remove(j.getId());d.length>0?c.type2names.put(k.old.getId(),d):c.type2names.remove(k.old.getId())}d=c.type2names.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2names.put(k.type.getId(),
+d)}else if(j.isOccurrence()){if(d=c.type2occurrences.get(k.old.getId())){d.remove(j.getId());d.length>0?c.type2occurrences.put(k.old.getId(),d):c.type2occurrences.remove(k.old.getId())}d=c.type2occurrences.get(k.type.getId());if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2occurrences.put(k.type.getId(),d)}else if(j.isRole()){if(d=c.type2roles.get(k.old.getId())){d.remove(j.getId());d.length>0?c.type2roles.put(k.old.getId(),d):c.type2roles.remove(k.old.getId())}d=c.type2roles.get(k.type.getId());
+if(typeof d==="undefined")d=new n;d.put(j.getId(),j);c.type2roles.put(k.type.getId(),d)}break}};a.addAssociationEvent.registerHandler(b);a.addNameEvent.registerHandler(b);a.addOccurrenceEvent.registerHandler(b);a.addRoleEvent.registerHandler(b);a.addTopicEvent.registerHandler(b);a.addTypeEvent.registerHandler(b);a.removeAssociationEvent.registerHandler(b);a.removeNameEvent.registerHandler(b);a.removeOccurrenceEvent.registerHandler(b);a.removeRoleEvent.registerHandler(b);a.removeTopicEvent.registerHandler(b);
+a.removeTypeEvent.registerHandler(b);a.setTypeEvent.registerHandler(b)};y.swiss(l,"close","isAutoUpdated","isOpen","open","reindex");y.prototype.getAssociations=function(a){a=this.type2associations.get(a.getId());if(!a)return[];return a};y.prototype.getAssociationTypes=function(){var a=[],b=this.type2associations.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getNames=function(a){a=this.type2names.get(a.getId());if(!a)return[];return a.values()};y.prototype.getNameTypes=
+function(){var a=[],b=this.type2names.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getOccurrences=function(a){a=this.type2occurrences.get(a.getId());if(!a)return[];return a.values()};y.prototype.getOccurrenceTypes=function(){var a=[],b=this.type2occurrences.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getRoles=function(a){a=this.type2roles.get(a.getId());if(!a)return[];return a.values()};y.prototype.getRoleTypes=
+function(){var a=[],b=this.type2roles.keys(),c;for(c=0;c<b.length;c+=1)a.push(this.tm.getConstructById(b[c]));return a};y.prototype.getTopics=function(a){a=this.type2topics.get(a?a.getId():"null");if(!a)return[];return a.values()};y.prototype.getTopicsByTypes=function(a,b){var c,d;c=E.getForKeys(this.type2topics,a);if(!b)return c;for(b=0;b<c.length;b+=1)for(d=0;d<a.length;d+=1)if(!O.contains(c[b].getTypes(),a[d])){c.splice(b,1);b-=1;break}return c};y.prototype.getTopicTypes=function(){var a=[],b=
+this.type2topics.keys(),c;for(c=0;c<b.length;c+=1)b[c]!=="null"&&a.push(this.tm.getConstructById(b[c]));return a};y.prototype.close=function(){};w=function(a){var b=this,c;this.tm=a;this.theme2associations=new n;this.theme2names=new n;this.theme2occurrences=new n;this.theme2variants=new n;c=function(d,j,k){var r,I,M,K,L;L=function(F,G,N){I=N.theme?N.theme.getId():"null";if(G.getScope().length===1)if((M=F.get("null"))&&M.get(G.getId())){M.remove(G.getId());F.put("null",M)}r=F.get(I);if(typeof r===
+"undefined")r=new n;r.put(G.getId(),G);F.put(I,r)};K=function(F,G,N){I=N.theme.getId();r=F.get(I);if(typeof r!=="undefined"){r.remove(G.getId());r.size()||F.remove(I)}};switch(d){case e.ADD_THEME:if(j.isAssociation())L(b.theme2associations,j,k);else if(j.isName())L(b.theme2names,j,k);else if(j.isOccurrence())L(b.theme2occurrences,j,k);else j.isVariant()&&L(b.theme2variants,j,k);break;case e.REMOVE_THEME:if(j.isAssociation())K(b.theme2associations,j,k);else if(j.isName())K(b.theme2names,j,k);else if(j.isOccurrence())K(b.theme2occurrences,
+j,k);else j.isVariant()&&K(b.theme2variants,j,k);break}};a.addThemeEvent.registerHandler(c);a.removeThemeEvent.registerHandler(c)};w.swiss(l,"close","isAutoUpdated","isOpen","open","reindex");w.prototype.close=function(){};w.prototype.getAssociations=function(a){a=this.theme2associations.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getAssociationsByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getAssociationsByThemes cannot be called without themes"};
+return E.getConstructsByThemes(this.theme2associations,a,b)};w.prototype.getAssociationThemes=function(){return E.getConstructThemes(this.tm,this.theme2associations)};w.prototype.getNames=function(a){a=this.theme2names.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getNamesByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getNamesByThemes cannot be called without themes"};return E.getConstructsByThemes(this.theme2names,a,b)};w.prototype.getNameThemes=
+function(){return E.getConstructThemes(this.tm,this.theme2names)};w.prototype.getOccurrences=function(a){a=this.theme2occurrences.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getOccurrencesByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getOccurrencesByThemes cannot be called without themes"};return E.getConstructsByThemes(this.theme2occurrences,a,b)};w.prototype.getOccurrenceThemes=function(){return E.getConstructThemes(this.tm,
+this.theme2occurrences)};w.prototype.getVariants=function(a){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getVariants cannot be called without themes"};a=this.theme2variants.get(a?a.getId():"null");if(!a)return[];return a.values()};w.prototype.getVariantsByThemes=function(a,b){if(a===null)throw{name:"IllegalArgumentException",message:"ScopedIndex.getVariantsByThemes cannot be called without themes"};return E.getConstructsByThemes(this.theme2variants,a,b)};w.prototype.getVariantThemes=
+function(){return E.getConstructThemes(this.tm,this.theme2variants)};z={assertBelongsTo:function(a,b){var c;if(!b)return false;if(b&&b instanceof f&&!a.equals(b.getTopicMap()))throw{name:"ModelConstraintException",message:"scope topic belongs to different topic map"};if(b&&b instanceof Array)for(c=0;c<b.length;c+=1)if(!a.equals(b[c].getTopicMap()))throw{name:"ModelConstraintException",message:"scope topic belong to different topic maps"};return true}};E={getForKeys:function(a,b){var c,d,j=new n,k,
+r;for(c=0;c<b.length;c+=1)if(k=a.get(b[c].getId())){r=k.keys();for(d=0;d<r.length;d+=1)j.put(k.get(r[d]).getId(),k.get(r[d]))}return j.values()},getConstructThemes:function(a,b){var c=[];b=b.keys();var d;for(d=0;d<b.length;d+=1)b[d]!=="null"&&c.push(a.getConstructById(b[d]));return c},getConstructsByThemes:function(a,b,c){var d;a=E.getForKeys(a,b);if(!c)return a;for(c=0;c<a.length;c+=1)for(d=0;d<b.length;d+=1)if(!O.contains(a[c].getScope(),b[d])){a.splice(c,1);c-=1;break}return a}};O={contains:function(a,
+b){for(var c in a)if(a.hasOwnProperty(c))if(a[c].equals(b))return true;return false}};J=function(a,b){var c;if(b&&typeof b==="object")if(b instanceof Array)for(c=0;c<b.length;c+=1)a.addTheme(b[c]);else b instanceof f&&a.addTheme(b);else a.getTopicMap().addThemeEvent.fire(a,{theme:null})};s={makeNameValueSignature:function(a){return a.getValue()},makeNameSignature:function(a){return s.makeNameValueSignature(a)+"#"+s.makeTypeSignature(a)+"#"+s.makeScopeSignature(a)},makeOccurrenceSignature:function(a){return s.makeOccurrenceValueSignature(a)+
+"#"+s.makeTypeSignature(a)+"#"+s.makeScopeSignature(a)},makeOccurrenceValueSignature:function(a){return"#"+a.getValue()+"#"+(a.getDatatype()?a.getDatatype().getReference():"null")},makeTypeSignature:function(a){return(a=a.getType())?a.getId():""},makeScopeSignature:function(a){var b,c=[];for(b=0;b<a.length;b+=1)c.push(a[b].getId());c.sort();return c.join("#")},makeAssociationSignature:function(a){var b,c,d=[];b=a.getRoles();for(c=0;c<b.length;c+=1)d.push(s.makeRoleSignature(b[c]));d.sort();return"#"+
+s.makeTypeSignature(a)+"#"+d.join("#")+s.makeScopeSignature(a)},makeRoleSignature:function(a){return s.makeTypeSignature(a)+"#"+a.getPlayer().getId()},makeVariantValueSignature:function(a){return"#"+a.getValue()+"#"+a.getDatatype().getReference()},makeVariantSignature:function(a){return s.makeVariantValueSignature(a)+"#"+s.makeScopeSignature(a)}};H={removeTopicMapDuplicates:function(a){var b,c,d=new n,j;c=a.getTopics();for(b=0;b<c.length;b+=1){H.removeOccurrencesDuplicates(c[b].getOccurrences());
+H.removeNamesDuplicates(c[b].getNames())}a=a.getAssociations();for(b=0;b<a.length;b+=1){H.removeAssociationDuplicates(a[b]);c=s.makeAssociationSignature(a[b]);if(j=d.get(c)){q.moveConstructCharacteristics(a[b],j);q.moveRoleCharacteristics(a[b],j);a[b].remove()}else d.put(c,a[b])}d.empty()},removeOccurrencesDuplicates:function(a){var b,c=new n,d,j,k;for(b=0;b<a.length;b+=1){d=a[b];j=s.makeOccurrenceSignature(d);if(k=c.get(j)){q.moveConstructCharacteristics(d,k);d.remove()}else c.put(j,d)}c.empty()},
+removeNamesDuplicates:function(a){var b,c=new n,d,j,k;for(b=0;b<a.length;b+=1){d=a[b];H.removeVariantsDuplicates(d.getVariants());j=s.makeNameSignature(d);if(k=c.get(j)){q.moveConstructCharacteristics(d,k);q.moveVariants(d,k);d.remove()}else c.put(j,d)}c.empty()},removeVariantsDuplicates:function(a){var b,c=new n,d,j,k;for(b=0;b<a.length;b+=1){d=a[b];j=s.makeVariantSignature(d);if(k=c.get(j)){q.moveConstructCharacteristics(d,k);d.remove()}else c.put(j,d)}c.empty()},removeAssociationDuplicates:function(a){var b=
+a.getRoles(),c=new n,d,j;for(a=0;a<b.length;a+=1){d=s.makeRoleSignature(b[a]);if(j=c.get(d)){q.moveConstructCharacteristics(b[a],j);b[a].remove()}else c.put(d,b[a])}}};q={moveTypes:function(a,b){var c;for(c=0;c<a.length;c+=1)a[c].setType(b)},moveThemes:function(a,b,c){for(var d=0;d<a.length;d+=1){a[d].removeTheme(b);a[d].addTheme(c)}},moveItemIdentifiers:function(a,b){var c,d;for(c=a.getItemIdentifiers();c.length;){d=c[c.length-1];a.removeItemIdentifier(d);b.addItemIdentifier(d)}},moveVariants:function(a,
+b){var c,d,j,k;c=b.getVariants();k={};for(d=0;d<c.length;d+=1)k[s.makeVariantSignature(c[d])]=c[d];c=a.getVariants();for(d=0;d<c.length;d+=1){a=c[d];if(j=k[s.makeVariantSignature(c[d])]){q.moveItemIdentifiers(a,j);q.moveReifier(a,j);a.remove()}else b.createVariant(a.getValue(),a.getDatatype(),a.getScope())}},moveReifier:function(a,b){var c;if(a.getReifier()!==null)if(b.getReifier()===null)b.setReifier(a.getReifier());else{c=a.getReifier();b=b.getReifier();a.setReifier(null);c.mergeIn(b)}},moveRoleCharacteristics:function(a,
+b){var c,d=new n;c=b.getRoles();for(b=0;b<c.length;b+=1)d.put(c[b],s.makeRoleSignature(c[b]));c=a.getRoles();for(b=0;b<c.length;b+=1){q.moveItemIdentifiers(c[b],d.get(s.makeRoleSignature(c[b])));c[b].remove()}},moveConstructCharacteristics:function(a,b){q.moveReifier(a,b);q.moveItemIdentifiers(a,b)}};P={convertAssociationsToType:function(a){var b,c,d,j,k;b=a.getTopicBySubjectIdentifier(a.createLocator(h.TYPE_INSTANCE));c=a.getTopicBySubjectIdentifier(a.createLocator(h.TYPE));d=a.getTopicBySubjectIdentifier(a.createLocator(h.INSTANCE));
+if(!(!b||!c||!d))if(a=a.getIndex("TypeInstanceIndex")){a.isAutoUpdated()||a.reindex();b=a.getAssociations(b);for(a=0;a<b.length;a+=1){j=b[a];if(!(j.getScope().length>0||j.getReifier()!==null||j.getItemIdentifiers().length>0)){k=j.getRoles();if(k.length===2){if(k[0].getType().equals(c)&&k[1].getType().equals(d))k[1].getPlayer().addType(k[0].getPlayer());else if(k[1].getType().equals(c)&&k[0].getType().equals(d))k[0].getPlayer().addType(k[1].getPlayer());else continue;j.remove()}}}}}};return{TopicMapSystemFactory:TopicMapSystemFactory,
+XSD:C,TMDM:h,Hash:n,Version:"0.4.0"}}();TopicMapSystemFactory=TM.TopicMapSystemFactory;if(typeof exports==="object"&&exports!==null){exports.TopicMapSystemFactory=TopicMapSystemFactory;exports.TM=TM}
+TM.JTM=function(){var n,C;n=function(h){var g=this;this.tm=h;this.version=null;this.prefixes={};this.defaultDatatype=this.tm.createLocator(TM.XSD.string);this.curieToLocator=function(e){var f,i;if(g.version==="1.1"&&e.substr(0,1)==="["){if(e.substr(e.length-1,1)!=="]")throw{name:"InvalidFormat",message:"Invaild CURIE: missing tailing bracket"};e=e.substr(1,e.length-2);i=e.indexOf(":");if(i!==-1){f=e.substr(0,i);if(g.prefixes[f])return e=g.prefixes[f]+e.substr(i+1,e.length-1);else throw{name:"InvalidFormat",
+message:"Missing prefix declaration: "+f};}else throw{name:"InvalidFormat",message:"Invaild CURIE: missing colon"};}return e};this.getTopicByReference=function(e){if(typeof e==="undefined"||e===null)return null;switch(e.substr(0,3)){case "si:":return this.tm.createTopicBySubjectIdentifier(this.tm.createLocator(this.curieToLocator(e.substr(3))));case "sl:":return this.tm.createTopicBySubjectLocator(this.tm.createLocator(this.curieToLocator(e.substr(3))));case "ii:":return this.tm.createTopicByItemIdentifier(this.tm.createLocator(this.curieToLocator(e.substr(3))))}throw{name:"InvalidFormat",
+message:"Invaild topic reference '"+e+"'"};}};n.prototype.fromString=function(h){return this.fromObject(JSON.parse(h))};n.prototype.fromObject=function(h,g){g=g||null;if(h.version!=="1.0"&&h.version!=="1.1")throw{name:"InvalidFormat",message:"Unknown version of JTM: "+h.version};this.version=h.version;if(h.version==="1.1"&&h.prefixes){if((this.prefixes=h.prefixes)&&h.prefixes.xsd&&h.prefixes.xsd!=="http://www.w3.org/2001/XMLSchema#")throw{name:"InvalidFormat",message:'The XSD prefix MUST have the value "http://www.w3.org/2001/XMLSchema#"'};
+}else if(h.prefixes)throw{name:"InvalidFormat",message:"Prefixes are invalid in JTM 1.0: "+h.version};if(!this.prefixes.xsd)this.prefixes.xsd="http://www.w3.org/2001/XMLSchema#";if(!h.item_type)throw{name:"InvalidFormat",message:"Missing item_type"};switch(h.item_type.toLowerCase()){case "topicmap":h=this.parseTopicMap(h);break;case "topic":h=this.parseTopic(h);break;case "name":h=this.parseName(g,h);break;case "variant":h=this.parseVariant(g,h);break;case "occurrence":h=this.parseOccurrence(g,h);
+break;case "association":h=this.parseAssociation(h);break;case "role":h=this.parseRole(g,h);break;default:throw{name:"InvalidFormat",message:"Unknown item_type property"};}return h};n.prototype.parseParentAsTopic=function(h){var g=null,e,f;if(h.parent){if(!(h.parent instanceof Array)||h.parent.length===0)throw{name:"InvalidFormat",message:"Missing parent topic reference in occurrence"};}else g=this.tm.createTopic();if(h.parent)for(f=0;f<h.parent.length;f+=1){e=this.getTopicByReference(h.parent[f]);
+if(g)g.mergeIn(e);else g=e}return g};n.prototype.parseTopicMap=function(h){var g,e,f;this.parseItemIdentifiers(this.tm,h.item_identifiers);this.parseReifier(this.tm,h.reifier);if(h.topics&&typeof h.topics==="object"&&h.topics instanceof Array){f=h.topics;e=f.length;for(g=0;g<e;g+=1)this.parseTopic(f[g])}if(h.associations&&typeof h.associations==="object"&&h.associations instanceof Array){f=h.associations;e=f.length;for(g=0;g<e;g+=1)this.parseAssociation(f[g])}this.tm.sanitize();return true};n.prototype.parseTopic=
+function(h){var g=this,e=null,f,i,l,m;f=function(o,t,u,p,D,x){var A,B,v;if(u&&typeof u==="object"&&u instanceof Array){B=u.length;for(A=0;A<B;A+=1){l=decodeURI(g.curieToLocator(u[A]));if(t)if((v=p.apply(o,[o.createLocator(l)]))&&v.isTopic()&&!t.equals(v))t.mergeIn(v);else v&&v.isTopic()&&t.equals(v)||t[x](o.createLocator(l));else t=D.apply(o,[o.createLocator(l)])}}return t};e=f(this.tm,e,h.subject_identifiers,this.tm.getTopicBySubjectIdentifier,this.tm.createTopicBySubjectIdentifier,"addSubjectIdentifier");
+e=f(this.tm,e,h.subject_locators,this.tm.getTopicBySubjectLocator,this.tm.createTopicBySubjectLocator,"addSubjectLocator");e=f(this.tm,e,h.item_identifiers,this.tm.getConstructByItemIdentifier,this.tm.createTopicByItemIdentifier,"addItemIdentifier");if((f=h.instance_of)&&this.version==="1.1")for(i=0;i<f.length;i+=1){m=this.getTopicByReference(f[i]);e.addType(m)}else if(h.instance_of&&this.version==="1.0")throw{name:"InvalidFormat",message:"instance_of is invalid in JTM 1.0"};if((f=h.names)&&typeof f===
+"object"&&f instanceof Array)for(i=0;i<f.length;i+=1)this.parseName(e,f[i]);if((f=h.occurrences)&&typeof f==="object"&&f instanceof Array)for(i=0;i<f.length;i+=1)this.parseOccurrence(e,f[i])};n.prototype.parseName=function(h,g){var e,f;h||(h=this.parseParentAsTopic(g));f=this.parseScope(g.scope);e=this.getTopicByReference(g.type);h=h.createName(g.value,e,f);if((e=g.variants)&&typeof e==="object"&&e instanceof Array)for(f=0;f<e.length;f+=1)this.parseVariant(h,e[f]);this.parseItemIdentifiers(h,g.item_identifiers);
+this.parseReifier(h,g.reifier)};n.prototype.parseVariant=function(h,g){var e;e=this.parseScope(g.scope);h=h.createVariant(g.value,g.datatype?this.tm.createLocator(this.curieToLocator(g.datatype)):this.defaultDatatype,e);this.parseItemIdentifiers(h,g.item_identifiers);this.parseReifier(h,g.reifier)};n.prototype.parseOccurrence=function(h,g){var e,f;h||(h=this.parseParentAsTopic(g));f=this.parseScope(g.scope);e=this.getTopicByReference(g.type);h=h.createOccurrence(e,g.value,g.datatype?this.tm.createLocator(this.curieToLocator(g.datatype)):
+this.defaultDatatype,f);this.parseItemIdentifiers(h,g.item_identifiers);this.parseReifier(h,g.reifier)};n.prototype.parseAssociation=function(h){var g,e,f;g=this.parseScope(h.scope);g=this.tm.createAssociation(this.getTopicByReference(h.type),g);if((e=h.roles)&&typeof e==="object"&&e instanceof Array){if(e.length===0)throw{name:"InvalidFormat",message:"Association needs roles"};for(f=0;f<e.length;f+=1)this.parseRole(g,e[f])}else throw{name:"InvalidFormat",message:"Association needs roles"};this.parseItemIdentifiers(g,
+h.item_identifiers);this.parseReifier(g,h.reifier)};n.prototype.parseRole=function(h,g){var e,f;e=this.getTopicByReference(g.type);f=this.getTopicByReference(g.player);h=h.createRole(e,f);this.parseItemIdentifiers(h,g.item_identifiers);this.parseReifier(h,g.reifier)};n.prototype.parseScope=function(h){var g,e=[];if(h&&typeof h==="object"&&h instanceof Array)for(g=0;g<h.length;g+=1)e.push(this.getTopicByReference(h[g]));return e};n.prototype.parseItemIdentifiers=function(h,g){var e,f,i;f=h.getTopicMap();
+if(g&&typeof g==="object"&&g instanceof Array)for(e=0;e<g.length;e+=1){i=this.curieToLocator(g[e]);f.getConstructByItemIdentifier(f.createLocator(i))||h.addItemIdentifier(f.createLocator(i))}};n.prototype.parseReifier=function(h,g){if((g=this.getTopicByReference(g))&&g.getReified()===null||!g)h.setReifier(g)};C=function(h){var g=this,e;this.defaultDatatype=TM.XSD.string;this.prefixes=new TM.Hash;this.version=h||"1.0";e=function(f){var i,l,m,o;if(g.version==="1.0")return f;l=g.prefixes.keys();for(m=
+0;m<l.length;m+=1){i=l[m];o=g.prefixes.get(i);if(f.substring(0,o.length)===o)return"["+i+":"+f.substr(o.length)+"]"}return f};this.setPrefixes=function(f){var i;for(i in f)f.hasOwnProperty(i)&&this.prefixes.put(i,f[i])};this.getTopicReference=function(f){var i;i=f.getSubjectIdentifiers();if(i.length>0)return"si:"+e(i[0].getReference());i=f.getSubjectLocators();if(i.length>0)return"sl:"+e(i[0].getReference());i=f.getItemIdentifiers();if(i.length>0)return"ii:"+e(i[0].getReference())};this.exportIdentifiers=
+function(f,i,l){var m,o=i.length;if(o>0){f[l]=[];for(m=0;m<o;m+=1)f[l].push(e(i[m].getReference()))}};this.exportScope=function(f,i){var l=i.getScope();if(l.length>0){f.scope=[];for(i=0;i<l.length;i+=1)f.scope.push(g.getTopicReference(l[i]))}};this.exportParent=function(f,i){i=i.getParent();g.exportIdentifiers(f,i.getItemIdentifiers(),"parent")};this.exportTopicMap=function(f){var i,l,m,o;o={topics:[],associations:[]};i=f.getTopics();m=i.length;for(l=0;l<m;l+=1)o.topics.push(g.exportTopic(i[l]));
+i=f.getAssociations();m=i.length;for(l=0;l<m;l+=1)o.associations.push(g.exportAssociation(i[l]));return o};this.exportTopic=function(f){var i,l,m,o;o={};g.exportIdentifiers(o,f.getSubjectIdentifiers(),"subject_identifiers");g.exportIdentifiers(o,f.getSubjectLocators(),"subject_locators");g.exportIdentifiers(o,f.getItemIdentifiers(),"item_identifiers");i=f.getNames();m=i.length;if(m>0){o.names=[];for(l=0;l<m;l+=1)o.names.push(g.exportName(i[l]))}i=f.getOccurrences();m=i.length;if(m>0){o.occurrences=
+[];for(l=0;l<m;l+=1)o.occurrences.push(g.exportOccurrence(i[l]))}i=f.getTypes();m=i.length;if(m>0){o.instance_of=[];for(l=0;l<m;l+=1)o.instance_of.push(g.getTopicReference(i[l]))}return o};this.exportName=function(f){var i,l,m;m={value:f.getValue()};if(i=f.getType())m.type=g.getTopicReference(i);if(i=f.getReifier())m.reifier=g.getTopicReference(i);g.exportIdentifiers(m,f.getItemIdentifiers(),"item_identifiers");g.exportScope(m,f);f=f.getVariants();l=f.length;if(l>0){m.variants=[];for(i=0;i<l;i+=1)m.variants.push(g.exportVariant(f[i]))}return m};
+this.exportVariant=function(f){var i,l;i={value:f.getValue()};if((l=f.getDatatype())&&l!==f.getTopicMap().createLocator(g.defaultDatatype))i.datatype=e(l.getReference());if(l=f.getReifier())i.reifier=g.getTopicReference(l);g.exportIdentifiers(i,f.getItemIdentifiers(),"item_identifiers");g.exportScope(i,f)};this.exportOccurrence=function(f){var i,l;i={value:f.getValue(),type:g.getTopicReference(f.getType())};if((l=f.getDatatype())&&l!==f.getTopicMap().createLocator(g.defaultDatatype))i.datatype=e(l.getReference());
+if(l=f.getReifier())i.reifier=g.getTopicReference(l);g.exportIdentifiers(i,f.getItemIdentifiers(),"item_identifiers");g.exportScope(i,f);return i};this.exportAssociation=function(f){var i,l;l={type:g.getTopicReference(f.getType()),roles:[]};if(i=f.getReifier())l.reifier=g.getTopicReference(i);g.exportIdentifiers(l,f.getItemIdentifiers(),"item_identifiers");g.exportScope(l,f);f=f.getRoles();for(i=0;i<f.length;i+=1)l.roles.push(g.exportRole(f[i]));return l};this.exportRole=function(f){var i,l;i={player:g.getTopicReference(f.getPlayer()),
+type:g.getTopicReference(f.getType())};if(l=f.getReifier())i.reifier=g.getTopicReference(l);g.exportIdentifiers(i,f.getItemIdentifiers(),"item_identifiers");return i}};C.prototype.toObject=function(h,g){var e,f,i;g=g||false;h.getTopicMap();if(h.isTopicMap()){e=this.exportTopicMap(h);e.item_type="topicmap"}else if(h.isRole()){e=this.exportRole(h);e.item_type="role"}else if(h.isTopic()){e=this.exportTopic(h);e.item_type="topic"}else if(h.isAssociation()){e=this.exportAssociation(h);e.item_type="association"}else if(h.isOccurrence()){e=
+this.exportOccurrence(h);e.item_type="occurrence"}else if(h.isName()){e=this.exportName(h);e.item_type="name"}else if(h.isVariant()){e=this.exportVariant(h);e.item_type="variant"}e.version=this.version;if(this.version==="1.1"&&this.prefixes)if(this.prefixes.size()){f=this.prefixes.keys();e.prefixes={};for(i=0;i<f.length;i+=1)e.prefixes[f[i]]=this.prefixes.get(f[i])}if(!h.isTopic()&&h.getReifier())e.reifier=this.getTopicReference(h.getReifier());g&&!h.isTopicMap()&&this.exportParent(e,h);return e};
+return{Reader:n,Writer:C}}();




More information about the Isidorus-cvs mailing list