code: package gr.uom.java.ast.delegation;
  
  import gr.uom.java.ast.*;
  
  import javax.swing.tree.DefaultMutableTreeNode;
  import java.util.Enumeration;
  import java.util.List;
  import java.util.ArrayList;
  
  
  public class DelegationTree {
      private DefaultMutableTreeNode rootNode;
      private SystemObject systemObject;
  
      public DelegationTree(SystemObject systemObject, MethodObject methodObject) {
          rootNode = new DefaultMutableTreeNode(methodObject);
          this.systemObject = systemObject;
          getDelegations(rootNode);
      }
  
      private void getDelegations(DefaultMutableTreeNode node) {
          MethodObject methodObject = (MethodObject)node.getUserObject();
          if(methodObject != null) {
              List<MethodInvocationObject> methodInvocationList = methodObject.getMethodInvocations();
              for(MethodInvocationObject mio : methodInvocationList) {
                  //int methodPos = systemObject.getPositionInClassList(methodObject.getClassName());
                  int methodInvocationPos = systemObject.getPositionInClassList(mio.getOriginClassName());
                  if(methodInvocationPos != -1) {
  	                MethodObject methodInvocation = systemObject.getClassObject(mio.getOriginClassName()).getMethod(mio);
  	                // methodPos != methodInvocationPos -> removes self-delegations
  	                // !existsNode(node.children(),methodInvocation) -> removes duplicate delegations
  	                // !existsNode(node.getUserObjectPath(),methodInvocation) -> avoids cyclic delegations
  	                if(!existsNode(node.children(),methodInvocation) && !existsNode(node.getUserObjectPath(),methodInvocation)) {
  	                    DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(methodInvocation);
  	                    node.add(childNode);
  	                    getDelegations(childNode);
  	                }
                  }
              }
          }
      }
  
      private boolean existsNode(Object[] path, MethodObject mo) {
          for(Object pathLevel : path) {
              if(mo.equals(pathLevel))
                  return true;
          }
          return false;
      }
  
      private boolean existsNode(Enumeration<DefaultMutableTreeNode> children, MethodObject mo) {
          while(children.hasMoreElements()) {
              DefaultMutableTreeNode child = children.nextElement();
              MethodObject childMethodObject = (MethodObject)child.getUserObject();
              if(childMethodObject.equals(mo))
                  return true;
          }
          return false;
      }
  
      public int getDepth() {
          return rootNode.getDepth();
      }
  
      public List<DelegationPath> getDelegationPathList() {
          List<DelegationPath> pathList = new ArrayList<DelegationPath>();
  
          DefaultMutableTreeNode leaf = rootNode.getFirstLeaf();
          while(leaf != null) {
              Object[] path = leaf.getUserObjectPath();
              DelegationPath delegationPath = new DelegationPath();
              for (Object pathLevel : path) {
                  MethodObject mo = (MethodObject)pathLevel;
                  delegationPath.addMethodInvocation(mo);
              }
              pathList.add(delegationPath);
              leaf = leaf.getNextLeaf();
          }
          return pathList;
      }
  }
  