code: package gr.uom.java.ast.metrics;
  
  import gr.uom.java.ast.ClassObject;
  import gr.uom.java.ast.FieldInstructionObject;
  import gr.uom.java.ast.MethodInvocationObject;
  import gr.uom.java.ast.MethodObject;
  import gr.uom.java.ast.SystemObject;
  
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.ListIterator;
  import java.util.Map;
  import java.util.Set;
  
  public class MMImportCoupling {
  	
  	private SystemObject system;
  	private Map<String, LinkedHashMap<String, Integer>> importCouplingMap;
  	
  	public MMImportCoupling(SystemObject system) {
  		this.system = system;
  		this.importCouplingMap = new LinkedHashMap<String, LinkedHashMap<String, Integer>>();
  		List<String> classNames = system.getClassNames();
  		for(String className : classNames) {
  			LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
  			for(String className2 : classNames) {
  				map.put(className2, 0);
  			}
  			importCouplingMap.put(className, map);
  		}
  		calculateCoupling();
  	}
  	
  	private void calculateCoupling() {
  		ListIterator<ClassObject> classIterator = system.getClassListIterator();
  		while(classIterator.hasNext()) {
  			ClassObject classObject = classIterator.next();
  			LinkedHashMap<String, Integer> map = importCouplingMap.get(classObject.getName());
  			ListIterator<MethodObject> methodIterator = classObject.getMethodIterator();
  			while(methodIterator.hasNext()) {
  				MethodObject method = methodIterator.next();
  				if(method.getMethodBody() != null) {
  					List<MethodInvocationObject> methodInvocations = method.getMethodInvocations();
  					for(MethodInvocationObject methodInvocation : methodInvocations) {
  						String methodInvocationOrigin = methodInvocation.getOriginClassName();
  						if(map.keySet().contains(methodInvocationOrigin)) {
  							ClassObject originClass = system.getClassObject(methodInvocationOrigin);
  							MethodObject originMethod = originClass.getMethod(methodInvocation);
  							if(!originMethod.isStatic())
  								map.put(methodInvocationOrigin, map.get(methodInvocationOrigin)+1);
  						}
  					}
  					List<FieldInstructionObject> fieldInstructions = method.getFieldInstructions();
  					for(FieldInstructionObject fieldInstruction : fieldInstructions) {
  						String fieldInstructionOrigin = fieldInstruction.getOwnerClass();
  						if(map.keySet().contains(fieldInstructionOrigin) && !fieldInstruction.isStatic()) {
  							map.put(fieldInstructionOrigin, map.get(fieldInstructionOrigin)+1);
  						}
  					}
  				}
  			}
  		}
  	}
  	
  	private double getClassAverageCoupling(String className) {
  		LinkedHashMap<String, Integer> map = importCouplingMap.get(className);
  		int sum = 0;
  		Set<String> keySet = map.keySet();
  		for(String key : keySet) {
  			if(!key.equals(className))
  				sum += map.get(key);
  		}
  		return (double)sum/(double)(keySet.size()-1);
  	}
  	
  	public double getSystemAverageCoupling() {
  		Set<String> keySet = importCouplingMap.keySet();
  		double sum = 0;
  		for(String key : keySet) {
  			sum += getClassAverageCoupling(key);
  		}
  		return sum/(double)keySet.size();
  	}
  }
  