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);
                    }
                }
            }
        }