private void update() {
		if (!updated) {

			subSuperPropMap = new HashMap<String, Set<String>>();

			// find parallel property usage
			for (String p : triplesPerProperty.keySet()) {
				
				Map<String, Set<String>> pSubjects = triplesPerProperty.get(p);
				int pNumSubjects = pSubjects.size();
				
				for (String superP : triplesPerProperty.keySet()) {
					if (!p.equals(superP)) {
						
						Map<String, Set<String>> superPSubjects = triplesPerProperty.get(superP);
						int superPNumSubjects = superPSubjects.size();
						
						if (pNumSubjects <= superPNumSubjects) {
							boolean containsAll = true;
							Set<String> pSub = pSubjects.keySet();
							
							// for all subjects: all objects contained?
							for (Iterator<String> i = pSub.iterator(); i.hasNext() && containsAll;) {
								String sub = i.next();
								Set<String> pObjects = pSubjects.get(sub);
								Set<String> superPObjects = superPSubjects.get(sub);
								containsAll = superPObjects != null && superPObjects.containsAll(pObjects);
							}
							
							// add hierarchy statement
							if (containsAll)
								addHierarchyEdge(p, superP);
						}						
					}						
				}				
			}
			updated = true;
		}
	}