/*******************************************************************************
 * Copyright (c) 2000, 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.views.navigator;

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

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ResourceWorkingSetFilter;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.PluginTransfer;
import org.eclipse.ui.part.ResourceTransfer;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.views.framelist.FrameList;
import org.eclipse.ui.views.framelist.TreeFrame;

/**
 * Implements the Resource Navigator view.
 */
public class ResourceNavigator extends ViewPart implements ISetSelectionTarget,
        IResourceNavigator {

    private TreeViewer viewer;

    private IDialogSettings settings;

    private IMemento memento;

    private FrameList frameList;

    private ResourceNavigatorActionGroup actionGroup;

    private ResourcePatternFilter patternFilter = new ResourcePatternFilter();

    private ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter();

    private boolean linkingEnabled;

    private boolean dragDetected;

    private Listener dragDetectListener;
    /**
     * Remembered working set.
     */
    private IWorkingSet workingSet;

    /**
	 * Marks whether the working set we're using is currently empty. In this
	 * event we're effectively not using a working set.
	 */
    private boolean emptyWorkingSet = false;
    
    /**
	 * Settings constant for section name (value <code>ResourceNavigator</code>).
	 */
    private static final String STORE_SECTION = "ResourceNavigator"; //$NON-NLS-1$

    /** 
     * Settings constant for sort order (value <code>ResourceViewer.STORE_SORT_TYPE</code>).
     */
    private static final String STORE_SORT_TYPE = "ResourceViewer.STORE_SORT_TYPE"; //$NON-NLS-1$

    /** 
     * Settings constant for working set (value <code>ResourceWorkingSetFilter.STORE_WORKING_SET</code>).
     */
    private static final String STORE_WORKING_SET = "ResourceWorkingSetFilter.STORE_WORKING_SET"; //$NON-NLS-1$

    /**
     * @deprecated No longer used but preserved to avoid an api change.
     */
    public static final String NAVIGATOR_VIEW_HELP_ID = INavigatorHelpContextIds.RESOURCE_VIEW;

    /**
     * True iff we've already scheduled an asynchronous call to linkToEditor
     */
    private boolean linkScheduled = false;
    
    // Persistance tags.
    private static final String TAG_SORTER = "sorter"; //$NON-NLS-1$

    private static final String TAG_FILTERS = "filters"; //$NON-NLS-1$

    private static final String TAG_FILTER = "filter"; //$NON-NLS-1$

    private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$

    private static final String TAG_EXPANDED = "expanded"; //$NON-NLS-1$

    private static final String TAG_ELEMENT = "element"; //$NON-NLS-1$

    private static final String TAG_IS_ENABLED = "isEnabled"; //$NON-NLS-1$

    private static final String TAG_PATH = "path"; //$NON-NLS-1$

    private static final String TAG_CURRENT_FRAME = "currentFrame"; //$NON-NLS-1$

    private IPartListener partListener = new IPartListener() {
        public void partActivated(IWorkbenchPart part) {
            if (part instanceof IEditorPart)
                editorActivated((IEditorPart) part);
        }

        public void partBroughtToTop(IWorkbenchPart part) {
        }

        public void partClosed(IWorkbenchPart part) {
        }

        public void partDeactivated(IWorkbenchPart part) {
        }

        public void partOpened(IWorkbenchPart part) {
        }
    };

    private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent event) {
            String property = event.getProperty();
            Object newValue = event.getNewValue();
            Object oldValue = event.getOldValue();
           
            if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)
                    && oldValue == workingSet) {
                setWorkingSet(null);
            } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE
                    .equals(property)
                    && newValue == workingSet) {
                updateTitle();
            } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE
                    .equals(property)
                    && newValue == workingSet) {
				if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
					// act as if the working set has been made null
					if (!emptyWorkingSet) {
						emptyWorkingSet = true;
						workingSetFilter.setWorkingSet(null);
					}
				} else {
					// we've gone from empty to non-empty on our set.
					// Restore it.
					if (emptyWorkingSet) {
					    emptyWorkingSet = false;
						workingSetFilter.setWorkingSet(workingSet);
					}
				}
				getViewer().refresh();
            }
        }
    };

    /**
     * Constructs a new resource navigator view.
     */
    public ResourceNavigator() {
        IDialogSettings viewsSettings = getPlugin().getDialogSettings();

        settings = viewsSettings.getSection(STORE_SECTION);
        if (settings == null) {
            settings = viewsSettings.addNewSection(STORE_SECTION);
            migrateDialogSettings();
        }

        initLinkingEnabled();
    }

    /**
     * Converts the given selection into a form usable by the viewer,
     * where the elements are resources.
     */
    private StructuredSelection convertSelection(ISelection selection) {
        ArrayList list = new ArrayList();
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection ssel = (IStructuredSelection) selection;
            for (Iterator i = ssel.iterator(); i.hasNext();) {
                Object o = i.next();
                IResource resource = null;
                if (o instanceof IResource) {
                    resource = (IResource) o;
                } else {
                    if (o instanceof IAdaptable) {
                        resource = (IResource) ((IAdaptable) o)
                                .getAdapter(IResource.class);
                    }
                }
                if (resource != null) {
                    list.add(resource);
                }
            }
        }
        return new StructuredSelection(list);
    }

    /* (non-Javadoc)
     * Method declared on IWorkbenchPart.
     */
    public void createPartControl(Composite parent) {
        TreeViewer viewer = createViewer(parent);
        this.viewer = viewer;

        if (memento != null) {
            restoreFilters();
            restoreLinkingEnabled();
        }
        frameList = createFrameList();
        initDragAndDrop();
        updateTitle();

        initContextMenu();

        initResourceSorter();
        initWorkingSetFilter();

        // make sure input is set after sorters and filters,
        // to avoid unnecessary refreshes
        viewer.setInput(getInitialInput());

        // make actions after setting input, because some actions
        // look at the viewer for enablement (e.g. the Up action)
        makeActions();

        // Fill the action bars and update the global action handlers'
        // enabled state to match the current selection.
        getActionGroup().fillActionBars(getViewSite().getActionBars());
        updateActionBars((IStructuredSelection) viewer.getSelection());

        getSite().setSelectionProvider(viewer);
        getSite().getPage().addPartListener(partListener);
        IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
                .getWorkingSetManager();
        workingSetManager.addPropertyChangeListener(propertyChangeListener);

        if (memento != null)
            restoreState(memento);
        memento = null;

        // Set help for the view 
        getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(
				viewer.getControl(), getHelpContextId());
    }

    /**
     * Returns the help context id to use for this view.
     * 
     * @since 2.0
     */
    protected String getHelpContextId() {
        return INavigatorHelpContextIds.RESOURCE_VIEW;
    }

    /**
     * Initializes and registers the context menu.
     * 
     * @since 2.0
     */
    protected void initContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                ResourceNavigator.this.fillContextMenu(manager);
            }
        });
        TreeViewer viewer = getTreeViewer();
        Menu menu = menuMgr.createContextMenu(viewer.getTree());
        viewer.getTree().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    /**
     * Creates the viewer.
     * 
     * @param parent the parent composite
     * @since 2.0
     */
    protected TreeViewer createViewer(Composite parent) {
        TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
                | SWT.V_SCROLL);
        viewer.setUseHashlookup(true);
        initContentProvider(viewer);
        initLabelProvider(viewer);
        initFilters(viewer);
        initListeners(viewer);

        return viewer;
    }

    /**
     * Sets the content provider for the viewer.
     * 
     * @param viewer the viewer
     * @since 2.0
     */
    protected void initContentProvider(TreeViewer viewer) {
        viewer.setContentProvider(new WorkbenchContentProvider());
    }

    /**
     * Sets the label provider for the viewer.
     * 
     * @param viewer the viewer
     * @since 2.0
     */
    protected void initLabelProvider(TreeViewer viewer) {
        viewer.setLabelProvider(new DecoratingLabelProvider(
                new WorkbenchLabelProvider(), getPlugin().getWorkbench()
                        .getDecoratorManager().getLabelDecorator()));
    }

    /**
     * Adds the filters to the viewer.
     * 
     * @param viewer the viewer
     * @since 2.0
     */
    protected void initFilters(TreeViewer viewer) {
        viewer.addFilter(patternFilter);
        viewer.addFilter(workingSetFilter);
    }

    /**
     * Initializes the linking enabled setting from the preference store.
     */
    private void initLinkingEnabled() {
        // Try the dialog settings first, which remember the last choice.
        String setting = settings
                .get(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
        if (setting != null) {
            linkingEnabled = setting.equals("true"); //$NON-NLS-1$
            return;
        }
        // If not in the dialog settings, check the preference store for the default setting. 
        // Use the UI plugin's preference store since this is a public preference.
        AbstractUIPlugin uiPlugin = (AbstractUIPlugin) Platform
                .getPlugin(PlatformUI.PLUGIN_ID);
        linkingEnabled = uiPlugin.getPreferenceStore().getBoolean(
                IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
    }

    /**
     * Adds the listeners to the viewer.
     * 
     * @param viewer the viewer
     * @since 2.0
     */
    protected void initListeners(TreeViewer viewer) {
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                handleSelectionChanged(event);
            }
        });
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                handleDoubleClick(event);
            }
        });
        viewer.addOpenListener(new IOpenListener() {
            public void open(OpenEvent event) {
                handleOpen(event);
            }
        });
        viewer.getControl().addKeyListener(new KeyListener() {
            public void keyPressed(KeyEvent event) {
                handleKeyPressed(event);
            }

            public void keyReleased(KeyEvent event) {
                handleKeyReleased(event);
            }
        });
    }

    /* (non-Javadoc)
     * Method declared on IWorkbenchPart.
     */
    public void dispose() {
        getSite().getPage().removePartListener(partListener);

        IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
                .getWorkingSetManager();
        workingSetManager.removePropertyChangeListener(propertyChangeListener);

        if (getActionGroup() != null) {
            getActionGroup().dispose();
        }
        Control control = viewer.getControl();
        if (dragDetectListener != null && control != null
                && control.isDisposed() == false) {
            control.removeListener(SWT.DragDetect, dragDetectListener);
        }
        super.dispose();
    }

    /**
     * An editor has been activated.  Sets the selection in this navigator
     * to be the editor's input, if linking is enabled.
     * 
     * @param editor the active editor
     * @since 2.0
     */
    protected void editorActivated(IEditorPart editor) {
        if (!isLinkingEnabled()) {
            return;
        }

        IFile file = ResourceUtil.getFile(editor.getEditorInput());
        if (file != null) {
            ISelection newSelection = new StructuredSelection(file);
            if (getTreeViewer().getSelection().equals(newSelection)) {
                getTreeViewer().getTree().showSelection();
            } else {
                getTreeViewer().setSelection(newSelection, true);
            }
        }
    }

    /**
     * Called when the context menu is about to open.
     * Delegates to the action group using the viewer's selection as the action context.
     * @since 2.0
     */
    protected void fillContextMenu(IMenuManager menu) {
        IStructuredSelection selection = (IStructuredSelection) getViewer()
                .getSelection();
        getActionGroup().setContext(new ActionContext(selection));
        getActionGroup().fillContextMenu(menu);
    }

    /*
     * @see IResourceNavigatorPart
     * @since 2.0
     */
    public FrameList getFrameList() {
        return frameList;
    }

    /** 
     * Returns the initial input for the viewer.
     * Tries to convert the page input to a resource, either directly or via IAdaptable.
     * If the resource is a container, it uses that.
     * If the resource is a file, it uses its parent folder.
     * If a resource could not be obtained, it uses the workspace root.
     * 
     * @since 2.0
     */
    protected IAdaptable getInitialInput() {
        IAdaptable input = getSite().getPage().getInput();
        if (input != null) {
            IResource resource = null;
            if (input instanceof IResource) {
                resource = (IResource) input;
            } else {
                resource = (IResource) input.getAdapter(IResource.class);
            }
            if (resource != null) {
                switch (resource.getType()) {
                case IResource.FILE:
                    return resource.getParent();
                case IResource.FOLDER:
                case IResource.PROJECT:
                case IResource.ROOT:
                    return (IContainer) resource;
                default:
                    // Unknown resource type.  Fall through.
                    break;
                }
            }
        }
        return ResourcesPlugin.getWorkspace().getRoot();
    }

    /**
     * Returns the pattern filter for this view.
     *
     * @return the pattern filter
     * @since 2.0
     */
    public ResourcePatternFilter getPatternFilter() {
        return this.patternFilter;
    }

    /**
     * Returns the working set for this view.
     *
     * @return the working set
     * @since 2.0
     */
    public IWorkingSet getWorkingSet() {
        return workingSetFilter.getWorkingSet();
    }

    /**
     * Returns the navigator's plugin.
     */
    public AbstractUIPlugin getPlugin() {
        return IDEWorkbenchPlugin.getDefault();
    }

    /**
     * Returns the sorter.
     * @since 2.0
     */
    public ResourceSorter getSorter() {
        return (ResourceSorter) getTreeViewer().getSorter();
    }

    /**
     * Returns the resource viewer which shows the resource hierarchy.
     * @since 2.0
     */
    public TreeViewer getViewer() {
        return viewer;
    }

    /**
     * Returns the tree viewer which shows the resource hierarchy.
     * @return the tree viewer
     * @since 2.0
     */
    public TreeViewer getTreeViewer() {
        return viewer;
    }

    /**
     * Returns the shell to use for opening dialogs.
     * Used in this class, and in the actions.
     * 
     * @return the shell
     * @deprecated use getViewSite().getShell()
     */
    public Shell getShell() {
        return getViewSite().getShell();
    }

    /**
     * Returns the message to show in the status line.
     *
     * @param selection the current selection
     * @return the status line message
     * @since 2.0
     */
    protected String getStatusLineMessage(IStructuredSelection selection) {
        if (selection.size() == 1) {
            Object o = selection.getFirstElement();
            if (o instanceof IResource) {
                return ((IResource) o).getFullPath().makeRelative().toString();
            } else {
                return ResourceNavigatorMessages.ResourceNavigator_oneItemSelected;
            }
        }
        if (selection.size() > 1) {
            return NLS.bind(ResourceNavigatorMessages.ResourceNavigator_statusLine, String.valueOf(selection.size()));
        }
        return ""; //$NON-NLS-1$
    }

    /**
     * Returns the name for the given element.
     * Used as the name for the current frame. 
     */
    String getFrameName(Object element) {
        if (element instanceof IResource) 
            return ((IResource) element).getName();
        String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
        .getText(element);
        if(text == null)
        	return "";//$NON-NLS-1$
        return text;
    }

    /**
     * Returns the tool tip text for the given element.
     * Used as the tool tip text for the current frame, and for the view title tooltip.
     */
    String getFrameToolTipText(Object element) {
        if (element instanceof IResource) {
            IPath path = ((IResource) element).getFullPath();
            if (path.isRoot()) 
                return ResourceNavigatorMessages.ResourceManager_toolTip;
            return path.makeRelative().toString();
        } 
        
        String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
        	.getText(element);
        if(text == null)
        	return "";//$NON-NLS-1$
        return text;
    }

    /**
     * Handles an open event from the viewer.
     * Opens an editor on the selected file.
     * 
     * @param event the open event
     * @since 2.0
     */
    protected void handleOpen(OpenEvent event) {
        IStructuredSelection selection = (IStructuredSelection) event
                .getSelection();
        getActionGroup().runDefaultAction(selection);
    }

    /**
     * Handles a double-click event from the viewer.
     * Expands or collapses a folder when double-clicked.
     * 
     * @param event the double-click event
     * @since 2.0
     */
    protected void handleDoubleClick(DoubleClickEvent event) {
        IStructuredSelection selection = (IStructuredSelection) event
                .getSelection();
        Object element = selection.getFirstElement();

        // 1GBZIA0: ITPUI:WIN2000 - Double-clicking in navigator should expand/collapse containers
        TreeViewer viewer = getTreeViewer();
        if (viewer.isExpandable(element)) {
            viewer.setExpandedState(element, !viewer.getExpandedState(element));
        }

    }

    /**
     * Handles a selection changed event from the viewer.
     * Updates the status line and the action bars, and links to editor (if option enabled).
     * 
     * @param event the selection event
     * @since 2.0
     */
    protected void handleSelectionChanged(SelectionChangedEvent event) {
        final IStructuredSelection sel = (IStructuredSelection) event
                .getSelection();
        updateStatusLine(sel);
        updateActionBars(sel);
        dragDetected = false;
        if (isLinkingEnabled() && !linkScheduled) {
            // Ensure that if another selection change arrives while we're waiting for the *syncExec,
            // we only do this work once.
            linkScheduled = true;
            getShell().getDisplay().asyncExec(new Runnable() {
                public void run() {
                    // There's no telling what might have changed since the syncExec was scheduled.
                    // Check to make sure that the widgets haven't been disposed.
                    linkScheduled = false;
                    
                    if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed()) {
                        return;
                    }
                    
                    if (dragDetected == false) {
                        ISelection sel = viewer.getSelection();
                        if (sel instanceof IStructuredSelection) {
                            IStructuredSelection selection = (IStructuredSelection)sel;
                        
                            // only synchronize with editor when the selection is not the result 
                            // of a drag. Fixes bug 22274.
                            linkToEditor(selection);
                        }
                    }
                }
            });
        }
    }

    /**
     * Handles a key press event from the viewer.
     * Delegates to the action group.
     * 
     * @param event the key event
     * @since 2.0
     */
    protected void handleKeyPressed(KeyEvent event) {
        getActionGroup().handleKeyPressed(event);
    }

    /**
     * Handles a key release in the viewer.  Does nothing by default.
     * 
     * @param event the key event
     * @since 2.0
     */
    protected void handleKeyReleased(KeyEvent event) {
    }

    /* (non-Javadoc)
     * Method declared on IViewPart.
     */
    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        this.memento = memento;
    }

    /**
     * Adds drag and drop support to the navigator.
     * 
     * @since 2.0
     */
    protected void initDragAndDrop() {
        int ops = DND.DROP_COPY | DND.DROP_MOVE;
        Transfer[] transfers = new Transfer[] {
                LocalSelectionTransfer.getInstance(),
                ResourceTransfer.getInstance(), FileTransfer.getInstance(),
                PluginTransfer.getInstance() };
        TreeViewer viewer = getTreeViewer();
        viewer.addDragSupport(ops, transfers, new NavigatorDragAdapter(viewer));
        NavigatorDropAdapter adapter = new NavigatorDropAdapter(viewer);
        adapter.setFeedbackEnabled(false);
        viewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, adapter);
        dragDetectListener = new Listener() {
            public void handleEvent(Event event) {
                dragDetected = true;
            }
        };
        viewer.getControl().addListener(SWT.DragDetect, dragDetectListener);
    }

    /**
     * Creates the frame source and frame list, and connects them.
     * 
     * @since 2.0
     */
    protected FrameList createFrameList() {
        NavigatorFrameSource frameSource = new NavigatorFrameSource(this);
        FrameList frameList = new FrameList(frameSource);
        frameSource.connectTo(frameList);
        return frameList;
    }

    /**
     * Initializes the sorter.
     */
    protected void initResourceSorter() {
        int sortType = ResourceSorter.NAME;
        try {
            int sortInt = 0;
            if (memento != null) {
                String sortStr = memento.getString(TAG_SORTER);
                if (sortStr != null)
                    sortInt = new Integer(sortStr).intValue();
            } else {
                sortInt = settings.getInt(STORE_SORT_TYPE);
            }
            if (sortInt == ResourceSorter.NAME
                    || sortInt == ResourceSorter.TYPE)
                sortType = sortInt;
        } catch (NumberFormatException e) {
        }
        setSorter(new ResourceSorter(sortType));
    }

    /**
     * Restores the working set filter from the persistence store.
     */
    void initWorkingSetFilter() {
        String workingSetName = settings.get(STORE_WORKING_SET);

        IWorkingSet workingSet = null;
        
        if (workingSetName != null && workingSetName.equals("") == false) { //$NON-NLS-1$
			IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
					.getWorkingSetManager();
			workingSet = workingSetManager.getWorkingSet(workingSetName);
		} else if (PlatformUI
				.getPreferenceStore()
				.getBoolean(
						IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT)) {
			// use the window set by default if the global preference is set
			workingSet = getSite().getPage().getAggregateWorkingSet();
		}

		if (workingSet != null) {
			// Only initialize filter. Don't set working set into viewer.
			// Working set is set via WorkingSetFilterActionGroup
			// during action creation.
			workingSetFilter.setWorkingSet(workingSet);
			internalSetWorkingSet(workingSet);
		}
    }

    /**
	 * Returns whether the navigator selection automatically tracks the active
	 * editor.
	 * 
	 * @return <code>true</code> if linking is enabled, <code>false</code>
	 *         if not
	 * @since 2.0 (this was protected in 2.0, but was made public in 2.1)
	 */
    public boolean isLinkingEnabled() {
        return linkingEnabled;
    }

    /**
     * Brings the corresponding editor to top if the selected resource is open.
     * 
     * @since 2.0
     */
    protected void linkToEditor(IStructuredSelection selection) {

        Object obj = selection.getFirstElement();
        if (obj instanceof IFile && selection.size() == 1) {
            IFile file = (IFile) obj;
            IWorkbenchPage page = getSite().getPage();
            IEditorPart editor = ResourceUtil.findEditor(page, file);
            if (editor != null) {
                page.bringToTop(editor);
                return;
            }
        }   
    }

    /**
     * Creates the action group, which encapsulates all actions for the view.
     */
    protected void makeActions() {
        setActionGroup(new MainActionGroup(this));
    }

    /**
     * Migrates the dialog settings from the UI plugin store to the 
     * Views plugin store.
     */
    private void migrateDialogSettings() {
        AbstractUIPlugin uiPlugin = (AbstractUIPlugin) Platform
                .getPlugin(PlatformUI.PLUGIN_ID);
        IDialogSettings uiSettings = uiPlugin.getDialogSettings();

        uiSettings = uiSettings.getSection(STORE_SECTION);
        if (uiSettings != null) {
            String workingSetName = uiSettings.get(STORE_WORKING_SET);
            if (workingSetName != null && workingSetName.length() > 0) {
                settings.put(STORE_WORKING_SET, workingSetName);
                uiSettings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$
            }
            String sortType = uiSettings.get(STORE_SORT_TYPE);
            if (sortType != null && sortType.length() > 0) {
                settings.put(STORE_SORT_TYPE, sortType);
                uiSettings.put(STORE_SORT_TYPE, ""); //$NON-NLS-1$
            }
        }
    }

    /**
     * Restores the saved filter settings.
     */
    private void restoreFilters() {
        IMemento filtersMem = memento.getChild(TAG_FILTERS);

        if (filtersMem != null) { //filters have been defined
            IMemento children[] = filtersMem.getChildren(TAG_FILTER);

            // check if first element has new tag defined, indicates new version
            if (children.length > 0
                    && children[0].getString(TAG_IS_ENABLED) != null) {
                ArrayList selectedFilters = new ArrayList();
                ArrayList unSelectedFilters = new ArrayList();
                for (int i = 0; i < children.length; i++) {
                    if (children[i].getString(TAG_IS_ENABLED).equals(
                            String.valueOf(true)))
                        selectedFilters.add(children[i].getString(TAG_ELEMENT));
                    else
                        //enabled == false
                        unSelectedFilters.add(children[i]
                                .getString(TAG_ELEMENT));
                }

                /* merge filters from Memento with selected = true filters from plugins
                 * ensure there are no duplicates & don't override user preferences	 */
                List pluginFilters = FiltersContentProvider.getDefaultFilters();
                for (Iterator iter = pluginFilters.iterator(); iter.hasNext();) {
                    String element = (String) iter.next();
                    if (!selectedFilters.contains(element)
                            && !unSelectedFilters.contains(element))
                        selectedFilters.add(element);
                }

                //Convert to an array of Strings
                String[] patternArray = new String[selectedFilters.size()];
                selectedFilters.toArray(patternArray);
                getPatternFilter().setPatterns(patternArray);

            } else { //filters defined, old version: ignore filters from plugins
                String filters[] = new String[children.length];
                for (int i = 0; i < children.length; i++) {
                    filters[i] = children[i].getString(TAG_ELEMENT);
                }
                getPatternFilter().setPatterns(filters);
            }
        } else { //no filters defined, old version: ignore filters from plugins
            getPatternFilter().setPatterns(new String[0]);
        }
    }

    /**
     * Restores the state of the receiver to the state described in the specified memento.
     *
     * @param memento the memento
     * @since 2.0
     */
    protected void restoreState(IMemento memento) {
        TreeViewer viewer = getTreeViewer();
        IMemento frameMemento = memento.getChild(TAG_CURRENT_FRAME);

        if (frameMemento != null) {
            TreeFrame frame = new TreeFrame(viewer);
            frame.restoreState(frameMemento);
            frame.setName(getFrameName(frame.getInput()));
            frame.setToolTipText(getFrameToolTipText(frame.getInput()));
            viewer.setSelection(new StructuredSelection(frame.getInput()));
            frameList.gotoFrame(frame);
        } else {
            IContainer container = ResourcesPlugin.getWorkspace().getRoot();
            IMemento childMem = memento.getChild(TAG_EXPANDED);
            if (childMem != null) {
                ArrayList elements = new ArrayList();
                IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
                for (int i = 0; i < elementMem.length; i++) {
                    Object element = container.findMember(elementMem[i]
                            .getString(TAG_PATH));
                    if (element != null) {
                        elements.add(element);
                    }
                }
                viewer.setExpandedElements(elements.toArray());
            }
            childMem = memento.getChild(TAG_SELECTION);
            if (childMem != null) {
                ArrayList list = new ArrayList();
                IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
                for (int i = 0; i < elementMem.length; i++) {
                    Object element = container.findMember(elementMem[i]
                            .getString(TAG_PATH));
                    if (element != null) {
                        list.add(element);
                    }
                }
                viewer.setSelection(new StructuredSelection(list));
            }
        }
    }

    /**
     * Restores the linking enabled state.
     */
    private void restoreLinkingEnabled() {
        Integer val = memento
                .getInteger(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
        if (val != null) {
            linkingEnabled = val.intValue() != 0;
        }
    }

    /**	
     * @see ViewPart#saveState
     */
    public void saveState(IMemento memento) {
        TreeViewer viewer = getTreeViewer();
        if (viewer == null) {
            if (this.memento != null) //Keep the old state;
                memento.putMemento(this.memento);
            return;
        }

        //save sorter
        memento.putInteger(TAG_SORTER, getSorter().getCriteria());

        //save filters
        String filters[] = getPatternFilter().getPatterns();
        List selectedFilters = Arrays.asList(filters);
        List allFilters = FiltersContentProvider.getDefinedFilters();
        IMemento filtersMem = memento.createChild(TAG_FILTERS);
        for (Iterator iter = allFilters.iterator(); iter.hasNext();) {
            String element = (String) iter.next();
            IMemento child = filtersMem.createChild(TAG_FILTER);
            child.putString(TAG_ELEMENT, element);
            child.putString(TAG_IS_ENABLED, String.valueOf(selectedFilters
                    .contains(element)));
        }

        if (frameList.getCurrentIndex() > 0) {
            //save frame, it's not the "home"/workspace frame
            TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame();
            IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME);
            currentFrame.saveState(frameMemento);
        } else {
            //save visible expanded elements
            Object expandedElements[] = viewer.getVisibleExpandedElements();
            if (expandedElements.length > 0) {
                IMemento expandedMem = memento.createChild(TAG_EXPANDED);
                for (int i = 0; i < expandedElements.length; i++) {
                    if (expandedElements[i] instanceof IResource) {
                        IMemento elementMem = expandedMem
                                .createChild(TAG_ELEMENT);
                        elementMem.putString(TAG_PATH,
                                ((IResource) expandedElements[i]).getFullPath()
                                        .toString());
                    }
                }
            }
            //save selection
            Object elements[] = ((IStructuredSelection) viewer.getSelection())
                    .toArray();
            if (elements.length > 0) {
                IMemento selectionMem = memento.createChild(TAG_SELECTION);
                for (int i = 0; i < elements.length; i++) {
                    if (elements[i] instanceof IResource) {
                        IMemento elementMem = selectionMem
                                .createChild(TAG_ELEMENT);
                        elementMem.putString(TAG_PATH,
                                ((IResource) elements[i]).getFullPath()
                                        .toString());
                    }
                }
            }
        }

        saveLinkingEnabled(memento);
    }

    /**
     * Saves the linking enabled state.
     */
    private void saveLinkingEnabled(IMemento memento) {
        memento.putInteger(
                IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
                linkingEnabled ? 1 : 0);
    }

    /**
     * Selects and reveals the specified elements.
     */
    public void selectReveal(ISelection selection) {
        StructuredSelection ssel = convertSelection(selection);
        if (!ssel.isEmpty()) {
            getViewer().getControl().setRedraw(false);
            getViewer().setSelection(ssel, true);
            getViewer().getControl().setRedraw(true);
        }
    }

    /**
     * Saves the filters defined as strings in <code>patterns</code> 
     * in the preference store.
     */
    public void setFiltersPreference(String[] patterns) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < patterns.length; i++) {
            if (i != 0)
                sb.append(ResourcePatternFilter.COMMA_SEPARATOR);
            sb.append(patterns[i]);
        }

        getPlugin().getPreferenceStore().setValue(
                ResourcePatternFilter.FILTERS_TAG, sb.toString());

        // remove value in old workbench preference store location 
        IPreferenceStore preferenceStore = IDEWorkbenchPlugin.getDefault()
                .getPreferenceStore();
        String storedPatterns = preferenceStore
                .getString(ResourcePatternFilter.FILTERS_TAG);
        if (storedPatterns.length() > 0)
            preferenceStore.setValue(ResourcePatternFilter.FILTERS_TAG, ""); //$NON-NLS-1$
    }

    /**
     * @see IWorkbenchPart#setFocus()
     */
    public void setFocus() {
        getTreeViewer().getTree().setFocus();
    }

    /**
     * Note: For experimental use only.
     * Sets the decorator for the navigator.
     * <p>
     * As of 2.0, this method no longer has any effect.
     * </p>
     *
     * @param decorator a label decorator or <code>null</code> for no decorations.
     * @deprecated use the decorators extension point instead; see IWorkbench.getDecoratorManager()
     */
    public void setLabelDecorator(ILabelDecorator decorator) {
        // do nothing
    }

    /**
     * @see IResourceNavigator#setLinkingEnabled(boolean)
     * @since 2.1
     */
    public void setLinkingEnabled(boolean enabled) {
        this.linkingEnabled = enabled;

        // remember the last setting in the dialog settings		
        settings.put(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
                enabled);

        // if turning linking on, update the selection to correspond to the active editor
        if (enabled) {
            IEditorPart editor = getSite().getPage().getActiveEditor();
            if (editor != null) {
                editorActivated(editor);
            }
        }
    }

    /**
     * Sets the resource sorter.
     * 
     * @param sorter the resource sorter
     * @since 2.0
     */
    public void setSorter(ResourceSorter sorter) {
        TreeViewer viewer = getTreeViewer();
        ViewerSorter viewerSorter = viewer.getSorter();

        viewer.getControl().setRedraw(false);
        if (viewerSorter == sorter) {
            viewer.refresh();
        } else {
            viewer.setSorter(sorter);
        }
        viewer.getControl().setRedraw(true);
        settings.put(STORE_SORT_TYPE, sorter.getCriteria());

        // update the sort actions' checked state
        updateActionBars((IStructuredSelection) viewer.getSelection());
    }

    /*
     * @see org.eclipse.ui.views.navigator.IResourceNavigatorPart#setWorkingSet(IWorkingSet)
     * @since 2.0
     */
    public void setWorkingSet(IWorkingSet workingSet) {
        TreeViewer treeViewer = getTreeViewer();
        Object[] expanded = treeViewer.getExpandedElements();
        ISelection selection = treeViewer.getSelection();
        
        internalSetWorkingSet(workingSet);
        
        workingSetFilter.setWorkingSet(emptyWorkingSet ? null : workingSet);
        if (workingSet != null) {
            settings.put(STORE_WORKING_SET, workingSet.getName());
        } else {
            settings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$
        }
        updateTitle();
        treeViewer.refresh();
        treeViewer.setExpandedElements(expanded);
        if (selection.isEmpty() == false
                && selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection = (IStructuredSelection) selection;
            treeViewer.reveal(structuredSelection.getFirstElement());
        }
    }

	/**
	 * Set the internal working set fields specific to the navigator.
	 * 
	 * @param workingSet
	 *            the new working set
	 * @since 3.2
	 */
	private void internalSetWorkingSet(IWorkingSet workingSet) {
		this.workingSet = workingSet;
		emptyWorkingSet = workingSet != null && workingSet.isAggregateWorkingSet() 
				&& workingSet.isEmpty();
	}

    /**
     * Updates the action bar actions.
     * 
     * @param selection the current selection
     * @since 2.0
     */
    protected void updateActionBars(IStructuredSelection selection) {
        ResourceNavigatorActionGroup group = getActionGroup();
        if (group != null) {
            group.setContext(new ActionContext(selection));
            group.updateActionBars();
        }
    }

    /**
     * Updates the message shown in the status line.
     *
     * @param selection the current selection
     */
    protected void updateStatusLine(IStructuredSelection selection) {
        String msg = getStatusLineMessage(selection);
        getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
    }

    /**
     * Updates the title text and title tool tip.
     * Called whenever the input of the viewer changes.
     * Called whenever the input of the viewer changes.
     * 
     * @since 2.0
     */
    public void updateTitle() {
        Object input = getViewer().getInput();
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IWorkingSet workingSet = workingSetFilter.getWorkingSet();

        if (input == null || input.equals(workspace)
                || input.equals(workspace.getRoot())) {
            setContentDescription(""); //$NON-NLS-1$
            if (workingSet != null) {
                setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetToolTip, workingSet.getLabel()));
            } else {
                setTitleToolTip(""); //$NON-NLS-1$
            }
        } else {
            ILabelProvider labelProvider = (ILabelProvider) getTreeViewer()
                    .getLabelProvider();
            String inputToolTip = getFrameToolTipText(input);
            String text = labelProvider.getText(input);
            if(text != null)
            	setContentDescription(text);
            if (workingSet != null) {
                setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetInputToolTip, inputToolTip, workingSet.getLabel()));
            } else {
                setTitleToolTip(inputToolTip);
            }
        }
    }

    /**
     * Returns the action group.
     * 
     * @return the action group
     */
    protected ResourceNavigatorActionGroup getActionGroup() {
        return actionGroup;
    }

    /**
     * Sets the action group.
     * 
     * @param actionGroup the action group
     */
    protected void setActionGroup(ResourceNavigatorActionGroup actionGroup) {
        this.actionGroup = actionGroup;
    }

    /*
     * @see IWorkbenchPart#getAdapter(Class)
     */
    public Object getAdapter(Class adapter) {
        if (adapter == IShowInSource.class) {
            return getShowInSource();
        }
        if (adapter == IShowInTarget.class) {
            return getShowInTarget();
        }
        return null;
    }

    /**
     * Returns the <code>IShowInSource</code> for this view.
     */
    protected IShowInSource getShowInSource() {
        return new IShowInSource() {
            public ShowInContext getShowInContext() {
                return new ShowInContext(getViewer().getInput(), getViewer()
                        .getSelection());
            }
        };
    }

    /**
     * Returns the <code>IShowInTarget</code> for this view.
     */
    protected IShowInTarget getShowInTarget() {
        return new IShowInTarget() {
            public boolean show(ShowInContext context) {
                ArrayList toSelect = new ArrayList();
                ISelection sel = context.getSelection();
                if (sel instanceof IStructuredSelection) {
                    IStructuredSelection ssel = (IStructuredSelection) sel;
                    for (Iterator i = ssel.iterator(); i.hasNext();) {
                        Object o = i.next();
                        if (o instanceof IResource) {
                            toSelect.add(o);
                        } else if (o instanceof IMarker) {
                            IResource r = ((IMarker) o).getResource();
                            if (r.getType() != IResource.ROOT) {
                                toSelect.add(r);
                            }
                        } else if (o instanceof IAdaptable) {
                            IAdaptable adaptable = (IAdaptable) o;
                            o = adaptable.getAdapter(IResource.class);
                            if (o instanceof IResource) {
                                toSelect.add(o);
                            } else {
                                o = adaptable.getAdapter(IMarker.class);
                                if (o instanceof IMarker) {
                                    IResource r = ((IMarker) o).getResource();
                                    if (r.getType() != IResource.ROOT) {
                                        toSelect.add(r);
                                    }
                                }
                            }
                        }
                    }
                }
                if (toSelect.isEmpty()) {
                    Object input = context.getInput();
                    if (input instanceof IAdaptable) {
                        IAdaptable adaptable = (IAdaptable) input;
                        Object o = adaptable.getAdapter(IResource.class);
                        if (o instanceof IResource) {
                            toSelect.add(o);
                        }
                    }
                }
                if (!toSelect.isEmpty()) {
                    selectReveal(new StructuredSelection(toSelect));
                    return true;
                }
                return false;
            }
        };
    }
}
