You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by sz...@apache.org on 2013/04/26 18:40:17 UTC

svn commit: r1476285 [3/3] - in /stanbol/trunk/demos/webvie/src/main/resources/META-INF/resources/static/enhancervie/lib: ./ backboneJS/ vie/

Added: stanbol/trunk/demos/webvie/src/main/resources/META-INF/resources/static/enhancervie/lib/vie/vie.js
URL: http://svn.apache.org/viewvc/stanbol/trunk/demos/webvie/src/main/resources/META-INF/resources/static/enhancervie/lib/vie/vie.js?rev=1476285&view=auto
==============================================================================
--- stanbol/trunk/demos/webvie/src/main/resources/META-INF/resources/static/enhancervie/lib/vie/vie.js (added)
+++ stanbol/trunk/demos/webvie/src/main/resources/META-INF/resources/static/enhancervie/lib/vie/vie.js Fri Apr 26 16:40:16 2013
@@ -0,0 +1,6969 @@
+/* VIE.js 2.1.0 - Semantic Interaction Toolkit
+by Henri Bergius and the IKS Project. Available under the MIT license.
+See http://viejs.org for more information
+*/(function () {//     VIE - Vienna IKS Editables
+//     (c) 2011 Henri Bergius, IKS Consortium
+//     (c) 2011 Sebastian Germesin, IKS Consortium
+//     (c) 2011 Szaby Grünwald, IKS Consortium
+//     VIE may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://viejs.org/
+
+/*global console:false exports:false require:false */
+
+var root = this,
+    jQuery = root.jQuery,
+    Backbone = root.Backbone,
+    _ = root._;
+
+
+// ## VIE constructor
+//
+// The VIE constructor is the way to initialize VIE for your
+// application. The instance of VIE handles all management of
+// semantic interaction, including keeping track of entities,
+// changes to them, the possible RDFa views on the page where
+// the entities are displayed, and connections to external
+// services like Stanbol and DBPedia.
+//
+// To get a VIE instance, simply run:
+//
+//     var vie = new VIE();
+//
+// You can also pass configurations to the VIE instance through
+// the constructor. For example, to set a different default
+// namespace to be used for names that don't have a namespace
+// specified, do:
+//
+//     var vie = new VIE({
+//         baseNamespace: 'http://example.net'
+//     });
+//
+// ### Differences with VIE 1.x
+//
+// VIE 1.x used singletons for managing entities and views loaded
+// from a page. This has been changed with VIE 2.x, and now all
+// data managed by VIE is tied to the instance of VIE being used.
+//
+// This means that VIE needs to be instantiated before using. So,
+// when previously you could get entities from page with:
+//
+//     VIE.RDFaEntities.getInstances();
+//
+// Now you need to instantiate VIE first. This example uses the
+// Classic API compatibility layer instead of the `load` method:
+//
+//     var vie = new VIE();
+//     vie.RDFaEntities.getInstances();
+//
+// Currently the Classic API is enabled by default, but it is
+// recommended to ensure it is enabled before using it. So:
+//
+//     var vie = new VIE({classic: true});
+//     vie.RDFaEntities.getInstances();
+var VIE = root.VIE = function(config) {
+    this.config = (config) ? config : {};
+    this.services = {};
+    this.jQuery = jQuery;
+    this.entities = new this.Collection([], {
+        vie: this
+    });
+
+    this.Entity.prototype.entities = this.entities;
+    this.Entity.prototype.entityCollection = this.Collection;
+    this.Entity.prototype.vie = this;
+
+    this.Namespaces.prototype.vie = this;
+// ### Namespaces in VIE
+// VIE supports different ontologies and an easy use of them.
+// Namespace prefixes reduce the amount of code you have to
+// write. In VIE, it does not matter if you access an entitie's
+// property with
+// `entity.get('<http://dbpedia.org/property/capitalOf>')` or
+// `entity.get('dbprop:capitalOf')` or even
+// `entity.get('capitalOf')` once the corresponding namespace
+// is registered as *baseNamespace*.
+// By default `"http://viejs.org/ns/"`is set as base namespace.
+// For more information about how to set, get and list all
+// registered namespaces, refer to the
+// <a href="Namespace.html">Namespaces documentation</a>.
+    this.namespaces = new this.Namespaces(
+        (this.config.baseNamespace) ? this.config.baseNamespace : "http://viejs.org/ns/",
+
+// By default, VIE is shipped with common namespace prefixes:
+
+// +    owl    : "http://www.w3.org/2002/07/owl#"
+// +    rdfs   : "http://www.w3.org/2000/01/rdf-schema#"
+// +    rdf    : "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+// +    schema : 'http://schema.org/'
+// +    foaf   : 'http://xmlns.com/foaf/0.1/'
+// +    geo    : 'http://www.w3.org/2003/01/geo/wgs84_pos#'
+// +    dbpedia: "http://dbpedia.org/ontology/"
+// +    dbprop : "http://dbpedia.org/property/"
+// +    skos   : "http://www.w3.org/2004/02/skos/core#"
+// +    xsd    : "http://www.w3.org/2001/XMLSchema#"
+// +    sioc   : "http://rdfs.org/sioc/ns#"
+// +    dcterms: "http://purl.org/dc/terms/"
+        {
+            owl    : "http://www.w3.org/2002/07/owl#",
+            rdfs   : "http://www.w3.org/2000/01/rdf-schema#",
+            rdf    : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+            schema : 'http://schema.org/',
+            foaf   : 'http://xmlns.com/foaf/0.1/',
+            geo    : 'http://www.w3.org/2003/01/geo/wgs84_pos#',
+            dbpedia: "http://dbpedia.org/ontology/",
+            dbprop : "http://dbpedia.org/property/",
+            skos   : "http://www.w3.org/2004/02/skos/core#",
+            xsd    : "http://www.w3.org/2001/XMLSchema#",
+            sioc   : "http://rdfs.org/sioc/ns#",
+            dcterms: "http://purl.org/dc/terms/"
+        }
+    );
+
+
+    this.Type.prototype.vie = this;
+    this.Types.prototype.vie = this;
+    this.Attribute.prototype.vie = this;
+    this.Attributes.prototype.vie = this;
+// ### Type hierarchy in VIE
+// VIE takes care about type hierarchy of entities
+// (aka. *schema* or *ontology*).
+// Once a type hierarchy is known to VIE, we can leverage
+// this information, to easily ask, whether an entity
+// is of type, e.g., *foaf:Person* or *schema:Place*.
+// For more information about how to generate such a type
+// hierarchy, refer to the
+// <a href="Type.html">Types documentation</a>.
+    this.types = new this.Types();
+// By default, there is a parent type in VIE, called
+// *owl:Thing*. All types automatically inherit from this
+// type and all registered entities, are of this type.
+    this.types.add("owl:Thing");
+
+// As described above, the Classic API of VIE 1.x is loaded
+// by default. As this might change in the future, it is
+// recommended to ensure it is enabled before using it. So:
+//
+//     var vie = new VIE({classic: true});
+//     vie.RDFaEntities.getInstances();
+    if (this.config.classic === true) {
+        /* Load Classic API as well */
+        this.RDFa = new this.ClassicRDFa(this);
+        this.RDFaEntities = new this.ClassicRDFaEntities(this);
+        this.EntityManager = new this.ClassicEntityManager(this);
+
+        this.cleanup = function() {
+            this.entities.reset();
+        };
+    }
+};
+
+// ### use(service, name)
+// This method registers services within VIE.
+// **Parameters**:
+// *{string|object}* **service** The service to be registered.
+// *{string}* **name** An optional name to register the service with. If this
+// is not set, the default name that comes with the service is taken.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE}* : The current VIE instance.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     var conf1 = {...};
+//     var conf2 = {...};
+//     vie.use(new vie.StanbolService());
+//     vie.use(new vie.StanbolService(conf1), "stanbol_1");
+//     vie.use(new vie.StanbolService(conf2), "stanbol_2");
+//     // <-- this means that there are now 3 services registered!
+VIE.prototype.use = function(service, name) {
+  if (!name && !service.name) {
+    throw new Error("Please provide a name for the service!");
+  }
+  service.vie = this;
+  service.name = (name)? name : service.name;
+  if (service.init) {
+      service.init();
+  }
+  this.services[service.name] = service;
+
+  return this;
+};
+
+// ### service(name)
+// This method returns the service object that is
+// registered under the given name.
+// **Parameters**:
+// *{string}* **name** ...
+// **Throws**:
+// *{Error}* if no service could be found.
+// **Returns**:
+// *{object}* : The service to be queried.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var service = vie.service("stanbol");
+VIE.prototype.service = function(name) {
+  if (!this.hasService(name)) {
+    throw "Undefined service " + name;
+  }
+  return this.services[name];
+};
+
+// ### hasService(name)
+// This method returns a boolean telling whether VIE has a particular
+// service loaded.
+// **Parameters**:
+// *{string}* **name**
+// **Returns**:
+// *{boolean}* whether service is available
+VIE.prototype.hasService = function(name) {
+  if (!this.services[name]) {
+    return false;
+  }
+  return true;
+};
+
+// ### getServicesArray()
+// This method returns an array of all registered services.
+// **Parameters**:
+// *nothing*
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{array}* : An array of service instances.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var services = vie.getServicesArray();
+//     services.length; // <-- 1
+VIE.prototype.getServicesArray = function() {
+  return _.map(this.services, function (v) {return v;});
+};
+
+// ### load(options)
+// This method instantiates a new VIE.Loadable in order to
+// perform queries on the services.
+// **Parameters**:
+// *{object}* **options** Options to be set.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Loadable}* : A new instance of VIE.Loadable.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var loader = vie.load({...});
+VIE.prototype.load = function(options) {
+  if (!options) { options = {}; }
+  options.vie = this;
+  return new this.Loadable(options);
+};
+
+// ### save(options)
+// This method instantiates a new VIE.Savable in order to
+// perform queries on the services.
+// **Parameters**:
+// *{object}* **options** Options to be set.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Savable}* : A new instance of VIE.Savable.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var saver = vie.save({...});
+VIE.prototype.save = function(options) {
+  if (!options) { options = {}; }
+  options.vie = this;
+  return new this.Savable(options);
+};
+
+// ### remove(options)
+// This method instantiates a new VIE.Removable in order to
+// perform queries on the services.
+// **Parameters**:
+// *{object}* **options** Options to be set.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Removable}* : A new instance of VIE.Removable.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var remover = vie.remove({...});
+VIE.prototype.remove = function(options) {
+  if (!options) { options = {}; }
+  options.vie = this;
+  return new this.Removable(options);
+};
+
+// ### analyze(options)
+// This method instantiates a new VIE.Analyzable in order to
+// perform queries on the services.
+// **Parameters**:
+// *{object}* **options** Options to be set.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Analyzable}* : A new instance of VIE.Analyzable.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var analyzer = vie.analyze({...});
+VIE.prototype.analyze = function(options) {
+  if (!options) { options = {}; }
+  options.vie = this;
+  return new this.Analyzable(options);
+};
+
+// ### find(options)
+// This method instantiates a new VIE.Findable in order to
+// perform queries on the services.
+// **Parameters**:
+// *{object}* **options** Options to be set.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Findable}* : A new instance of VIE.Findable.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.use(new vie.StanbolService(), "stanbol");
+//     var finder = vie.find({...});
+VIE.prototype.find = function(options) {
+  if (!options) { options = {}; }
+  options.vie = this;
+  return new this.Findable(options);
+};
+
+// ### loadSchema(url, options)
+// VIE only knows the *owl:Thing* type by default.
+// You can use this method to import another
+// schema (ontology) from an external resource.
+// (Currently, this supports only the JSON format!!)
+// As this method works asynchronously, you might want
+// to register `success` and `error` callbacks via the
+// options.
+// **Parameters**:
+// *{string}* **url** The url, pointing to the schema to import.
+// *{object}* **options** Options to be set.
+// (Set ```success``` and ```error``` as callbacks.).
+// **Throws**:
+// *{Error}* if the url is not set.
+// **Returns**:
+// *{VIE}* : The VIE instance itself.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.loadSchema("http://schema.rdfs.org/all.json",
+//        {
+//          baseNS : "http://schema.org/",
+//          success : function () {console.log("success");},
+//          error  : function (msg) {console.warn(msg);}
+//        });
+VIE.prototype.loadSchema = function(url, options) {
+    options = (!options)? {} : options;
+
+    if (!url) {
+        throw new Error("Please provide a proper URL");
+    }
+    else {
+        var vie = this;
+        jQuery.getJSON(url)
+        .success(function(data) {
+            try {
+                VIE.Util.loadSchemaOrg(vie, data, options.baseNS);
+                if (options.success) {
+                    options.success.call(vie);
+                }
+            } catch (e) {
+                options.error.call(vie, e);
+                return;
+            }
+         })
+        .error(function(data, textStatus, jqXHR) {
+            if (options.error) {
+                console.warn(data, textStatus, jqXHR);
+                options.error.call(vie, "Could not load schema from URL (" + url + "): " + textStatus);
+            }
+         });
+    }
+
+    return this;
+};
+
+// ### getTypedEntityClass(type)
+// This method generates a special type of `Entity` based on the given type.
+// **Parameters**:
+// *{string}* **type** The type.
+// **Throws**:
+// *{Error}* if the type is unknown to VIE.
+// **Returns**:
+// *{VIE.Entity}* : A subclass of `VIE.Entity`.
+// **Example usage**:
+//
+//     var vie = new VIE();
+//     vie.types.add("Person");
+//     var PersonClass = vie.getTypedEntityClass("Person");
+//     var Person = new PersonClass({"name", "Sebastian"});
+VIE.prototype.getTypedEntityClass = function (type) {
+  var typeType = this.types.get(type);
+  if (!typeType) {
+    throw new Error("Unknown type " + type);
+  }
+  if (!this.typeEntityClasses[type.id]) {
+    this.typeEntityClasses[type.id] = this.Entity.extend({
+      defaults: {
+        '@type': type
+      }
+    });
+  }
+  return this.typeEntityClasses[type.id];
+};
+VIE.prototype.typeEntityClasses = {};
+
+// ## Running VIE on Node.js
+//
+// When VIE is running under Node.js we can use the CommonJS
+// require interface to load our dependencies automatically.
+//
+// This means Node.js users don't need to care about dependencies
+// and can just run VIE with:
+//
+//     var VIE = require('vie');
+//
+// In browser environments the dependencies have to be included
+// before including VIE itself.
+if (typeof exports === 'object') {
+    exports.VIE = VIE;
+
+    if (!jQuery) {
+        jQuery = require('jquery');
+    }
+    if (!Backbone) {
+        Backbone = require('backbone');
+        Backbone.$ = jQuery;
+    }
+    if (!_) {
+        _ = require('underscore')._;
+    }
+}
+
+//     VIE - Vienna IKS Editables
+//     (c) 2011 Henri Bergius, IKS Consortium
+//     (c) 2011 Sebastian Germesin, IKS Consortium
+//     (c) 2011 Szaby Grünwald, IKS Consortium
+//     VIE may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://viejs.org/
+
+// ## VIE.Able
+// VIE implements asynchronius service methods through
+// [jQuery.Deferred](http://api.jquery.com/category/deferred-object/) objects.
+// Loadable, Analysable, Savable, etc. are part of the VIE service API and
+// are implemented with the generic VIE.Able class.
+// Example:
+//
+//      VIE.prototype.Loadable = function (options) {
+//          this.init(options,"load");
+//      };
+//      VIE.prototype.Loadable.prototype = new VIE.prototype.Able();
+//
+// This defines
+//
+//     someVIEService.load(options)
+//     .using(...)
+//     .execute()
+//     .success(...)
+//     .fail(...)
+// which will run the asynchronius `load` function of the service with the created Loadable
+// object.
+
+// ### VIE.Able()
+// This is the constructor of a VIE.Able. This should not be called
+// globally but using the inherited classes below.
+// **Parameters**:
+// *nothing*
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Able}* : A **new** VIE.Able object.
+// Example:
+//
+//      VIE.prototype.Loadable = function (options) {
+//          this.init(options,"load");
+//      };
+//      VIE.prototype.Loadable.prototype = new VIE.prototype.Able();
+VIE.prototype.Able = function(){
+
+// ### init(options, methodName)
+// Internal method, called during initialization.
+// **Parameters**:
+// *{object}* **options** the *able* options coming from the API call
+// *{string}* **methodName** the service method called on `.execute`.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Able}* : The current instance.
+// **Example usage**:
+//
+//      VIE.prototype.Loadable = function (options) {
+//          this.init(options,"load");
+//      };
+//      VIE.prototype.Loadable.prototype = new VIE.prototype.Able();
+    this.init = function(options, methodName) {
+        this.options = options;
+        this.services = options.from || options.using || options.to || [];
+        this.vie = options.vie;
+
+        this.methodName = methodName;
+
+        // Instantiate the deferred object
+        this.deferred = jQuery.Deferred();
+
+// In order to get more information and documentation about the passed-through
+// deferred methods and their synonyms, please see the documentation of
+// the [jQuery.Deferred object](http://api.jquery.com/category/deferred-object/)
+        /* Public deferred-methods */
+        this.resolve = this.deferred.resolve;
+        this.resolveWith = this.deferred.resolveWith;
+        this.reject = this.deferred.reject;
+        this.rejectWith = this.deferred.rejectWith;
+        this.success = this.done = this.deferred.done;
+        this.fail = this.deferred.fail;
+        this.then = this.deferred.then;
+        this.always = this.deferred.always;
+        this.from = this.using;
+        this.to = this.using;
+
+        return this;
+    };
+
+
+// ### using(services)
+// This method registers services with the current able instance.
+// **Parameters**:
+// *{string|array}* **services** An id of a service or an array of strings.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{VIE.Able}* : The current instance.
+// **Example usage**:
+//
+//     var loadable = vie.load({id: "http://example.com/entity/1234"});
+//     able.using("myService");
+    this.using = function(services) {
+        var self = this;
+        services = (_.isArray(services))? services : [ services ];
+        _.each (services, function (s) {
+            var obj = (typeof s === "string")? self.vie.service(s) : s;
+            self.services.push(obj);
+        });
+        return this;
+    };
+
+// ### execute()
+// This method runs the actual method on all registered services.
+// **Parameters**:
+// *nothing*
+// **Throws**:
+// *nothing* ...
+// **Returns**:
+// *{VIE.Able}* : The current instance.
+// **Example usage**:
+//
+//     var able = new vie.Able().init();
+//     able.using("stanbol")
+//     .done(function () {alert("finished");})
+//     .execute();
+    this.execute = function() {
+        /* call service[methodName] */
+        var able = this;
+        _(this.services).each(function(service){
+            service[able.methodName](able);
+        });
+        return this;
+    };
+};
+
+// ## VIE.Loadable
+// A ```VIE.Loadable``` is a wrapper around the deferred object
+// to **load** semantic data from a semantic web service.
+VIE.prototype.Loadable = function (options) {
+    this.init(options,"load");
+};
+VIE.prototype.Loadable.prototype = new VIE.prototype.Able();
+
+// ## VIE.Savable
+// A ```VIE.Savable``` is a wrapper around the deferred object
+// to **save** entities by a VIE service. The RDFaService would write the data
+// in the HTML as RDFa, the StanbolService stores the data in its Entityhub, etc.
+VIE.prototype.Savable = function(options){
+    this.init(options, "save");
+};
+VIE.prototype.Savable.prototype = new VIE.prototype.Able();
+
+// ## VIE.Removable
+// A ```VIE.Removable``` is a wrapper around the deferred object
+// to **remove** semantic data from a semantic web service.
+VIE.prototype.Removable = function(options){
+    this.init(options, "remove");
+};
+VIE.prototype.Removable.prototype = new VIE.prototype.Able();
+
+// ## VIE.Analyzable
+// A ```VIE.Analyzable``` is a wrapper around the deferred object
+// to **analyze** data and extract semantic information with the
+// help of a semantic web service.
+VIE.prototype.Analyzable = function (options) {
+    this.init(options, "analyze");
+};
+VIE.prototype.Analyzable.prototype = new VIE.prototype.Able();
+
+// ## VIE.Findable
+// A ```VIE.Findable``` is a wrapper around the deferred object
+// to **find** semantic data on a semantic storage.
+VIE.prototype.Findable = function (options) {
+    this.init(options, "find");
+};
+VIE.prototype.Findable.prototype = new VIE.prototype.Able();
+
+
+//     VIE - Vienna IKS Editables
+//     (c) 2011 Henri Bergius, IKS Consortium
+//     (c) 2011 Sebastian Germesin, IKS Consortium
+//     (c) 2011 Szaby Grünwald, IKS Consortium
+//     VIE may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://viejs.org/
+
+// ## VIE Utils
+//
+// The here-listed methods are utility methods for the day-to-day
+// VIE.js usage. All methods are within the static namespace ```VIE.Util```.
+VIE.Util = {
+
+// ### VIE.Util.toCurie(uri, safe, namespaces)
+// This method converts a given
+// URI into a CURIE (or SCURIE), based on the given ```VIE.Namespaces``` object.
+// If the given uri is already a URI, it is left untouched and directly returned.
+// If no prefix could be found, an ```Error``` is thrown.
+// **Parameters**:
+// *{string}* **uri** The URI to be transformed.
+// *{boolean}* **safe** A flag whether to generate CURIEs or SCURIEs.
+// *{VIE.Namespaces}* **namespaces** The namespaces to be used for the prefixes.
+// **Throws**:
+// *{Error}* If no prefix could be found in the passed namespaces.
+// **Returns**:
+// *{string}* The CURIE or SCURIE.
+// **Example usage**:
+//
+//     var ns = new myVIE.Namespaces(
+//           "http://viejs.org/ns/",
+//           { "dbp": "http://dbpedia.org/ontology/" }
+//     );
+//     var uri = "<http://dbpedia.org/ontology/Person>";
+//     VIE.Util.toCurie(uri, false, ns); // --> dbp:Person
+//     VIE.Util.toCurie(uri, true, ns); // --> [dbp:Person]
+    toCurie : function (uri, safe, namespaces) {
+        if (VIE.Util.isCurie(uri, namespaces)) {
+            return uri;
+        }
+        var delim = ":";
+        for (var k in namespaces.toObj()) {
+            if (uri.indexOf(namespaces.get(k)) === 1) {
+                var pattern = new RegExp("^" + "<?" + namespaces.get(k));
+                if (k === '') {
+                    delim = '';
+                }
+                return ((safe)? "[" : "") +
+                        uri.replace(pattern, k + delim).replace(/>$/, '') +
+                        ((safe)? "]" : "");
+            }
+        }
+        throw new Error("No prefix found for URI '" + uri + "'!");
+    },
+
+// ### VIE.Util.isCurie(curie, namespaces)
+// This method checks, whether
+// the given string is a CURIE and returns ```true``` if so and ```false```otherwise.
+// **Parameters**:
+// *{string}* **curie** The CURIE (or SCURIE) to be checked.
+// *{VIE.Namespaces}* **namespaces** The namespaces to be used for the prefixes.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{boolean}* ```true``` if the given curie is a CURIE or SCURIE and ```false``` otherwise.
+// **Example usage**:
+//
+//     var ns = new myVIE.Namespaces(
+//           "http://viejs.org/ns/",
+//           { "dbp": "http://dbpedia.org/ontology/" }
+//     );
+//     var uri = "<http://dbpedia.org/ontology/Person>";
+//     var curie = "dbp:Person";
+//     var scurie = "[dbp:Person]";
+//     var text = "This is some text.";
+//     VIE.Util.isCurie(uri, ns);    // --> false
+//     VIE.Util.isCurie(curie, ns);  // --> true
+//     VIE.Util.isCurie(scurie, ns); // --> true
+//     VIE.Util.isCurie(text, ns);   // --> false
+    isCurie : function (curie, namespaces) {
+        if (VIE.Util.isUri(curie)) {
+            return false;
+        } else {
+            try {
+                VIE.Util.toUri(curie, namespaces);
+                return true;
+            } catch (e) {
+                return false;
+            }
+        }
+    },
+
+// ### VIE.Util.toUri(curie, namespaces)
+// This method converts a
+// given CURIE (or save CURIE) into a URI, based on the given ```VIE.Namespaces``` object.
+// **Parameters**:
+// *{string}* **curie** The CURIE to be transformed.
+// *{VIE.Namespaces}* **namespaces** The namespaces object
+// **Throws**:
+// *{Error}* If no URI could be assembled.
+// **Returns**:
+// *{string}* : A string, representing the URI.
+// **Example usage**:
+//
+//     var ns = new myVIE.Namespaces(
+//           "http://viejs.org/ns/",
+//           { "dbp": "http://dbpedia.org/ontology/" }
+//     );
+//     var curie = "dbp:Person";
+//     var scurie = "[dbp:Person]";
+//     VIE.Util.toUri(curie, ns);
+//          --> <http://dbpedia.org/ontology/Person>
+//     VIE.Util.toUri(scurie, ns);
+//          --> <http://dbpedia.org/ontology/Person>
+    toUri : function (curie, namespaces) {
+        if (VIE.Util.isUri(curie)) {
+            return curie;
+        }
+        var delim = ":";
+        for (var prefix in namespaces.toObj()) {
+            if (prefix !== "" && (curie.indexOf(prefix + ":") === 0 || curie.indexOf("[" + prefix + ":") === 0)) {
+                var pattern = new RegExp("^" + "\\[{0,1}" + prefix + delim);
+                return "<" + curie.replace(pattern, namespaces.get(prefix)).replace(/\]{0,1}$/, '') + ">";
+            }
+        }
+        /* check for the default namespace */
+        if (curie.indexOf(delim) === -1) {
+            return "<" + namespaces.base() + curie + ">";
+        }
+        throw new Error("No prefix found for CURIE '" + curie + "'!");
+    },
+
+// ### VIE.Util.isUri(something)
+// This method checks, whether the given string is a URI.
+// **Parameters**:
+// *{string}* **something** : The string to be checked.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{boolean}* : ```true``` if the string is a URI, ```false``` otherwise.
+// **Example usage**:
+//
+//     var uri = "<http://dbpedia.org/ontology/Person>";
+//     var curie = "dbp:Person";
+//     VIE.Util.isUri(uri);   // --> true
+//     VIE.Util.isUri(curie); // --> false
+    isUri : function (something) {
+        return (typeof something === "string" && something.search(/^<.+>$/) === 0);
+    },
+
+// ### VIE.Util.mapAttributeNS(attr, ns)
+// This method maps an attribute of an entity into namespaces if they have CURIEs.
+// **Parameters**:
+// *{string}* **attr** : The attribute to be transformed.
+// *{VIE.Namespaces}* **ns** : The namespaces.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{string}* : The transformed attribute's name.
+// **Example usage**:
+//
+//      var attr = "name";
+//      var ns = myVIE.namespaces;
+//      VIE.Util.mapAttributeNS(attr, ns); // '<' + ns.base() + attr + '>';
+    mapAttributeNS : function (attr, ns) {
+        var a = attr;
+        if (ns.isUri (attr) || attr.indexOf('@') === 0) {
+            //ignore
+        } else if (ns.isCurie(attr)) {
+            a = ns.uri(attr);
+        } else if (!ns.isUri(attr)) {
+            if (attr.indexOf(":") === -1) {
+                a = '<' + ns.base() + attr + '>';
+            } else {
+                a = '<' + attr + '>';
+            }
+        }
+        return a;
+    },
+
+// ### VIE.Util.rdf2Entities(service, results)
+// This method converts *rdf/json* data from an external service
+// into VIE.Entities.
+// **Parameters**:
+// *{object}* **service** The service that retrieved the data.
+// *{object}* **results** The data to be transformed.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{[VIE.Entity]}* : An array, containing VIE.Entity instances which have been transformed from the given data.
+    rdf2Entities: function (service, results) {
+        if (typeof jQuery.rdf !== 'function') {
+            /* fallback if no rdfQuery has been loaded */
+            return VIE.Util._rdf2EntitiesNoRdfQuery(service, results);
+        }
+        var entities = {};
+        try {
+            var rdf = (results instanceof jQuery.rdf)?
+                    results.base(service.vie.namespaces.base()) :
+                        jQuery.rdf().base(service.vie.namespaces.base()).load(results, {});
+
+            /* if the service contains rules to apply special transformation, they are executed here.*/
+            if (service.rules) {
+                var rules = jQuery.rdf.ruleset();
+                for (var prefix in service.vie.namespaces.toObj()) {
+                    if (prefix !== "") {
+                        rules.prefix(prefix, service.vie.namespaces.get(prefix));
+                    }
+                }
+                for (var i = 0; i < service.rules.length; i++)if(service.rules.hasOwnProperty(i)) {
+                    var rule = service.rules[i];
+                    rules.add(rule.left, rule.right);
+                }
+                rdf = rdf.reason(rules, 10); /* execute the rules only 10 times to avoid looping */
+            }
+            rdf.where('?subject ?property ?object').each(function() {
+                var subject = this.subject.toString();
+                if (!entities[subject]) {
+                    entities[subject] = {
+                        '@subject': subject,
+                        '@context': service.vie.namespaces.toObj(true),
+                        '@type': []
+                    };
+                }
+                var propertyUri = this.property.toString();
+                var propertyCurie;
+
+                try {
+                    propertyCurie = service.vie.namespaces.curie(propertyUri);
+                    //jQuery.createCurie(propertyUri, {namespaces: service.vie.namespaces.toObj(true)});
+                } catch (e) {
+                    propertyCurie = propertyUri;
+                    // console.warn(propertyUri + " doesn't have a namespace definition in '", service.vie.namespaces.toObj());
+                }
+                entities[subject][propertyCurie] = entities[subject][propertyCurie] || [];
+
+                function getValue(rdfQueryLiteral){
+                    if(typeof rdfQueryLiteral.value === "string"){
+                        if (rdfQueryLiteral.lang){
+                            var literal = {
+                                toString: function(){
+                                    return this["@value"];
+                                },
+                                "@value": rdfQueryLiteral.value.replace(/^"|"$/g, ''),
+                                "@language": rdfQueryLiteral.lang
+                            };
+                            return literal;
+                        }
+                        else
+                            return rdfQueryLiteral.value;
+                        return rdfQueryLiteral.value.toString();
+                    } else if (rdfQueryLiteral.type === "uri"){
+                        return rdfQueryLiteral.toString();
+                    } else {
+                        return rdfQueryLiteral.value;
+                    }
+                }
+                entities[subject][propertyCurie].push(getValue(this.object));
+            });
+
+            _(entities).each(function(ent){
+                ent["@type"] = ent["@type"].concat(ent["rdf:type"]);
+                delete ent["rdf:type"];
+                _(ent).each(function(value, property){
+                    if(value.length === 1){
+                        ent[property] = value[0];
+                    }
+                });
+            });
+        } catch (e) {
+            console.warn("Something went wrong while parsing the returned results!", e);
+            return [];
+        }
+        var vieEntities = [];
+        jQuery.each(entities, function() {
+            try {
+                var entityInstance = new service.vie.Entity(this);
+                vieEntities.push(entityInstance);
+            } catch (e) {
+                console.warn("Something went wrong while creating VIE entities out of the returned results!", e, this, entityInstance);
+            }
+        });
+        return vieEntities;
+    },
+
+    /*
+    VIE.Util.getPreferredLangForPreferredProperty(entity, preferredFields, preferredLanguages)
+    looks for specific ranking fields and languages. It calculates all possibilities and gives them
+    a score. It returns the value with the best score.
+    */
+    getPreferredLangForPreferredProperty: function(entity, preferredFields, preferredLanguages) {
+      var labelArr, lang, property, resArr, valueArr, _len, _len2,
+        _this = this;
+      resArr = [];
+      /* Try to find a label in the preferred language
+      */
+      _.each(preferredLanguages, function (lang, l) {
+        _.each(preferredFields, function (property, p) {
+          labelArr = null;
+          /* property can be a string e.g. "skos:prefLabel"
+          */
+          if (typeof property === "string" && entity.get(property)) {
+            labelArr = _.flatten([entity.get(property)]);
+            _(labelArr).each(function(label) {
+              /*
+              The score is a natural number with 0 for the
+              best candidate with the first preferred language
+              and first preferred property
+              */
+              var labelLang, value, p, score, l;
+              score = p = l = 0;
+              labelLang = label["@language"];
+              /*
+                                      legacy code for compatibility with uotdated stanbol,
+                                      to be removed after may 2012
+              */
+              if (typeof label === "string" && (label.indexOf("@") === label.length - 3 || label.indexOf("@") === label.length - 5)) {
+                labelLang = label.replace(/(^\"*|\"*@)..(..)?$/g, "");
+              }
+              /* end of legacy code
+              */
+              if (labelLang) {
+                if (labelLang === lang) {
+                  score += l;
+                } else {
+                  score += 20;
+                }
+              } else {
+                score += 10;
+              }
+              value = label.toString();
+              /* legacy code for compatibility with uotdated stanbol, to be removed after may 2012
+              */
+              value = value.replace(/(^\"*|\"*@..$)/g, "");
+              /* end of legacy code
+              */
+              return resArr.push({
+                score: score,
+                value: value
+              });
+            });
+            /*
+            property can be an object like
+            {
+              property: "skos:broader",
+              makeLabel: function(propertyValueArr) { return "..."; }
+            }
+            */
+          } else if (typeof property === "object" && entity.get(property.property)) {
+            valueArr = _.flatten([entity.get(property.property)]);
+            valueArr = _(valueArr).map(function(termUri) {
+              if (termUri.isEntity) {
+                return termUri.getSubject();
+              } else {
+                return termUri;
+              }
+            });
+            resArr.push({
+              score: p,
+              value: property.makeLabel(valueArr)
+            });
+          }
+        });
+      });
+      /*
+              take the result with the best score
+      */
+      resArr = _(resArr).sortBy(function(a) {
+        return a.score;
+      });
+      if(resArr.length) {
+        return resArr[0].value;
+      } else {
+        return "n/a";
+      }
+    },
+
+
+// ### VIE.Util._rdf2EntitiesNoRdfQuery(service, results)
+// This is a **private** method which should
+// only be accessed through ```VIE.Util._rdf2Entities()``` and is a helper method in case there is no
+// rdfQuery loaded (*not recommended*).
+// **Parameters**:
+// *{object}* **service** The service that retrieved the data.
+// *{object}* **results** The data to be transformed.
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{[VIE.Entity]}* : An array, containing VIE.Entity instances which have been transformed from the given data.
+    _rdf2EntitiesNoRdfQuery: function (service, results) {
+        var jsonLD = [];
+        _.forEach(results, function(value, key) {
+            var entity = {};
+            entity['@subject'] = '<' + key + '>';
+            _.forEach(value, function(triples, predicate) {
+                predicate = '<' + predicate + '>';
+                _.forEach(triples, function(triple) {
+                    if (triple.type === 'uri') {
+                        triple.value = '<' + triple.value + '>';
+                    }
+
+                    if (entity[predicate] && !_.isArray(entity[predicate])) {
+                        entity[predicate] = [entity[predicate]];
+                    }
+
+                    if (_.isArray(entity[predicate])) {
+                        entity[predicate].push(triple.value);
+                        return;
+                    }
+                    entity[predicate] = triple.value;
+                });
+            });
+            jsonLD.push(entity);
+        });
+        return jsonLD;
+    },
+
+// ### VIE.Util.loadSchemaOrg(vie, SchemaOrg, baseNS)
+// This method is a wrapper around
+// the <a href="http://schema.org/">schema.org</a> ontology. It adds all the
+// given types and properties as ```VIE.Type``` instances to the given VIE instance.
+// If the paramenter **baseNS** is set, the method automatically sets the namespace
+// to the provided one. If it is not set, it will keep the base namespace of VIE untouched.
+// **Parameters**:
+// *{VIE}* **vie** The instance of ```VIE```.
+// *{object}* **SchemaOrg** The data imported from schema.org.
+// *{string|undefined}* **baseNS** If set, this will become the new baseNamespace within the given ```VIE``` instance.
+// **Throws**:
+// *{Error}* If the parameter was not given.
+// **Returns**:
+// *nothing*
+    loadSchemaOrg : function (vie, SchemaOrg, baseNS) {
+
+        if (!SchemaOrg) {
+            throw new Error("Please load the schema.json file.");
+        }
+        vie.types.remove("<http://schema.org/Thing>");
+
+        var baseNSBefore = (baseNS)? baseNS : vie.namespaces.base();
+        vie.namespaces.base(baseNS);
+
+        var datatypeMapping = {
+            'DataType': 'xsd:anyType',
+            'Boolean' : 'xsd:boolean',
+            'Date'    : 'xsd:date',
+            'DateTime': 'xsd:dateTime',
+            'Time'    : 'xsd:time',
+            'Float'   : 'xsd:float',
+            'Integer' : 'xsd:integer',
+            'Number'  : 'xsd:anySimpleType',
+            'Text'    : 'xsd:string',
+            'URL'     : 'xsd:anyURI'
+        };
+
+        var dataTypeHelper = function (ancestors, id) {
+            var type = vie.types.add(id, [{'id' : 'value', 'range' : datatypeMapping[id]}]);
+
+            for (var i = 0; i < ancestors.length; i++) {
+                var supertype = (vie.types.get(ancestors[i]))? vie.types.get(ancestors[i]) :
+                    dataTypeHelper.call(vie, SchemaOrg.datatypes[ancestors[i]].supertypes, ancestors[i]);
+                type.inherit(supertype);
+            }
+            return type;
+        };
+
+        for (var dt in SchemaOrg.datatypes) {
+            if (!vie.types.get(dt)) {
+                var ancestors = SchemaOrg.datatypes[dt].supertypes;
+                dataTypeHelper.call(vie, ancestors, dt);
+            }
+        }
+
+        var metadataHelper = function (definition) {
+            var metadata = {};
+
+            if (definition.label) {
+              metadata.label = definition.label;
+            }
+
+            if (definition.url) {
+              metadata.url = definition.url;
+            }
+
+            if (definition.comment) {
+              metadata.comment = definition.comment;
+            }
+
+            if (definition.metadata) {
+              metadata = _.extend(metadata, definition.metadata);
+            }
+            return metadata;
+        };
+
+        var typeProps = function (id) {
+            var props = [];
+            _.each(SchemaOrg.types[id].specific_properties, function (pId) {
+                var property = SchemaOrg.properties[pId];
+                props.push({
+                    'id'    : property.id,
+                    'range' : property.ranges,
+                    'min'   : property.min,
+                    'max'   : property.max,
+                    'metadata': metadataHelper(property)
+                });
+            });
+            return props;
+        };
+
+        var typeHelper = function (ancestors, id, props, metadata) {
+            var type = vie.types.add(id, props, metadata);
+
+            for (var i = 0; i < ancestors.length; i++) {
+                var supertype = (vie.types.get(ancestors[i]))? vie.types.get(ancestors[i]) :
+                    typeHelper.call(vie, SchemaOrg.types[ancestors[i]].supertypes, ancestors[i], typeProps.call(vie, ancestors[i]), metadataHelper(SchemaOrg.types[ancestors[i]]));
+                type.inherit(supertype);
+            }
+            if (id === "Thing" && !type.isof("owl:Thing")) {
+                type.inherit("owl:Thing");
+            }
+            return type;
+        };
+
+        _.each(SchemaOrg.types, function (typeDef) {
+            if (vie.types.get(typeDef.id)) {
+                return;
+            }
+            var ancestors = typeDef.supertypes;
+            var metadata = metadataHelper(typeDef);
+            typeHelper.call(vie, ancestors, typeDef.id, typeProps.call(vie, typeDef.id), metadata);
+        });
+
+        /* set the namespace to either the old value or the provided baseNS value */
+        vie.namespaces.base(baseNSBefore);
+    },
+
+// ### VIE.Util.getEntityTypeUnion(entity)
+// This generates a entity-specific VIE type that is a subtype of all the
+// types of the entity. This makes it easier to deal with attribute definitions
+// specific to an entity because they're merged to a single list. This custom
+// type is transient, meaning that it won't be automatilly added to the entity
+// or the VIE type registry.
+    getEntityTypeUnion : function(entity) {
+      var vie = entity.vie;
+      return new vie.Type('Union').inherit(entity.get('@type'));
+    },
+
+// ### VIE.Util.getFormSchemaForType(type)
+// This creates a [Backbone Forms](https://github.com/powmedia/backbone-forms)
+// -compatible form schema for any VIE Type.
+    getFormSchemaForType : function(type, allowNested) {
+      var schema = {};
+
+      // Generate a schema
+      _.each(type.attributes.toArray(), function (attribute) {
+        var key = VIE.Util.toCurie(attribute.id, false, attribute.vie.namespaces);
+        schema[key] = VIE.Util.getFormSchemaForAttribute(attribute);
+      });
+
+      // Clean up unknown attribute types
+      _.each(schema, function (field, id) {
+        if (!field.type) {
+          delete schema[id];
+        }
+
+        if (field.type === 'URL') {
+          field.type = 'Text';
+          field.dataType = 'url';
+        }
+
+        if (field.type === 'List' && !field.listType) {
+          delete schema[id];
+        }
+
+        if (!allowNested) {
+          if (field.type === 'NestedModel' || field.listType === 'NestedModel') {
+            delete schema[id];
+          }
+        }
+      });
+
+      return schema;
+    },
+
+/// ### VIE.Util.getFormSchemaForAttribute(attribute)
+    getFormSchemaForAttribute : function(attribute) {
+      var primaryType = attribute.range[0];
+      var schema = {};
+
+      var getWidgetForType = function (type) {
+        switch (type) {
+          case 'xsd:anySimpleType':
+          case 'xsd:float':
+          case 'xsd:integer':
+            return 'Number';
+          case 'xsd:string':
+            return 'Text';
+          case 'xsd:date':
+            return 'Date';
+          case 'xsd:dateTime':
+            return 'DateTime';
+          case 'xsd:boolean':
+            return 'Checkbox';
+          case 'xsd:anyURI':
+            return 'URL';
+          default:
+            var typeType = attribute.vie.types.get(type);
+            if (!typeType) {
+              return null;
+            }
+            if (typeType.attributes.get('value')) {
+              // Convert to proper xsd type
+              return getWidgetForType(typeType.attributes.get('value').range[0]);
+            }
+            return 'NestedModel';
+        }
+      };
+
+      // TODO: Generate a nicer label
+      schema.title = VIE.Util.toCurie(attribute.id, false, attribute.vie.namespaces);
+
+      // TODO: Handle attributes linking to other VIE entities
+
+      if (attribute.min > 0) {
+        schema.validators = ['required'];
+      }
+
+      if (attribute.max > 1) {
+        schema.type = 'List';
+        schema.listType = getWidgetForType(primaryType);
+        if (schema.listType === 'NestedModel') {
+          schema.nestedModelType = primaryType;
+        }
+        return schema;
+      }
+
+      schema.type = getWidgetForType(primaryType);
+      if (schema.type === 'NestedModel') {
+        schema.nestedModelType = primaryType;
+      }
+      return schema;
+    },
+
+// ### VIE.Util.getFormSchema(entity)
+// This creates a [Backbone Forms](https://github.com/powmedia/backbone-forms)
+// -compatible form schema for any VIE Entity. The form schema creation
+// utilizes type information attached to the entity.
+// **Parameters**:
+// *{```Entity```}* **entity** An instance of VIE ```Entity```.
+// **Throws**:
+// *nothing*..
+// **Returns**:
+// *{object}* a JavaScript object representation of the form schema
+    getFormSchema : function(entity) {
+      if (!entity || !entity.isEntity) {
+        return {};
+      }
+
+      var unionType = VIE.Util.getEntityTypeUnion(entity);
+      var schema = VIE.Util.getFormSchemaForType(unionType, true);
+
+      // Handle nested models
+      _.each(schema, function (property, id) {
+        if (property.type !== 'NestedModel' && property.listType !== 'NestedModel') {
+          return;
+        }
+        schema[id].model = entity.vie.getTypedEntityClass(property.nestedModelType);
+      });
+
+      return schema;
+    },
+
+// ### VIE.Util.xsdDateTime(date)
+// This transforms a ```Date``` instance into an xsd:DateTime format.
+// **Parameters**:
+// *{```Date```}* **date** An instance of a javascript ```Date```.
+// **Throws**:
+// *nothing*..
+// **Returns**:
+// *{string}* A string representation of the dateTime in the xsd:dateTime format.
+    xsdDateTime : function(date) {
+        function pad(n) {
+            var s = n.toString();
+            return s.length < 2 ? '0'+s : s;
+        }
+
+        var yyyy = date.getFullYear();
+        var mm1  = pad(date.getMonth()+1);
+        var dd   = pad(date.getDate());
+        var hh   = pad(date.getHours());
+        var mm2  = pad(date.getMinutes());
+        var ss   = pad(date.getSeconds());
+
+        return yyyy +'-' +mm1 +'-' +dd +'T' +hh +':' +mm2 +':' +ss;
+    },
+
+// ### VIE.Util.extractLanguageString(entity, attrs, langs)
+// This method extracts a literal string from an entity, searching through the given attributes and languages.
+// **Parameters**:
+// *{```VIE.Entity```}* **entity** An instance of a VIE.Entity.
+// *{```array|string```}* **attrs** Either a string or an array of possible attributes.
+// *{```array|string```}* **langs** Either a string or an array of possible languages.
+// **Throws**:
+// *nothing*..
+// **Returns**:
+// *{string|undefined}* The string that was found at the attribute with the wanted language, undefined if nothing could be found.
+// **Example usage**:
+//
+//          var attrs = ["name", "rdfs:label"];
+//          var langs = ["en", "de"];
+//          VIE.Util.extractLanguageString(someEntity, attrs, langs); // "Barack Obama";
+    extractLanguageString : function(entity, attrs, langs) {
+        var p, attr, name, i, n;
+        if (entity && typeof entity !== "string") {
+            attrs = (_.isArray(attrs))? attrs : [ attrs ];
+            langs = (_.isArray(langs))? langs : [ langs ];
+            for (p = 0; p < attrs.length; p++) {
+                for (var l = 0; l < langs.length; l++) {
+                    var lang = langs[l];
+                    attr = attrs[p];
+                    if (entity.has(attr)) {
+                        name = entity.get(attr);
+                        name = (_.isArray(name))? name : [ name ];
+                        for (i = 0; i < name.length; i++) {
+                            n = name[i];
+                            if (n.isEntity) {
+                                n = VIE.Util.extractLanguageString(n, attrs, lang);
+                            } else if (typeof n === "string") {
+                                n = n;
+                            } else {
+                                n = "";
+                            }
+                            if (n && n.indexOf('@' + lang) > -1) {
+                                return n.replace(/"/g, "").replace(/@[a-z]+/, '').trim();
+                            }
+                        }
+                    }
+                }
+            }
+            /* let's do this again in case we haven't found a name but are dealing with
+            broken data where no language is given */
+            for (p = 0; p < attrs.length; p++) {
+                attr = attrs[p];
+                if (entity.has(attr)) {
+                    name = entity.get(attr);
+                    name = (_.isArray(name))? name : [ name ];
+                    for (i = 0; i < name.length; i++) {
+                        n = name[i];
+                        if (n.isEntity) {
+                            n = VIE.Util.extractLanguageString(n, attrs, []);
+                        }
+                        if (n && (typeof n === "string") && n.indexOf('@') === -1) {
+                            return n.replace(/"/g, "").replace(/@[a-z]+/, '').trim();
+                        }
+                    }
+                }
+            }
+        }
+        return undefined;
+    },
+
+// ### VIE.Util.transformationRules(service)
+// This returns a default set of rdfQuery rules that transform semantic data into the
+// VIE entity types.
+// **Parameters**:
+// *{object}* **service** An instance of a vie.service.
+// **Throws**:
+// *nothing*..
+// **Returns**:
+// *{array}* An array of rules with 'left' and 'right' side.
+    transformationRules : function (service) {
+        var res = [
+            // rule(s) to transform a dbpedia:Person into a VIE:Person
+             {
+                'left' : [
+                    '?subject a dbpedia:Person',
+                    '?subject rdfs:label ?label'
+                 ],
+                 'right': function(ns){
+                     return function(){
+                         return [
+                             jQuery.rdf.triple(this.subject.toString(),
+                                 'a',
+                                 '<' + ns.base() + 'Person>', {
+                                     namespaces: ns.toObj()
+                                 }),
+                             jQuery.rdf.triple(this.subject.toString(),
+                                 '<' + ns.base() + 'name>',
+                                 this.label, {
+                                     namespaces: ns.toObj()
+                                 })
+                             ];
+                     };
+                 }(service.vie.namespaces)
+             },
+             // rule(s) to transform a foaf:Person into a VIE:Person
+             {
+             'left' : [
+                     '?subject a foaf:Person',
+                     '?subject rdfs:label ?label'
+                  ],
+                  'right': function(ns){
+                      return function(){
+                          return [
+                              jQuery.rdf.triple(this.subject.toString(),
+                                  'a',
+                                  '<' + ns.base() + 'Person>', {
+                                      namespaces: ns.toObj()
+                                  }),
+                              jQuery.rdf.triple(this.subject.toString(),
+                                  '<' + ns.base() + 'name>',
+                                  this.label, {
+                                      namespaces: ns.toObj()
+                                  })
+                              ];
+                      };
+                  }(service.vie.namespaces)
+              },
+             // rule(s) to transform a dbpedia:Place into a VIE:Place
+             {
+                 'left' : [
+                     '?subject a dbpedia:Place',
+                     '?subject rdfs:label ?label'
+                  ],
+                  'right': function(ns) {
+                      return function() {
+                          return [
+                          jQuery.rdf.triple(this.subject.toString(),
+                              'a',
+                              '<' + ns.base() + 'Place>', {
+                                  namespaces: ns.toObj()
+                              }),
+                          jQuery.rdf.triple(this.subject.toString(),
+                                  '<' + ns.base() + 'name>',
+                              this.label.toString(), {
+                                  namespaces: ns.toObj()
+                              })
+                          ];
+                      };
+                  }(service.vie.namespaces)
+              },
+             // rule(s) to transform a dbpedia:City into a VIE:City
+              {
+                 'left' : [
+                     '?subject a dbpedia:City',
+                     '?subject rdfs:label ?label',
+                     '?subject dbpedia:abstract ?abs',
+                     '?subject dbpedia:country ?country'
+                  ],
+                  'right': function(ns) {
+                      return function() {
+                          return [
+                          jQuery.rdf.triple(this.subject.toString(),
+                              'a',
+                              '<' + ns.base() + 'City>', {
+                                  namespaces: ns.toObj()
+                              }),
+                          jQuery.rdf.triple(this.subject.toString(),
+                                  '<' + ns.base() + 'name>',
+                              this.label.toString(), {
+                                  namespaces: ns.toObj()
+                              }),
+                          jQuery.rdf.triple(this.subject.toString(),
+                                  '<' + ns.base() + 'description>',
+                              this.abs.toString(), {
+                                  namespaces: ns.toObj()
+                              }),
+                          jQuery.rdf.triple(this.subject.toString(),
+                                  '<' + ns.base() + 'containedIn>',
+                              this.country.toString(), {
+                                  namespaces: ns.toObj()
+                              })
+                          ];
+                      };
+                  }(service.vie.namespaces)
+              }
+        ];
+        return res;
+    },
+
+    getAdditionalRules : function (service) {
+
+        var mapping = {
+            Work : "CreativeWork",
+            Film : "Movie",
+            TelevisionEpisode : "TVEpisode",
+            TelevisionShow : "TVSeries", // not listed as equivalent class on dbpedia.org
+            Website : "WebPage",
+            Painting : "Painting",
+            Sculpture : "Sculpture",
+
+            Event : "Event",
+            SportsEvent : "SportsEvent",
+            MusicFestival : "Festival",
+            FilmFestival : "Festival",
+
+            Place : "Place",
+            Continent : "Continent",
+            Country : "Country",
+            City : "City",
+            Airport : "Airport",
+            Station : "TrainStation", // not listed as equivalent class on dbpedia.org
+            Hospital : "GovernmentBuilding",
+            Mountain : "Mountain",
+            BodyOfWater : "BodyOfWater",
+
+            Company : "Organization",
+            Person : "Person"
+        };
+
+        var additionalRules = [];
+        _.each(mapping, function (map, key) {
+            var tripple = {
+                'left' : [ '?subject a dbpedia:' + key, '?subject rdfs:label ?label' ],
+                'right' : function(ns) {
+                    return function() {
+                        return [ jQuery.rdf.triple(this.subject.toString(), 'a', '<' + ns.base() + map + '>', {
+                            namespaces : ns.toObj()
+                        }), jQuery.rdf.triple(this.subject.toString(), '<' + ns.base() + 'name>', this.label.toString(), {
+                            namespaces : ns.toObj()
+                        }) ];
+                    };
+                }(service.vie.namespaces)
+            };
+            additionalRules.push(tripple);
+        });
+        return additionalRules;
+    }
+};
+
+//     VIE - Vienna IKS Editables
+//     (c) 2011 Henri Bergius, IKS Consortium
+//     (c) 2011 Sebastian Germesin, IKS Consortium
+//     (c) 2011 Szaby Grünwald, IKS Consortium
+//     VIE may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://viejs.org/
+
+// ## VIE Entities
+//
+// In VIE there are two low-level model types for storing data.
+// **Collections** and **Entities**. Considering `var v = new VIE();` a VIE instance,
+// `v.entities` is a Collection with `VIE Entity` objects in it.
+// VIE internally uses JSON-LD to store entities.
+//
+// Each Entity has a few special attributes starting with an `@`. VIE has an API
+// for correctly using these attributes, so in order to stay compatible with later
+// versions of the library, possibly using a later version of JSON-LD, use the API
+// to interact with your entities.
+//
+// * `@subject` stands for the identifier of the entity. Use `e.getSubject()`
+// * `@type` stores the explicit entity types. VIE internally handles Type hierarchy,
+// which basically enables to define subtypes and supertypes. Every entity has
+// the type 'owl:Thing'. Read more about Types in <a href="Type.html">VIE.Type</a>.
+// * `@context` stores namespace definitions used in the entity. Read more about
+// Namespaces in <a href="Namespace.html">VIE Namespaces</a>.
+VIE.prototype.Entity = Backbone.Model.extend({
+  idAttribute: '@subject',
+  isEntity: true,
+
+  defaults: {
+    '@type': 'owl:Thing'
+  },
+
+  initialize: function(attributes, options) {
+    if (!attributes) {
+      attributes = {};
+    }
+    if (!options) {
+      options = {};
+    }
+    if (attributes['@subject']) {
+      this.id = this['@subject'] = this.toReference(attributes['@subject']);
+    } else {
+      this.id = this['@subject'] = attributes['@subject'] = this.cid.replace('c', '_:bnode');
+    }
+    return this;
+  },
+
+  schema: function() {
+    return VIE.Util.getFormSchema(this);
+  },
+
+  // ### Getter, Has, Setter
+  // #### `.get(attr)`
+  // To be able to communicate to a VIE Entity you can use a simple get(property)
+  // command as in `entity.get('rdfs:label')` which will give you one or more literals.
+  // If the property points to a collection, its entities can be browsed further.
+  get: function (attr) {
+    attr = VIE.Util.mapAttributeNS(attr, this.vie.namespaces);
+    var value = Backbone.Model.prototype.get.call(this, attr);
+
+    value = (_.isArray(value)) ? value : [ value ];
+    if (value.length === 0) {
+      return undefined;
+    }
+
+    // Handle value conversions
+    value = _.map(value, function(v) {
+      if (v !== undefined && attr === '@type') {
+        // Reference to a type. Return actual type instance
+        if (!this.vie.types.get(v)) {
+          // if there is no such type -> add it and let it inherit from 
+          // "owl:Thing"
+          this.vie.types.add(v).inherit("owl:Thing");
+        }
+
+        return this.vie.types.get(v);
+      } else if (v !== undefined && this.vie.entities.get(v)) {
+        // Reference to another entity
+        return this.vie.entities.get(v);
+      } else {
+        // Literal value, return as-is
+        return v;
+      }
+    }, this);
+
+    // if there is only one element, just return that one
+    value = (value.length === 1)? value[0] : value;
+    return value;
+  },
+
+  // #### `.has(attr)`
+  // Sometimes you'd like to determine if a specific attribute is set
+  // in an entity. For this reason you can call for example `person.has('friend')`
+  // to determine if a person entity has friends.
+  has: function(attr) {
+    attr = VIE.Util.mapAttributeNS(attr, this.vie.namespaces);
+    return Backbone.Model.prototype.has.call(this, attr);
+  },
+
+  hasRelations: function() {
+    var found = false;
+    _.each(this.attributes, function (value) {
+      if (value && value.isCollection) {
+        found = true;
+      }
+    });
+    return found;
+  },
+
+  // #### `.set(attrName, value, opts)`,
+  // The `options` parameter always refers to a `Backbone.Model.set` `options` object.
+  //
+  // **`.set(attributes, options)`** is the most universal way of calling the
+  // `.set` method. In this case the `attributes` object is a map of all
+  // attributes to be changed.
+  set: function(attrs, options, opts) {
+    if (!attrs) {
+      return this;
+    }
+
+    if (attrs['@subject']) {
+      attrs['@subject'] = this.toReference(attrs['@subject']);
+    }
+
+    // Use **`.set(attrName, value, options)`** for setting or changing exactly one
+    // entity attribute.
+    if (_.isString(attrs)) {
+      var obj = {};
+      obj[attrs] = options;
+      return this.set(obj, opts);
+    }
+
+    // VIE's type system is more strict than default Backbone. Unless validation is
+    // explicitly disabled, we should always validate on set
+    if (!options) {
+      options = {};
+    }
+    if (options.validate !== false && options.silent !== true) {
+      options.validate = true;
+    }
+
+    // **`.set(entity)`**: In case you'd pass a VIE entity,
+    // the passed entities attributes are being set for the entity.
+    if (attrs.attributes) {
+      attrs = attrs.attributes;
+    }
+    var coll;
+    // resolve shortened URIs like rdfs:label..
+    _.each (attrs, function (value, key) {
+      var newKey = VIE.Util.mapAttributeNS(key, this.vie.namespaces);
+      if (key !== newKey) {
+        delete attrs[key];
+        attrs[newKey] = value;
+      }
+    }, this);
+
+    // Finally iterate through the *attributes* to be set and prepare
+    // them for the Backbone.Model.set method.
+    _.each (attrs, function (value, key) {
+      if (!value) { return; }
+      if (key.indexOf('@') === -1) {
+        if (value.isCollection) {
+          // ignore
+          value.each(function (child) {
+            this.vie.entities.addOrUpdate(child);
+          }, this);
+        } else if (value.isEntity) {
+          this.vie.entities.addOrUpdate(value);
+          coll = new this.vie.Collection(value, {
+            vie: this.vie,
+            predicate: key
+          });
+          attrs[key] = coll;
+        } else if (_.isArray(value)) {
+          if (this.attributes[key] && this.attributes[key].isCollection) {
+            var newEntities = this.attributes[key].addOrUpdate(value);
+            attrs[key] = this.attributes[key];
+            attrs[key].reset(newEntities);
+          }
+        } else if (value["@value"]) {
+          // The value is a literal object, ignore
+        } else if (_.isObject(value) && !_.isDate(value)) {
+          // The value is another VIE Entity
+          var child = new this.vie.Entity(value, options);
+          // which is being stored in `v.entities`
+          this.vie.entities.addOrUpdate(child);
+          // and set as VIE Collection attribute on the original entity
+          coll = new this.vie.Collection(value, {
+            vie: this.vie,
+            predicate: key
+          });
+          attrs[key] = coll;
+        } else {
+          // ignore
+        }
+      }
+    }, this);
+    var ret = Backbone.Model.prototype.set.call(this, attrs, options);
+    if (options && options.ignoreChanges) {
+      // TODO: This will need to be changed to reflect now change
+      // tracking mechanisms in Backbone.js 1.0.0
+      this.changed = {};
+      this._previousAttributes = _.clone(this.attributes);
+    }
+    return ret;
+  },
+
+  // **`.unset(attr, opts)` ** removes an attribute from the entity.
+  unset: function (attr, opts) {
+    attr = VIE.Util.mapAttributeNS(attr, this.vie.namespaces);
+    return Backbone.Model.prototype.unset.call(this, attr, opts);
+  },
+
+  // Validation based on type rules.
+  //
+  // There are two ways to skip validation for entity operations:
+  //
+  // * `options.silent = true`
+  // * `options.validate = false`
+  validate: function (attrs, opts) {
+    if (opts && opts.validate === false) {
+      return;
+    }
+    var types = this.get('@type');
+    if (!types) {
+      return;
+    }
+    if (_.isArray(types)) {
+      var results = [];
+      _.each(types, function (type) {
+        var res = this.validateByType(type, attrs, opts);
+        if (res) {
+          results.push(res);
+        }
+      }, this);
+      if (_.isEmpty(results)) {
+        return;
+      }
+      return _.flatten(results);
+    }
+
+    return this.validateByType(types, attrs, opts);
+  },
+
+  validateByType: function (type, attrs, opts) {
+    var messages = {
+      max: '<%= property %> cannot contain more than <%= num %> items',
+      min: '<%= property %> must contain at least <%= num %> items',
+      required: '<%= property %> is required'
+    };
+
+    if (!type.attributes) {
+      return;
+    }
+
+    var toError = function (definition, constraint, messageValues) {
+      return {
+        property: definition.id,
+        constraint: constraint,
+        message: _.template(messages[constraint], _.extend({
+          property: definition.id
+        }, messageValues))
+      };
+    };
+
+    var checkMin = function (definition, attrs) {
+      if (!attrs[definition.id] || _.isEmpty(attrs[definition.id])) {
+        return toError(definition, 'required', {});
+      }
+    };
+
+    // Check the number of items in attr against max
+    var checkMax = function (definition, attrs) {
+      if (!attrs || !attrs[definition.id]) {
+        return;
+      }
+
+      if (!attrs[definition.id].isCollection && !_.isArray(attrs[definition.id])) {
+        return;
+      }
+
+      if (attrs[definition.id].length > definition.max) {
+        return toError(definition, 'max', {
+          num: definition.max
+        });
+      }
+    };
+
+    var results = [];
+    _.each(type.attributes.list(), function (definition) {
+      var res;
+      if (definition.max && definition.max != -1) {
+        res = checkMax(definition, attrs);
+        if (res) {
+          results.push(res);
+        }
+      }
+
+      if (definition.min && definition.min > 0) {
+        res = checkMin(definition, attrs);
+        if (res) {
+          results.push(res);
+        }
+      }
+    });
+
+    if (_.isEmpty(results)) {
+      return;
+    }
+    return results;
+  },
+
+  isNew: function() {
+    if (this.getSubjectUri().substr(0, 7) === '_:bnode') {
+      return true;
+    }
+    return false;
+  },
+
+  hasChanged: function(attr) {
+    if (this.markedChanged) {
+      return true;
+    }
+
+    return Backbone.Model.prototype.hasChanged.call(this, attr);
+  },
+
+  // Force hasChanged to return true
+  forceChanged: function(changed) {
+    this.markedChanged = changed ? true : false;
+  },
+
+  // **`getSubject()`** is the getter for the entity identifier.
+  getSubject: function(){
+    if (typeof this.id === "undefined") {
+      this.id = this.attributes[this.idAttribute];
+    }
+    if (typeof this.id === 'string') {
+      if (this.id.substr(0, 7) === 'http://' || this.id.substr(0, 4) === 'urn:') {
+        return this.toReference(this.id);
+      }
+      return this.id;
+    }
+    return this.cid.replace('c', '_:bnode');
+  },
+
+  // TODO describe
+  getSubjectUri: function(){
+    return this.fromReference(this.getSubject());
+  },
+
+  isReference: function(uri){
+    var matcher = new RegExp("^\\<([^\\>]*)\\>$");
+    if (matcher.exec(uri)) {
+      return true;
+    }
+    return false;
+  },
+
+  toReference: function(uri){
+    if (_.isArray(uri)) {
+      return _.map(uri, function(part) {
+       return this.toReference(part);
+      }, this);
+    }
+    var ns = this.vie.namespaces;
+    var ret = uri;
+    if (uri.substring(0, 2) === "_:") {
+      ret = uri;
+    } else if (ns.isCurie(uri)) {
+      ret = ns.uri(uri);
+      if (ret === "<" + ns.base() + uri + ">") {
+        // no base namespace extension with IDs
+        ret = '<' + uri + '>';
+      }
+    } else if (!ns.isUri(uri)) {
+      ret = '<' + uri + '>';
+    }
+    return ret;
+  },
+
+  fromReference: function(uri){
+    var ns = this.vie.namespaces;
+    if (!ns.isUri(uri)) {
+      return uri;
+    }
+    return uri.substring(1, uri.length - 1);
+  },
+
+  as: function(encoding){
+    if (encoding === "JSON") {
+      return this.toJSON();
+    }
+    if (encoding === "JSONLD") {
+      return this.toJSONLD();
+    }
+    throw new Error("Unknown encoding " + encoding);
+  },
+
+  toJSONLD: function(){
+    var instanceLD = {};
+    _.each(this.attributes, function(value, name){
+      var entityValue = this.get(name);
+
+      if (value instanceof this.vie.Collection) {
+        entityValue = value.map(function(instance) {
+          return instance.getSubject();
+        });
+      }
+
+      instanceLD[name] = entityValue;
+    }, this);
+
+    instanceLD['@subject'] = this.getSubject();
+
+    return instanceLD;
+  },
+
+  // **`.setOrAdd(arg1, arg2)`** similar to `.set(..)`, `.setOrAdd(..)` can
+  // be used for setting one or more attributes of an entity, but in
+  // this case it's a collection of values, not just one. That means, if the
+  // entity already has the attribute set, make the value to a VIE Collection
+  // and use the collection as value. The collection can contain entities
+  // or literals, but not both at the same time.
+  setOrAdd: function (arg1, arg2, option) {
+    if (_.isString(arg1) && arg2) {
+      // calling entity.setOrAdd("rdfs:type", "example:Musician")
+      this._setOrAddOne(arg1, arg2, option);
+    } else if (_.isObject(arg1)) {
+      // calling entity.setOrAdd({"rdfs:type": "example:Musician", ...})
+      _.each(arg1, function(val, key){
+        this._setOrAddOne(key, val, arg2);
+      }, this);
+    }
+    return this;
+  },
+
+
+  /* attr is always of type string */
+  /* value can be of type: string,int,double,object,VIE.Entity,VIE.Collection */
+  /*  val can be of type: undefined,string,int,double,array,VIE.Collection */
+
+  /* depending on the type of value and the type of val, different actions need to be made */
+  _setOrAddOne: function (attr, value, options) {
+    if (!attr || !value) {
+      return;
+    }
+    options = (options)? options : {};
+
+    attr = VIE.Util.mapAttributeNS(attr, this.vie.namespaces);
+
+    if (_.isArray(value)) {
+      _.each(value, function (v) {
+        this._setOrAddOne(attr, value[v], options);
+      }, this);
+      return;
+    }
+
+    if (attr === "@type" && value instanceof this.vie.Type) {
+      value = value.id;
+    }
+
+    var obj = {};
+    var existing = Backbone.Model.prototype.get.call(this, attr);
+
+    if (!existing) {
+      obj[attr] = value;
+      this.set(obj, options);
+    } else if (existing.isCollection) {
+      if (value.isCollection) {
+        value.each(function (model) {
+          existing.add(model);
+        });
+      } else if (value.isEntity) {
+        existing.add(value);
+      } else if (_.isObject(value)) {
+        value = new this.vie.Entity(value);
+        existing.add(value);
+      } else {
+        throw new Error("you cannot add a literal to a collection of entities!");
+      }
+      this.trigger('change:' + attr, this, value, {});
+      //this.change({});
+    } else if (_.isArray(existing)) {
+      if (value.isCollection) {
+        value.each(function (v) {
+          this._setOrAddOne(attr, value.at(v).getSubject(), options);
+        }, this);
+      } else if (value.isEntity) {
+        this._setOrAddOne(attr, value.getSubject(), options);
+      } else if (_.isObject(value)) {
+        value = new this.vie.Entity(value);
+        this._setOrAddOne(attr, value, options);
+      } else {
+        /* yes, we (have to) allow multiple equal values */
+        var newArray = existing.slice(0);
+        newArray.push(value);
+        this.set(attr, newArray);
+      }
+    } else {
+      var arr = [ existing ];
+      arr.push(value);
+      obj[attr] = arr;
+      return this.set(obj, options);
+    }
+  },
+
+  // **`.hasType(type)`** determines if the entity has the explicit `type` set.
+  hasType: function(type){
+    type = this.vie.types.get(type);
+    return this.hasPropertyValue("@type", type);
+  },
+
+  // TODO describe
+  hasPropertyValue: function(property, value) {
+    var t = this.get(property);
+    if (!_.isObject(value)) {
+      value = this.vie.entities.get(value);
+    }
+    if (_.isArray(t)) {
+      return t.indexOf(value) !== -1;
+    } else {
+      return t === value;
+    }
+  },
+
+  // **`.isof(type)`** determines if the entity is of `type` by explicit or implicit
+  // declaration. E.g. if Employee is a subtype of Person and e Entity has
+  // explicitly set type Employee, e.isof(Person) will evaluate to true.
+  isof: function (type) {
+    var types = this.get('@type');
+
+    if (types === undefined) {
+      return false;
+    }
+    types = (_.isArray(types))? types : [ types ];
+
+    type = (this.vie.types.get(type)) ? this.vie.types.get(type) : new this.vie.Type(type);
+
+    var isof = false;
+    _.each(types, function (t) {
+      if (this.vie.types.get(t).isof(type)) {
+        isof = true;
+      }
+    }, this);
+    return isof;
+  },
+
+  // TODO describe
+  addTo : function (collection, update) {
+    if (collection instanceof this.vie.Collection) {
+      if (update) {
+        collection.addOrUpdate(this);
+      } else {
+        collection.add(this);
+      }
+      return this;
+    }
+    throw new Error("Please provide a proper collection of type VIE.Collection as argument!");
+  }
+
+});
+
+//     VIE - Vienna IKS Editables
+//     (c) 2011 Henri Bergius, IKS Consortium
+//     (c) 2011 Sebastian Germesin, IKS Consortium
+//     (c) 2011 Szaby Grünwald, IKS Consortium
+//     VIE may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://viejs.org/
+VIE.prototype.Collection = Backbone.Collection.extend({
+    model: VIE.prototype.Entity,
+
+    initialize: function (models, options) {
+      if (!options || !options.vie) {
+        throw new Error('Each collection needs a VIE reference');
+      }
+      this.vie = options.vie;
+      this.predicate = options.predicate;
+    },
+
+    canAdd: function (type) {
+      return true;
+    },
+
+    get: function(id) {
+        if (id === null) {
+            return null;
+        }
+
+        id = (id.getSubject)? id.getSubject() : id;
+        if (typeof id === "string" && id.indexOf("_:") === 0) {
+            if (id.indexOf("bnode") === 2) {
+                //bnode!
+                id = id.replace("_:bnode", 'c');
+                return this._byId[id];
+            } else {
+                return this._byId["<" + id + ">"];
+            }
+        } else {
+            if (this._byId[id]) {
+              return this._byId[id];
+            }
+            id = this.toReference(id);
+            return this._byId[id];
+        }
+    },
+
+    addOrUpdate: function(model, options) {
+        options = options || {};
+
+        var collection = this;
+        var existing;
+        if (_.isArray(model)) {
+            var entities = [];
+            _.each(model, function(item) {
+                entities.push(collection.addOrUpdate(item, options));
+            });
+            return entities;
+        }
+
+        if (model === undefined) {
+            throw new Error("No model given");
+        }
+
+        if (_.isString(model)) {
+          model = {
+            '@subject': model,
+            id: model
+          };
+        }
+
+        if (!model.isEntity) {
+            model = new this.model(model);
+        }
+
+        if (model.id && this.get(model.id)) {
+            existing = this.get(model.id);
+        }
+        if (this.get(model.cid)) {
+            existing = this.get(model.cid);
+        }
+        if (existing) {
+            var newAttribs = {};
+            _.each(model.attributes, function(value, attribute) {
+                if (!existing.has(attribute)) {
+                    newAttribs[attribute] = value;
+                    return true;
+                }
+
+                if (attribute === '@subject') {
+                    if (model.isNew() && !existing.isNew()) {
+                        // Save order issue, skip
+                        return true;
+                    }
+                }
+
+                if (existing.get(attribute) === value) {
+                    return true;
+                }
+                //merge existing attribute values with new ones!
+                //not just overwrite 'em!!
+                var oldVals = existing.attributes[attribute];
+                var newVals = value;
+                if (oldVals instanceof collection.vie.Collection) {
+                    // TODO: Merge collections
+                    return true;
+                }
+                if (options.overrideAttributes) {
+                   newAttribs[attribute] = value;
+                   return true;
+                }
+                if (attribute === '@context') {
+                    newAttribs[attribute] = jQuery.extend(true, {}, oldVals, newVals);
+                } else {
+                    oldVals = (jQuery.isArray(oldVals))? oldVals : [ oldVals ];
+                    newVals = (jQuery.isArray(newVals))? newVals : [ newVals ];
+                    newAttribs[attribute] = _.uniq(oldVals.concat(newVals));
+                    newAttribs[attribute] = (newAttribs[attribute].length === 1)? newAttribs[attribute][0] : newAttribs[attribute];
+                }
+            });
+
+            if (!_.isEmpty(newAttribs)) {
+                existing.set(newAttribs, options.updateOptions);
+            }
+            return existing;
+        }
+        this.add(model, options.addOptions);
+        return model;
+    },
+
+    isReference: function(uri){
+        var matcher = new RegExp("^\\<([^\\>]*)\\>$");
+        if (matcher.exec(uri)) {
+            return true;
+        }
+        return false;
+    },
+
+    toReference: function(uri){
+        if (this.isReference(uri)) {
+            return uri;
+        }
+        return '<' + uri + '>';
+    },
+
+    fromReference: function(uri){
+        if (!this.isReference(uri)) {
+            return uri;
+        }
+        return uri.substring(1, uri.length - 1);
+    },
+
+    isCollection: true
+});
+
+//     VIE - Vienna IKS Editables
+//     (c) 2011 Henri Bergius, IKS Consortium
+//     (c) 2011 Sebastian Germesin, IKS Consortium
+//     (c) 2011 Szaby Grünwald, IKS Consortium
+//     VIE may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://viejs.org/
+//
+
+// ## VIE.Types
+// Within VIE, we provide special capabilities of handling types of entites. This helps
+// for example to query easily for certain entities (e.g., you only need to query for *Person*s
+// and not for all subtypes).
+if (VIE.prototype.Type) {
+    throw new Error("ERROR: VIE.Type is already defined. Please check your installation!");
+}
+if (VIE.prototype.Types) {
+    throw new Error("ERROR: VIE.Types is already defined. Please check your installation!");
+}
+
+// ### VIE.Type(id, attrs, metadata)
+// This is the constructor of a VIE.Type.
+// **Parameters**:
+// *{string}* **id** The id of the type.
+// *{string|array|VIE.Attribute}* **attrs** A string, proper ```VIE.Attribute``` or an array of these which
+// *{object}* **metadata** Possible metadata about the type
+// are the possible attributes of the type
+// **Throws**:
+// *{Error}* if one of the given paramenters is missing.
+// **Returns**:
+// *{VIE.Type}* : A **new** VIE.Type object.
+// **Example usage**:
+//
+//     var person = new vie.Type("Person", ["name", "knows"]);
+VIE.prototype.Type = function (id, attrs, metadata) {
+    if (id === undefined || typeof id !== 'string') {
+        throw "The type constructor needs an 'id' of type string! E.g., 'Person'";
+    }
+
+// ### id
+// This field stores the id of the type's instance.
+// **Parameters**:
+// nothing
+// **Throws**:
+// nothing
+// **Returns**:
+// *{string}* : The id of the type as a URI.
+// **Example usage**:
+//
+//     console.log(person.id);
+//      // --> "<http://viejs.org/ns/Person>"
+    this.id = this.vie.namespaces.isUri(id) ? id : this.vie.namespaces.uri(id);
+
+    /* checks whether such a type is already defined. */
+    if (this.vie.types.get(this.id)) {
+        throw new Error("The type " + this.id + " is already defined!");
+    }
+
+// ### supertypes
+// This field stores all parent types of the type's instance. This
+// is set if the current type inherits from another type.
+// **Parameters**:
+// nothing
+// **Throws**:
+// nothing
+// **Returns**:
+// *{VIE.Types}* : The supertypes (parents) of the type.
+// **Example usage**:
+//
+//     console.log(person.supertypes);
+    this.supertypes = new this.vie.Types();
+
+// ### subtypes
+// This field stores all children types of the type's instance. This
+// will be set if another type inherits from the current type.
+// **Parameters**:
+// nothing
+// **Throws**:
+// nothing
+// **Returns**:
+// *{VIE.Types}* : The subtypes (parents) of the type.
+// **Example usage**:
+//
+//     console.log(person.subtypes);
+    this.subtypes = new this.vie.Types();
+
+// ### attributes
+// This field stores all attributes of the type's instance as
+// a proper ```VIE.Attributes``` class. (see also <a href="Attribute.html">VIE.Attributes</a>)
+// **Parameters**:
+// nothing
+// **Throws**:
+// nothing
+// **Returns**:
+// *{VIE.Attributes}* : The attributes of the type.
+// **Example usage**:
+//
+//     console.log(person.attributes);
+    this.attributes = new this.vie.Attributes(this, (attrs)? attrs : []);
+
+// ### metadata
+// This field stores possible additional information about the type, like
+// a human-readable label.
+    this.metadata = metadata ? metadata : {};
+
+// ### isof(type)
+// This method checks whether the current type is a child of the given type.
+// **Parameters**:
+// *{string|VIE.Type}* **type** The type (or the id of that type) to be checked.
+// **Throws**:
+// *{Error}* If the type is not valid.
+// **Returns**:
+// *{boolean}* : ```true``` if the current type inherits from the type, ```false``` otherwise.
+// **Example usage**:
+//
+//     console.log(person.isof("owl:Thing"));
+//     // <-- true
+    this.isof = function (type) {
+        type = this.vie.types.get(type);
+        if (type) {
+            return type.subsumes(this.id);
+        } else {
+            throw new Error("No valid type given");
+        }
+    };
+
+// ### subsumes(type)
+// This method checks whether the current type is a parent of the given type.
+// **Parameters**:
+// *{string|VIE.Type}* **type** The type (or the id of that type) to be checked.
+// **Throws**:
+// *{Error}* If the type is not valid.
+// **Returns**:
+// *{boolean}* : ```true``` if the current type is a parent of the type, ```false``` otherwise.
+// **Example usage**:
+//
+//     var x = new vie.Type(...);
+//     var y = new vie.Type(...).inherit(x);
+//     y.isof(x) === x.subsumes(y);
+    this.subsumes = function (type) {
+        type = this.vie.types.get(type);
+        if (type) {
+            if (this.id === type.id) {
+                return true;
+            }
+            var subtypes = this.subtypes.list();
+            for (var c = 0; c < subtypes.length; c++) {
+                var childObj = subtypes[c];
+                if (childObj) {
+                     if (childObj.id === type.id || childObj.subsumes(type)) {
+                         return true;
+                     }
+                }
+            }
+            return false;
+        } else {
+            throw new Error("No valid type given");
+        }
+    };
+
+// ### inherit(supertype)
+// This method invokes inheritance throught the types. This adds the current type to the
+// subtypes of the supertype and vice versa.
+// **Parameters**:
+// *{string|VIE.Type|array}* **supertype** The type to be inherited from. If this is an array
+// the inherit method is called sequentially on all types.
+// **Throws**:
+// *{Error}* If the type is not valid.
+// **Returns**:
+// *{VIE.Type}* : The instance itself.
+// **Example usage**:
+//
+//     var x = new vie.Type(...);
+//     var y = new vie.Type(...).inherit(x);
+//     y.isof(x) // <-- true
+    this.inherit = function (supertype) {
+        if (typeof supertype === "string") {
+            this.inherit(this.vie.types.get(supertype));
+        }
+        else if (supertype instanceof this.vie.Type) {
+            supertype.subtypes.addOrOverwrite(this);
+            this.supertypes.addOrOverwrite(supertype);
+            try {
+                /* only for validation of attribute-inheritance!
+                   if this throws an error (inheriting two attributes
+                   that cannot be combined) we reverse all changes. */
+                this.attributes.list();
+            } catch (e) {
+                supertype.subtypes.remove(this);
+                this.supertypes.remove(supertype);
+                throw e;
+            }
+        } else if (jQuery.isArray(supertype)) {
+            for (var i = 0, slen = supertype.length; i < slen; i++) {
+                this.inherit(supertype[i]);
+            }
+        } else {
+            throw new Error("Wrong argument in VIE.Type.inherit()");
+        }
+        return this;
+    };
+
+// ### hierarchy()
+// This method serializes the hierarchy of child types into an object.
+// **Parameters**:
+// *nothing*
+// **Throws**:
+// *nothing*
+// **Returns**:
+// *{object}* : The hierachy of child types as an object.
+// **Example usage**:
+//
+//     var x = new vie.Type(...);
+//     var y = new vie.Type(...).inherit(x);
+//     x.hierarchy();
+    this.hierarchy = function () {
+        var obj = {id : this.id, subtypes: []};
+        var list = this.subtypes.list();
+        for (var c = 0, llen = list.length; c < llen; c++) {
+            var childObj = this.vie.types.get(list[c]);
+            obj.subtypes.push(childObj.hierarchy());
+        }
+        return obj;
+    };
+
+// ### instance()
+// This method creates a ```VIE.Entity``` instance from this type.
+// **Parameters**:
+// *{object}* **attrs**  see <a href="Entity.html">constructor of VIE.Entity</a>
+// *{object}* **opts**  see <a href="Entity.html">constructor of VIE.Entity</a>
+// **Throws**:
+// *{Error}* if the instance could not be built
+// **Returns**:
+// *{VIE.Entity}* : A **new** instance of a ```VIE.Entity``` with the current type.
+// **Example usage**:
+//
+//     var person = new vie.Type("person");
+//     var sebastian = person.instance(
+//         {"@subject" : "#me",
+//          "name" : "Sebastian"});
+//     console.log(sebastian.get("name")); // <-- "Sebastian"
+    this.instance = function (attrs, opts) {
+        attrs = (attrs)? attrs : {};
+        opts = (opts)? opts : {};
+
+        /* turn type/attribute checking on by default! */
+        if (opts.typeChecking !== false) {
+            for (var a in attrs) {
+                if (a.indexOf('@') !== 0 && !this.attributes.get(a)) {

[... 4436 lines stripped ...]