public static synchronized boolean isSingleValued(
     OntClass cls, OntProperty prop, String rngString) {
   if (prop.isFunctionalProperty()) {
     return true;
   }
   if (cls != null) {
     ExtendedIterator<OntClass> eitr = cls.listSuperClasses(false);
     while (eitr.hasNext()) {
       OntClass supercls = eitr.next();
       if (supercls.isRestriction()) {
         Restriction rstrct = supercls.asRestriction();
         if (rstrct.isMaxCardinalityRestriction()) {
           MaxCardinalityRestriction mxcr = rstrct.asMaxCardinalityRestriction();
           if (mxcr.getOnProperty().equals(prop) && mxcr.getMaxCardinality() == 1) {
             return true;
           }
         } else if (rstrct.isCardinalityRestriction()) {
           if (rstrct.isCardinalityRestriction()) {
             CardinalityRestriction cr = rstrct.asCardinalityRestriction();
             if (cr.getOnProperty().equals(prop) && cr.getCardinality() == 1) {
               return true;
             }
           }
         } else {
           if (rstrct.hasProperty(OWL2.maxQualifiedCardinality)) {
             if (rstrct.getOnProperty().equals(prop)
                 && rstrct.getProperty(OWL2.maxQualifiedCardinality).getInt() == 1) {
               // check class
               if (rstrct.getProperty(OWL2.onClass).getResource().toString().equals(rngString)) {
                 return true;
               }
             }
           } else if (rstrct.hasProperty(OWL2.qualifiedCardinality)) {
             if (rstrct.getOnProperty().equals(prop)
                 && rstrct.getProperty(OWL2.qualifiedCardinality).getInt() == 1) {
               // check class
               if (rstrct.getProperty(OWL2.onClass).getResource().toString().equals(rngString)) {
                 return true;
               }
             }
           }
           //						StmtIterator siter = rstrct.listProperties();
           //						while (siter.hasNext()) {
           //							System.out.println(siter.nextStatement().toString());
           //						}
         }
       }
     }
   }
   return false;
 }
  public Collection<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {

    List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();

    if (vclasses == null || vclasses.isEmpty()) {
      return propInsts;
    }

    Collections.sort(
        vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));

    OntModel ontModel = getOntModelSelector().getTBoxModel();

    try {

      ontModel.enterCriticalSection(Lock.READ);

      // map object property URI to an array of two resources:
      // the first is the "allValuesFrom" resource and the second is
      // "someValuesFrom"
      Map<String, Resource[]> applicableProperties = new HashMap<String, Resource[]>();

      try {
        for (VClass vclass : vclasses) {
          if (vclass.isAnonymous()) {
            continue;
          }
          String VClassURI = vclass.getURI();

          OntClass ontClass = getOntClass(ontModel, VClassURI);
          if (ontClass != null) {
            List<OntClass> relatedClasses = new ArrayList<OntClass>();
            relatedClasses.addAll(ontClass.listEquivalentClasses().toList());
            relatedClasses.addAll(ontClass.listSuperClasses().toList());
            for (OntClass relatedClass : relatedClasses) {
              // find properties in restrictions
              if (relatedClass.isRestriction()) {
                // TODO: check if restriction is something like
                // maxCardinality 0 or allValuesFrom owl:Nothing,
                // in which case the property is NOT applicable!
                Restriction rest = (Restriction) relatedClass.as(Restriction.class);
                OntProperty onProperty = rest.getOnProperty();
                if (onProperty != null && onProperty.canAs(ObjectProperty.class)) {
                  Resource[] ranges = new Resource[2];
                  if (rest.isAllValuesFromRestriction()) {
                    ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
                  } else if (rest.isSomeValuesFromRestriction()) {
                    ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom();
                  }
                  updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges);
                }
              }
            }

            // find properties with class in domain
            ResIterator pit = ontModel.listSubjectsWithProperty(RDFS.domain, ontClass);
            while (pit.hasNext()) {
              Resource prop = pit.nextResource();
              if (prop.getNameSpace() != null
                  && !NONUSER_NAMESPACES.contains(prop.getNameSpace())) {
                StmtIterator rangeSit = prop.listProperties(RDFS.range);
                Resource rangeRes = null;
                while (rangeSit.hasNext()) {
                  Statement s = rangeSit.nextStatement();
                  if (s.getObject().isURIResource()) {
                    rangeRes = (Resource) s.getObject();
                  }
                }
                Resource[] ranges = new Resource[2];
                ranges[0] = rangeRes;
                updatePropertyRangeMap(applicableProperties, prop.getURI(), ranges);
              }
            }
          }
        }
      } catch (Exception e) {
        log.error(
            "Unable to get applicable properties "
                + "by examining property restrictions and domains",
            e);
      }

      // make the PropertyInstance objects
      for (String propertyURI : applicableProperties.keySet()) {
        ObjectProperty op = ontModel.getObjectProperty(propertyURI);
        if (op == null) {
          continue;
        }
        String domainURIStr = getURIStr(op.getDomain());
        Resource[] foundRanges = applicableProperties.get(propertyURI);
        Resource rangeRes =
            (foundRanges[0] != null)
                ? foundRanges[0]
                : (op.getRange() == null && foundRanges[1] != null)
                    ? foundRanges[1]
                    : op.getRange();
        PropertyInstance pi = new PropertyInstance();
        if (rangeRes != null) {
          String rangeClassURI;
          if (rangeRes.isAnon()) {
            rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId().toString();
          } else {
            rangeClassURI = (String) rangeRes.getURI();
          }
          pi.setRangeClassURI(rangeClassURI);
          try {
            pi.setRangeClassName(
                getWebappDaoFactory().getVClassDao().getVClassByURI(rangeClassURI).getName());
            // pi.setRangeClassName(getLabel(getOntModel().getOntResource(rangeClassURI)));
          } catch (NullPointerException e) {
            /* probably a union or intersection - need to handle this somehow */
          }
        } else {
          pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
        }
        pi.setDomainClassURI(domainURIStr);
        try {
          pi.setDomainClassName(
              getWebappDaoFactory().getVClassDao().getVClassByURI(domainURIStr).getName());
          // pi.setDomainClassName(getLabel(getOntModel().getOntResource(op.getDomain().getURI())));
        } catch (NullPointerException e) {
          /* probably a union or intersection - need to handle this somehow */
        }
        pi.setSubjectSide(true);
        pi.setPropertyURI(op.getURI());
        pi.setPropertyName(getLabelOrId(op)); // TODO
        pi.setRangePublic(getLabelOrId(op));
        pi.setDomainPublic(getLabelOrId(op));
        propInsts.add(pi);
      }
    } finally {
      ontModel.leaveCriticalSection();
    }

    Collections.sort(propInsts, new PropInstSorter());
    return propInsts;
  }
  private void tryRestriction(
      OntClass theClass,
      VClassDao vcDao,
      ObjectPropertyDao opDao,
      IndividualDao iDao,
      ArrayList results,
      String vClassURI) {
    if (theClass.isRestriction()) {
      Restriction rest = (Restriction) theClass.as(Restriction.class);
      try {
        results.add("XX");
        Property onProperty = rest.getOnProperty();
        ObjectProperty op = opDao.getObjectPropertyByURI(onProperty.getURI());
        results.add(op.getLocalNameWithPrefix());
        if (rest.isAllValuesFromRestriction()) {
          results.add("all values from");
          AllValuesFromRestriction avfrest =
              (AllValuesFromRestriction) rest.as(AllValuesFromRestriction.class);
          Resource allValuesFrom = avfrest.getAllValuesFrom();
          results.add(printAsClass(vcDao, allValuesFrom));
        } else if (rest.isSomeValuesFromRestriction()) {
          results.add("some values from");
          SomeValuesFromRestriction svfrest =
              (SomeValuesFromRestriction) rest.as(SomeValuesFromRestriction.class);
          Resource someValuesFrom = svfrest.getSomeValuesFrom();
          results.add(printAsClass(vcDao, someValuesFrom));
        } else if (rest.isHasValueRestriction()) {
          results.add("has value");
          HasValueRestriction hvrest = (HasValueRestriction) rest.as(HasValueRestriction.class);
          RDFNode hasValue = hvrest.getHasValue();
          if (hasValue.isResource()) {
            Resource hasValueRes = (Resource) hasValue.as(Resource.class);
            try {
              if (hasValueRes.getURI() != null) {
                Individual ind = iDao.getIndividualByURI(hasValueRes.getURI());
                if (ind.getName() != null) {
                  results.add(ind.getName());
                }
              }
            } catch (Exception e) {
              results.add("???");
            }
          }

        } else if (rest.isMinCardinalityRestriction()) {
          MinCardinalityRestriction crest =
              (MinCardinalityRestriction) rest.as(MinCardinalityRestriction.class);
          results.add("at least " + crest.getMinCardinality());
          results.add(LAMBDA);
        } else if (rest.isMaxCardinalityRestriction()) {
          MaxCardinalityRestriction crest =
              (MaxCardinalityRestriction) rest.as(MaxCardinalityRestriction.class);
          results.add("at most " + crest.getMaxCardinality());
          results.add(LAMBDA);
        } else if (rest.isCardinalityRestriction()) {
          CardinalityRestriction crest =
              (CardinalityRestriction) rest.as(CardinalityRestriction.class);
          results.add("exactly " + crest.getCardinality());
          results.add(LAMBDA);
        }

        results.add(
            "<form action=\"addRestriction\" method=\"post\">"
                + "<input type=\"hidden\" name=\"_action\" value=\"delete\"/>"
                + "<input type=\"submit\" value=\"Delete\"/>"
                + "<input type=\"hidden\" name=\"_epoKey\" value=\""
                + epo.getKey()
                + "\"/>"
                + "<input type=\"hidden\" name=\"classUri\" value=\""
                + vClassURI
                + "\"/>"
                + "<input type=\"hidden\" name=\"restrictionId\" value=\""
                + ((rest.getId() != null) ? rest.getId() : rest.getURI())
                + "\"/>"
                + "</form>");

      } catch (Exception e) {
        e.printStackTrace(); // results.add("unknown property");
      }
    }
  }
  // gets the URIs of the classes and their translation
  public HashMap<String, String> getClassesIdentifiers(
      float percentage,
      boolean activeRandomString,
      boolean activeTranslateString,
      boolean activeSynonym,
      int activeStringOperation) {
    HashMap<String, String> classesIdentifiers =
        new HashMap<String, String>(); // the HashMap of classes identifiers

    int nbClasses, toBeRenamed, renamedClasses;

    List<OntClass> notRenamedClasses = new ArrayList<OntClass>(); // the list of not renamed classes
    List<OntClass> classes = getOntologyClasses(); // the list of ontology classes
    List<OntClass> classesTo = new ArrayList<OntClass>(); // the list of classes to be renamed

    // alignment contains those classes which have already been renamed
    // builds the list of all unrenamed classes from the model
    for (OntClass c : classes) {
      String local = getLocalName(c.getURI());
      if (alignment.containsKey(local)) {
        if (alignment.getProperty(local).equals(local))
          notRenamedClasses.add(c); // add the class to not renamed classes
      }
    }

    nbClasses = classes.size();
    renamedClasses = nbClasses - notRenamedClasses.size(); // the number of renamed classes
    toBeRenamed =
        Math.round(percentage * nbClasses) - renamedClasses; // -renamedClasses -> for Benchmark

    // logger.trace( "NbClasses = {}; YetToRename = {}; I will rename = {};", nbClasses,
    // notRenamedClasses.size(), toBeRenamed );

    // toBeRenamed is negative when classes have been added to the model
    if (toBeRenamed < 0) toBeRenamed = 0;
    // build the list of classes to be renamed
    int[] n = randNumbers(notRenamedClasses.size(), toBeRenamed);
    for (int i = 0; i < toBeRenamed; i++) {
      OntClass cls = notRenamedClasses.get(n[i]);
      classesTo.add(cls);
    }

    for (OntClass cls : classesTo) {
      if (!cls.isRestriction()) {
        if (!cls.isAnon()) {
          String prefix = getNameSpace(cls.getURI());
          String localName = getLocalName(cls.getURI());

          // has the same Namespace as the Ontology Namespace
          if (prefix.equals(modifiedOntologyNS)) {
            if (!classesIdentifiers.containsKey(localName)) {
              if (activeTranslateString) { // replace the URI with the translated one
                String translateStrg = parseString(localName, true, false);
                classesIdentifiers.put(localName, translateStrg);
                replaceClassLabel(
                    cls.getURI(),
                    translateStrg,
                    activeRandomString,
                    activeTranslateString,
                    activeSynonym,
                    activeStringOperation);
                if (alignment.containsKey(localName)) { // alignment.remove( cls.getURI() );
                  alignment.put(localName, translateStrg); // the reference alignment
                }
              } else if (activeRandomString) { // replace the URI with a random string
                String newStrg = getRandomString();
                classesIdentifiers.put(localName, newStrg);
                replaceClassLabel(
                    cls.getURI(),
                    newStrg,
                    activeRandomString,
                    activeTranslateString,
                    activeSynonym,
                    activeStringOperation);
                if (alignment.containsKey(localName)) { // alignment.remove( cls.getURI() );
                  alignment.put(localName, newStrg); // the reference alignment
                }
              } else if (activeSynonym) { // replace the URI with a synonym
                String synonym = parseString(localName, false, true);
                classesIdentifiers.put(localName, synonym);
                replaceClassLabel(
                    cls.getURI(),
                    synonym,
                    activeRandomString,
                    activeTranslateString,
                    activeSynonym,
                    activeStringOperation);
                if (alignment.containsKey(localName)) { // alignment.remove( cls.getURI() );
                  alignment.put(localName, synonym); // the reference alignment
                }
              } else if (activeStringOperation == 1) { // replace the URI with the UpperCase URI
                classesIdentifiers.put(localName, localName.toUpperCase());
                replaceClassLabel(
                    cls.getURI(),
                    localName.toUpperCase(),
                    activeRandomString,
                    activeTranslateString,
                    activeSynonym,
                    activeStringOperation);
                if (alignment.containsKey(localName)) { // alignment.remove( cls.getURI() );
                  alignment.put(localName, localName.toUpperCase()); // the reference alignment
                }
              } else if (activeStringOperation == 2) { // replace the URI with the LowerCase URI
                classesIdentifiers.put(localName, localName.toLowerCase());
                replaceClassLabel(
                    cls.getURI(),
                    localName.toLowerCase(),
                    activeRandomString,
                    activeTranslateString,
                    activeSynonym,
                    activeStringOperation);
                if (alignment.containsKey(localName)) { // alignment.remove( cls.getURI() );
                  alignment.put(localName, localName.toLowerCase()); // the reference alignment
                }
              } else {
                classesIdentifiers.put(localName, localName + "CLASS");
                replaceClassLabel(
                    cls.getURI(),
                    localName + "CLASS",
                    activeRandomString,
                    activeTranslateString,
                    activeSynonym,
                    activeStringOperation);
                if (alignment.containsKey(localName)) { // alignment.remove( cls.getURI() );
                  alignment.put(localName, localName + "CLASS");
                }
              }
            }
          }
        }
      }
    }
    return classesIdentifiers;
  }