diff --git a/procedures/deleteIsaCache.sql b/procedures/deleteIsaCache.sql
index c0fc831fb3482419a2c8215a06c693cdef16179c..4af004e5475ec9a82e6425f66ba389f92213c63d 100644
--- a/procedures/deleteIsaCache.sql
+++ b/procedures/deleteIsaCache.sql
@@ -51,11 +51,11 @@ BEGIN
             WHERE entity_id = EntityID;
 
         -- move to archive_isa before deleting (only direct child-parent relations)
-        INSERT INTO archive_isa (child, child_iversion, parent)
+        INSERT IGNORE INTO archive_isa (child, child_iversion, parent)
+            -- TODO copy rpath as well
             SELECT e.child, IVersion AS child_iversion, e.parent
             FROM isa_cache AS e
-            WHERE e.child = EntityID
-            AND e.rpath = CAST(EntityID AS CHAR);
+            WHERE e.child = EntityID;
     END IF;
 
     DELETE FROM isa_cache
diff --git a/procedures/entityVersioning.sql b/procedures/entityVersioning.sql
index b009d3f2ab8dd58ecb2199e57c40b99419007a0d..02a4a118cfd65dab8fbdd91a41111f5ccca0372e 100644
--- a/procedures/entityVersioning.sql
+++ b/procedures/entityVersioning.sql
@@ -226,6 +226,38 @@ BEGIN
 END;
 //
 
+DROP FUNCTION IF EXISTS db_2_0._get_head_iversion //
+
+/**
+ * Get the _iversion number of the HEAD of an entity.
+ *
+ * Parameters
+ * ----------
+ * EntityID
+ *   The entity id.
+ *
+ * Returns
+ * -------
+ * The _iversion of the HEAD.
+ */
+CREATE FUNCTION db_2_0._get_head_iversion(
+    EntityID INT UNSIGNED)
+RETURNS INT UNSIGNED
+READS SQL DATA
+BEGIN
+    -- This implementation assumes that the distance from the head equals the
+    -- difference between the _iversion numbers. This will not be correct anymore
+    -- as soon as branches may split and merge. Then, a walk over the primary
+    -- parents (_ipparent) will be necessary.
+    RETURN (
+        SELECT e._iversion
+            FROM entity_version AS e
+            WHERE e.entity_id = EntityID
+            ORDER BY e._iversion DESC
+            LIMIT 1
+        );
+END;
+
 
 DROP FUNCTION IF EXISTS db_2_0.get_head_relative //
 
diff --git a/procedures/query/applyIDFilter.sql b/procedures/query/applyIDFilter.sql
index 56adf53d19916049accbaf71e866ab36efb6abd2..8b8cf188b45a1749b5f365d6167a0b1444d57256 100644
--- a/procedures/query/applyIDFilter.sql
+++ b/procedures/query/applyIDFilter.sql
@@ -25,32 +25,97 @@ DROP PROCEDURE IF EXISTS db_2_0.applyIDFilter;
 
 DELIMITER //
 
-CREATE PROCEDURE db_2_0.applyIDFilter(in sourceSet VARCHAR(255), in targetSet VARCHAR(255), in o CHAR(2), in vInt BIGINT, in agg CHAR(3))
+CREATE PROCEDURE db_2_0.applyIDFilter(in sourceSet VARCHAR(255), in targetSet VARCHAR(255), in o CHAR(2), in vInt BIGINT, in agg CHAR(3), in versioned BOOLEAN)
 IDFILTER_LABEL: BEGIN
 DECLARE data VARCHAR(20000) DEFAULT NULL;
 DECLARE aggVal VARCHAR(255) DEFAULT NULL;
 
 #-- get aggVal if possible
 IF agg IS NOT NULL THEN
-	SET @stmtIDAggValStr = CONCAT("SELECT ", agg, "(id) INTO @sAggVal FROM `", sourceSet, "`");
-	PREPARE stmtIDAggVal FROM @stmtIDAggValStr;
-	EXECUTE stmtIDAggVal;
+    IF versioned THEN
+        -- TODO
+        SELECT 1 FROM id_agg_with_versioning_not_implemented;
+    END IF;
+    SET @stmtIDAggValStr = CONCAT(
+        "SELECT ",
+        agg,
+        "(id) INTO @sAggVal FROM `",
+        sourceSet,
+        "`");
+    PREPARE stmtIDAggVal FROM @stmtIDAggValStr;
+    EXECUTE stmtIDAggVal;
     DEALLOCATE PREPARE stmtIDAggVal;
     SET aggVal = @sAggVal;
 END IF;
 
 #-- generate stmt string
 IF targetSet IS NULL OR targetSet = sourceSet THEN
-    SET data = CONCAT("DELETE FROM `",sourceSet,"` WHERE ",IF(o IS NULL OR vInt IS NULL,"1=1",CONCAT("NOT id",o,vInt)),IF(aggVal IS NULL, "", CONCAT(" AND id!=",aggVal)));
+    SET data = CONCAT(
+        "DELETE FROM `",
+        sourceSet,
+        "` WHERE ",
+        IF(o IS NULL OR vInt IS NULL,
+            "1=1",
+            CONCAT("NOT id",
+                o,
+                vInt)),
+        IF(aggVal IS NULL,
+            "",
+            CONCAT(" AND id!=",
+                aggVal)));
+ELSEIF versioned AND sourceSet = "entities" THEN
+
+    -- ################# VERSIONING #####################
+    SET data = CONCAT(
+        "INSERT IGNORE INTO `",
+        targetSet,
+        '` (id, _iversion) SELECT id, _get_head_iversion(id) FROM `entities` WHERE ',
+        IF(o IS NULL OR vInt IS NULL,
+            "1=1",
+            CONCAT("id",
+                o,
+                vInt)),
+        IF(aggVal IS NULL,
+            "",
+            CONCAT(" AND id=",
+                aggVal)),
+        ' UNION SELECT id, _iversion FROM `archive_entities` WHERE ',
+        IF(o IS NULL OR vInt IS NULL,
+            "1=1",
+            CONCAT("id",
+                o,
+                vInt)),
+        IF(aggVal IS NULL,
+            "",
+            CONCAT(" AND id=",
+                aggVal)));
+    -- ##################################################
+
 ELSE
-    SET data = CONCAT("INSERT IGNORE INTO `",targetSet,"` SELECT data.id as id FROM `",sourceSet,"` AS data WHERE ",IF(o IS NULL OR vInt IS NULL,"1=1",CONCAT("data.id",o,vInt)),IF(aggVal IS NULL, "", CONCAT(" AND data.id=", aggVal)));
+    SET data = CONCAT(
+        "INSERT IGNORE INTO `",
+        targetSet,
+        IF(versioned,
+            '` (id, _iversion) SELECT data.id, data._iversion FROM `',
+            '` (id) SELECT data.id FROM `'),
+        sourceSet,
+        "` AS data WHERE ",
+        IF(o IS NULL OR vInt IS NULL,
+            "1=1",
+            CONCAT("data.id",
+                o,
+                vInt)),
+        IF(aggVal IS NULL,
+            "",
+            CONCAT(" AND data.id=",
+                aggVal)));
 END IF;
 
 Set @stmtIDFilterStr = data;
 PREPARE stmtIDFilter FROM @stmtIDFilterStr;
 EXECUTE stmtIDFilter;
 DEALLOCATE PREPARE stmtIDFilter;
-	
+
 END;
 //
 
diff --git a/procedures/query/applyPOV.sql b/procedures/query/applyPOV.sql
index bf49d930a7daab9d1cd81de482b5dc6d8dd4f462..e648637e68745949e068b51cc82ffe9c11a9ac1b 100644
--- a/procedures/query/applyPOV.sql
+++ b/procedures/query/applyPOV.sql
@@ -51,7 +51,8 @@ CREATE PROCEDURE db_2_0.applyPOV(in sourceSet VARCHAR(255), /* (?) Name of the t
                                  in vDateTime VARCHAR(255),
                                  in vDateTimeDotNotation VARCHAR(255),
                                  in agg CHAR(3), /* an SQL aggregate function or NULL when no aggregation should be used */
-                                 in pname VARCHAR(255)) /* name of the property, this name is only used for reporting more meaningful warnings */
+                                 in pname VARCHAR(255), /* name of the property, this name is only used for reporting more meaningful warnings */
+                                 in versioned BOOLEAN)
 POV_LABEL: BEGIN
     DECLARE data TEXT DEFAULT NULL; /*data subselect statement string*/
     DECLARE sTextData VARCHAR(20000) DEFAULT NULL; /*SELECT PREFIX for data subselect plus WHERE CLAUSE for text_data*/
@@ -71,7 +72,7 @@ POV_LABEL: BEGIN
 
     IF o = '->' THEN
         #-- special case: pure reference property
-        call applyRefPOV(sourceSet,targetSet, propertiesTable, refIdsTable);
+        call applyRefPOV(sourceSet,targetSet, propertiesTable, refIdsTable, versioned);
         LEAVE POV_LABEL;
     ELSEIF o = '0' THEN
         #-- special case: property IS NULL
@@ -101,14 +102,27 @@ POV_LABEL: BEGIN
         SET sTextData = 'SELECT DISTINCT domain_id, entity_id, property_id FROM `text_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `name_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `enum_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `integer_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `double_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data` AS subdata WHERE subdata.value IS NOT NULL UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `reference_data` AS subdata WHERE subdata.value IS NOT NULL';
 
     ELSEIF o = "(" or o = "!(" THEN
-        SET sTextData = IF(vText IS NULL, ' SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data`',
-                                          IF(vDateTimeDotNotation IS NULL, NULL,
-                                                                           CONCAT(' SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data` AS subdata WHERE ', getDateWhereClause(vDateTimeDotNotation, o))));
-        SET sDatetimeData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data`',
-                                              IF(vDateTime IS NULL, NULL,
-                                                                    CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data` AS subdata WHERE ', getDateTimeWhereClause(vDateTime, o))));
+        IF versioned THEN
+            -- TODO is vText = NULL even possible?
+            SET sTextData = IF(vText IS NULL, ' SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `date_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_date_data`',
+                                              IF(vDateTimeDotNotation IS NULL, NULL,
+                                                                               CONCAT(' SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `date_data` AS subdata WHERE ', getDateWhereClause(vDateTimeDotNotation, o), ' UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_date_data` AS subdata WHERE ', getDateWhereClause(vDateTimeDotNotation, o))));
+            SET sDatetimeData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `datetime_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_datetime_data`',
+                                                  IF(vDateTime IS NULL, NULL,
+                                                                        CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `datetime_data` AS subdata WHERE ', getDateTimeWhereClause(vDateTime, o), ' UNION ALL SELECT DISTINCT domain_id, entity_id,_iversion, property_id FROM `archive_datetime_data` AS subdata WHERE ', getDateTimeWhereClause(vDateTime, o))));
+        ELSE
+            SET sTextData = IF(vText IS NULL, ' SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data`',
+                                              IF(vDateTimeDotNotation IS NULL, NULL,
+                                                                               CONCAT(' SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data` AS subdata WHERE ', getDateWhereClause(vDateTimeDotNotation, o))));
+            SET sDatetimeData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data`',
+                                                  IF(vDateTime IS NULL, NULL,
+                                                                        CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data` AS subdata WHERE ', getDateTimeWhereClause(vDateTime, o))));
+        END IF;
         SET vText = NULL;
     ELSEIF agg IS NOT NULL THEN
+        IF versioned THEN
+            SELECT 1 FROM versioned_agg_pov_filter_not_implemented;
+        END IF;
         #-- find aggregated value (min/max...)
 
         #-- construct where clause
@@ -116,7 +130,7 @@ POV_LABEL: BEGIN
         SET aggValueWhereClause = CONCAT(IF(aggValueWhereClause IS NULL, '', aggValueWhereClause), getAggValueWhereClause(sourceSet, propertiesTable));
 
         #-- construct statement
-        SET @aggValueStmtStr = CONCAT('SELECT ',agg,'(subdata.value), ', agg, '(convert_unit(subdata.unit_sig,subdata.value)), COUNT(DISTINCT standard_unit(subdata.unit_sig)), max(standard_unit(subdata.unit_sig)) INTO @sAggValue, @sAggValueConvert, @distinctUnits, @StdUnitSig FROM (SELECT entity_id, property_id, value, unit_sig FROM `integer_data` UNION SELECT entity_id, property_id, value, unit_sig FROM `double_data`) AS subdata WHERE ', aggValueWhereClause);
+        SET @aggValueStmtStr = CONCAT('SELECT ',agg,'(subdata.value), ', agg, '(convert_unit(subdata.unit_sig,subdata.value)), COUNT(DISTINCT standard_unit(subdata.unit_sig)), max(standard_unit(subdata.unit_sig)) INTO @sAggValue, @sAggValueConvert, @distinctUnits, @StdUnitSig FROM (SELECT entity_id, property_id, value, unit_sig FROM `integer_data` UNION ALL SELECT entity_id, property_id, value, unit_sig FROM `double_data`) AS subdata WHERE ', aggValueWhereClause);
 
         #-- run statement
         PREPARE stmtAggValueStmt FROM @aggValueStmtStr;
@@ -145,15 +159,27 @@ POV_LABEL: BEGIN
         SET vText = NULL;
     ELSE
         #-- generate statement parts
-        SET sTextData = IF(vText IS NULL, 'SELECT DISTINCT domain_id, entity_id, property_id FROM `text_data`', CONCAT('SELECT DISTINCT domain_id, entity_id, property_id FROM `text_data` AS subdata WHERE subdata.value ',o,' ?'));
-        SET sNameData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `name_data`', CONCAT(' UNION SELECT DISTINCT domain_id, entity_id, property_id FROM `name_data` AS subdata WHERE subdata.value ', o, ' ?'));
-        SET sEnumData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `enum_data`', CONCAT(' UNION SELECT DISTINCT domain_id, entity_id, property_id FROM `enum_data` AS subdata WHERE subdata.value ', o, ' ?'));
-        SET sIntData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT subdata.domain_id, subdata.entity_id, subdata.property_id FROM `integer_data` AS subdata', IF(vInt IS NULL AND vDoubleStdUnit IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `integer_data` AS subdata WHERE ', getDoubleWhereClause(vInt, unit_sig, vDoubleStdUnit, stdUnit_sig, o))));
-        SET sDoubleData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT subdata.domain_id, subdata.entity_id, subdata.property_id FROM `double_data` AS subdata', IF(vDouble IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `double_data` AS subdata WHERE ', getDoubleWhereClause(vDouble,unit_sig,vDoubleStdUnit,stdUnit_sig,o))));
-        SET sDatetimeData = IF(vText IS NULL,' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data`', IF(vDateTime IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data` AS subdata WHERE ',getDateTimeWhereClause(vDateTime,o))));
-        SET sDateData = IF(vText IS NULL,' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data`', IF(vDateTimeDotNotation IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data` AS subdata WHERE ',getDateWhereClause(vDateTimeDotNotation,o))));
-        SET sRefData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `reference_data`', IF(refIdsTable IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refIdsTable, '` AS refIdsTable WHERE subdata.value=refIdsTable.id LIMIT 1)')));
-        SET sNullData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `null_data`', NULL);
+        IF versioned THEN
+            SET sTextData = IF(vText IS NULL, 'SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `text_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_text_data` ', CONCAT('SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `text_data` AS subdata WHERE subdata.value ',o,' ? UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_text_data` AS subdata WHERE subdata.value ', o, '?'));
+            SET sNameData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `name_data`', CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `name_data` AS subdata WHERE subdata.value ', o, ' ?'));
+            SET sEnumData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `enum_data`', CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `enum_data` AS subdata WHERE subdata.value ', o, ' ?'));
+            SET sRefData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `reference_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_reference_data`', IF(refIdsTable IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refIdsTable, '` AS refIdsTable WHERE subdata.value=refIdsTable.id LIMIT 1) UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refIdsTable, '` AS refIdsTable WHERE subdata.value=refIdsTable.id LIMIT 1)')));
+            SET sDoubleData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT subdata.domain_id, subdata.entity_id, _get_head_iversion(subdata.entity_id) AS _iversion, subdata.property_id FROM `double_data` AS subdata UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_double_data` ', IF(vDouble IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id), property_id FROM `double_data` AS subdata WHERE ', getDoubleWhereClause(vDouble,unit_sig,vDoubleStdUnit,stdUnit_sig,o), ' UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_double_data` AS subdata WHERE ', getDoubleWhereClause(vDouble, unit_sig, vDoubleStdUnit, stdUnit_sig, o))));
+            SET sIntData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT subdata.domain_id, subdata.entity_id, _get_head_iversion(subdata.entity_id) AS _iversion, subdata.property_id FROM `integer_data` AS subdata UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_integer_data`', IF(vInt IS NULL AND vDoubleStdUnit IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `integer_data` AS subdata WHERE ', getDoubleWhereClause(vInt, unit_sig, vDoubleStdUnit, stdUnit_sig, o), ' UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_integer_data` AS subdata WHERE ', getDoubleWhereClause(vInt, unit_sig, vDoubleStdUnit, stdUnit_sig, o))));
+            SET sDatetimeData = IF(vText IS NULL,' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `datetime_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_datetime_data`', IF(vDateTime IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `datetime_data` AS subdata WHERE ',getDateTimeWhereClause(vDateTime,o), ' UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_datetime_data` AS subdata WHERE ',getDateTimeWhereClause(vDateTime,o))));
+            SET sDateData = IF(vText IS NULL,' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `date_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_date_data`', IF(vDateTimeDotNotation IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `date_data` AS subdata WHERE ', getDateWhereClause(vDateTimeDotNotation,o), ' UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_date_data` AS subdata WHERE ', getDateWhereClause(vDateTimeDotNotation,o))));
+            SET sNullData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `null_data` UNION ALL SELECT DISTINCT domain_id, entity_id, _iversion, property_id FROM `archive_null_data`', NULL);
+        ELSE
+            SET sTextData = IF(vText IS NULL, 'SELECT DISTINCT domain_id, entity_id, property_id FROM `text_data`', CONCAT('SELECT DISTINCT domain_id, entity_id, property_id FROM `text_data` AS subdata WHERE subdata.value ',o,' ?'));
+            SET sNameData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `name_data`', CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `name_data` AS subdata WHERE subdata.value ', o, ' ?'));
+            SET sEnumData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `enum_data`', CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `enum_data` AS subdata WHERE subdata.value ', o, ' ?'));
+            SET sRefData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `reference_data`', IF(refIdsTable IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refIdsTable, '` AS refIdsTable WHERE subdata.value=refIdsTable.id LIMIT 1)')));
+            SET sDoubleData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT subdata.domain_id, subdata.entity_id, subdata.property_id FROM `double_data` AS subdata', IF(vDouble IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `double_data` AS subdata WHERE ', getDoubleWhereClause(vDouble,unit_sig,vDoubleStdUnit,stdUnit_sig,o))));
+            SET sIntData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT subdata.domain_id, subdata.entity_id, subdata.property_id FROM `integer_data` AS subdata', IF(vInt IS NULL AND vDoubleStdUnit IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `integer_data` AS subdata WHERE ', getDoubleWhereClause(vInt, unit_sig, vDoubleStdUnit, stdUnit_sig, o))));
+            SET sDatetimeData = IF(vText IS NULL,' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data`', IF(vDateTime IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `datetime_data` AS subdata WHERE ',getDateTimeWhereClause(vDateTime,o))));
+            SET sDateData = IF(vText IS NULL,' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data`', IF(vDateTimeDotNotation IS NULL, NULL, CONCAT(' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `date_data` AS subdata WHERE ',getDateWhereClause(vDateTimeDotNotation,o))));
+            SET sNullData = IF(vText IS NULL, ' UNION ALL SELECT DISTINCT domain_id, entity_id, property_id FROM `null_data`', NULL);
+        END IF;
 
     END IF;
 
@@ -170,32 +196,68 @@ POV_LABEL: BEGIN
             );
 
 
-    call createTmpTable(keepTabl);
 
-    #-- generate statement from statement parts
-    SET @stmtPOVkeepTblStr = CONCAT("INSERT IGNORE INTO `", keepTabl, "` (id) SELECT DISTINCT entity_id AS id FROM ", data, " as data", IF(propertiesTable IS NULL, '', CONCAT(' WHERE EXISTS (Select 1 from `', propertiesTable, '` AS prop WHERE prop.id = data.property_id AND (prop.id2=data.entity_id OR prop.id2=0))')));
 
-    SET @stmtPOVStr = CONCAT(
-            IF(targetSet IS NULL,
-                CONCAT('DELETE FROM `',sourceSet,'` WHERE NOT EXISTS (SELECT 1 FROM `'),
-                CONCAT('INSERT IGNORE INTO `',targetSet,'` (id) SELECT id FROM `',sourceSet,'` WHERE EXISTS (SELECT 1 FROM `')),
-            keepTabl,
-            '` AS data WHERE data.id=`', sourceSet, '`.`id` LIMIT 1)'
-        );
+    IF versioned AND sourceSet = "entities" THEN
+        call createVersionedTmpTable(keepTabl);
+
+        #-- generate statement from statement parts
+        SET @stmtPOVkeepTblStr = CONCAT("INSERT IGNORE INTO `", keepTabl, "` (id, _iversion) SELECT entity_id AS id, _iversion FROM ", data, " as data", IF(propertiesTable IS NULL, '', CONCAT(' WHERE EXISTS (Select 1 from `', propertiesTable, '` AS prop WHERE prop.id = data.property_id AND (prop.id2=data.entity_id OR prop.id2=0))')));
 
+        SET @stmtPOVStr = CONCAT(
+                CONCAT('INSERT IGNORE INTO `',
+                    targetSet,
+                    '` (id, _iversion) SELECT source.id, source._iversion FROM `',
+                    keepTabl,
+                    '` AS source'));
 
-    #-- prepare and execute
-    PREPARE stmt3 FROM @stmtPOVStr;
-    PREPARE stmtPOVkeepTbl FROM @stmtPOVkeepTblStr;
-    IF vText IS NULL THEN
-        EXECUTE stmtPOVkeepTbl;
+        #-- prepare and execute
+        PREPARE stmt3 FROM @stmtPOVStr;
+        PREPARE stmtPOVkeepTbl FROM @stmtPOVkeepTblStr;
+        IF vText IS NULL THEN
+            EXECUTE stmtPOVkeepTbl;
+        ELSE
+            SET @vText = vText;
+            EXECUTE stmtPOVkeepTbl USING @vText, @vText, @vText, @vText;
+        END IF;
+        EXECUTE stmt3;
+        DEALLOCATE PREPARE stmt3;
+        DEALLOCATE PREPARE stmtPOVkeepTbl;
     ELSE
-        SET @vText = vText;
-        EXECUTE stmtPOVkeepTbl USING @vText, @vText, @vText;
+        call createTmpTable(keepTabl);
+
+        #-- generate statement from statement parts
+        SET @stmtPOVkeepTblStr = CONCAT("INSERT IGNORE INTO `", keepTabl, "` (id) SELECT DISTINCT entity_id AS id FROM ", data, " as data", IF(propertiesTable IS NULL, '', CONCAT(' WHERE EXISTS (Select 1 from `', propertiesTable, '` AS prop WHERE prop.id = data.property_id AND (prop.id2=data.entity_id OR prop.id2=0))')));
+
+        SET @stmtPOVStr = CONCAT(
+                IF(targetSet IS NULL,
+                    CONCAT('DELETE FROM `',
+                        sourceSet,
+                        '` WHERE NOT EXISTS (SELECT 1 FROM `'),
+                    CONCAT('INSERT IGNORE INTO `',
+                        targetSet,
+                        '` (id) SELECT id FROM `',
+                        sourceSet,
+                        '` WHERE EXISTS (SELECT 1 FROM `')),
+                keepTabl,
+                '` AS data WHERE data.id=`',
+                sourceSet,
+                '`.`id` LIMIT 1)'
+            );
+
+        #-- prepare and execute
+        PREPARE stmt3 FROM @stmtPOVStr;
+        PREPARE stmtPOVkeepTbl FROM @stmtPOVkeepTblStr;
+        IF vText IS NULL THEN
+            EXECUTE stmtPOVkeepTbl;
+        ELSE
+            SET @vText = vText;
+            EXECUTE stmtPOVkeepTbl USING @vText, @vText, @vText;
+        END IF;
+        EXECUTE stmt3;
+        DEALLOCATE PREPARE stmt3;
+        DEALLOCATE PREPARE stmtPOVkeepTbl;
     END IF;
-    EXECUTE stmt3;
-    DEALLOCATE PREPARE stmt3;
-    DEALLOCATE PREPARE stmtPOVkeepTbl;
 
     /* Question: why select AS and not select INTO? */
 
diff --git a/procedures/query/applyRefPOV.sql b/procedures/query/applyRefPOV.sql
index 0771d3d02051ac1388cf0792bdc680b9b9f9f1bd..1770d928c868c7125f04638b0f69b9c0314c6251 100644
--- a/procedures/query/applyRefPOV.sql
+++ b/procedures/query/applyRefPOV.sql
@@ -23,14 +23,18 @@
 DROP PROCEDURE IF EXISTS db_2_0.applyRefPOV;
 DELIMITER //
 
-CREATE PROCEDURE db_2_0.applyRefPOV(in sourceSet VARCHAR(255), in targetSet VARCHAR(255), in properties VARCHAR(255), in refs VARCHAR(255))
+CREATE PROCEDURE db_2_0.applyRefPOV(in sourceSet VARCHAR(255), in targetSet VARCHAR(255), in properties VARCHAR(255), in refs VARCHAR(255), in versioned BOOLEAN)
 BEGIN
     DECLARE data VARCHAR(20000) DEFAULT CONCAT('(SELECT domain_id, entity_id, property_id FROM `reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refs, '` AS refs WHERE subdata.value=refs.id LIMIT 1))');
-    SET @stmtRefPOVStr = makeStmt(sourceSet,targetSet,data,properties);
+
+    IF versioned THEN
+        SET data = CONCAT('(SELECT domain_id, entity_id, _get_head_iversion(entity_id) AS _iversion, property_id FROM `reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refs, '` AS refs WHERE subdata.value=refs.id LIMIT 1) UNION ALL SELECT domain_id, entity_id, _iversion, property_id FROM `archive_reference_data` AS subdata WHERE EXISTS (SELECT 1 FROM `', refs, '` AS refs WHERE subdata.value=refs.id LIMIT 1))');
+    END IF;
+    SET @stmtRefPOVStr = makeStmt(sourceSet,targetSet,data,properties, versioned);
 
     PREPARE stmt4 FROM @stmtRefPOVStr;
     EXECUTE stmt4;
-		
+
     SELECT @stmtRefPOVstr as applyRefPOVStmt;
 
 END;
diff --git a/procedures/query/cleanUpQuery.sql b/procedures/query/cleanUpQuery.sql
index 7de562e8c1c210d91a6613319cb8254d780e4c83..cdb143f442998634d3eae21bfc36264e3bf4f71a 100644
--- a/procedures/query/cleanUpQuery.sql
+++ b/procedures/query/cleanUpQuery.sql
@@ -29,13 +29,15 @@ DELIMITER //
 
 CREATE PROCEDURE db_2_0.cleanUpQuery()
 BEGIN
-   SELECT * from warnings;
+    CREATE TEMPORARY TABLE IF NOT EXISTS warnings (warning TEXT NOT NULL);
+    SELECT * from warnings;
 
-   SET @pstmtstr = CONCAT('DROP TEMPORARY TABLE IF EXISTS `warnings`', IF(@tempTableList IS NULL, '', CONCAT(',',@tempTableList)));
-   PREPARE pstmt FROM @pstmtstr;
-   EXECUTE pstmt;
+    SET @pstmtstr = CONCAT('DROP TEMPORARY TABLE IF EXISTS `warnings`',
+        IF(@tempTableList IS NULL, '', CONCAT(',',@tempTableList)));
+    PREPARE pstmt FROM @pstmtstr;
+    EXECUTE pstmt;
 
-   SET @tempTableList = NULL;
+    SET @tempTableList = NULL;
 END;
 //
 DELIMITER ;
diff --git a/procedures/query/createTmpTable.sql b/procedures/query/createTmpTable.sql
index 180f9bab2bc27b2ada5324598dc136034ba485ab..a14f07c9c0b6c5568b0dfebfe12a90576b257b78 100644
--- a/procedures/query/createTmpTable.sql
+++ b/procedures/query/createTmpTable.sql
@@ -35,12 +35,15 @@ DELIMITER ;
 DROP PROCEDURE IF EXISTS db_2_0.createTmpTable;
 DELIMITER //
 
+/**
+ * Creates a temporary table for query results with only a single ID column.
+ */
 CREATE PROCEDURE db_2_0.createTmpTable(out newTableName VARCHAR(255))
 BEGIN
     call registerTempTableName(newTableName);
-    
+
     SET @createTableStmtStr = CONCAT('CREATE TEMPORARY TABLE `', newTableName,'` ( id INT UNSIGNED PRIMARY KEY)' );
-    
+
     PREPARE createTableStmt FROM @createTableStmtStr; 
     EXECUTE createTableStmt;
     DEALLOCATE PREPARE createTableStmt;
@@ -51,14 +54,42 @@ DELIMITER ;
 
 
 
+/**
+ * Creates a temporary table for intermediate query results with three columns
+ *     id - for entity ids (e.g. property ids or reference values)
+ *     id2 - for entity ids (usually those entities which have the other id as property or value)
+ *     domain - for domain ids
+ */
 DROP PROCEDURE IF EXISTS db_2_0.createTmpTable2;
 DELIMITER //
 
 CREATE PROCEDURE db_2_0.createTmpTable2(out newTableName VARCHAR(255))
 BEGIN
     call registerTempTableName(newTableName);
-	SET @createTableStmtStr = CONCAT('CREATE TEMPORARY TABLE `', newTableName,'` ( id INT UNSIGNED, id2 INT UNSIGNED, domain INT UNSIGNED, CONSTRAINT `', newTableName,'PK` PRIMARY KEY (id,id2,domain) )' );
-    
+    SET @createTableStmtStr = CONCAT('CREATE TEMPORARY TABLE `', newTableName,'` ( id INT UNSIGNED, id2 INT UNSIGNED, domain INT UNSIGNED, CONSTRAINT `', newTableName,'PK` PRIMARY KEY (id,id2,domain) )' );
+
+    PREPARE createTableStmt FROM @createTableStmtStr; 
+    EXECUTE createTableStmt;
+    DEALLOCATE PREPARE createTableStmt;
+END;
+//
+
+DELIMITER ;
+
+
+DROP PROCEDURE IF EXISTS db_2_0.createVersionedTmpTable;
+DELIMITER //
+
+/**
+ * Creates a temporary table for query results with an id column and an
+ * _iversion column.
+ */
+CREATE PROCEDURE db_2_0.createVersionedTmpTable(out newTableName VARCHAR(255))
+BEGIN
+    call registerTempTableName(newTableName);
+
+    SET @createTableStmtStr = CONCAT('CREATE TEMPORARY TABLE `', newTableName,'` ( id INT UNSIGNED, _iversion INT UNSIGNED, PRIMARY KEY (id, _iversion))' );
+
     PREPARE createTableStmt FROM @createTableStmtStr; 
     EXECUTE createTableStmt;
     DEALLOCATE PREPARE createTableStmt;
@@ -66,3 +97,4 @@ END;
 //
 
 DELIMITER ;
+
diff --git a/procedures/query/getChildren.sql b/procedures/query/getChildren.sql
index 1a61995ebd76105bb07a93ab96247f8463de1b96..1c5bdd0eaa448370a104eef207944eb1d0c79551 100644
--- a/procedures/query/getChildren.sql
+++ b/procedures/query/getChildren.sql
@@ -23,28 +23,59 @@
 
 Drop Procedure if exists db_2_0.getChildren;
 Delimiter //
-Create Procedure db_2_0.getChildren(in tableName varchar(255))
+Create Procedure db_2_0.getChildren(in tableName varchar(255), in versioned BOOLEAN)
 
 BEGIN
+    DECLARE found_children INT UNSIGNED DEFAULT 0;
 
-    CREATE TEMPORARY TABLE dependTemp (id INT UNSIGNED PRIMARY KEY);
+    DROP TEMPORARY TABLE IF EXISTS dependTemp;
+    CREATE TEMPORARY TABLE dependTemp (id INT UNSIGNED, _iversion INT UNSIGNED, PRIMARY KEY(id, _iversion));
 
 
-
-    SET @initDepend = CONCAT('INSERT IGNORE INTO dependTemp (id) SELECT i.child FROM isa_cache AS i INNER JOIN `', tableName, '` AS t ON (i.parent=t.id);');
+    SET @initDepend = CONCAT(
+        'INSERT IGNORE INTO dependTemp (id, _iversion) SELECT i.child, ',
+        IF(versioned,
+            '_get_head_iversion(i.child)',
+            '0'),
+        ' FROM isa_cache AS i INNER JOIN `',
+        tableName,
+        '` AS t ON (i.parent=t.id);');
     PREPARE initDependStmt FROM @initDepend;
 
-	EXECUTE initDependStmt;
-	IF ROW_COUNT() != 0 THEN
-    	SET @transfer = CONCAT('INSERT IGNORE INTO `', tableName, '` (id) SELECT id FROM dependTemp');
+    EXECUTE initDependStmt;
+    SET found_children = found_children + ROW_COUNT();
+
+    -- ################# VERSIONING #####################
+
+    IF versioned IS TRUE THEN
+        SET @initDepend = CONCAT(
+            'INSERT IGNORE INTO dependTemp (id, _iversion) ',
+            'SELECT i.child, i.child_iversion FROM archive_isa AS i INNER JOIN `',
+            tableName,
+            '` AS t ON (i.parent=t.id);');
+        PREPARE initDependStmt FROM @initDepend;
+
+        EXECUTE initDependStmt;
+        SET found_children = found_children + ROW_COUNT();
+    END IF;
+
+    -- ##################################################
+
+
+    IF found_children != 0 THEN
+        SET @transfer = CONCAT(
+            'INSERT IGNORE INTO `',
+            tableName,
+            IF(versioned,
+                '` (id, _iversion) SELECT id, _iversion FROM dependTemp',
+                '` (id) SELECT id FROM dependTemp'));
         PREPARE transferstmt FROM @transfer;
-		EXECUTE transferstmt;
-		DEALLOCATE PREPARE transferstmt;
-	END IF;
+        EXECUTE transferstmt;
+        DEALLOCATE PREPARE transferstmt;
+    END IF;
 
 
-	DEALLOCATE PREPARE initDependStmt;
-	DROP TEMPORARY TABLE dependTemp;
+    DEALLOCATE PREPARE initDependStmt;
 
 END;
 //
diff --git a/procedures/query/initEntity.sql b/procedures/query/initEntity.sql
index f8877303a6d47a3cbf620b45c2fd8484caa1804b..8dfe5fd61a476041c803b90de8374bcfc7b31660 100644
--- a/procedures/query/initEntity.sql
+++ b/procedures/query/initEntity.sql
@@ -24,29 +24,36 @@
 DROP PROCEDURE IF EXISTS db_2_0.initEntity;
 DELIMITER //
 
-CREATE PROCEDURE db_2_0.initEntity(in eid INT UNSIGNED, in ename VARCHAR(255), in enameLike VARCHAR(255), in enameRegexp VARCHAR(255), in resultset VARCHAR(255))
+CREATE PROCEDURE db_2_0.initEntity(in eid INT UNSIGNED, in ename VARCHAR(255), in enameLike VARCHAR(255), in enameRegexp VARCHAR(255), in resultset VARCHAR(255), in versioned BOOLEAN)
 initEntityLabel: BEGIN
+    DECLARE select_columns VARCHAR(255) DEFAULT "` (id) SELECT entity_id FROM name_data ";
     SET @initEntityStmtStr = NULL;
 
     -- Prepare a statement which resolves the name or pattern to ids. The ids
     -- are collected in a temporary table (resultset).
+    IF versioned IS TRUE THEN
+        SET select_columns = "` (id, _iversion) SELECT entity_id, _get_head_iversion(entity_id) FROM name_data ";
+    END IF;
     IF ename IS NOT NULL THEN
         SET @initEntityStmtStr = CONCAT(
             'INSERT IGNORE INTO `',
             resultset,
-            '` (id) SELECT entity_id FROM name_data WHERE value=?; ');
+            select_columns,
+            'WHERE value=?; ');
         SET @query_param = ename;
     ELSEIF enameLike IS NOT NULL THEN
         SET @initEntityStmtStr = CONCAT(
             'INSERT IGNORE INTO `',
             resultset,
-            '` (id) SELECT entity_id FROM name_data WHERE value LIKE ?;');
+            select_columns,
+            'WHERE value LIKE ?;');
         SET @query_param = enameLike;
     ELSEIF enameRegexp IS NOT NULL THEN 
         SET @initEntityStmtStr = CONCAT(
             'INSERT IGNORE INTO `',
             resultset,
-            '` (id) SELECT entity_id FROM name_data WHERE value REGEXP ?;');
+            select_columns,
+            'WHERE value REGEXP ?;');
         SET @query_param = enameRegexp;
     END IF;
 
@@ -58,15 +65,57 @@ initEntityLabel: BEGIN
     END IF;
 
     IF eid IS NOT NULL THEN
-        SET @initEntityStmtStr = CONCAT('INSERT IGNORE INTO `',resultset,'` (id) SELECT id FROM entities WHERE id=',eid,';');
+        -- add an explicitely given id to the resultset (if it exists)
+        SET @initEntityStmtStr = CONCAT(
+            'INSERT IGNORE INTO `',
+            resultset,
+            IF(versioned,
+                '` (id, _iversion) SELECT id, _get_head_iversion(id) ',
+                '` (id) SELECT id '),
+            'FROM entities WHERE id=',eid,';');
         PREPARE initEntityStmt FROM @initEntityStmtStr;
         EXECUTE initEntityStmt;
         DEALLOCATE PREPARE initEntityStmt;
     END IF;
 
 
+    -- ################# VERSIONING #####################
+    IF versioned IS TRUE THEN
+        SET select_columns = "` (id, _iversion) SELECT entity_id, _iversion FROM archive_name_data ";
+        IF ename IS NOT NULL THEN
+            SET @initEntityStmtStr = CONCAT(
+                'INSERT IGNORE INTO `',
+                resultset,
+                select_columns,
+                'WHERE value=?; ');
+            SET @query_param = ename;
+        ELSEIF enameLike IS NOT NULL THEN
+            SET @initEntityStmtStr = CONCAT(
+                'INSERT IGNORE INTO `',
+                resultset,
+                select_columns,
+                'WHERE value LIKE ?;');
+            SET @query_param = enameLike;
+        ELSEIF enameRegexp IS NOT NULL THEN 
+            SET @initEntityStmtStr = CONCAT(
+                'INSERT IGNORE INTO `',
+                resultset,
+                'WHERE value REGEXP ?;');
+            SET @query_param = enameRegexp;
+        END IF;
+
+        -- execute the statement
+        IF @initEntityStmtStr IS NOT NULL THEN
+            PREPARE initEntityStmt FROM @initEntityStmtStr;
+            EXECUTE initEntityStmt USING @query_param;
+            DEALLOCATE PREPARE initEntityStmt;
+        END IF;
+    END IF;
+    -- ##################################################
+
+
     IF @initEntityStmtStr IS NOT NULL THEN
-        call getChildren(resultset);
+        call getChildren(resultset, versioned);
     END IF;
 
 END;
diff --git a/procedures/query/initPOV.sql b/procedures/query/initPOV.sql
index d1fa16300e4ef36902fd702739e389d336f1b3f5..27a063a7c3159b5f4530610b8c740f4fb65ec76f 100644
--- a/procedures/query/initPOV.sql
+++ b/procedures/query/initPOV.sql
@@ -29,7 +29,7 @@ CREATE PROCEDURE db_2_0.initPOVPropertiesTable(in pid INT UNSIGNED, in pname VAR
 BEGIN
     DECLARE propertiesTable VARCHAR(255) DEFAULT NULL; /*table for property ids*/
     DECLARE replTbl VARCHAR(255) DEFAULT NULL;
-   	DECLARE ecount INT DEFAULT 0;
+    DECLARE ecount INT DEFAULT 0;
     DECLARE t1 BIGINT DEFAULT 0;
     DECLARE t2 BIGINT DEFAULT 0;
     DECLARE t3 BIGINT DEFAULT 0;
@@ -62,9 +62,10 @@ BEGIN
         -- expand with all children
         SELECT conv( concat( substring(uid,16,3), substring(uid,10,4), substring(uid,1,8)),16,10) div 10000 - (141427 * 24 * 60 * 60 * 1000) as current_mills INTO t3 from (select uuid() uid) as alias;
         IF ecount > 0 THEN
-            call getChildren(propertiesTable);
+            -- TODO versioning
+            call getChildren(propertiesTable, False);
         END IF;
-        
+
         -- expand with all replacements
         SELECT conv( concat( substring(uid,16,3), substring(uid,10,4), substring(uid,1,8)),16,10) div 10000 - (141427 * 24 * 60 * 60 * 1000) as current_mills INTO t4 from (select uuid() uid) as alias;
         IF ecount > 0 THEN
@@ -93,7 +94,7 @@ DROP PROCEDURE IF EXISTS db_2_0.initPOVRefidsTable //
 CREATE PROCEDURE db_2_0.initPOVRefidsTable(in vInt INT UNSIGNED, in vText VARCHAR(255))
 BEGIN
     DECLARE refIdsTable VARCHAR(255) DEFAULT NULL; /*table for referenced entity ids*/
-	
+
     #-- for reference properties: the value is interpreted as a record type name.
     IF vText IS NOT NULL THEN
         call createTmpTable(refIdsTable);
diff --git a/procedures/query/initQuery.sql b/procedures/query/initQuery.sql
index b233972d2ca7bb72aab768ef5be300273f5ec382..95bdec12cc29b24e00583daa09736eb47c66d2d0 100644
--- a/procedures/query/initQuery.sql
+++ b/procedures/query/initQuery.sql
@@ -35,8 +35,22 @@ DELIMITER //
 CREATE PROCEDURE db_2_0.initQuery()
 BEGIN
     CREATE TEMPORARY TABLE IF NOT EXISTS warnings (warning TEXT NOT NULL);
-	
-	call createTmpTable(@resultSet);
+
+    call createTmpTable(@resultSet);
+    SELECT @resultSet as tablename;
+
+END;
+//
+DELIMITER ;
+
+DROP PROCEDURE IF EXISTS db_2_0.initVersionedQuery;
+DELIMITER //
+
+CREATE PROCEDURE db_2_0.initVersionedQuery()
+BEGIN
+    CREATE TEMPORARY TABLE IF NOT EXISTS warnings (warning TEXT NOT NULL);
+
+    call createVersionedTmpTable(@resultSet);
     SELECT @resultSet as tablename;
 
 END;
diff --git a/procedures/query/initSubEntity.sql b/procedures/query/initSubEntity.sql
index 543a0ce0f4745561ad0fa489da580d5e30fc3267..3cb31aa2c9d7e8fcc4bf8de26bc726862044e1fc 100644
--- a/procedures/query/initSubEntity.sql
+++ b/procedures/query/initSubEntity.sql
@@ -56,7 +56,8 @@ BEGIN
     END IF;
 
     IF ecount > 0 THEN
-        call getChildren(tableName);
+        -- TODO versioning
+        call getChildren(tableName, False);
     END IF;
 
 END;
diff --git a/procedures/query/makeStmt.sql b/procedures/query/makeStmt.sql
index 7ef80bfb9db6a0026642f6cc64eeaf560b9fbfe8..f30549a89033c7c5485d2278ad31d9f8b2fcba05 100644
--- a/procedures/query/makeStmt.sql
+++ b/procedures/query/makeStmt.sql
@@ -23,9 +23,17 @@
 DROP FUNCTION IF EXISTS db_2_0.makeStmt;
 DELIMITER //
 
-CREATE FUNCTION db_2_0.makeStmt(sourceSet VARCHAR(255), targetSet VARCHAR(255), data VARCHAR(20000), properties VARCHAR(20000)) RETURNS VARCHAR(20000) NO SQL
-BEGIN		
+CREATE FUNCTION db_2_0.makeStmt(sourceSet VARCHAR(255), targetSet VARCHAR(255), data VARCHAR(20000), properties VARCHAR(20000), versioned BOOLEAN) RETURNS VARCHAR(20000) NO SQL
+BEGIN
 
+        IF sourceSet = "entities" AND versioned THEN
+            RETURN CONCAT('INSERT IGNORE INTO `',
+                targetSet,
+                '` (id, _iversion) SELECT entity_id, _iversion FROM ',
+                data,
+                IF(properties IS NULL, '',
+                    CONCAT(' AS data JOIN `', properties, '` AS prop ON (data.property_id = prop.id) WHERE data.entity_id = prop.id2 OR prop.id2 = 0')));
+        END IF;
         RETURN CONCAT(
             IF(targetSet IS NULL,
                 CONCAT('DELETE FROM `',sourceSet,'` WHERE NOT EXISTS (SELECT 1 FROM '),