/*******************************************************************************
 * Copyright (c) 2003, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.ide;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeMatcher;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IMarkerHelpRegistry;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.EditorManager;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.registry.MarkerHelpRegistry;
import org.eclipse.ui.internal.ide.registry.MarkerHelpRegistryReader;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.part.FileEditorInput;

/**
 * Collection of IDE-specific APIs factored out of existing workbench.
 * This class cannot be instantiated; all functionality is provided by 
 * static methods and fields.
 * 
 * @since 3.0
 */
public final class IDE {
    /**
     * The persistent property key used on IFile resources to contain
     * the preferred editor ID to use.
     * <p>
     * Example of retrieving the persisted editor id:
     * <pre><code>
     * IFile file = ...
     * IEditorDescriptor editorDesc = null;
     * try {
     * 	String editorID = file.getPersistentProperty(EDITOR_KEY);
     * 	if (editorID != null) {
     * 		editorDesc = editorReg.findEditor(editorID);
     * 	}
     * } catch (CoreException e) {
     * 	// handle problem accessing persistent property here
     * }
     * </code></pre>
     * </p><p>
     * Example of persisting the editor id:
     * <pre><code>
     * IFile file = ...
     * try {
     * 	file.setPersistentProperty(EDITOR_KEY, editorDesc.getId());
     * } catch (CoreException e) {
     * 	// handle problem setting persistent property here
     * }
     * </code></pre>
     * </p>
     */
    public static final QualifiedName EDITOR_KEY = new QualifiedName(
            "org.eclipse.ui.internal.registry.ResourceEditorRegistry", "EditorProperty");//$NON-NLS-2$//$NON-NLS-1$

    /**
     * An optional attribute within a workspace marker (<code>IMarker</code>) which
     * identifies the preferred editor type to be opened.
     */
    public static final String EDITOR_ID_ATTR = "org.eclipse.ui.editorID"; //$NON-NLS-1$

    /**
     * The resource based perspective identifier.
     */
    public static final String RESOURCE_PERSPECTIVE_ID = "org.eclipse.ui.resourcePerspective"; //$NON-NLS-1$

    /**
     * Marker help registry mapping markers to help context ids and resolutions;
     * lazily initialized on fist access.
     */
    private static MarkerHelpRegistry markerHelpRegistry = null;

    /**
     * Standard shared images defined by the IDE. These are over and above the
     * standard workbench images declared in {@link org.eclipse.ui.ISharedImages
     * ISharedImages}.
     * <p>
     * This interface is not intended to be implemented by clients.
     * </p>
     * 
     * @see org.eclipse.ui.ISharedImages
     */
    public interface SharedImages {
        /**
         * Identifies a project image.
         */
        public final static String IMG_OBJ_PROJECT = "IMG_OBJ_PROJECT"; //$NON-NLS-1$

        /**
         * Identifies a closed project image.
         */
        public final static String IMG_OBJ_PROJECT_CLOSED = "IMG_OBJ_PROJECT_CLOSED"; //$NON-NLS-1$

        /**
         * Identifies the image used for "open marker".
         */
        public final static String IMG_OPEN_MARKER = "IMG_OPEN_MARKER"; //$NON-NLS-1$

        /**
         * Identifies the default image used to indicate a task.
         */
        public final static String IMG_OBJS_TASK_TSK = "IMG_OBJS_TASK_TSK"; //$NON-NLS-1$

        /**
         * Identifies the default image used to indicate a bookmark.
         */
        public final static String IMG_OBJS_BKMRK_TSK = "IMG_OBJS_BKMRK_TSK"; //$NON-NLS-1$
    }

    /**
     * Preferences defined by the IDE workbench.
     * <p>
     * This interface is not intended to be implemented by clients.
     * </p>
     */
    public interface Preferences {
        
        /**
         * A named preference for how a new perspective should be opened
         * when a new project is created.
         * <p>
         * Value is of type <code>String</code>.  The possible values are defined 
         * by the constants <code>OPEN_PERSPECTIVE_WINDOW, OPEN_PERSPECTIVE_PAGE, 
         * OPEN_PERSPECTIVE_REPLACE, and NO_NEW_PERSPECTIVE</code>.
         * </p>
         * 
         * @see org.eclipse.ui.IWorkbenchPreferenceConstants#OPEN_PERSPECTIVE_WINDOW
         * @see org.eclipse.ui.IWorkbenchPreferenceConstants#OPEN_PERSPECTIVE_PAGE
         * @see org.eclipse.ui.IWorkbenchPreferenceConstants#OPEN_PERSPECTIVE_REPLACE
         * @see org.eclipse.ui.IWorkbenchPreferenceConstants#NO_NEW_PERSPECTIVE
         */
        public static final String PROJECT_OPEN_NEW_PERSPECTIVE = "PROJECT_OPEN_NEW_PERSPECTIVE"; //$NON-NLS-1$
        
        /**
         * <p>
         * Specifies whether or not the workspace selection dialog should be shown on startup.
         * </p>
         * <p>
         * The default value for this preference is <code>true</code>.
         * </p>
         * 
         * @since 3.1
         */
        public static final String SHOW_WORKSPACE_SELECTION_DIALOG = "SHOW_WORKSPACE_SELECTION_DIALOG"; //$NON-NLS-1$

        /**
         * <p>
         * Stores the maximum number of workspaces that should be displayed in the
         * ChooseWorkspaceDialog.
         * </p>
         * 
         * @since 3.1
         */
        public static final String MAX_RECENT_WORKSPACES = "MAX_RECENT_WORKSPACES"; //$NON-NLS-1$

        /**
         * <p>
         * Stores a comma separated list of the recently used workspace paths.
         * </p>
         * 
         * @since 3.1
         */
        public static final String RECENT_WORKSPACES = "RECENT_WORKSPACES"; //$NON-NLS-1$

        /**
         * <p>
         * Stores the version of the protocol used to decode/encode the list of recent workspaces.
         * </p>
         * 
         * @since 3.1
         */
        public static final String RECENT_WORKSPACES_PROTOCOL = "RECENT_WORKSPACES_PROTOCOL"; //$NON-NLS-1$
        
    }

    /**
     * Block instantiation.
     */
    private IDE() {
        // do nothing
    }

    /**
     * Returns the marker help registry for the workbench.
     * 
     * @return the marker help registry
     */
    public static IMarkerHelpRegistry getMarkerHelpRegistry() {
        if (markerHelpRegistry == null) {
            markerHelpRegistry = new MarkerHelpRegistry();
            new MarkerHelpRegistryReader().addHelp(markerHelpRegistry);
        }
        return markerHelpRegistry;
    }

    /**
     * Sets the cursor and selection state for the given editor to 
     * reveal the position of the given marker.
     * This is done on a best effort basis.  If the editor does not
     * provide an <code>IGotoMarker</code> interface (either directly
     * or via <code>IAdaptable.getAdapter</code>), this has no effect.
     * 
     * @param editor the editor
     * @param marker the marker
     */
    public static void gotoMarker(IEditorPart editor, IMarker marker) {
        IGotoMarker gotoMarker = null;
        if (editor instanceof IGotoMarker) {
            gotoMarker = (IGotoMarker) editor;
        } else {
            gotoMarker = (IGotoMarker) editor.getAdapter(IGotoMarker.class);
        }
        if (gotoMarker != null) {
            gotoMarker.gotoMarker(marker);
        }
    }

    /**
     * Opens an editor on the given object.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened.
     * <p>
     * 
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @param editorId
     *            the id of the editor extension to use
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String)
     */
    public static IEditorPart openEditor(IWorkbenchPage page,
            IEditorInput input, String editorId) throws PartInitException {
        //sanity checks
        if (page == null)
            throw new IllegalArgumentException();

        // open the editor on the file
        return page.openEditor(input, editorId);
    }

    /**
     * Opens an editor on the given object.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened. If
     * <code>activate == true</code> the editor will be activated.
     * <p>
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @param editorId
     *            the id of the editor extension to use
     * @param activate
     * 			  if <code>true</code> the editor will be activated
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String, boolean)
     */
    public static IEditorPart openEditor(IWorkbenchPage page,
            IEditorInput input, String editorId, boolean activate)
            throws PartInitException {
        //sanity checks
        if (page == null)
            throw new IllegalArgumentException();

        // open the editor on the file
        return page.openEditor(input, editorId, activate);
    }

    /**
     * Opens an editor on the given file resource.  This method will attempt to
	 * resolve the editor based on content-type bindings as well as traditional
	 * name/extension bindings.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened. If
     * <code>activate == true</code> the editor will be activated.
     * <p>
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @param activate
     * 			  if <code>true</code> the editor will be activated
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(org.eclipse.ui.IEditorInput,
     *      String, boolean)
     */
    public static IEditorPart openEditor(IWorkbenchPage page, IFile input,
            boolean activate) throws PartInitException {
		return openEditor(page, input, activate, true);
    }
	
	/**
     * Opens an editor on the given file resource.  This method will attempt to
	 * resolve the editor based on content-type bindings as well as traditional
	 * name/extension bindings if <code>determineContentType</code> is
	 * <code>true</code>.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened. If
     * <code>activate == true</code> the editor will be activated.
     * <p>
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @param activate
     * 			  if <code>true</code> the editor will be activated
     * @param determineContentType
     * 			  attempt to resolve the content type for this file
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(org.eclipse.ui.IEditorInput,
     *      String, boolean)
     * @since 3.1
     */
	public static IEditorPart openEditor(IWorkbenchPage page, IFile input,
            boolean activate, boolean determineContentType) throws PartInitException {
        //sanity checks
        if (page == null)
            throw new IllegalArgumentException();

        // open the editor on the file
        IEditorDescriptor editorDesc = getEditorDescriptor(input, determineContentType);
        return page.openEditor(new FileEditorInput(input), editorDesc.getId(),
                activate);
    }

    /**
     * Opens an editor on the given file resource.  This method will attempt to
	 * resolve the editor based on content-type bindings as well as traditional
	 * name/extension bindings.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened.
     * <p>
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String)
     */
    public static IEditorPart openEditor(IWorkbenchPage page, IFile input)
            throws PartInitException {
        //sanity checks
        if (page == null)
            throw new IllegalArgumentException();

        // open the editor on the file
        IEditorDescriptor editorDesc = getEditorDescriptor(input);
        return page.openEditor(new FileEditorInput(input), editorDesc.getId());
    }

    /**
     * Opens an editor on the given file resource.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened.
     * <p>
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @param editorId
     *            the id of the editor extension to use
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String)
     */
    public static IEditorPart openEditor(IWorkbenchPage page, IFile input,
            String editorId) throws PartInitException {
        //sanity checks
        if (page == null)
            throw new IllegalArgumentException();

        // open the editor on the file
        return page.openEditor(new FileEditorInput(input), editorId);
    }

    /**
     * Opens an editor on the given file resource.
     * <p>
     * If the page already has an editor open on the target object then that
     * editor is brought to front; otherwise, a new editor is opened. If
     * <code>activate == true</code> the editor will be activated.
     * <p>
     * @param page
     *            the page in which the editor will be opened
     * @param input
     *            the editor input
     * @param editorId
     *            the id of the editor extension to use
     * @param activate
     * 			  if <code>true</code> the editor will be activated
     * @return an open editor or <code>null</code> if an external editor was
     *         opened
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String, boolean)
     */
    public static IEditorPart openEditor(IWorkbenchPage page, IFile input,
            String editorId, boolean activate) throws PartInitException {
        //sanity checks
        if (page == null)
            throw new IllegalArgumentException();

        // open the editor on the file
        return page.openEditor(new FileEditorInput(input), editorId, activate);
    }

    /**
	 * Returns an editor descriptor appropriate for opening the given file
	 * resource.  
	 * <p>
	 * The editor descriptor is determined using a multistep process. This
	 * method will attempt to resolve the editor based on content-type bindings
	 * as well as traditional name/extension bindings.
	 * </p>
	 * <ol>
	 * <li>The file is consulted for a persistent property named
	 * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be
	 * used.</li>
	 * <li>The workbench editor registry is consulted to determine if an editor
	 * extension has been registered for the file type. If so, an instance of
	 * the editor extension is opened on the file. See
	 * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li>
	 * <li>The operating system is consulted to determine if an in-place
	 * component editor is available (e.g. OLE editor on Win32 platforms).</li>
	 * <li>The operating system is consulted to determine if an external editor
	 * is available.</li>
	 * </ol>
	 * </p>
	 * 
	 * @param file
	 *            the file
	 * @return an editor descriptor, appropriate for opening the file
	 * @throws PartInitException
	 *             if no editor can be found
	 */
    public static IEditorDescriptor getEditorDescriptor(IFile file)
            throws PartInitException {
		return getEditorDescriptor(file, true);
	}

    /**
	 * Returns an editor descriptor appropriate for opening the given file
	 * resource.
	 * <p>
	 * The editor descriptor is determined using a multistep process. This
	 * method will attempt to resolve the editor based on content-type bindings
	 * as well as traditional name/extension bindings if
	 * <code>determineContentType</code>is <code>true</code>.
	 * </p>
	 * <ol>
	 * <li>The file is consulted for a persistent property named
	 * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be
	 * used.</li>
	 * <li>The workbench editor registry is consulted to determine if an editor
	 * extension has been registered for the file type. If so, an instance of
	 * the editor extension is opened on the file. See
	 * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li>
	 * <li>The operating system is consulted to determine if an in-place
	 * component editor is available (e.g. OLE editor on Win32 platforms).</li>
	 * <li>The operating system is consulted to determine if an external editor
	 * is available.</li>
	 * </ol>
	 * </p>
	 * 
	 * @param file
	 *            the file
	 * @param determineContentType
	 *            query the content type system for the content type of the file
	 * @return an editor descriptor, appropriate for opening the file
	 * @throws PartInitException
	 *             if no editor can be found
	 * @since 3.1
	 */
    public static IEditorDescriptor getEditorDescriptor(IFile file, boolean determineContentType)
            throws PartInitException {

		if (file == null) {
			throw new IllegalArgumentException();
		}

		return getEditorDescriptor(file.getName(), PlatformUI.getWorkbench()
				.getEditorRegistry(), getDefaultEditor(file, determineContentType));
	}

	/**
	 * Returns an editor descriptor appropriate for opening a file resource with
	 * the given name.
	 * <p>
	 * The editor descriptor is determined using a multistep process. This
	 * method will attempt to infer content type from the file name.
	 * </p>
	 * <ol>
	 * <li>The file is consulted for a persistent property named
	 * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be
	 * used.</li>
	 * <li>The workbench editor registry is consulted to determine if an editor
	 * extension has been registered for the file type. If so, an instance of
	 * the editor extension is opened on the file. See
	 * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li>
	 * <li>The operating system is consulted to determine if an in-place
	 * component editor is available (e.g. OLE editor on Win32 platforms).</li>
	 * <li>The operating system is consulted to determine if an external editor
	 * is available.</li>
	 * </ol>
	 * </p>
	 * 
	 * @param name
	 *            the file name
	 * @return an editor descriptor, appropriate for opening the file
	 * @throws PartInitException
	 *             if no editor can be found
     * @since 3.1
	 */
	public static IEditorDescriptor getEditorDescriptor(String name) throws PartInitException {
		return getEditorDescriptor(name, true);
	}
	
	/**
	 * Returns an editor descriptor appropriate for opening a file resource with
	 * the given name.
	 * <p>
	 * The editor descriptor is determined using a multistep process. This
	 * method will attempt to infer the content type of the file if
	 * <code>inferContentType</code> is <code>true</code>.
	 * </p>
	 * <ol>
	 * <li>The file is consulted for a persistent property named
	 * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be
	 * used.</li>
	 * <li>The workbench editor registry is consulted to determine if an editor
	 * extension has been registered for the file type. If so, an instance of
	 * the editor extension is opened on the file. See
	 * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li>
	 * <li>The operating system is consulted to determine if an in-place
	 * component editor is available (e.g. OLE editor on Win32 platforms).</li>
	 * <li>The operating system is consulted to determine if an external editor
	 * is available.</li>
	 * </ol>
	 * </p>
	 * 
	 * @param name
	 *            the file name
	 * @param inferContentType
	 *            attempt to infer the content type from the file name if this
	 *            is <code>true</code>
	 * @return an editor descriptor, appropriate for opening the file
	 * @throws PartInitException
	 *             if no editor can be found
	 * @since 3.1
	 */
	public static IEditorDescriptor getEditorDescriptor(String name, boolean inferContentType)
			throws PartInitException {

		if (name == null) {
			throw new IllegalArgumentException();
		}

		IContentType contentType = inferContentType ? Platform
				.getContentTypeManager().findContentTypeFor(name) : null;
		IEditorRegistry editorReg = PlatformUI.getWorkbench()
				.getEditorRegistry();

		return getEditorDescriptor(name, editorReg, editorReg
				.getDefaultEditor(name, contentType));
	}

	/**
	 * Get the editor descriptor for a given name using the editorDescriptor
	 * passed in as a default as a starting point.
	 * 
	 * @param name
	 *            The name of the element to open.
	 * @param editorReg
	 *            The editor registry to do the lookups from.
	 * @param defaultDescriptor
	 *            IEditorDescriptor or <code>null</code>
	 * @return IEditorDescriptor
	 * @throws PartInitException
	 *             if no valid editor can be found
     *             
     * @since 3.1
	 */
	private static IEditorDescriptor getEditorDescriptor(String name,
			IEditorRegistry editorReg, IEditorDescriptor defaultDescriptor)
			throws PartInitException {

		if (defaultDescriptor != null)
			return defaultDescriptor;

		IEditorDescriptor editorDesc = defaultDescriptor;

		// next check the OS for in-place editor (OLE on Win32)
		if (editorReg.isSystemInPlaceEditorAvailable(name))
			editorDesc = editorReg
					.findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID);

		// next check with the OS for an external editor
		if (editorDesc == null
				&& editorReg.isSystemExternalEditorAvailable(name))
			editorDesc = editorReg
					.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);

		// next lookup the default text editor
		if (editorDesc == null)
			editorDesc = editorReg
					.findEditor(IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID);

		// if no valid editor found, bail out
		if (editorDesc == null)
			throw new PartInitException(IDEWorkbenchMessages.IDE_noFileEditorFound);

		return editorDesc;
	}

    /**
     * Opens an editor on the file resource of the given marker.
     * <p>
     * If this page already has an editor open on the marker resource file that
     * editor is brought to front; otherwise, a new editor is opened.The cursor
     * and selection state of the editor are then updated from information
     * recorded in the marker.
     * </p>
     * <p>
     * If the marker contains an <code>EDITOR_ID_ATTR</code> attribute the
     * attribute value will be used to determine the editor type to be opened.
     * If not, the registered editor for the marker resource file will be used.
     * </p>
     * 
     * @param page
     *            the workbench page to open the editor in
     * @param marker
     *            the marker to open
     * @return an open editor or <code>null</code> not possible
     * @exception PartInitException
     *                if the editor could not be initialized
     * @see #openEditor(org.eclipse.ui.IWorkbenchPage,
     *      org.eclipse.core.resources.IMarker, boolean)
     */
    public static IEditorPart openEditor(IWorkbenchPage page, IMarker marker)
            throws PartInitException {
        return openEditor(page, marker, true);
    }

    /**
     * Opens an editor on the file resource of the given marker. 
     * <p>
     * If this page already has an editor open on the marker resource file that 
     * editor is brought to front; otherwise, a new editor is opened. If 
     * <code>activate == true</code> the editor will be activated.  The cursor and 
     * selection state of the editor are then updated from information recorded in 
     * the marker.
     * </p><p>
     * If the marker contains an <code>EDITOR_ID_ATTR</code> attribute 
     * the attribute value will be used to determine the editor type to be opened. 
     * If not, the registered editor for the marker resource file will be used. 
     * </p>
     *
     * @param page the workbench page to open the editor in
     * @param marker the marker to open
     * @param activate if <code>true</code> the editor will be activated
     * @return an open editor or <code>null</code> not possible
     * @exception PartInitException if the editor could not be initialized
     */
    public static IEditorPart openEditor(IWorkbenchPage page, IMarker marker,
            boolean activate) throws PartInitException {
        // sanity checks
        if (page == null || marker == null) {
            throw new IllegalArgumentException();
        }

        // get the marker resource file
        if (!(marker.getResource() instanceof IFile)) {
            IDEWorkbenchPlugin
                    .log("Open editor on marker failed; marker resource not an IFile"); //$NON-NLS-1$
            return null;
        }
        IFile file = (IFile) marker.getResource();

        // get the preferred editor id from the marker
        IEditorRegistry editorReg = PlatformUI.getWorkbench()
                .getEditorRegistry();
        IEditorDescriptor editorDesc = null;
        try {
            String editorID = (String) marker.getAttribute(EDITOR_ID_ATTR);
            if (editorID != null) {
                editorDesc = editorReg.findEditor(editorID);
            }
        } catch (CoreException e) {
            // ignore this
        }

        // open the editor on the marker resource file
        IEditorPart editor = null;
        if (editorDesc == null) {
            editor = openEditor(page, file, activate);
        } else {
            editor = page.openEditor(new FileEditorInput(file), editorDesc
                    .getId(), activate);
        }

        // get the editor to update its position based on the marker
        if (editor != null) {
            gotoMarker(editor, marker);
        }

        return editor;
    }

    /**
     * Save all dirty editors in the workbench whose editor input is  
     * a child resource of one of the <code>IResource</code>'s provided.
     * Opens a dialog to prompt the user if <code>confirm</code> is true. 
     * Return true if successful. Return false if the user has cancelled 
     * the command.
     * 
     * @since 3.0
     * 
     * @param resourceRoots
     *            the resource roots under which editor input should be saved,
     *            other will be left dirty
     * @param confirm
     *            prompt the user if true
     * @return boolean false if the operation was cancelled.
     */
    public static boolean saveAllEditors(IResource[] resourceRoots,
            boolean confirm) {
        final IResource[] finalResources = resourceRoots;
        final boolean finalConfirm = confirm;
        final boolean[] result = new boolean[1];
        result[0] = true;

        if (resourceRoots.length == 0)
            return result[0];

        Platform.run(new SafeRunnable(IDEWorkbenchMessages.ErrorClosing) {
                    public void run() {
                        //Collect dirtyEditors
                        ArrayList dirtyEditors = new ArrayList();

                        IWorkbenchWindow[] windows = PlatformUI.getWorkbench()
                                .getWorkbenchWindows();
                        for (int i = 0; i < windows.length; i++) {
                            IWorkbenchWindow window = windows[i];
                            IWorkbenchPage[] pages = window.getPages();
                            for (int j = 0; j < pages.length; j++) {
                                IWorkbenchPage page = pages[j];
                                IEditorPart[] dirty = page.getDirtyEditors();
                                for (int k = 0; k < dirty.length; k++) {
                                    IEditorPart part = dirty[k];
                                    IFile file = ResourceUtil.getFile(part.getEditorInput());
                                    if (file != null) {
                                        for (int l = 0; l < finalResources.length; l++) {
                                            IResource resource = finalResources[l];
                                            if (resource.getFullPath()
                                                    .isPrefixOf(
                                                            file.getFullPath())) {
                                                dirtyEditors.add(part);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                        }
                        if (dirtyEditors.size() > 0) {
                            IWorkbenchWindow w = Workbench.getInstance()
                                    .getActiveWorkbenchWindow();
                            if (w == null)
                                w = windows[0];
                            result[0] = EditorManager.saveAll(dirtyEditors,
                                    finalConfirm, w);
                        }
                    }
                });
        return result[0];
    }

    /**
     * Sets the default editor id for a given file.  This value will be used
     * to determine the default editor descriptor for the file in future calls to
     * <code>getDefaultEditor(IFile)</code>.
     *
     * @param file the file
     * @param editorID the editor id
     */
    public static void setDefaultEditor(IFile file, String editorID) {
        try {
            file.setPersistentProperty(EDITOR_KEY, editorID);
        } catch (CoreException e) {
            // do nothing
        }
    }

    /**
	 * Returns the default editor for a given file. This method will attempt to
	 * resolve the editor based on content-type bindings as well as traditional
	 * name/extension bindings.
	 * <p>
	 * A default editor id may be registered for a specific file using
	 * <code>setDefaultEditor</code>. If the given file has a registered
	 * default editor id the default editor will derived from it. If not, the
	 * default editor is determined by taking the file name for the file and
	 * obtaining the default editor for that name.
	 * </p>
	 * 
	 * @param file
	 *            the file
	 * @return the descriptor of the default editor, or <code>null</code> if
	 *         not found
	 */
    public static IEditorDescriptor getDefaultEditor(IFile file) {
		return getDefaultEditor(file, true);
    }
	
    /**
	 * Returns the default editor for a given file. This method will attempt to
	 * resolve the editor based on content-type bindings as well as traditional
	 * name/extension bindings if <code>determineContentType</code> is
	 * <code>true</code>.
	 * <p>
	 * A default editor id may be registered for a specific file using
	 * <code>setDefaultEditor</code>. If the given file has a registered
	 * default editor id the default editor will derived from it. If not, the
	 * default editor is determined by taking the file name for the file and
	 * obtaining the default editor for that name.
	 * </p>
	 * 
	 * @param file
	 *            the file
	 * @param determineContentType
	 *            determine the content type for the given file
	 * @return the descriptor of the default editor, or <code>null</code> if
	 *         not found
	 * @since 3.1
	 */
    public static IEditorDescriptor getDefaultEditor(IFile file, boolean determineContentType) {
        // Try file specific editor.
        IEditorRegistry editorReg = PlatformUI.getWorkbench()
                .getEditorRegistry();
        try {
            String editorID = file.getPersistentProperty(EDITOR_KEY);
            if (editorID != null) {
                IEditorDescriptor desc = editorReg.findEditor(editorID);
                if (desc != null)
                    return desc;
            }
        } catch (CoreException e) {
            // do nothing
        }
        
		IContentType contentType = null;
		if (determineContentType)
			contentType = getContentType(file);    
        // Try lookup with filename
        return editorReg.getDefaultEditor(file.getName(), contentType);
    }

    /**
     * Extracts and returns the <code>IResource</code>s in the given
     * selection or the resource objects they adapts to.
     * 
     * @param originalSelection the original selection, possibly empty
     * @return list of resources (element type: <code>IResource</code>), 
     *    possibly empty
     */
    public static List computeSelectedResources(
            IStructuredSelection originalSelection) {
        List resources = null;
        for (Iterator e = originalSelection.iterator(); e.hasNext();) {
            Object next = e.next();
            Object resource = null;
            if (next instanceof IResource) {
                resource = next;
            } else if (next instanceof IAdaptable) {
                resource = ((IAdaptable) next).getAdapter(IResource.class);
            }
            if (resource != null) {
                if (resources == null) {
                    // lazy init to avoid creating empty lists
                    // assume selection contains mostly resources most times
                    resources = new ArrayList(originalSelection.size());
                }
                resources.add(resource);
            }
        }
        if (resources == null) {
            return Collections.EMPTY_LIST;
        }
        return resources;
        
    }

	/**
	 * Return the content type for the given file.
	 * 
	 * @param file the file to test
	 * @return the content type, or <code>null</code> if it cannot be determined.
	 * @since 3.1
	 */
	public static IContentType getContentType(IFile file) {
		try {
			UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, file.getName());
			IContentDescription contentDescription = file.getContentDescription();
			if (contentDescription == null)
				return null;
			return contentDescription.getContentType();
		} catch (CoreException e) {
			return null;		
		} finally {
			UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, file.getName());
		}
	}
	
	
	/**
	 * Guess at the content type of the given file based on the filename.
	 * 
	 * @param file the file to test
	 * @return the content type, or <code>null</code> if it cannot be determined.
	 * @since 3.2
	 */
	public static IContentType guessContentType(IFile file) {
		String fileName = file.getName();
		try {
			UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, fileName);
			IContentTypeMatcher matcher = file.getProject().getContentTypeMatcher();
			return matcher.findContentTypeFor(fileName);
		} catch (CoreException e) {
			return null;		
		} finally {
			UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, fileName);
		}
	}
}
