protected void InitSuperClassSchema(DataSchema schema)
        {
            var superClass = new Class(OwlConfig.SuperClassID)
            {
                CompactID      = OwlConfig.SuperClassCompactID,
                Name           = OwlConfig.SuperClassID,
                ObjectLocation = ObjectLocationType.ObjectTable
            };

            schema.AddClass(superClass);

            var superIdProp = new Property(OwlConfig.SuperIdPropertyID)
            {
                CompactID = OwlConfig.SuperIdPropertyCompactID,
                Name      = OwlConfig.SuperIdPropertyID,
                DataType  = PropertyDataType.String
            };

            schema.AddProperty(superIdProp);

            schema.AddClassProperty(new ClassPropertyLocation(superClass, superIdProp));
        }
        protected void InitMetaSchema(DataSchema schema, IEnumerable <ObjectContainer> metaClassObjects)
        {
            var metaClasses = new List <Class>();

            foreach (var metaClassObj in metaClassObjects)
            {
                var id = metaClassObj[OwlConfig.SuperIdPropertyID] as string;
                if (id != null)
                {
                    var c = new Class(id)
                    {
                        CompactID = metaClassObj.ID.Value,
                        Name      = id
                    };
                    schema.AddClass(c);
                    metaClasses.Add(c);
                }
            }

            foreach (var c in metaClasses)
            {
                schema.AddClassProperty(new ClassPropertyLocation(c, schema.FindPropertyByID(OwlConfig.SuperIdPropertyID)));
            }

            var superClass        = schema.FindClassByID(OwlConfig.SuperClassID);
            var domainClass       = FindAndAssertMetaClass(schema, OwlConfig.DomainClassID);
            var rangeClass        = FindAndAssertMetaClass(schema, OwlConfig.RangeClassID);
            var objClass          = FindAndAssertMetaClass(schema, OwlConfig.ObjectClassID);
            var objPropClass      = FindAndAssertMetaClass(schema, OwlConfig.ObjectPropertyClassID);
            var datatypePropClass = FindAndAssertMetaClass(schema, OwlConfig.DatatypePropertyClassID);
            var datatypeClass     = FindAndAssertMetaClass(schema, OwlConfig.DatatypeClassID);
            var labelClass        = FindAndAssertMetaClass(schema, OwlConfig.LabelClassID);
            var rdfTypeClass      = FindAndAssertMetaClass(schema, OwlConfig.RdfTypeClassID);
            var funcPropClass     = FindAndAssertMetaClass(schema, OwlConfig.FunctionalPropertyClassID);
            var invFuncPropClass  = FindAndAssertMetaClass(schema, OwlConfig.InverseFunctionalPropertyClassID);
            var pkPropClass       = FindAndAssertMetaClass(schema, OwlConfig.PkPropertyID);

            // object property relations
            var objPropDomainRelRev = new Relationship(objClass, domainClass, objPropClass, true, true, null);

            schema.AddRelationship(new Relationship(objPropClass, domainClass, objClass, true, false, objPropDomainRelRev));

            var objPropRangeRelRev = new Relationship(objClass, rangeClass, objPropClass, true, true, null);

            schema.AddRelationship(new Relationship(objPropClass, rangeClass, objClass, true, false, objPropRangeRelRev));

            // for superclass (TBD: subclass-of should resolve these duplicate relationships)
            var objPropDomainForSuperRelRev = new Relationship(superClass, domainClass, objPropClass, true, true, null);

            schema.AddRelationship(new Relationship(objPropClass, domainClass, superClass, true, false, objPropDomainForSuperRelRev));
            var objPropRangeForSuperRelRev = new Relationship(superClass, rangeClass, objPropClass, true, true, null);

            schema.AddRelationship(new Relationship(objPropClass, rangeClass, superClass, true, false, objPropRangeForSuperRelRev));

            var objPropTypeRelRev = new Relationship(superClass, rdfTypeClass, objPropClass, true, true, null);

            schema.AddRelationship(new Relationship(objPropClass, rdfTypeClass, superClass, true, false, objPropTypeRelRev));

            // datatype properties relations
            var dtPropDomainRelRev = new Relationship(objClass, domainClass, datatypePropClass, true, true, null);

            schema.AddRelationship(new Relationship(datatypePropClass, domainClass, objClass, true, false, dtPropDomainRelRev));

            var dtPropRangeRelRev = new Relationship(objClass, rangeClass, datatypePropClass, true, true, null);

            schema.AddRelationship(new Relationship(datatypePropClass, rangeClass, datatypeClass, false, false, dtPropRangeRelRev));

            var dtPropTypeRelRev = new Relationship(superClass, rdfTypeClass, datatypePropClass, true, true, null);

            schema.AddRelationship(new Relationship(datatypePropClass, rdfTypeClass, superClass, true, false, dtPropTypeRelRev));

            var labelProp = new Property(labelClass.ID)
            {
                CompactID = labelClass.CompactID,
                Name      = labelClass.ID,
                DataType  = PropertyDataType.String
            };

            schema.AddProperty(labelProp);
            schema.AddClassProperty(new ClassPropertyLocation(objClass, labelProp));
            schema.AddClassProperty(new ClassPropertyLocation(datatypePropClass, labelProp));
            schema.AddClassProperty(new ClassPropertyLocation(objPropClass, labelProp));

            var pkProp = new Property(pkPropClass.ID)
            {
                CompactID  = pkPropClass.CompactID,
                Name       = pkPropClass.ID,
                DataType   = PropertyDataType.Integer,
                PrimaryKey = true
            };

            schema.AddProperty(pkProp);
            schema.AddClassProperty(new ClassPropertyLocation(datatypeClass, pkProp, ObjectPkColumn));
        }
        protected void InitDataSchema(DataSchema schema)
        {
            var objectClassIds       = ObjectStorage.GetObjectIds(new Query(OwlConfig.ObjectClassID));
            var datatypePropClassIds = ObjectStorage.GetObjectIds(new Query(OwlConfig.DatatypePropertyClassID));
            var objPropClassIds      = ObjectStorage.GetObjectIds(new Query(OwlConfig.ObjectPropertyClassID));
            var datatypeIds          = ObjectStorage.GetObjectIds(new Query(OwlConfig.DatatypeClassID));

            var allIds = new List <long>();

            allIds.AddRange(objectClassIds);
            allIds.AddRange(datatypePropClassIds);
            allIds.AddRange(objPropClassIds);
            allIds.AddRange(datatypeIds);

            var idToObj = ObjectStorage.Load(allIds.ToArray());

            foreach (var metaClassObj in objectClassIds.Select(o => idToObj[o]))
            {
                var id = metaClassObj[OwlConfig.SuperIdPropertyID] as string;
                if (id != null)
                {
                    var name = (metaClassObj[OwlConfig.LabelClassID] as string) ?? id;
                    var c    = new Class(id)
                    {
                        CompactID = metaClassObj.ID.Value,
                        Name      = name
                    };
                    schema.AddClass(c);
                    schema.AddClassProperty(new ClassPropertyLocation(c, schema.FindPropertyByID(OwlConfig.PkPropertyID), ObjectPkColumn));
                }
            }

            var allDatatypePropObjects = datatypePropClassIds.Select(o => idToObj[o]).ToArray();

            foreach (var metaPropObj in allDatatypePropObjects)
            {
                var id = metaPropObj[OwlConfig.SuperIdPropertyID] as string;
                if (id != null)
                {
                    var name = (metaPropObj[OwlConfig.LabelClassID] as string) ?? id;
                    schema.AddProperty(new Property(id)
                    {
                        CompactID  = metaPropObj.ID.Value,
                        Name       = name,
                        Multivalue = true,                         // by default all props are multivalue in OWL
                        PrimaryKey = id == OwlConfig.PkPropertyID,
                        DataType   = PropertyDataType.String       // default type used for properties without explicit range definition
                    });
                }
            }

            var allObjPropObjects = objPropClassIds.Select(o => idToObj[o]).ToArray();

            foreach (var obj in allObjPropObjects)
            {
                var id = obj[OwlConfig.SuperIdPropertyID] as string;
                if (id != null)
                {
                    var name = (obj[OwlConfig.LabelClassID] as string) ?? id;
                    var c    = new Class(id)
                    {
                        CompactID   = obj.ID.Value,
                        Name        = name,
                        IsPredicate = true
                    };
                    schema.AddClass(c);
                }
            }

            var superClass        = schema.FindClassByID(OwlConfig.SuperClassID);
            var datatypePropClass = schema.FindClassByID(OwlConfig.DatatypePropertyClassID);
            var datatypeClass     = schema.FindClassByID(OwlConfig.DatatypeClassID);
            var domainClass       = schema.FindClassByID(OwlConfig.DomainClassID);
            var rangeClass        = schema.FindClassByID(OwlConfig.RangeClassID);
            var objClass          = schema.FindClassByID(OwlConfig.ObjectClassID);
            var rdfTypeClass      = schema.FindClassByID(OwlConfig.RdfTypeClassID);
            var funcPropClass     = schema.FindClassByID(OwlConfig.FunctionalPropertyClassID);
            var invFuncPropClass  = schema.FindClassByID(OwlConfig.InverseFunctionalPropertyClassID);

            // resolve datatype properties
            var dataTypePropRels = ObjectStorage.LoadRelations(allDatatypePropObjects,
                                                               new [] {
                datatypePropClass.FindRelationship(rangeClass, datatypeClass),
                datatypePropClass.FindRelationship(domainClass, objClass),
                datatypePropClass.FindRelationship(rdfTypeClass, superClass)
            });
            var dataTypeMap = BuildDataTypeMap(datatypeIds, idToObj);

            foreach (var rangeRel in dataTypePropRels.Where(r => r.Relation.Predicate == rangeClass))
            {
                var p = schema.FindPropertyByCompactID(rangeRel.SubjectID);
                if (dataTypeMap.ContainsKey(rangeRel.ObjectID))
                {
                    p.DataType = dataTypeMap[rangeRel.ObjectID];
                }
            }

            foreach (var funcPropRel in dataTypePropRels.Where(r => r.Relation.Predicate == rdfTypeClass && r.ObjectID == funcPropClass.CompactID))
            {
                var p = schema.FindPropertyByCompactID(funcPropRel.SubjectID);
                p.Multivalue = false;
            }

            foreach (var domainRel in dataTypePropRels.Where(r => r.Relation.Predicate == domainClass))
            {
                var p = schema.FindPropertyByCompactID(domainRel.SubjectID);
                var c = schema.FindClassByCompactID(domainRel.ObjectID);
                if (c != null && p != null)
                {
                    AddClassProperty(schema, new ClassPropertyLocation(c, p));
                }
            }

            // resolve object properties into relationships
            var objPropClass     = schema.FindClassByID(OwlConfig.ObjectPropertyClassID);
            var objPropRangeRel  = objPropClass.FindRelationship(rangeClass, objClass);
            var objPropDomainRel = objPropClass.FindRelationship(domainClass, objClass);

            var objPropRels = ObjectStorage.LoadRelations(allObjPropObjects,
                                                          new [] {
                objPropClass.FindRelationship(domainClass, objClass),
                objPropClass.FindRelationship(rangeClass, objClass),
                objPropClass.FindRelationship(rdfTypeClass, superClass),
                // TBD: subclass-of to avoid these duplicate relationships
                objPropClass.FindRelationship(domainClass, superClass),
                objPropClass.FindRelationship(rangeClass, superClass)
            });

            foreach (var predicateClass in schema.Classes.Where(c => c.IsPredicate))
            {
                var predRels = objPropRels.Where(r => r.SubjectID == predicateClass.CompactID).ToArray();
                foreach (var domainRel in predRels.Where(r => r.Relation.Predicate == domainClass))
                {
                    foreach (var rangeRel in predRels.Where(r => r.Relation.Predicate == rangeClass))
                    {
                        var rSubjClass = schema.FindClassByCompactID(domainRel.ObjectID);
                        var rObjClass  = schema.FindClassByCompactID(rangeRel.ObjectID);

                        var subjectMultiplicity = !predRels.Any(r => r.Relation.Predicate == rdfTypeClass && r.ObjectID == invFuncPropClass.CompactID);
                        var objectMultiplicity  = !predRels.Any(r => r.Relation.Predicate == rdfTypeClass && r.ObjectID == funcPropClass.CompactID);
                        var revRelationship     = new Relationship(rObjClass, predicateClass, rSubjClass, subjectMultiplicity, true, null);
                        schema.AddRelationship(new Relationship(rSubjClass, predicateClass, rObjClass, objectMultiplicity, false, revRelationship));
                        schema.AddRelationship(revRelationship);
                    }
                }
            }
        }