private static String[] getTypes(ICompareInput input) {
    ITypedElement ancestor = input.getAncestor();
    ITypedElement left = input.getLeft();
    ITypedElement right = input.getRight();

    ArrayList tmp = new ArrayList();
    if (ancestor != null) {
      String type = ancestor.getType();
      if (type != null) tmp.add(normalizeCase(type));
    }
    if (left != null) {
      String type = left.getType();
      if (type != null) tmp.add(normalizeCase(type));
    }
    if (right != null) {
      String type = right.getType();
      if (type != null) tmp.add(normalizeCase(type));
    }
    return (String[]) tmp.toArray(new String[tmp.size()]);
  }
  private DiffNode addDirectoryFiles(ITypedElement elem, int diffType) {
    ITypedElement l = null;
    ITypedElement r = null;
    if (diffType == Differencer.DELETION) {
      r = elem;
    } else {
      l = elem;
    }

    if (elem.getType().equals(ITypedElement.FOLDER_TYPE)) {
      DiffNode diffNode = null;
      diffNode = new DiffNode(null, Differencer.CHANGE, null, l, r);
      ITypedElement[] children = (ITypedElement[]) ((IStructureComparator) elem).getChildren();
      for (ITypedElement child : children) {
        diffNode.add(addDirectoryFiles(child, diffType));
      }
      return diffNode;
    }
    return new DiffNode(diffType, null, l, r);
  }
 /* (non Javadoc)
  * see ITypedElement.getType
  */
 public String getType() {
   ITypedElement id = getId();
   if (id != null) return id.getType();
   return ITypedElement.UNKNOWN_TYPE;
 }
  public ViewerDescriptor[] findContentViewerDescriptor(
      Viewer oldViewer, Object in, CompareConfiguration cc) {
    Set result = new LinkedHashSet();
    if (in instanceof IStreamContentAccessor) {
      String type = ITypedElement.TEXT_TYPE;

      if (in instanceof ITypedElement) {
        ITypedElement tin = (ITypedElement) in;

        IContentType ct = getContentType(tin);
        if (ct != null) {
          initializeRegistries();
          List list = fContentViewers.searchAll(ct);
          if (list != null) result.addAll(list);
        }

        String ty = tin.getType();
        if (ty != null) type = ty;
      }

      initializeRegistries();
      List list = fContentViewers.searchAll(type);
      if (list != null) result.addAll(list);
      // fallback
      result.add(
          fContentViewers.search(
              Platform.getContentTypeManager().getContentType(IContentTypeManager.CT_TEXT)));
      return (ViewerDescriptor[]) result.toArray(new ViewerDescriptor[0]);
    }

    if (!(in instanceof ICompareInput)) return null;

    ICompareInput input = (ICompareInput) in;

    IContentType ctype = getCommonType(input);
    if (ctype != null) {
      initializeRegistries();
      List list = fContentMergeViewers.searchAll(ctype);
      if (list != null) result.addAll(list);
    }

    String[] types = getTypes(input);
    String type = null;
    if (isHomogenous(types)) type = types[0];

    if (ITypedElement.FOLDER_TYPE.equals(type)) return null;

    if (type == null) {
      int n = 0;
      for (int i = 0; i < types.length; i++)
        if (!ITypedElement.UNKNOWN_TYPE.equals(types[i])) {
          n++;
          if (type == null) type = types[i]; // remember the first known type
        }
      if (n > 1) // don't use the type if there were more than one
      type = null;
    }

    if (type != null) {
      initializeRegistries();
      List list = fContentMergeViewers.searchAll(type);
      if (list != null) result.addAll(list);
    }

    // fallback
    String leftType = guessType(input.getLeft());
    String rightType = guessType(input.getRight());

    if (leftType != null || rightType != null) {
      boolean right_text = rightType != null && ITypedElement.TEXT_TYPE.equals(rightType);
      boolean left_text = leftType != null && ITypedElement.TEXT_TYPE.equals(leftType);
      initializeRegistries();
      if ((rightType != null && !right_text) || (leftType != null && !left_text)) {
        List list = fContentMergeViewers.searchAll(BINARY_TYPE);
        if (list != null) result.addAll(list);
      }
      List list = fContentMergeViewers.searchAll(ITypedElement.TEXT_TYPE);
      if (list != null) result.addAll(list);

      return (ViewerDescriptor[]) result.toArray(new ViewerDescriptor[0]);
    }
    return null;
  }
 private DiffNode compare(ITypedElement left, ITypedElement right) {
   if (left.getType().equals(ITypedElement.FOLDER_TYPE)) {
     // return new MyDiffContainer(null, left,right);
     DiffNode diffNode = new DiffNode(null, Differencer.CHANGE, null, left, right);
     ITypedElement[] lc = (ITypedElement[]) ((IStructureComparator) left).getChildren();
     ITypedElement[] rc = (ITypedElement[]) ((IStructureComparator) right).getChildren();
     int li = 0;
     int ri = 0;
     while (li < lc.length && ri < rc.length) {
       ITypedElement ln = lc[li];
       ITypedElement rn = rc[ri];
       int compareTo = ln.getName().compareTo(rn.getName());
       // TODO: Git ordering!
       if (compareTo == 0) {
         if (!ln.equals(rn)) diffNode.add(compare(ln, rn));
         ++li;
         ++ri;
       } else if (compareTo < 0) {
         DiffNode childDiffNode = new DiffNode(Differencer.ADDITION, null, ln, null);
         diffNode.add(childDiffNode);
         if (ln.getType().equals(ITypedElement.FOLDER_TYPE)) {
           ITypedElement[] children = (ITypedElement[]) ((IStructureComparator) ln).getChildren();
           if (children != null && children.length > 0) {
             for (ITypedElement child : children) {
               childDiffNode.add(addDirectoryFiles(child, Differencer.ADDITION));
             }
           }
         }
         ++li;
       } else {
         DiffNode childDiffNode = new DiffNode(Differencer.DELETION, null, null, rn);
         diffNode.add(childDiffNode);
         if (rn.getType().equals(ITypedElement.FOLDER_TYPE)) {
           ITypedElement[] children = (ITypedElement[]) ((IStructureComparator) rn).getChildren();
           if (children != null && children.length > 0) {
             for (ITypedElement child : children) {
               childDiffNode.add(addDirectoryFiles(child, Differencer.DELETION));
             }
           }
         }
         ++ri;
       }
     }
     while (li < lc.length) {
       ITypedElement ln = lc[li];
       DiffNode childDiffNode = new DiffNode(Differencer.ADDITION, null, ln, null);
       diffNode.add(childDiffNode);
       if (ln.getType().equals(ITypedElement.FOLDER_TYPE)) {
         ITypedElement[] children = (ITypedElement[]) ((IStructureComparator) ln).getChildren();
         if (children != null && children.length > 0) {
           for (ITypedElement child : children) {
             childDiffNode.add(addDirectoryFiles(child, Differencer.ADDITION));
           }
         }
       }
       ++li;
     }
     while (ri < rc.length) {
       ITypedElement rn = rc[ri];
       DiffNode childDiffNode = new DiffNode(Differencer.DELETION, null, null, rn);
       diffNode.add(childDiffNode);
       if (rn.getType().equals(ITypedElement.FOLDER_TYPE)) {
         ITypedElement[] children = (ITypedElement[]) ((IStructureComparator) rn).getChildren();
         if (children != null && children.length > 0) {
           for (ITypedElement child : children) {
             childDiffNode.add(addDirectoryFiles(child, Differencer.DELETION));
           }
         }
       }
       ++ri;
     }
     return diffNode;
   }
   return new DiffNode(left, right);
 }