public ViewerDescriptor[] findStructureViewerDescriptor(
      Viewer oldViewer, ICompareInput input, CompareConfiguration configuration) {
    if (input == null) return null;
    // we don't show the structure of additions or deletions
    if (input == null || input.getLeft() == null || input.getRight() == null) return null;

    Set result = new LinkedHashSet();

    // content type search
    IContentType ctype = getCommonType(input);
    if (ctype != null) {
      initializeRegistries();
      List list = fStructureMergeViewers.searchAll(ctype);
      if (list != null) result.addAll(list);
    }

    // old style search
    String[] types = getTypes(input);
    String type = null;
    if (isHomogenous(types)) {
      type = normalizeCase(types[0]);
      initializeRegistries();
      List list = fStructureMergeViewers.searchAll(type);
      if (list != null) result.addAll(list);
      String alias = getStructureViewerAlias(type);
      if (alias != null) {
        list = fStructureMergeViewers.searchAll(alias);
        if (list != null) result.addAll(list);
      }
    }

    return result.size() > 0 ? (ViewerDescriptor[]) result.toArray(new ViewerDescriptor[0]) : null;
  }
  String findStructureTypeNameOrType(
      ICompareInput input, ViewerDescriptor vd, CompareConfiguration cc) {
    if (input == null) return null;
    // we don't show the structure of additions or deletions
    if (input == null || input.getLeft() == null || input.getRight() == null) return null;

    // content type search
    IContentType ctype = getCommonType(input);
    if (ctype != null) {
      initializeRegistries();
      List list = fStructureMergeViewers.searchAll(ctype);
      if (list != null) if (list.contains(vd)) return ctype.getName();
    }

    // old style search
    String[] types = getTypes(input);
    String type = null;
    if (isHomogenous(types)) {
      type = normalizeCase(types[0]);
      initializeRegistries();
      List list = fStructureMergeViewers.searchAll(type);
      if (list != null) if (list.contains(vd)) return type;
      String alias = getStructureViewerAlias(type);
      if (alias != null) {
        list = fStructureMergeViewers.searchAll(alias);
        if (list != null) if (list.contains(vd)) return alias;
      }
    }

    return null;
  }
  String findContentTypeNameOrType(
      ICompareInput input, ViewerDescriptor vd, CompareConfiguration cc) {
    IContentType ctype = getCommonType(input);
    if (ctype != null) {
      initializeRegistries();
      List list = fContentMergeViewers.searchAll(ctype);
      if (list != null) if (list.contains(vd)) return ctype.getName();
    }

    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) if (list.contains(vd)) return type;
    }

    // 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) if (list.contains(vd)) return type;
      }
      List list = fContentMergeViewers.searchAll(ITypedElement.TEXT_TYPE);
      if (list != null) if (list.contains(vd)) return type;
    }
    return null;
  }
  /**
   * Returns a structure compare viewer based on an old viewer and an input object. If the old
   * viewer is suitable for showing the input, the old viewer is returned. Otherwise, the input's
   * type is used to find a viewer descriptor in the registry which in turn is used to create a
   * structure compare viewer under the given parent composite. If no viewer descriptor can be found
   * <code>null</code> is returned.
   *
   * @param oldViewer a new viewer is only created if this old viewer cannot show the given input
   * @param input the input object for which to find a structure viewer
   * @param parent the SWT parent composite under which the new viewer is created
   * @param configuration a configuration which is passed to a newly created viewer
   * @return the compare viewer which is suitable for the given input object or <code>null</code>
   */
  public Viewer findStructureViewer(
      Viewer oldViewer, ICompareInput input, Composite parent, CompareConfiguration configuration) {
    ViewerDescriptor[] descriptors = findStructureViewerDescriptor(oldViewer, input, configuration);
    if (descriptors == null || descriptors.length == 0) {
      // we didn't found any viewer so far.
      // now we try to find a structure creator for the generic StructureDiffViewer
      IContentType ctype = getCommonType(input);

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

      StructureCreatorDescriptor scc = null;
      initializeRegistries();
      Object desc = fStructureCreators.search(ctype); // search for content type
      if (desc instanceof StructureCreatorDescriptor) scc = (StructureCreatorDescriptor) desc;
      if (scc == null && type != null)
        scc = getStructureCreator(type); // search for old-style type scheme
      if (scc != null) {
        IStructureCreator sc = scc.createStructureCreator();
        if (sc != null) {
          StructureDiffViewer sdv = new StructureDiffViewer(parent, configuration);
          sdv.setStructureCreator(sc);
          return sdv;
        }
      }
      return null;
    }
    return getViewer(descriptors[0], oldViewer, parent, configuration);
  }
  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;
  }
 /**
  * Returns a stream merger for the given content type.
  *
  * @param type the type for which to find a stream merger
  * @return a stream merger for the given type, or <code>null</code> if no stream merger has been
  *     registered
  */
 public IStreamMerger createStreamMerger(IContentType type) {
   initializeRegistries();
   StreamMergerDescriptor descriptor = (StreamMergerDescriptor) fStreamMergers.search(type);
   if (descriptor != null) return descriptor.createStreamMerger();
   return null;
 }
 /**
  * Returns an structure creator descriptor for the given type.
  *
  * @param type the type for which to find a descriptor
  * @return a descriptor for the given type, or <code>null</code> if no descriptor has been
  *     registered
  */
 public StructureCreatorDescriptor getStructureCreator(String type) {
   initializeRegistries();
   return (StructureCreatorDescriptor) fStructureCreators.search(type);
 }
  /**
   * Registers all stream mergers, structure creators, content merge viewers, and structure merge
   * viewers that are found in the XML plugin files.
   */
  private void registerExtensions() {
    IExtensionRegistry registry = Platform.getExtensionRegistry();

    // collect all IStreamMergers
    IConfigurationElement[] elements =
        registry.getConfigurationElementsFor(PLUGIN_ID, STREAM_MERGER_EXTENSION_POINT);
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      if (STREAM_MERGER.equals(element.getName()))
        fStreamMergers.register(element, new StreamMergerDescriptor(element));
    }
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      if (CONTENT_TYPE_BINDING.equals(element.getName()))
        fStreamMergers.createBinding(element, STREAM_MERGER_ID_ATTRIBUTE);
    }

    // collect all IStructureCreators
    elements = registry.getConfigurationElementsFor(PLUGIN_ID, STRUCTURE_CREATOR_EXTENSION_POINT);
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      String name = element.getName();
      if (!CONTENT_TYPE_BINDING.equals(name)) {
        if (!STRUCTURE_CREATOR.equals(name))
          logErrorMessage(
              Utilities.getFormattedString(
                  "CompareUIPlugin.unexpectedTag",
                  name,
                  STRUCTURE_CREATOR)); //$NON-NLS-1$
        fStructureCreators.register(element, new StructureCreatorDescriptor(element));
      }
    }
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      if (CONTENT_TYPE_BINDING.equals(element.getName()))
        fStructureCreators.createBinding(element, STRUCTURE_CREATOR_ID_ATTRIBUTE);
    }

    // collect all viewers which define the structure merge viewer extension point
    elements =
        registry.getConfigurationElementsFor(PLUGIN_ID, STRUCTURE_MERGE_VIEWER_EXTENSION_POINT);
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      String name = element.getName();
      if (!CONTENT_TYPE_BINDING.equals(name)) {
        if (!VIEWER_TAG.equals(name))
          logErrorMessage(
              Utilities.getFormattedString(
                  "CompareUIPlugin.unexpectedTag", name, VIEWER_TAG)); // $NON-NLS-1$		
        fStructureMergeViewers.register(element, new ViewerDescriptor(element));
      }
    }
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      if (CONTENT_TYPE_BINDING.equals(element.getName()))
        fStructureMergeViewers.createBinding(element, STRUCTURE_MERGE_VIEWER_ID_ATTRIBUTE);
    }

    // collect all viewers which define the content merge viewer extension point
    elements =
        registry.getConfigurationElementsFor(PLUGIN_ID, CONTENT_MERGE_VIEWER_EXTENSION_POINT);
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      String name = element.getName();
      if (!CONTENT_TYPE_BINDING.equals(name)) {
        if (!VIEWER_TAG.equals(name))
          logErrorMessage(
              Utilities.getFormattedString(
                  "CompareUIPlugin.unexpectedTag", name, VIEWER_TAG)); // $NON-NLS-1$		
        fContentMergeViewers.register(element, new ViewerDescriptor(element));
      }
    }
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      if (CONTENT_TYPE_BINDING.equals(element.getName()))
        fContentMergeViewers.createBinding(element, CONTENT_MERGE_VIEWER_ID_ATTRIBUTE);
    }

    // collect all viewers which define the content viewer extension point
    elements = registry.getConfigurationElementsFor(PLUGIN_ID, CONTENT_VIEWER_EXTENSION_POINT);
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      String name = element.getName();
      if (!CONTENT_TYPE_BINDING.equals(name)) {
        if (!VIEWER_TAG.equals(name))
          logErrorMessage(
              Utilities.getFormattedString(
                  "CompareUIPlugin.unexpectedTag", name, VIEWER_TAG)); // $NON-NLS-1$		
        fContentViewers.register(element, new ViewerDescriptor(element));
      }
    }
    for (int i = 0; i < elements.length; i++) {
      IConfigurationElement element = elements[i];
      if (CONTENT_TYPE_BINDING.equals(element.getName()))
        fContentViewers.createBinding(element, CONTENT_VIEWER_ID_ATTRIBUTE);
    }
  }