*/
for (Iterator<Map.Entry<XMethod, Property>> i = propertyMap.entrySet().iterator(); i.hasNext();) { Map.Entry<XMethod, Property> entry = i.next(); XMethod sourceMethod = entry.getKey(); JavaClass sourceClass = getClassFor(sourceMethod); if (sourceClass == null) continue;  Property sourceProperty = entry.getValue();  Set<XMethod> targetMethodSet = getTargetMethods(sourceClass, sourceMethod); for (Iterator<XMethod> j = targetMethodSet.iterator(); j.hasNext();) { XMethod targetMethod = j.next(); if (targetMethod.isStatic()) continue;  Property targetProperty = propertyMap.get(targetMethod); Property result = getPropertyCombinator().combine(sourceProperty, targetProperty); targetProperty.makeSameAs(result); } }
	public void propagateThroughClassHierarchy() {		/*		Subtypes subtypes = AnalysisContext.currentAnalysisContext().getSubtypes();				Set<XMethod> methodSet = new HashSet<XMethod>();		methodSet.addAll(propertyMap.keySet());				// Step 1.  Add all target methods (overridden methods or overriding methods,		// depending on which direction we're walking the class hierarchy in.)		for (Iterator<XMethod> i = propertyMap.keySet().iterator(); i.hasNext();) {			XMethod sourceMethod = i.next();			JavaClass sourceClass = getClassFor(sourceMethod);			if (sourceClass == null)				continue;						Set<XMethod> targetMethods = getTargetMethods(sourceClass, sourceMethod);			methodSet.addAll(targetMethods);		}				// Step 2.  Make sure the database has an entry for all reachable methods.		for (Iterator<XMethod> i = methodSet.iterator(); i.hasNext();) {			XMethod xmethod = i.next();			if (propertyMap.get(xmethod) == null) {				propertyMap.put(xmethod, createDefault());			}		}				// Step 3.  Propagate method properties to super or subtype methods.		// As long as the combine operation is commutative, it doesn't matter		// what order we do this in.		 */		////		// Build a new database to avoid ConcurrentModificationExceptions//		Map<XMethod, Property> resultMap = new HashMap<XMethod, Property>();//		resultMap.putAll(propertyMap);//		//		// For each method,property pair...//		for (Iterator<Map.Entry<XMethod, Property>> i = propertyMap.entrySet().iterator(); i.hasNext();) {//			Map.Entry<XMethod, Property> entry = i.next();//			try {//				XMethod sourceMethod = entry.getKey();//				if (sourceMethod.isStatic())//					continue;//				Property sourceProperty = entry.getValue();////				// Get source class//				String sourceClassName = sourceMethod.getClassName();//				JavaClass sourceClass = AnalysisContext.currentAnalysisContext().lookupClass(sourceClassName);//				//				// Based on source class, get target classes (either subtypes or supertypes)//				Set<JavaClass> targetClassSet = getHierarchyWalkDirection().getHierarchyGraphTargets(sourceClass);////				// Look for overriding or overridden methods in target classes//				for (Iterator<JavaClass> j = targetClassSet.iterator(); j.hasNext(); ) {//					JavaClass targetClass = j.next();//					//					XMethod targetMethod = Hierarchy.findXMethod(targetClass, sourceMethod.getName(), sourceMethod.getSignature());//					if (targetMethod == null)//						continue;//					if (targetMethod.isStatic())//						continue;//					//					// Combine properties//					Property targetProperty = propertyMap.get(targetMethod);//					if (targetProperty == null)//						resultMap.put(targetMethod, sourceProperty.duplicate());//					else//						resultMap.put(targetMethod, getPropertyCombinator().combine(sourceProperty, targetProperty));//				}//			} catch (ClassNotFoundException e) {//				AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportMissingClass(e);//			}//		}//		this.propertyMap = resultMap;	}