/// <summary>
        /// Loads the fact instances from the given graph into the given ontology
        /// </summary>
        internal static void LoadFacts(RDFGraph ontGraph, RDFOntology ontology, RDFGraph rdfType) {

            #region Facts
            foreach (var c in ontology.Model.ClassModel) {
                foreach (var t in rdfType.SelectTriplesByObject((RDFResource)c.Value)) {                    
                    var fct  = ontology.Data.SelectFact(t.Subject.ToString());
                    if (fct == null) {
                        fct  = new RDFOntologyFact((RDFResource)t.Subject);                        
                        ontology.Data.AddFact(fct); 
                    }
                    fct.AddClassType(c);
                }
            }
            #endregion

            #region Attributes
            foreach (var attrProp  in ontology.Model.PropertyModel) {
                if (!attrProp.IsAnnotationProperty()) {
                    foreach (var t in ontGraph.SelectTriplesByPredicate((RDFResource)attrProp.Value)) {

                        //Do not parse attributes of the ontology
                        if (!t.Subject.Equals(ontology.Value)) {

                            var subjFct        = ontology.Data.SelectFact(t.Subject.ToString());
                            if (subjFct       != null) {
                                var objFct     = ontology.Data.SelectFact(t.Object.ToString());
                                if (objFct    != null) {
                                    subjFct.AddOntologyAttribute(attrProp, objFct);
                                }
                                else {
                                    if (t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO) {
                                        throw new RDFSemanticsException("Cannot load attributes of fact '" + t.Subject + "' from graph, because it has a range object fact '" + t.Object + "' which has not been found in the ontology data.");
                                    }
                                    else {
                                        //Literal fact must be created on the fly, since they do not exist in ontology data
                                        objFct = new RDFOntologyFact((RDFLiteral)t.Object);
                                        ontology.Data.AddFact(objFct);
                                        subjFct.AddOntologyAttribute(attrProp, objFct);
                                    }
                                }
                            }
                            else {
                                throw new RDFSemanticsException("Cannot load attributes of fact '" + t.Subject + "' from graph, because it has not been found in the ontology data.");
                            }

                        }

                    }
                }
            }
            #endregion

            #region SameAs
            foreach (var t     in ontGraph.SelectTriplesByPredicate(RDFVocabulary.OWL.SAME_AS)) {
                var subjFct     = ontology.Data.SelectFact(t.Subject.ToString());
                if (subjFct    != null) {
                    var objFct  = ontology.Data.SelectFact(t.Object.ToString());
                    if (objFct != null) {
                        subjFct.AddSameAs(objFct);
                    }
                    else {
                        throw new RDFSemanticsException("Cannot load taxonomy of fact '" + t.Subject + "' from graph, because its equivalent fact '" + t.Object + "' has not been found in the ontology data.");
                    }
                }
                else {
                    throw new RDFSemanticsException("Cannot load taxonomy of fact '" + t.Subject + "' from graph, because it has not been found in the ontology data.");
                }
            }
            #endregion

            #region DifferentFrom
            foreach (var t in ontGraph.SelectTriplesByPredicate(RDFVocabulary.OWL.DIFFERENT_FROM)) {
                var subjFct     = ontology.Data.SelectFact(t.Subject.ToString());
                if (subjFct    != null) {
                    var objFct  = ontology.Data.SelectFact(t.Object.ToString());
                    if (objFct != null) {
                        subjFct.AddDifferentFrom(objFct);
                    }
                    else {
                        throw new RDFSemanticsException("Cannot load taxonomy of fact '" + t.Subject + "' from graph, because its different fact '" + t.Object + "' has not been found in the ontology data.");
                    }
                }
                else {
                    throw new RDFSemanticsException("Cannot load taxonomy of fact '" + t.Subject + "' from graph, because it has not been found in the ontology data.");
                }
            }
            #endregion

        }
        /// <summary>
        /// Loads the restrictions from the given graph into the given ontology
        /// </summary>
        internal static void LoadRestrictions(RDFGraph ontGraph, RDFOntology ontology, RDFGraph rdfType) {
            foreach (var t in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.RESTRICTION)) {

                #region onProperty
                var p = ontGraph.SelectTriplesBySubject((RDFResource)t.Subject)
                                .SelectTriplesByPredicate(RDFVocabulary.OWL.ON_PROPERTY)
                                .FirstOrDefault();
                if (p != null) {
                    var onProp  = ontology.Model.PropertyModel.SelectProperty(p.Object.ToString());
                    if (onProp != null) {
                        var ontRestr             = new RDFOntologyRestriction(onProp);
                        ontRestr.Value           = t.Subject;
                        ontRestr.PatternMemberID = t.Subject.PatternMemberID;
                        ontology.Model.ClassModel.AddRestriction(ontRestr);
                    }
                    else {
                        throw new RDFSemanticsException("Cannot load restriction '" + t.Subject + "' from graph, because its applied property '" + p.Object + "' has not been found in the ontology model.");
                    }
                }
                #endregion

            }
        }
 /// <summary>
 /// Loads the classes from the given graph into the given ontology
 /// </summary>
 internal static void LoadClasses(RDFGraph ontGraph, RDFOntology ontology, RDFGraph rdfType) {
     foreach (var t in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.CLASS)
                              .UnionWith(rdfType.SelectTriplesByObject(RDFVocabulary.RDFS.CLASS))) {
         ontology.Model.ClassModel.AddClass(new RDFOntologyClass((RDFResource)t.Subject));
     }
 }
        internal static void LoadOntology(RDFGraph ontGraph, RDFOntology ontology, RDFGraph rdfType,
                                          RDFGraph owlVersInfo, RDFGraph rdfsComment, RDFGraph rdfsLabel,
                                          RDFGraph rdfsSeeAlso, RDFGraph rdfsIsDefBy, RDFGraph customAnnot) {
            var o  = rdfType.SelectTriplesByObject(RDFVocabulary.OWL.ONTOLOGY)
                            .FirstOrDefault();
            if (o != null) {
                ontology.Value           = o.Subject;
                ontology.PatternMemberID = o.Subject.PatternMemberID;

                #region Annotations

                #region VersionInfo
                foreach (var t in owlVersInfo.SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor  == RDFModelEnums.RDFTripleFlavors.SPL) {
                        var fact         = ontology.Data.SelectFact(t.Object.ToString());

                        //If the literal fact is not found in the ontology data, update the ontology data
                        if (fact        == null) {
                            fact         = new RDFOntologyFact((RDFLiteral)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddVersionInfo(fact);
                    }
                }
                #endregion

                #region Comment
                foreach (var t in rdfsComment.SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor  == RDFModelEnums.RDFTripleFlavors.SPL) {
                        var fact         = ontology.Data.SelectFact(t.Object.ToString());

                        //If the literal fact is not found in the ontology data, update the ontology data
                        if (fact        == null) {
                            fact         = new RDFOntologyFact((RDFLiteral)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddComment(fact);
                    }
                }
                #endregion

                #region Label
                foreach (var t in rdfsLabel.SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor  == RDFModelEnums.RDFTripleFlavors.SPL) {
                        var fact         = ontology.Data.SelectFact(t.Object.ToString());

                        //If the literal fact is not found in the ontology data, update the ontology data
                        if (fact        == null) {
                            fact         = new RDFOntologyFact((RDFLiteral)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddLabel(fact);
                    }
                }
                #endregion

                #region SeeAlso
                foreach (var t in rdfsSeeAlso.SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor  == RDFModelEnums.RDFTripleFlavors.SPO) {
                        var fact         = ontology.Data.SelectFact(t.Object.ToString());

                        //If the resource fact is not found in the ontology data, update the ontology data
                        if (fact        == null) {
                            fact         = new RDFOntologyFact((RDFResource)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddSeeAlso(fact);
                    }
                }
                #endregion

                #region IsDefinedBy
                foreach (var t in rdfsIsDefBy.SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor  == RDFModelEnums.RDFTripleFlavors.SPO) {
                        var fact         = ontology.Data.SelectFact(t.Object.ToString());

                        //If the resource fact is not found in the ontology data, update the ontology data
                        if (fact        == null) {
                            fact         = new RDFOntologyFact((RDFResource)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddIsDefinedBy(fact);
                    }
                }
                #endregion

                #region Custom Annotations
                foreach (var ap in customAnnot) {
                    var annotationProp          = (RDFOntologyAnnotationProperty)ontology.Model.PropertyModel.SelectProperty(ap.Subject.ToString());

                    foreach (var t in ontGraph.SelectTriplesBySubject((RDFResource)ontology.Value)
                                                .SelectTriplesByPredicate((RDFResource)annotationProp.Value)) {
                        var fact                = ontology.Data.SelectFact(t.Object.ToString());

                        //If the resource fact is not found in the ontology data, update the ontology data
                        if (fact               == null) {
                            if (t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO) {
                                fact            = new RDFOntologyFact((RDFResource)t.Object);
                            }
                            else {
                                fact            = new RDFOntologyFact((RDFLiteral)t.Object);
                            }
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddCustomAnnotation(annotationProp, fact);
                    }

                }
                #endregion

                #endregion

                #region Versioning

                #region Imports
                foreach (var t in ontGraph.SelectTriplesByPredicate(RDFVocabulary.OWL.IMPORTS)
                                          .SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor   == RDFModelEnums.RDFTripleFlavors.SPO) {
                        var fact          = ontology.Data.SelectFact(t.Object.ToString());

                        //If the object fact is not found in the ontology data, update the ontology data
                        if (fact         == null) {
                            fact          = new RDFOntologyFact((RDFResource)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.ImportOntology(new RDFOntology((RDFResource)fact.Value, false));
                    }
                }
                #endregion

                #region BackwardCompatibleWith
                foreach (var t in ontGraph.SelectTriplesByPredicate(RDFVocabulary.OWL.BACKWARD_COMPATIBLE_WITH)
                                          .SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor   == RDFModelEnums.RDFTripleFlavors.SPO) {
                        var fact          = ontology.Data.SelectFact(t.Object.ToString());

                        //If the object fact is not found in the ontology data, update the ontology data
                        if (fact         == null) {
                            fact          = new RDFOntologyFact((RDFResource)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddBackwardCompatibleWith(fact);
                    }
                }
                #endregion

                #region IncompatibleWith
                foreach (var t in ontGraph.SelectTriplesByPredicate(RDFVocabulary.OWL.INCOMPATIBLE_WITH)
                                          .SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor   == RDFModelEnums.RDFTripleFlavors.SPO) {
                        var fact          = ontology.Data.SelectFact(t.Object.ToString());

                        //If the object fact is not found in the ontology data, update the ontology data
                        if (fact         == null) {
                            fact          = new RDFOntologyFact((RDFResource)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddIncompatibleWith(fact);
                    }
                }
                #endregion

                #region PriorVersion
                foreach (var t in ontGraph.SelectTriplesByPredicate(RDFVocabulary.OWL.PRIOR_VERSION)
                                          .SelectTriplesBySubject((RDFResource)ontology.Value)) {
                    if (t.TripleFlavor   == RDFModelEnums.RDFTripleFlavors.SPO) {
                        var fact          = ontology.Data.SelectFact(t.Object.ToString());

                        //If the object fact is not found in the ontology data, update the ontology data
                        if (fact         == null) {
                            fact          = new RDFOntologyFact((RDFResource)t.Object);
                            ontology.Data.AddFact(fact);
                        }

                        ontology.AddPriorVersion(fact);
                    }
                }
                #endregion

                #endregion

            }
        }
        /// <summary>
        /// Loads the object properties from the given graph into the given ontology
        /// </summary>
        internal static void LoadObjectProperties(RDFGraph ontGraph, RDFOntology ontology, RDFGraph rdfType) {

            #region Explicit ObjectProperty
            foreach (var t in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.OBJECT_PROPERTY)) {
                var objProp = new RDFOntologyObjectProperty((RDFResource)t.Subject);
                ontology.Model.PropertyModel.AddProperty(objProp);

                #region FunctionalProperty
                var fp      = rdfType.SelectTriplesBySubject((RDFResource)objProp.Value)
                                     .SelectTriplesByObject(RDFVocabulary.OWL.FUNCTIONAL_PROPERTY)
                                     .FirstOrDefault();
                if (fp     != null) {
                    objProp.SetFunctional();
                }
                #endregion

                #region InverseFunctionalProperty
                var ifp     = rdfType.SelectTriplesBySubject((RDFResource)objProp.Value)
                                     .SelectTriplesByObject(RDFVocabulary.OWL.INVERSE_FUNCTIONAL_PROPERTY)
                                     .FirstOrDefault();
                if (ifp    != null) {
                    objProp.SetInverseFunctional();
                }
                #endregion

                #region SymmetricProperty
                var sp      = rdfType.SelectTriplesBySubject((RDFResource)objProp.Value)
                                     .SelectTriplesByObject(RDFVocabulary.OWL.SYMMETRIC_PROPERTY)
                                     .FirstOrDefault();
                if (sp     != null) {
                    objProp.SetSymmetric();
                }
                #endregion

                #region TransitiveProperty
                var tp      = rdfType.SelectTriplesBySubject((RDFResource)objProp.Value)
                                     .SelectTriplesByObject(RDFVocabulary.OWL.TRANSITIVE_PROPERTY)
                                     .FirstOrDefault();
                if (tp     != null) {
                    objProp.SetTransitive();
                }
                #endregion

            }
            #endregion

            #region Implicit ObjectProperty

            #region InverseFunctionalProperty
            foreach (var t  in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.INVERSE_FUNCTIONAL_PROPERTY)) {
                var ivfProp  = ontology.Model.PropertyModel.SelectProperty(t.Subject.ToString());
                if(ivfProp  == null) {
                    ivfProp  = new RDFOntologyObjectProperty((RDFResource)t.Subject);
                    ontology.Model.PropertyModel.AddProperty(ivfProp);

                    #region FunctionalProperty
                    var fp   = rdfType.SelectTriplesBySubject((RDFResource)ivfProp.Value)
                                      .SelectTriplesByObject(RDFVocabulary.OWL.FUNCTIONAL_PROPERTY)
                                      .FirstOrDefault();
                    if (fp  != null) {
                        ivfProp.SetFunctional();
                    }
                    #endregion

                }
                ((RDFOntologyObjectProperty)ivfProp).SetInverseFunctional();
            }
            #endregion

            #region SymmetricProperty
            foreach (var t  in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.SYMMETRIC_PROPERTY)) {
                var symProp  = ontology.Model.PropertyModel.SelectProperty(t.Subject.ToString());
                if (symProp == null) {
                    symProp  = new RDFOntologyObjectProperty((RDFResource)t.Subject);
                    ontology.Model.PropertyModel.AddProperty(symProp);

                    #region FunctionalProperty
                    var fp   = rdfType.SelectTriplesBySubject((RDFResource)symProp.Value)
                                      .SelectTriplesByObject(RDFVocabulary.OWL.FUNCTIONAL_PROPERTY)
                                      .FirstOrDefault();
                    if (fp  != null) {
                        symProp.SetFunctional();
                    }
                    #endregion

                }
                ((RDFOntologyObjectProperty)symProp).SetSymmetric();
            }
            #endregion

            #region TransitiveProperty
            foreach (var t  in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.TRANSITIVE_PROPERTY)) {
                var trnProp  = ontology.Model.PropertyModel.SelectProperty(t.Subject.ToString());
                if (trnProp == null) {
                    trnProp  = new RDFOntologyObjectProperty((RDFResource)t.Subject);
                    ontology.Model.PropertyModel.AddProperty(trnProp);

                    #region FunctionalProperty
                    var fp   = rdfType.SelectTriplesBySubject((RDFResource)trnProp.Value)
                                      .SelectTriplesByObject(RDFVocabulary.OWL.FUNCTIONAL_PROPERTY)
                                      .FirstOrDefault();
                    if (fp  != null) {
                        trnProp.SetFunctional();
                    }
                    #endregion

                }
                ((RDFOntologyObjectProperty)trnProp).SetTransitive();
            }
            #endregion

            #endregion

        }
        /// <summary>
        /// Loads the datatype properties from the given graph into the given ontology
        /// </summary>
        internal static void LoadDatatypeProperties(RDFGraph ontGraph, RDFOntology ontology, RDFGraph rdfType) {
            foreach (var t in rdfType.SelectTriplesByObject(RDFVocabulary.OWL.DATATYPE_PROPERTY)) {
                var dtProp  = new RDFOntologyDatatypeProperty((RDFResource)t.Subject);
                ontology.Model.PropertyModel.AddProperty(dtProp);

                #region FunctionalProperty
                var fp      = rdfType.SelectTriplesBySubject((RDFResource)dtProp.Value)
                                     .SelectTriplesByObject(RDFVocabulary.OWL.FUNCTIONAL_PROPERTY)
                                     .FirstOrDefault();
                if (fp     != null) {
                    dtProp.SetFunctional();
                }
                #endregion

            }
        }