code: package gr.uom.java.distance;
  
  import gr.uom.java.ast.MethodObject;
  import gr.uom.java.ast.decomposition.AbstractStatement;
  
  import java.util.*;
  
  public class MyMethod extends Entity {
  
      private String classOrigin;
      private String methodName;
      private String returnType;
      private List<String> parameterList;
      private MyMethodBody methodBody;
      private boolean isAbstract;
      private String access;
      private MethodObject methodObject;
      private volatile int hashCode = 0;
  
      public MyMethod(String classOrigin, String methodName, String returnType, List<String> parameterList) {
          this.classOrigin = classOrigin;
          this.methodName = methodName;
          this.returnType = returnType;
          this.parameterList = parameterList;
          this.isAbstract = false;
      }
  
      public void setMethodObject(MethodObject methodObject) {
      	this.methodObject = methodObject;
      }
  
      public MethodObject getMethodObject() {
      	return this.methodObject;
      }
  
      public String getAccess() {
          return access;
      }
  
      public void setAccess(String access) {
          this.access = access;
      }
  
      public void setMethodBody(MyMethodBody methodBody) {
      	this.methodBody = methodBody;
      }
  
      public MyMethodInvocation generateMethodInvocation() {
          return new MyMethodInvocation(this.classOrigin,this.methodName,this.returnType,this.parameterList);
      }
  
      public boolean isAbstract() {
          return isAbstract;
      }
  
      public void setAbstract(boolean anAbstract) {
          isAbstract = anAbstract;
      }
  
      public boolean containsParameter(String p) {
          for(String parameter : parameterList) {
              if(parameter.equals(p))
                  return true;
          }
          return false;
      }
  
      public void setClassOrigin(String className) {
          this.classOrigin = className;
      }
  
      public void removeParameter(String className) {
          this.parameterList.remove(className);
      }
  
      public void addParameter(String parameter) {
          if(!parameterList.contains(parameter))
              parameterList.add(parameter);
      }
  
      public String getClassOrigin() {
          return classOrigin;
      }
  
      public String getMethodName() {
          return methodName;
      }
  
      public void setMethodName(String methodName) {
  		this.methodName = methodName;
  	}
  
  	public String getReturnType() {
          return returnType;
      }
  
      public List<String> getParameterList() {
          return parameterList;
      }
  
      public void setAttributeInstructionReference(MyAttributeInstruction myAttributeInstruction, boolean reference) {
      	if(this.methodBody != null)
      		this.methodBody.setAttributeInstructionReference(myAttributeInstruction, reference);
      }
  
      public MyAbstractStatement getAbstractStatement(AbstractStatement statement) {
      	if(this.methodBody != null)
      		return this.methodBody.getAbstractStatement(statement);
      	else
      		return null;
      }
  
      public ListIterator<MyMethodInvocation> getMethodInvocationIterator() {
      	if(this.methodBody != null)
      		return this.methodBody.getMethodInvocationIterator();
      	else
      		return new ArrayList<MyMethodInvocation>().listIterator();
      }
  
      public ListIterator<MyAttributeInstruction> getAttributeInstructionIterator() {
      	if(this.methodBody != null)
      		return this.methodBody.getAttributeInstructionIterator();
      	else
      		return new ArrayList<MyAttributeInstruction>().listIterator();
      }
  
      public int getNumberOfAttributeInstructions() {
      	if(this.methodBody != null)
      		return this.methodBody.getNumberOfAttributeInstructions();
      	else
      		return 0;
      }
  
      public int getNumberOfMethodInvocations() {
      	if(this.methodBody != null)
      		return this.methodBody.getNumberOfMethodInvocations();
      	else return 0;
      }
  
      public int getNumberOfParameters() {
          return this.parameterList.size();
      }
  
      public boolean equals(MyMethodInvocation methodInvocation) {
          return this.classOrigin.equals(methodInvocation.getClassOrigin()) &&
              this.methodName.equals(methodInvocation.getMethodName()) &&
              this.returnType.equals(methodInvocation.getReturnType()) &&
              this.parameterList.equals(methodInvocation.getParameterList());
      }
  
      public boolean equals(Object o) {
          if(this == o) {
              return true;
          }
  
          if (o instanceof MyMethod) {
              MyMethod method = (MyMethod)o;
              return this.classOrigin.equals(method.classOrigin) &&
                  this.methodName.equals(method.methodName) &&
                  this.returnType.equals(method.returnType) &&
                  this.parameterList.equals(method.parameterList);
          }
          return false;
      }
  
      public int hashCode() {
      	if(hashCode == 0) {
      		int result = 17;
      		result = 37*result + classOrigin.hashCode();
      		result = 37*result + methodName.hashCode();
      		result = 37*result + returnType.hashCode();
      		for(String parameter : parameterList) {
      			result = 37*result + parameter.hashCode();
      		}
      		hashCode = result;
      	}
      	return hashCode;
      }
  
      public String toString() {
          StringBuilder sb = new StringBuilder();
          if(!classOrigin.equals(methodName))
              sb.append(classOrigin).append("::");
          sb.append(methodName);
          sb.append("(");
          if(!parameterList.isEmpty()) {
              for(int i=0; i<parameterList.size()-1; i++)
                  sb.append(parameterList.get(i)).append(", ");
              sb.append(parameterList.get(parameterList.size()-1));
          }
          sb.append(")");
          if(returnType != null)
              sb.append(":").append(returnType);
          return sb.toString();
      }
  
      public Set<String> getEntitySet() {
      	Set<String> set = new HashSet<String>();
          ListIterator<MyAttributeInstruction> attributeInstructionIterator = getAttributeInstructionIterator();
          while(attributeInstructionIterator.hasNext()) {
          	MyAttributeInstruction attributeInstruction = attributeInstructionIterator.next();
              if(!attributeInstruction.isReference())
                  set.add(attributeInstruction.toString());
          }
          ListIterator<MyMethodInvocation> methodInvocationIterator = getMethodInvocationIterator();
          while(methodInvocationIterator.hasNext()) {
          	MyMethodInvocation methodInvocation = methodInvocationIterator.next();
              if(!this.equals(methodInvocation))
              	set.add(methodInvocation.toString());
          }
          return set;
      }
  
  	public Set<String> getFullEntitySet() {
  		Set<String> set = new HashSet<String>();
  		set.add(this.toString());
          ListIterator<MyAttributeInstruction> attributeInstructionIterator = getAttributeInstructionIterator();
          while(attributeInstructionIterator.hasNext()) {
          	MyAttributeInstruction attributeInstruction = attributeInstructionIterator.next();
              set.add(attributeInstruction.toString());
          }
          ListIterator<MyMethodInvocation> methodInvocationIterator = getMethodInvocationIterator();
          while(methodInvocationIterator.hasNext()) {
          	MyMethodInvocation methodInvocation = methodInvocationIterator.next();
              set.add(methodInvocation.toString());
          }
          return set;
  	}
  }
  