/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.compare.internal;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.preference.IPreferenceStore;

import org.eclipse.ui.internal.SharedImages;
import org.eclipse.core.runtime.*;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.*;
import org.eclipse.compare.*;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.ui.plugin.AbstractUIPlugin;


/**
 * The Compare UI plug-in defines the entry point to initiate a configurable
 * compare operation on arbitrary resources. The result of the compare
 * is opened into a compare editor where the details can be browsed and
 * edited in dynamically selected structure and content viewers.
 * <p>
 * The Compare UI provides a registry for content and structure compare viewers,
 * which is initialized from extensions contributed to extension points
 * declared by this plug-in.
 * <p>
 * This class is the plug-in runtime class for the 
 * <code>"org.eclipse.compare"</code> plug-in.
 * </p>
 */
public final class CompareUIPlugin extends AbstractUIPlugin {
	
	public static final String DTOOL_NEXT= "dlcl16/next_nav.gif";	//$NON-NLS-1$
	public static final String CTOOL_NEXT= "clcl16/next_nav.gif";	//$NON-NLS-1$
	public static final String ETOOL_NEXT= "elcl16/next_nav.gif";	//$NON-NLS-1$
	
	public static final String DTOOL_PREV= "dlcl16/prev_nav.gif";	//$NON-NLS-1$
	public static final String CTOOL_PREV= "clcl16/prev_nav.gif";	//$NON-NLS-1$
	public static final String ETOOL_PREV= "elcl16/prev_nav.gif";	//$NON-NLS-1$
				
	/** Status code describing an internal error */
	public static final int INTERNAL_ERROR= 1;

	private static boolean NORMALIZE_CASE= true;

	private final static String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$
	private final static String EXTENSIONS_ATTRIBUTE= "extensions"; //$NON-NLS-1$

	public static final String PLUGIN_ID= "org.eclipse.compare"; //$NON-NLS-1$

	private static final String STRUCTURE_CREATOR_EXTENSION_POINT= "structureCreators"; //$NON-NLS-1$
	private static final String STRUCTURE_MERGEVIEWER_EXTENSION_POINT= "structureMergeViewers"; //$NON-NLS-1$
	private static final String CONTENT_MERGEVIEWER_EXTENSION_POINT= "contentMergeViewers"; //$NON-NLS-1$
	private static final String CONTENT_VIEWER_EXTENSION_POINT= "contentViewers"; //$NON-NLS-1$
	
	private static final String COMPARE_EDITOR= PLUGIN_ID + ".CompareEditor"; //$NON-NLS-1$
	
	private static final String STRUCTUREVIEWER_ALIASES_PREFERENCE_NAME= "StructureViewerAliases";	//$NON-NLS-1$
	
	/** Maps type to icons */
	private static Map fgImages= new Hashtable(10);
	/** Maps type to ImageDescriptors */
	private static Map fgImageDescriptors= new Hashtable(10);
	/** Maps ImageDescriptors to Images */
	private static Map fgImages2= new Hashtable(10);
	
	private static Map fgStructureCreators= new Hashtable(10);
	private static Map fgStructureViewerDescriptors= new Hashtable(10);
	private static Map fgStructureViewerAliases= new Hashtable(10);
	private static Map fgContentViewerDescriptors= new Hashtable(10);
	private static Map fgContentMergeViewerDescriptors= new Hashtable(10);
	
	private static List fgDisposeOnShutdownImages= new ArrayList();
	
	private static ResourceBundle fgResourceBundle;

	private static CompareUIPlugin fgComparePlugin;

	/**
	 * Creates the <code>CompareUIPlugin</code> object and registers all
	 * structure creators, content merge viewers, and structure merge viewers
	 * contributed to this plug-in's extension points.
	 * <p>
	 * Note that instances of plug-in runtime classes are automatically created 
	 * by the platform in the course of plug-in activation.
	 * </p>
	 *
	 * @param descriptor the plug-in descriptor
	 */
	public CompareUIPlugin(IPluginDescriptor descriptor) {
		super(descriptor);
				
		fgComparePlugin= this;
		
		fgResourceBundle= descriptor.getResourceBundle();
		
		registerExtensions();
		
		initPreferenceStore();
	}
	
	/**
	 * @see AbstractUIPlugin#initializeDefaultPreferences
	 */
	protected void initializeDefaultPreferences(IPreferenceStore store) {
		super.initializeDefaultPreferences(store);
		
		ComparePreferencePage.initDefaults(store);		
	}
	
	/**
	 * Registers all structure creators, content merge viewers, and structure merge viewers
	 * that are found in the XML plugin files.
	 */
	private void registerExtensions() {
		IPluginRegistry registry= Platform.getPluginRegistry();
		
		// collect all IStructureCreators
		IConfigurationElement[] elements= registry.getConfigurationElementsFor(PLUGIN_ID, STRUCTURE_CREATOR_EXTENSION_POINT);
		for (int i= 0; i < elements.length; i++) {
			final IConfigurationElement conf= elements[i];
			String extensions= conf.getAttribute(EXTENSIONS_ATTRIBUTE);
			registerStructureCreator(extensions,
				new IStructureCreatorDescriptor() {
					public IStructureCreator createStructureCreator() {
						try {
							return (IStructureCreator) conf.createExecutableExtension(CLASS_ATTRIBUTE);
						} catch (CoreException ex) {
						}
						return null;
					}
				}
			);
		}
				
		// collect all viewers which define the structure mergeviewer extension point
		elements= registry.getConfigurationElementsFor(PLUGIN_ID, STRUCTURE_MERGEVIEWER_EXTENSION_POINT);
		for (int i= 0; i < elements.length; i++) {
			ViewerDescriptor desc= new ViewerDescriptor(elements[i]);
			String ext= desc.getExtension();
			if (ext != null)
				registerStructureViewerDescriptor(desc.getExtension(), desc);
		}
		
		// collect all viewers which define the content mergeviewer extension point
		elements= registry.getConfigurationElementsFor(PLUGIN_ID, CONTENT_MERGEVIEWER_EXTENSION_POINT);
		for (int i= 0; i < elements.length; i++) {
			ViewerDescriptor desc= new ViewerDescriptor(elements[i]);
			String ext= desc.getExtension();
			if (ext != null)
				registerContentMergeViewerDescriptor(desc.getExtension(), desc);
		}
		
		// 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++) {
			ViewerDescriptor desc= new ViewerDescriptor(elements[i]);
			String ext= desc.getExtension();
			if (ext != null)
				registerContentViewerDescriptor(desc.getExtension(), desc);
		}
	}
	
	/**
	 * Returns the singleton instance of this plug-in runtime class.
	 *
	 * @return the compare plug-in instance
	 */
	public static CompareUIPlugin getDefault() {
		return fgComparePlugin;
	}
	
	/**
	 * Returns this plug-in's resource bundle.
	 *
	 * @return the plugin's resource bundle
	 */
	public static ResourceBundle getResourceBundle() {
		return fgResourceBundle;
	}
	
	public static IWorkbench getActiveWorkbench() {
		CompareUIPlugin plugin= getDefault();
		if (plugin == null)
			return null;
		return plugin.getWorkbench();
	}
	
	public static IWorkbenchWindow getActiveWorkbenchWindow() {
		IWorkbench workbench= getActiveWorkbench();
		if (workbench == null)
			return null;	
		return workbench.getActiveWorkbenchWindow();
	}
	
	/**
	 * Returns the active workkbench page or <code>null</code> if
	 * no active workkbench page can be determined.
	 *
	 * @return the active workkbench page or <code>null</code> if
	 * 	no active workkbench page can be determined
	 */
	private static IWorkbenchPage getActivePage() {
		IWorkbenchWindow window= getActiveWorkbenchWindow();
		if (window == null)
			return null;
		return window.getActivePage();
	}
	
	/**
	 * Returns the SWT Shell of the active workbench window or <code>null</code> if
	 * no workbench window is active.
	 *
	 * @return the SWT Shell of the active workbench window, or <code>null</code> if
	 * 	no workbench window is active
	 */
	public static Shell getShell() {
		IWorkbenchWindow window= getActiveWorkbenchWindow();
		if (window == null)
			return null;
		return window.getShell();
	}

	/**
	 * Registers the given image for being disposed when this plug-in is shutdown.
	 *
	 * @param image the image to register for disposal
	 */
	public static void disposeOnShutdown(Image image) {
		if (image != null)
			fgDisposeOnShutdownImages.add(image);
	}
	
	/* (non-Javadoc)
	 * Method declared on Plugin.
	 * Frees all resources of the compare plug-in.
	 */
	public void shutdown() throws CoreException {
			
		/*
		 * Converts the aliases into a single string before they are stored
		 * in the preference store.
		 * The format is:
		 * <key> '.' <alias> ' ' <key> '.' <alias> ...
		 */
		IPreferenceStore ps= getPreferenceStore();
		if (ps != null) {
			StringBuffer sb= new StringBuffer();
			Iterator iter= fgStructureViewerAliases.keySet().iterator();
			while (iter.hasNext()) {
				String key= (String) iter.next();
				String alias= (String) fgStructureViewerAliases.get(key);
				sb.append(key);
				sb.append('.');
				sb.append(alias);
				sb.append(' ');
			}
			ps.setValue(STRUCTUREVIEWER_ALIASES_PREFERENCE_NAME, sb.toString());
		}
		
		super.shutdown();
		
		if (fgDisposeOnShutdownImages != null) {
			Iterator i= fgDisposeOnShutdownImages.iterator();
			while (i.hasNext()) {
				Image img= (Image) i.next();
				if (!img.isDisposed())
					img.dispose();
			}
			fgImages= null;
		}
	}
	
	/**
	 * Performs the comparison described by the given input and opens a
	 * compare editor on the result.
	 *
	 * @param input the input on which to open the compare editor
	 * @see CompareEditorInput
	 */
	public void openCompareEditor(CompareEditorInput input) {
		
		if (compareResultOK(input)) {				
			IWorkbenchPage activePage= getActivePage();
			if (activePage != null) {
				try {
					activePage.openEditor(input, COMPARE_EDITOR);
				} catch (PartInitException e) {
					MessageDialog.openError(getShell(), Utilities.getString("CompareUIPlugin.openEditorError"), e.getMessage()); //$NON-NLS-1$
				}
			} else {
				MessageDialog.openError(getShell(),
						Utilities.getString("CompareUIPlugin.openEditorError"), //$NON-NLS-1$
						Utilities.getString("CompareUIPlugin.noActiveWorkbenchPage")); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Performs the comparison described by the given input and opens a
	 * compare dialog on the result.
	 *
	 * @param input the input on which to open the compare editor
	 * @see CompareEditorInput
	 */
	public void openCompareDialog(final CompareEditorInput input) {
				
		if (compareResultOK(input)) {
			CompareDialog dialog= new CompareDialog(getShell(), input);
			dialog.open();
		}
	}
	
	/**
	 * @return <code>true</code> if compare result is OK to show, <code>false</code> otherwise
	 */
	private boolean compareResultOK(CompareEditorInput input) {
		final Shell shell= getShell();
		try {
			
			// run operation in separate thread and make it canceable
			new ProgressMonitorDialog(shell).run(true, true, input);
			
			String message= input.getMessage();
			if (message != null) {
				MessageDialog.openError(shell, Utilities.getString("CompareUIPlugin.compareFailed"), message); //$NON-NLS-1$
				return false;
			}
			
			if (input.getCompareResult() == null) {
				MessageDialog.openInformation(shell, Utilities.getString("CompareUIPlugin.dialogTitle"), Utilities.getString("CompareUIPlugin.noDifferences")); //$NON-NLS-2$ //$NON-NLS-1$
				return false;
			}
			
			return true;

		} catch (InterruptedException x) {
			// cancelled by user		
		} catch (InvocationTargetException x) {
			MessageDialog.openError(shell, Utilities.getString("CompareUIPlugin.compareFailed"), x.getTargetException().getMessage()); //$NON-NLS-1$
		}
		return false;
	}
		
	/**
	 * Registers an image for the given type.
	 */
	private static void registerImage(String type, Image image, boolean dispose) {
		fgImages.put(normalizeCase(type), image);
		if (image != null && dispose) {
			fgDisposeOnShutdownImages.add(image);
		}
	}
	
	/**
	 * Registers an image descriptor for the given type.
	 *
	 * @param type the type
	 * @param descriptor the image descriptor
	 */
	public static void registerImageDescriptor(String type, ImageDescriptor descriptor) {
		fgImageDescriptors.put(normalizeCase(type), descriptor);
	}
	
	public static ImageDescriptor getImageDescriptor(String relativePath) {
		
		URL installURL= null;
		if (fgComparePlugin != null)
			installURL= fgComparePlugin.getDescriptor().getInstallURL();
					
		if (installURL != null) {
			try {
				URL url= new URL(installURL, Utilities.getIconPath(null) + relativePath);
				return ImageDescriptor.createFromURL(url);
			} catch (MalformedURLException e) {
				Assert.isTrue(false);
			}
		}
		return null;
	}
	
	/**
	 * Returns a shared image for the given type, or a generic image if none
	 * has been registered for the given type.
	 * <p>
	 * Note: Images returned from this method will be automitically disposed
	 * of when this plug-in shuts down. Callers must not dispose of these
	 * images themselves.
	 * </p>
	 *
	 * @param type the type
	 * @return the image
	 */
	public static Image getImage(String type) {
		
		type= normalizeCase(type);
		
		boolean dispose= false;
		Image image= null;
		if (type != null)
			image= (Image) fgImages.get(type);
		if (image == null) {
			ImageDescriptor id= (ImageDescriptor) fgImageDescriptors.get(type);
			if (id != null) {
				image= id.createImage();
				dispose= true;
			}
				
			if (image == null) {
				if (fgComparePlugin != null) {
					if (ITypedElement.FOLDER_TYPE.equals(type)) {
						image= getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
						//image= SharedImages.getImage(ISharedImages.IMG_OBJ_FOLDER);
					} else {
						image= createWorkbenchImage(type);
						dispose= true;
					}
				} else {
					id= (ImageDescriptor) fgImageDescriptors.get(normalizeCase("file")); //$NON-NLS-1$
					image= id.createImage();
					dispose= true;
				}
			}
			if (image != null)
				registerImage(type, image, dispose);
		}
		return image;
	}
	
	/**
	 * Returns a shared image for the given adaptable.
	 * This convenience method queries the given adaptable
	 * for its <code>IWorkbenchAdapter.getImageDescriptor</code>, which it
	 * uses to create an image if it does not already have one.
	 * <p>
	 * Note: Images returned from this method will be automitically disposed
	 * of when this plug-in shuts down. Callers must not dispose of these
	 * images themselves.
	 * </p>
	 *
	 * @param adaptable the adaptable for which to find an image
	 * @return an image
	 */
	public static Image getImage(IAdaptable adaptable) {
		if (adaptable != null) {
			Object o= adaptable.getAdapter(IWorkbenchAdapter.class);
			if (o instanceof IWorkbenchAdapter) {
				ImageDescriptor id= ((IWorkbenchAdapter) o).getImageDescriptor(adaptable);
				if (id != null) {
					Image image= (Image)fgImages2.get(id);
					if (image == null) {
						image= id.createImage();
						try {
							fgImages2.put(id, image);
						} catch (NullPointerException ex) {
						}
						fgDisposeOnShutdownImages.add(image);

					}
					return image;
				}
			}
		}
		return null;
	}
	
	private static Image createWorkbenchImage(String type) {
		IEditorRegistry er= getDefault().getWorkbench().getEditorRegistry();
		ImageDescriptor id= er.getImageDescriptor("foo." + type); //$NON-NLS-1$
		return id.createImage();
	}
	
	/**
	 * Registers the given structure creator descriptor for one or more types.
	 *
	 * @param types one or more types separated by commas and whitespace
	 * @param descriptor the descriptor to register
	 */
	public static void registerStructureCreator(String types, IStructureCreatorDescriptor descriptor) {
		if (types != null) {
			StringTokenizer tokenizer= new StringTokenizer(types, ","); //$NON-NLS-1$
			while (tokenizer.hasMoreElements()) {
				String extension= tokenizer.nextToken().trim();
				fgStructureCreators.put(normalizeCase(extension), descriptor);
			}
		}
	}
	
	/**
	 * 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 static IStructureCreatorDescriptor getStructureCreator(String type) {
		return (IStructureCreatorDescriptor) fgStructureCreators.get(normalizeCase(type));
	}
	
	/**
	 * Registers the given structure viewer descriptor for one or more types.
	 *
	 * @param types one or more types separated by commas and whitespace
	 * @param the descriptor to register
	 */
	public static void registerStructureViewerDescriptor(String types, IViewerDescriptor descriptor) {
		StringTokenizer tokenizer= new StringTokenizer(types, ","); //$NON-NLS-1$
		while (tokenizer.hasMoreElements()) {
			String extension= tokenizer.nextToken().trim();
			fgStructureViewerDescriptors.put(normalizeCase(extension), descriptor);
		}
	}
	
	/**
	 * Registers the given content merge viewer descriptor for one or more types.
	 *
	 * @param types one or more types separated by commas and whitespace
	 * @param descriptor the descriptor to register
	 */
	public static void registerContentMergeViewerDescriptor(String types, IViewerDescriptor descriptor) {
		StringTokenizer tokenizer= new StringTokenizer(types, ","); //$NON-NLS-1$
		while (tokenizer.hasMoreElements()) {
			String extension= tokenizer.nextToken().trim();
			fgContentMergeViewerDescriptors.put(normalizeCase(extension), descriptor);
		}
	}
	
	/**
	 * Registers the given content viewer descriptor for one or more types.
	 *
	 * @param types one or more types separated by commas and whitespace
	 * @param descriptor the descriptor to register
	 */
	public static void registerContentViewerDescriptor(String types, IViewerDescriptor descriptor) {
		StringTokenizer tokenizer= new StringTokenizer(types, ","); //$NON-NLS-1$
		while (tokenizer.hasMoreElements()) {
			String extension= tokenizer.nextToken().trim();
			fgContentViewerDescriptors.put(normalizeCase(extension), descriptor);
		}
	}
		
	/**
	 * 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 static Viewer findStructureViewer(Viewer oldViewer, ICompareInput input, Composite parent,
				CompareConfiguration configuration) {

		if (input.getLeft() == null || input.getRight() == null)	// we don't show the structure of additions or deletions
			return null;
			
		String type= getType(input);
		if (type == null)
			return null;
			
		type= normalizeCase(type);
			
		IViewerDescriptor vd= (IViewerDescriptor) fgStructureViewerDescriptors.get(type);
		if (vd == null) {
			String alias= (String) fgStructureViewerAliases.get(type);
			if (alias != null)
				vd= (IViewerDescriptor) fgStructureViewerDescriptors.get(alias);
		}
		if (vd != null)
			return vd.createViewer(oldViewer, parent, configuration);
			
		IStructureCreatorDescriptor scc= getStructureCreator(type);
		if (scc != null) {
			IStructureCreator sc= scc.createStructureCreator();
			if (sc != null) {
				StructureDiffViewer sdv= new StructureDiffViewer(parent, configuration);
				sdv.setStructureCreator(sc);
				return sdv;
			}
		}
		return null;
	}
	
	/**
	 * Returns a content 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 content 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 content 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 static Viewer findContentViewer(Viewer oldViewer, Object in, Composite parent, CompareConfiguration cc) {
		
		if (in instanceof IStreamContentAccessor) {
			String type= ITypedElement.TEXT_TYPE;
			
			if (in instanceof ITypedElement) {
				ITypedElement tin= (ITypedElement) in;
				String ty= tin.getType();
				if (ty != null)
					type= ty;
			}
			type= normalizeCase(type);
			
			IViewerDescriptor vd= (IViewerDescriptor) fgContentViewerDescriptors.get(type);
			Viewer viewer= null;
			if (vd != null) {
				viewer= vd.createViewer(oldViewer, parent, cc);
				if (viewer != null)
					return viewer;
			}
			// fallback
			return new SimpleTextViewer(parent);
		}

		if (!(in instanceof ICompareInput))
			return null;
			
		ICompareInput input= (ICompareInput) in;
		String type= getType(input);
		type= normalizeCase(type);
		
		if (ITypedElement.FOLDER_TYPE.equals(type))
			return null;
			
		if (type != null) {
			IViewerDescriptor vd= (IViewerDescriptor) fgContentMergeViewerDescriptors.get(type);
			Viewer viewer= null;
			if (vd != null) {
				viewer= vd.createViewer(oldViewer, parent, cc);
				if (viewer != null)
					return viewer;
			}
		}
		
		// 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);
			if ((leftType == null && right_text) || (left_text && rightType == null) || (left_text && right_text))
				type= ITypedElement.TEXT_TYPE;
			else
				type= "binary"; //$NON-NLS-1$
			
			IViewerDescriptor vd= (IViewerDescriptor) fgContentMergeViewerDescriptors.get(normalizeCase(type));
			if (vd != null)
				return vd.createViewer(oldViewer, parent, cc);
		}
		return null;
	}
		
	/**
	 * Determines the type of the given threeway input by analyzing
	 * the types (file extension) of the individual parts.
	 * Returns null if no type can be determined.
	 */
	private static String getType(ICompareInput input) {
		ITypedElement ancestor= input.getAncestor();
		ITypedElement left= input.getLeft();
		ITypedElement right= input.getRight();
		
		String[] types= new String[3];
		int cnt= 0;
		
		if (ancestor != null) {
			String type= ancestor.getType();
			if (type != null)
				types[cnt++]= type;
		}
		if (left != null) {
			String type= left.getType();
			if (type != null)
				types[cnt++]= type;
		}
		if (right != null) {
			String type= right.getType();
			if (type != null)
				types[cnt++]= type;
		}
		boolean homogenous= false;
		switch (cnt) {
		case 1:
			homogenous= true;
			break;
		case 2:
			homogenous= types[0].equals(types[1]);
			break;
		case 3:
			homogenous= types[0].equals(types[1]) && types[1].equals(types[2]);
			break;
		}
		if (homogenous)
			return types[0];
		return null;
	}
	
	/**
	 * Guesses the file type of the given input.
	 * Returns ITypedElement.TEXT_TYPE if none of the first 10 lines is longer than 1000 bytes.
	 * Returns ITypedElement.UNKNOWN_TYPE otherwise.
	 * Returns <code>null</code> if the input isn't an <code>IStreamContentAccessor</code>.
	 */
	private static String guessType(ITypedElement input) {
		if (input instanceof IStreamContentAccessor) {
			IStreamContentAccessor sca= (IStreamContentAccessor) input;
			InputStream is= null;
			try {
				is= sca.getContents();
				if (is == null)
					return null;
				int lineLength= 0;
				int lines= 0;
				while (lines < 10) {
					int c= is.read();
					if (c == -1)	// EOF
						break;
					if (c == '\n' || c == '\r') { // reset line length
						lineLength= 0;
						lines++;
					} else
						lineLength++;
					if (lineLength > 1000)
						return ITypedElement.UNKNOWN_TYPE;
				}
				return ITypedElement.TEXT_TYPE;
			} catch (CoreException ex) {
				// be silent and return UNKNOWN_TYPE
			} catch (IOException ex) {
				// be silent and return UNKNOWN_TYPE
			} finally {
				if (is != null) {
					try {
						is.close();
					} catch (IOException ex) {
					}
				}
			}
			return ITypedElement.UNKNOWN_TYPE;
		}
		return null;
	}
	
	private static IViewerDescriptor getContentViewerDescriptor2(String type) {
		return (IViewerDescriptor) fgContentMergeViewerDescriptors.get(normalizeCase(type));
	}
	
	private static String normalizeCase(String s) {
		if (NORMALIZE_CASE && s != null)
			return s.toUpperCase();
		return s;
	}
	
	//---- alias mgmt
	
	private void initPreferenceStore() {
		//System.out.println("initPreferenceStore");
		IPreferenceStore ps= getPreferenceStore();
		if (ps != null) {
			String aliases= ps.getString(STRUCTUREVIEWER_ALIASES_PREFERENCE_NAME);
			//System.out.println("  <" + aliases + ">");
			if (aliases != null && aliases.length() > 0) {
				StringTokenizer st= new StringTokenizer(aliases, " ");	//$NON-NLS-1$
				while (st.hasMoreTokens()) {
					String pair= st.nextToken();
					int pos= pair.indexOf('.');
					if (pos > 0) {
						String key= pair.substring(0, pos);
						String alias= pair.substring(pos+1);
						fgStructureViewerAliases.put(key, alias);
						//System.out.println("<" + key + "><" + alias + ">");
					}
				}
			}
		}		
	}
	
	public static void addStructureViewerAlias(String type, String alias) {
		//System.out.println("addStructureViewerAlias: " + type + " " + alias);
		fgStructureViewerAliases.put(normalizeCase(alias), normalizeCase(type));
	}
	
	public static void removeAllStructureViewerAliases(String type) {
		String t= normalizeCase(type);
		Set entrySet= fgStructureViewerAliases.entrySet();
		for (Iterator iter= entrySet.iterator(); iter.hasNext(); ) {
			Map.Entry entry= (Map.Entry)iter.next();
			if (entry.getValue().equals(t))
				iter.remove();
		}
	}
	
	/**
	 * Returns an array of all editors that have an unsaved content. If the identical content is 
	 * presented in more than one editor, only one of those editor parts is part of the result.
	 * 
	 * @return an array of all dirty editor parts.
	 */
	public static IEditorPart[] getDirtyEditors() {
		Set inputs= new HashSet(7);
		ArrayList result= new ArrayList(0);
		IWorkbench workbench= CompareUIPlugin.getDefault().getWorkbench();
		IWorkbenchWindow[] windows= workbench.getWorkbenchWindows();
		for (int i= 0; i < windows.length; i++) {
			IWorkbenchPage[] pages= windows[i].getPages();
			for (int x= 0; x < pages.length; x++) {
				IEditorPart[] editors= pages[x].getEditors();
				for (int z= 0; z < editors.length; z++) {
					IEditorPart editor= editors[z];
					IEditorInput input= editor.getEditorInput();
					if (editor.isDirty() && !inputs.contains(input)) {
						inputs.add(input);
						result.add(editor);
					}
				}
			}
		}
		return (IEditorPart[])result.toArray(new IEditorPart[result.size()]);
	}
	
	public static void log(Throwable e) {
		log(new Status(IStatus.ERROR, getPluginId(), INTERNAL_ERROR, CompareMessages.getString("ComparePlugin.internal_error"), e)); //$NON-NLS-1$
	}
	
	public static void log(IStatus status) {
		getDefault().getLog().log(status);
	}
	
	public static String getPluginId() {
		return getDefault().getDescriptor().getUniqueIdentifier();
	}
}
