org.eclipse.edt.ide.ui.internal.editor.EGLEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.edt.ide.ui.internal.editor.EGLEditor.java

Source

/*******************************************************************************
 * Copyright  2000, 2013 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.edt.ide.ui.internal.editor;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Stack;

import java_cup.runtime.Symbol;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.edt.compiler.core.ast.ImportDeclaration;
import org.eclipse.edt.compiler.core.ast.Lexer;
import org.eclipse.edt.compiler.core.ast.Node;
import org.eclipse.edt.compiler.core.ast.NodeTypes;
import org.eclipse.edt.compiler.core.ast.PackageDeclaration;
import org.eclipse.edt.ide.core.internal.model.document.EGLDocument;
import org.eclipse.edt.ide.core.model.EGLCore;
import org.eclipse.edt.ide.core.model.IEGLElement;
import org.eclipse.edt.ide.core.model.document.IEGLDocument;
import org.eclipse.edt.ide.ui.EDTUIPlugin;
import org.eclipse.edt.ide.ui.EDTUIPreferenceConstants;
import org.eclipse.edt.ide.ui.bidi.IBIDIProvider;
import org.eclipse.edt.ide.ui.editor.IEGLEditor;
import org.eclipse.edt.ide.ui.editor.IFoldingStructureProvider;
import org.eclipse.edt.ide.ui.internal.EGLLogger;
import org.eclipse.edt.ide.ui.internal.EGLUI;
import org.eclipse.edt.ide.ui.internal.IUIHelpConstants;
import org.eclipse.edt.ide.ui.internal.outline.ImportGroup;
import org.eclipse.edt.ide.ui.internal.outline.OutlineAdapterFactory;
import org.eclipse.edt.ide.ui.internal.outline.OutlineLabelProvider;
import org.eclipse.edt.ide.ui.internal.outline.OutlinePage;
import org.eclipse.edt.ide.ui.internal.preferences.ContentAssistPreference;
import org.eclipse.edt.ide.ui.internal.results.views.AbstractResultsViewPart;
import org.eclipse.help.IContextProvider;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedModeUI;
import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags;
import org.eclipse.jface.text.link.LinkedModeUI.IExitPolicy;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

public class EGLEditor extends TextEditor implements IEGLEditor {
    /**
     * ID of the action to toggle the style of the presentation.
     */
    public static final String TOGGLE_PRESENTATION = "togglePresentation"; //$NON-NLS-1$
    public static final String FOLDING_TOGGLE_ID = "FoldingToggle"; //$NON-NLS-1$
    public static final String FOLDING_EXPANDALL_ID = "FoldingExpandAll"; //$NON-NLS-1$
    public static final String FOLDING_EXPAND_ID = "FoldingExpand"; //$NON-NLS-1$   
    public static final String FOLDING_COLLAPSE_ID = "FoldingCollapse"; //$NON-NLS-1$
    public static final String RENAME_ID = "org.eclipse.jdt.ui.actions.Rename"; //$NON-NLS-1$
    public static final String MOVE_ID = "org.eclipse.jdt.ui.actions.Move"; //$NON-NLS-1$

    /** Preference key for compiler task tags */
    private static final String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;

    private OutlinePage fOutlinePage;
    protected String fOutlinerContextMenuID;
    private boolean disableRulerArea;

    // HashMaps to contain nodes that have errors or warnings.  This is initialized
    // when the editor is opened and then is updated each time the markers change (which
    // happens on save).  These hashMaps are used by the outline adapters to put the
    // appropriate red X's on icons in the outline view.
    protected HashMap nodesWithSavedErrors;
    protected HashMap nodesWithSavedWarnings;

    AbstractResultsViewPart sqlErrorView;
    protected TextTools tools;

    /** The preference property change listener */
    private IPropertyChangeListener fPropertyChangeListener;

    protected ISelectionChangedListener fSelectionChangedListener = new SelectionChangedListener();
    private int fIgnoreOutlinePageSelection = 0;

    private OutlineAdapterFactory factory;

    private ProjectionSupport fProjectionSupport;
    private IFoldingStructureProvider fFoldingStructureProvider;
    private IBIDIProvider fBIDIProvider;

    private ToggleFoldingRunner fFoldingRunner;

    /** The bracket inserter. */
    private BracketInserter fBracketInserter = new BracketInserter();

    class AdaptedSourceViewer extends EGLSourceViewer {
        public AdaptedSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
                boolean showAnnotationsOverview, int styles) {
            super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles);
        }

        public IContentAssistant getContentAssistant() {
            return fContentAssistant;
        }
    }

    class SelectionChangedListener implements ISelectionChangedListener {
        public void selectionChanged(SelectionChangedEvent event) {
            if (primGetOutlinePage() != null) {
                Control control = primGetOutlinePage().getControl();
                if (control != null && !control.isDisposed() && control.isFocusControl()) {
                    doSelectionChanged(event);
                }
            }
        }
    };

    /**
     * Runner that will toggle folding either instantly (if the editor is
     * visible) or the next time it becomes visible. If a runner is started when
     * there is already one registered, the registered one is canceled as
     * toggling folding twice is a no-op.
     * <p>
     * The access to the fFoldingRunner field is not thread-safe, it is assumed
     * that <code>runWhenNextVisible</code> is only called from the UI thread.
     * </p>
     *
     * @since 3.1
     */
    private final class ToggleFoldingRunner implements IPartListener2 {
        /**
         * The workbench page we registered the part listener with, or
         * <code>null</code>.
         */
        private IWorkbenchPage fPage;

        /**
         * Does the actual toggling of projection.
         */
        private void toggleFolding() {
            ISourceViewer sourceViewer = getSourceViewer();
            if (sourceViewer instanceof ProjectionViewer) {
                ProjectionViewer pv = (ProjectionViewer) sourceViewer;
                if (pv.isProjectionMode() != isFoldingEnabled()) {
                    if (pv.canDoOperation(ProjectionViewer.TOGGLE))
                        pv.doOperation(ProjectionViewer.TOGGLE);
                }
            }
        }

        /**
         * Makes sure that the editor's folding state is correct the next time
         * it becomes visible. If it already is visible, it toggles the folding
         * state. If not, it either registers a part listener to toggle folding
         * when the editor becomes visible, or cancels an already registered
         * runner.
         */
        public void runWhenNextVisible() {
            // if there is one already: toggling twice is the identity
            if (fFoldingRunner != null) {
                fFoldingRunner.cancel();
                return;
            }

            IWorkbenchPartSite site = getSite();

            // The visual editor (EvEditor) is a multi page editor
            // Always do the toggle for the visual editor
            if (site != null && site instanceof MultiPageEditorSite == false) {
                IWorkbenchPage page = site.getPage();

                // This visibility check returns false for the visual
                // editor when the Source page (EGLEditor) is visible
                // because the Source page does not have its own pane
                if (!page.isPartVisible(EGLEditor.this)) {
                    // if we're not visible - defer until visible
                    fPage = page;
                    fFoldingRunner = this;
                    page.addPartListener(this);
                    return;
                }
            }
            // we're visible - run now
            toggleFolding();
        }

        /**
         * Remove the listener and clear the field.
         */
        private void cancel() {
            if (fPage != null) {
                fPage.removePartListener(this);
                fPage = null;
            }
            if (fFoldingRunner == this)
                fFoldingRunner = null;
        }

        /*
         * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference)
         */
        public void partVisible(IWorkbenchPartReference partRef) {
            if (EGLEditor.this.equals(partRef.getPart(false))) {
                cancel();
                toggleFolding();
            }
        }

        /*
         * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
         */
        public void partClosed(IWorkbenchPartReference partRef) {
            if (EGLEditor.this.equals(partRef.getPart(false))) {
                cancel();
            }
        }

        public void partActivated(IWorkbenchPartReference partRef) {
        }

        public void partBroughtToTop(IWorkbenchPartReference partRef) {
        }

        public void partDeactivated(IWorkbenchPartReference partRef) {
        }

        public void partOpened(IWorkbenchPartReference partRef) {
        }

        public void partHidden(IWorkbenchPartReference partRef) {
        }

        public void partInputChanged(IWorkbenchPartReference partRef) {
        }
    }

    /** Listener to annotation model changes that updates the error tick in the tab image */
    private EditorErrorTickUpdater fEGLEditorErrorTickUpdater;

    /**
     * Handles a property change event describing a change
     * of the java core's preferences and updates the preference
     * related editor properties.
     * 
     * @param event the property change event
     */
    protected void handlePreferencePropertyChanged(PropertyChangeEvent event) {
        ISourceViewer sourceViewer = getSourceViewer();
        if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
            if (sourceViewer != null && affectsTextPresentation(new PropertyChangeEvent(event.getSource(),
                    event.getProperty(), event.getOldValue(), event.getNewValue())))
                sourceViewer.invalidateTextPresentation();
        }
        if (PreferenceConstants.EDITOR_SHOW_SEGMENTS.equals(event.getProperty())) {
            if ((sourceViewer != null) && affectsTextPresentation(new PropertyChangeEvent(event.getSource(),
                    event.getProperty(), event.getOldValue(), event.getNewValue()))) {
                sourceViewer.invalidateTextPresentation();
            }
        }
    }

    public EGLEditor() {
        this(false);
    }

    //The ruler is disabled when this editor is used within the Quick Edit view of Seoul to
    //prevent various problems which may need to get fix in a later release
    public EGLEditor(boolean disableRulerArea) {
        super();
        this.disableRulerArea = disableRulerArea;

        if (tools == null)
            tools = new TextTools(EDTUIPlugin.getDefault().getPreferenceStore());

        initializeKeyBindingScopes();

        fEGLEditorErrorTickUpdater = new EditorErrorTickUpdater(this);
    }

    /*
     * @see org.eclipse.ui.texteditor.AbstractTextEditor#initializeEditor()
     */
    protected void initializeEditor() {

        DocumentProvider documentProvider = (DocumentProvider) EGLUI.getDocumentProvider();
        setDocumentProvider(documentProvider);

        setRangeIndicator(new DefaultRangeIndicator());

        setEditorContextMenuId("#EGLEditorContext"); //$NON-NLS-1$
        setRulerContextMenuId("#EGLRulerContext"); //$NON-NLS-1$
        setOutlinerContextMenuId("#EGLOutlinerContext"); //$NON-NLS-1$

        // ensure that the TextTools adds its listener before this editor adds its listener
        if (tools == null)
            tools = new TextTools(EDTUIPlugin.getDefault().getPreferenceStore());

        // adds PropertyChangeListener
        setPreferenceStore(createCombinedPreferenceStore());

        setSourceViewerConfiguration(new EGLSourceViewerConfiguration(tools, this));

        // Instantiate this factory here and cache the value since it is
        // used by the outline adapters for the outline view.
        factory = new OutlineAdapterFactory(null, this);

    }

    protected boolean isEditorInputIncludedInContextMenu() {
        return true;
    }

    protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
        fAnnotationAccess = getAnnotationAccess();
        fOverviewRuler = createOverviewRuler(getSharedColors());

        //@bd1a Start
        if (Locale.getDefault().toString().toLowerCase().indexOf("ar") != -1) {
            styles |= SWT.LEFT_TO_RIGHT;
        }
        //@bd1a End

        AdaptedSourceViewer sourceViewer = new AdaptedSourceViewer(parent, ruler, getOverviewRuler(),
                isOverviewRulerVisible(), styles);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sourceViewer.getTextWidget(),
                IUIHelpConstants.EGL_EDITOR);

        /*
         * This is a performance optimization to reduce the computation of
         * the text presentation triggered by {@link #setVisibleDocument(IDocument)}
         */
        if (sourceViewer != null && isFoldingEnabled())
            sourceViewer.prepareDelayedProjection();

        ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;
        createFoldingSupport(projectionViewer);
        //       if (isFoldingEnabled()) {
        //          projectionViewer.doOperation(ProjectionViewer.TOGGLE);
        //       }         

        fFoldingStructureProvider = EDTUIPlugin.getDefault().getFoldingStructureProviderRegistry()
                .getCurrentFoldingProvider();
        //fFoldingStructureProvider = new FoldingStructureProvider();
        if (fFoldingStructureProvider != null) {
            fFoldingStructureProvider.install(this, projectionViewer);
        }

        // ensure decoration support has been created and configured.
        getSourceViewerDecorationSupport(sourceViewer);

        return sourceViewer;
    }

    public void doSelectionChanged(SelectionChangedEvent event) {
        int offset;
        int nodeLength;
        StructuredSelection selection = (StructuredSelection) event.getSelection();

        if (selection == null || selection.isEmpty())
            return;

        IEGLDocument document = (IEGLDocument) getDocumentProvider().getDocument(getEditorInput());

        if (document == null)
            return;

        // Use the 1st for selection (know it's not empty because of
        // test above) 
        Object selectedElement = selection.getFirstElement();
        if (selectedElement == null)
            return;

        if (selectedElement instanceof ImportGroup) {
            offset = ((ImportGroup) selectedElement).getOffset();
            nodeLength = ((ImportGroup) selectedElement).getLength();
        } else if (selectedElement instanceof ImportDeclaration || selectedElement instanceof PackageDeclaration) {
            offset = ((Node) selectedElement).getOffset();
            nodeLength = ((Node) selectedElement).getLength();
        } else {
            offset = ((Node) selectedElement).getOffset();
            nodeLength = ((Node) selectedElement).getLength();
        }

        try {
            editingScriptStarted();
            setSelection(offset, nodeLength);
            TreeViewer tv = (TreeViewer) event.getSource();
            ILabelProvider provider = (ILabelProvider) tv.getLabelProvider();
            IRegion region = ((OutlineLabelProvider) provider).getHighlightRange(selectedElement);
            if (region.getLength() != 0) {
                getSourceViewer().revealRange(region.getOffset(), region.getLength());
                getSourceViewer().setSelectedRange(region.getOffset(), region.getLength());
            }
        } finally {
            editingScriptEnded();
        }
    }

    /*
     * @see AbstractTextEditor#doSetInput
     */
    protected void doSetInput(IEditorInput input) throws CoreException {
        ISourceViewer sourceViewer = getSourceViewer();
        EGLSourceViewer eglSourceViewer = null;
        if (sourceViewer instanceof EGLSourceViewer)
            eglSourceViewer = (EGLSourceViewer) sourceViewer;

        IPreferenceStore store = getPreferenceStore();
        if (eglSourceViewer != null && isFoldingEnabled()
                && (store == null || !store.getBoolean(EDTUIPreferenceConstants.EDITOR_SHOW_SEGMENTS)))
            eglSourceViewer.prepareDelayedProjection();

        super.doSetInput(input);

        if (eglSourceViewer != null && eglSourceViewer.getReconciler() == null) {
            IReconciler reconciler = getSourceViewerConfiguration().getReconciler(eglSourceViewer);
            if (reconciler != null) {
                reconciler.install(sourceViewer);
            }
        }

        if (fEncodingSupport != null)
            fEncodingSupport.reset();

        // Initialize the error and warning hashmaps so the outline icons
        // are correct.  Must be done after the input is initialized.    
        EditorUtility.populateNodeErrorWarningHashMaps(this);

        setOutlinePageInput(fOutlinePage, input);
    }

    /*
     * @see JavaEditor#setOutlinePageInput(JavaOutlinePage, IEditorInput)
     */
    protected void setOutlinePageInput(OutlinePage page, IEditorInput input) {
        if (page != null) {
            DocumentProvider provider = (DocumentProvider) getDocumentProvider();
            page.setInput((IEGLDocument) provider.getDocument(input));
        }
    }

    /**
     * Creates the outline page used with this editor.
     */
    protected OutlinePage createOutlinePage() {
        IDocument doc = getDocumentProvider().getDocument(getEditorInput());
        if (doc instanceof IEGLDocument) {
            OutlinePage page = new OutlinePage((IEGLDocument) doc, fOutlinerContextMenuID, this);

            page.addSelectionChangedListener(fSelectionChangedListener);
            setOutlinePageInput(page, getEditorInput());

            fOutlinePage = page;
            return page;
        }
        return null;
    }

    /**
     * Informs the editor that its outliner has been closed.
     */
    public void outlinePageClosed() {
        if (fOutlinePage != null) {
            fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
            fOutlinePage = null;
            resetHighlightRange();
        }
    }

    public int getLineAtOffset(int offset) {
        try {
            EGLDocument document = (EGLDocument) getViewer().getDocument();
            return document.getLineOfOffset(offset);
        } catch (BadLocationException e) {
            e.printStackTrace();
            EGLLogger.log(this, e);
        }
        return 0;
    }

    public synchronized void editingScriptStarted() {
        ++fIgnoreOutlinePageSelection;
    }

    public synchronized void editingScriptEnded() {
        --fIgnoreOutlinePageSelection;
    }

    private boolean isFoldingEnabled() {
        IPreferenceStore store = getPreferenceStore();
        return store.getBoolean(EDTUIPreferenceConstants.EDITOR_FOLDING_ENABLED);
    }

    public synchronized boolean isEditingScriptRunning() {
        return (fIgnoreOutlinePageSelection > 0);
    }

    public void setSelection(int offset, int nodeLength) {

        StyledText textWidget = null;

        ISourceViewer sourceViewer = getSourceViewer();
        if (sourceViewer != null)
            textWidget = sourceViewer.getTextWidget();

        if (textWidget == null)
            return;

        try {
            if (offset < 0 || nodeLength < 0)
                return;

            textWidget.setRedraw(false);

            //TODO Do we need to pass in moveCursor value?
            setHighlightRange(offset, nodeLength, true);
            //      sourceViewer.revealRange(offset, nodeLength);
            //      sourceViewer.setSelectedRange(offset, nodeLength);
        } catch (IllegalArgumentException x) {
        } finally {
            if (textWidget != null)
                textWidget.setRedraw(true);
        }

    }

    public void dispose() {

        ISourceViewer sourceViewer = getSourceViewer();
        if (sourceViewer instanceof ITextViewerExtension)
            ((ITextViewerExtension) sourceViewer).removeVerifyKeyListener(fBracketInserter);

        if (sqlErrorView != null) {
            sqlErrorView.closeMyViewerIfNecessary(this);
        }

        if (tools != null) {
            tools.dispose();
            tools = null;
        }

        if (fFoldingStructureProvider != null) {
            fFoldingStructureProvider.uninstall();
            fFoldingStructureProvider = null;
        }

        if (fBIDIProvider != null) {
            fBIDIProvider.uninstall();
            fBIDIProvider = null;
        }

        //((ProjectionViewer)getViewer()).removeProjectionListener(this);
        if (fProjectionSupport != null) {
            fProjectionSupport.dispose();
            fProjectionSupport = null;
        }

        if (fPropertyChangeListener != null) {
            IPreferenceStore pref = getPreferenceStore();

            if (pref != null)
                pref.removePropertyChangeListener(fPropertyChangeListener);

            fPropertyChangeListener = null;
        }

        if (fEGLEditorErrorTickUpdater != null) {
            fEGLEditorErrorTickUpdater.dispose();
            fEGLEditorErrorTickUpdater = null;
        }
        super.dispose();
    }

    /**
     * Returns the outline page
     */
    public OutlinePage getOutlinePage() {
        if (fOutlinePage == null) {
            return createOutlinePage();
        }
        return fOutlinePage;
    }

    private IPreferenceStore createCombinedPreferenceStore() {
        List stores = new ArrayList(3);

        stores.add(EDTUIPlugin.getDefault().getPreferenceStore());
        stores.add(EditorsUI.getPreferenceStore());
        stores.add(PlatformUI.getPreferenceStore());

        return new ChainedPreferenceStore((IPreferenceStore[]) stores.toArray(new IPreferenceStore[stores.size()]));
    }

    protected void initializeKeyBindingScopes() {
        setKeyBindingScopes(new String[] { "org.eclipse.edt.ide.ui.eglEditorScope" }); //$NON-NLS-1$
    }

    /**
     * Sets the outliner's context menu ID.
     */
    protected void setOutlinerContextMenuId(String menuId) {
        fOutlinerContextMenuID = menuId;
    }

    /* (non-Javadoc)
     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
     */
    public Object getAdapter(Class required) {
        if (required == IEGLEditor.class || required == EGLEditor.class) {
            return this;
        }
        if (IContentOutlinePage.class.equals(required)) {
            return getOutlinePage();
        }
        if (required == IShowInTargetList.class) {
            return new IShowInTargetList() {
                public String[] getShowInTargetIds() {
                    return new String[] { IPageLayout.ID_PROJECT_EXPLORER, IPageLayout.ID_OUTLINE,
                            IPageLayout.ID_RES_NAV };
                }
            };
        }

        if (required == IShowInSource.class) {
            IEditorInput editorInput = getEditorInput();
            if (editorInput instanceof IFileEditorInput) {
                IResource resource = ((IFileEditorInput) getEditorInput()).getFile();
                IEGLElement element = EGLCore.create(resource);
                if (element != null) {
                    final StructuredSelection selection = new StructuredSelection(element);
                    return new IShowInSource() {
                        public ShowInContext getShowInContext() {
                            return new ShowInContext(getEditorInput(), selection);
                        }
                    };
                }
            }
        }

        if (fProjectionSupport != null) {
            Object adapter = fProjectionSupport.getAdapter(getSourceViewer(), required);
            if (adapter != null) {
                return adapter;
            }
        }

        if (required == IContextProvider.class)
            return EGLUIHelp.getHelpContextProvider(this, IUIHelpConstants.EGL_EDITOR);

        return super.getAdapter(required);
    }

    public StyledText getSourceViewerStyledText() {
        return getSourceViewer().getTextWidget();
    }

    public AbstractResultsViewPart getSqlErrorView() {
        return sqlErrorView;
    }

    public ISourceViewer getViewer() {
        return getSourceViewer();
    }

    public void setSqlErrorView(AbstractResultsViewPart sqlErrorView) {
        this.sqlErrorView = sqlErrorView;
    }

    /*
     * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection)
     */
    protected void doSetSelection(ISelection selection) {
        super.doSetSelection(selection);
        synchronizeOutlinePageSelection();
    }

    /**
     * Synchronizes the outliner selection with the actual cursor
     * position in the editor.
     */
    public void synchronizeOutlinePageSelection() {

        if (isEditingScriptRunning())
            return;

        ISourceViewer sourceViewer = getSourceViewer();
        if (sourceViewer == null || fOutlinePage == null)
            return;

        StyledText styledText = sourceViewer.getTextWidget();
        if (styledText == null)
            return;

        // get the node at the current cursor location
        int offset = getSourceViewer().getTextWidget().getSelection().x;
        IEGLDocument document = (IEGLDocument) getDocumentProvider().getDocument(getEditorInput());
        if (offset > 0) {
            offset--;
        }
        Node node = document.getNewModelNodeAtOffset(offset);

        factory = new OutlineAdapterFactory(null, this);
        while (node != null && !factory.isDisplayableElement(node)) {
            node = node.getParent();
        }

        if (node == null)
            return;

        int nodeEndOffset = node.getOffset() + node.getLength();
        if (offset + 1 > nodeEndOffset) {
            do {
                node = node.getParent();
            } while (node != null && !factory.isDisplayableElement(node));
        }

        fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
        fOutlinePage.select(node);
        fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
    }

    /*
     * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
     */
    protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {

        try {

            ISourceViewer sourceViewer = getSourceViewer();
            if (sourceViewer == null)
                return;

            String property = event.getProperty();

            if (EDTUIPreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
                Object value = event.getNewValue();
                if (value instanceof Integer) {
                    sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
                } else if (value instanceof String) {
                    sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value));
                }
                return;
            }

            if (EDTUIPreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) {
                if (sourceViewer instanceof ProjectionViewer) {
                    ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;
                    if (fFoldingStructureProvider != null)
                        fFoldingStructureProvider.uninstall();
                    //either freshly enabled or provider changed
                    fFoldingStructureProvider = EDTUIPlugin.getDefault().getFoldingStructureProviderRegistry()
                            .getCurrentFoldingProvider();
                    //fFoldingStructureProvider = new FoldingStructureProvider();
                    if (fFoldingStructureProvider != null)
                        fFoldingStructureProvider.install(this, projectionViewer);
                }
            }

            if (EDTUIPreferenceConstants.EDITOR_FOLDING_ENABLED.equals(property)) {
                if (sourceViewer instanceof ProjectionViewer) {
                    new ToggleFoldingRunner().runWhenNextVisible();
                }
                return;
            }

            if (EDTUIPreferenceConstants.CODEASSIST_AUTOACTIVATION.equals(property)) {
                IContentAssistant c = ((AdaptedSourceViewer) sourceViewer).getContentAssistant();
                if (c instanceof ContentAssistant) {
                    ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
                }
                return;
            }

            if (EDTUIPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY.equals(property)) {
                IContentAssistant c = ((AdaptedSourceViewer) sourceViewer).getContentAssistant();
                if (c instanceof ContentAssistant) {
                    ContentAssistPreference.changeConfiguration((ContentAssistant) c, getPreferenceStore(), event);
                }
                return;
            }

        } finally {
            super.handlePreferenceStoreChanged(event);
        }
    }

    /*
     * @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
     */
    protected boolean affectsTextPresentation(PropertyChangeEvent event) {
        return tools.affectsBehavior(event);
    }

    /*
     * Update the icon used on the editor's tab
     */
    public void updatedTitleImage(Image image) {
        setTitleImage(image);
    }

    public void setNodesWithSavedErrors(HashMap hashMap) {
        nodesWithSavedErrors = hashMap;
    }

    public HashMap getNodesWithSavedErrors() {
        return nodesWithSavedErrors;
    }

    public void setNodesWithSavedWarnings(HashMap hashMap) {
        nodesWithSavedWarnings = hashMap;
    }

    public HashMap getNodesWithSavedWarnings() {
        return nodesWithSavedWarnings;
    }

    public OutlineAdapterFactory getOutlineAdapterFactory() {
        return factory;
    }

    public OutlinePage primGetOutlinePage() {
        return fOutlinePage;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     * 
     * the ruler is disabled when this editor is used within the Quick Edit view of Seoul
     */
    public void createPartControl(Composite parent) {
        super.createPartControl(parent);
        getVerticalRuler().getControl().setEnabled(!disableRulerArea);

        fBracketInserter.setCloseBracketsEnabled(true); //always true for now, it could be read from egl editor preference      
        fBracketInserter.setCloseStringsEnabled(true); //if we decide to add this as preference in the future

        ISourceViewer sourceViewer = getSourceViewer();
        if (sourceViewer instanceof ITextViewerExtension)
            ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);

    }

    private void createFoldingSupport(ProjectionViewer projectionViewer) {
        fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors());
        fProjectionSupport.addSummarizableAnnotationType(EGLMarkerAnnotation.ERROR_ANNOTATION_TYPE); //$NON-NLS-1$
        fProjectionSupport.addSummarizableAnnotationType(EGLMarkerAnnotation.WARNING_ANNOTATION_TYPE); //$NON-NLS-1$      
        fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
            public IInformationControl createInformationControl(Shell shell) {
                return new SourceViewerInformationControl(shell);
            }
        });
        fProjectionSupport.install();
    }

    protected void performRevert() {
        ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
        projectionViewer.setRedraw(false);
        try {

            boolean projectionMode = projectionViewer.isProjectionMode();
            if (projectionMode) {
                projectionViewer.disableProjection();
                if (fFoldingStructureProvider != null)
                    fFoldingStructureProvider.uninstall();
            }

            super.performRevert();
            if (projectionMode) {
                if (fFoldingStructureProvider != null)
                    fFoldingStructureProvider.install(this, projectionViewer);
                projectionViewer.enableProjection();
            }
        } finally {
            projectionViewer.setRedraw(true);
        }
    }

    /**
     * Position updater that takes any changes at the borders of a position to not belong to the position.
     *
     * @since 3.0
     */
    private static class ExclusivePositionUpdater implements IPositionUpdater {

        /** The position category. */
        private final String fCategory;

        /**
         * Creates a new updater for the given <code>category</code>.
         *
         * @param category the new category.
         */
        public ExclusivePositionUpdater(String category) {
            fCategory = category;
        }

        /*
         * @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
         */
        public void update(DocumentEvent event) {

            int eventOffset = event.getOffset();
            int eventOldLength = event.getLength();
            int eventNewLength = event.getText() == null ? 0 : event.getText().length();
            int deltaLength = eventNewLength - eventOldLength;

            try {
                Position[] positions = event.getDocument().getPositions(fCategory);

                for (int i = 0; i != positions.length; i++) {

                    Position position = positions[i];

                    if (position.isDeleted())
                        continue;

                    int offset = position.getOffset();
                    int length = position.getLength();
                    int end = offset + length;

                    if (offset >= eventOffset + eventOldLength)
                        // position comes
                        // after change - shift
                        position.setOffset(offset + deltaLength);
                    else if (end <= eventOffset) {
                        // position comes way before change -
                        // leave alone
                    } else if (offset <= eventOffset && end >= eventOffset + eventOldLength) {
                        // event completely internal to the position - adjust length
                        position.setLength(length + deltaLength);
                    } else if (offset < eventOffset) {
                        // event extends over end of position - adjust length
                        int newEnd = eventOffset;
                        position.setLength(newEnd - offset);
                    } else if (end > eventOffset + eventOldLength) {
                        // event extends from before position into it - adjust offset
                        // and length
                        // offset becomes end of event, length adjusted accordingly
                        int newOffset = eventOffset + eventNewLength;
                        position.setOffset(newOffset);
                        position.setLength(end - newOffset);
                    } else {
                        // event consumes the position - delete it
                        position.delete();
                    }
                }
            } catch (BadPositionCategoryException e) {
                // ignore and return
            }
        }

        /**
         * Returns the position category.
         *
         * @return the position category
         */
        public String getCategory() {
            return fCategory;
        }

    }

    private static class BracketLevel {
        int fOffset;
        int fLength;
        LinkedModeUI fUI;
        Position fFirstPosition;
        Position fSecondPosition;
    }

    private class ExitPolicy implements IExitPolicy {

        final char fExitCharacter;
        final char fEscapeCharacter;
        final Stack fStack;
        final int fSize;

        public ExitPolicy(char exitCharacter, char escapeCharacter, Stack stack) {
            fExitCharacter = exitCharacter;
            fEscapeCharacter = escapeCharacter;
            fStack = stack;
            fSize = fStack.size();
        }

        /*
         * @see org.eclipse.jdt.internal.ui.text.link.LinkedPositionUI.ExitPolicy#doExit(org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager, org.eclipse.swt.events.VerifyEvent, int, int)
         */
        public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) {

            if (fSize == fStack.size() && !isMasked(offset)) {
                if (event.character == fExitCharacter) {
                    BracketLevel level = (BracketLevel) fStack.peek();
                    if (level.fFirstPosition.offset > offset || level.fSecondPosition.offset < offset)
                        return null;
                    if (level.fSecondPosition.offset == offset && length == 0)
                        // don't enter the character if if its the closing peer
                        return new ExitFlags(ILinkedModeListener.UPDATE_CARET, false);
                }
                // when entering an anonymous class between the parenthesis', we don't want
                // to jump after the closing parenthesis when return is pressed
                if (event.character == SWT.CR && offset > 0) {
                    IDocument document = getSourceViewer().getDocument();
                    try {
                        if (document.getChar(offset - 1) == '{')
                            return new ExitFlags(ILinkedModeListener.EXIT_ALL, true);
                    } catch (BadLocationException e) {
                    }
                }
            }
            return null;
        }

        private boolean isMasked(int offset) {
            IDocument document = getSourceViewer().getDocument();
            try {
                return fEscapeCharacter == document.getChar(offset - 1);
            } catch (BadLocationException e) {
            }
            return false;
        }
    }

    private class BracketInserter implements VerifyKeyListener, ILinkedModeListener {

        private boolean fCloseBrackets = true;
        private boolean fCloseStrings = true;
        private final String CATEGORY = toString();
        private IPositionUpdater fUpdater = new ExclusivePositionUpdater(CATEGORY);
        private Stack fBracketLevelStack = new Stack();

        public void setCloseBracketsEnabled(boolean enabled) {
            fCloseBrackets = enabled;
        }

        public void setCloseStringsEnabled(boolean enabled) {
            fCloseStrings = enabled;
        }

        /*
         * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
         */
        public void verifyKey(VerifyEvent event) {

            // early pruning to slow down normal typing as little as possible
            if (!event.doit || getInsertMode() != SMART_INSERT)
                return;
            switch (event.character) {
            case '(':
            case '{':
            case '[':
            case '\'':
            case '\"':
                break;
            default:
                return;
            }

            final ISourceViewer sourceViewer = getSourceViewer();
            IDocument document = sourceViewer.getDocument();

            final Point selection = sourceViewer.getSelectedRange();
            final int offset = selection.x;
            final int length = selection.y;

            try {
                IRegion startLine = document.getLineInformationOfOffset(offset);
                IRegion endLine = document.getLineInformationOfOffset(offset + length);

                //only scan the selection part
                int scanOffset = startLine.getOffset();
                String leftOfSelection = document.get(scanOffset, offset - scanOffset);
                String rightOfSelection = document.get(offset,
                        endLine.getOffset() + endLine.getLength() - offset - length);

                Symbol prevToken = new Symbol(NodeTypes.EOF);
                Symbol nextToken = new Symbol(NodeTypes.EOF);
                java_cup.runtime.Scanner leftScanner = null, rightScanner = null;

                leftScanner = new Lexer(new StringReader(leftOfSelection));
                //find the last token in the leftScanner, which is the previous token of the cursor offset
                Symbol tmp = leftScanner.next_token();
                while (tmp.sym != NodeTypes.EOF) {
                    prevToken = tmp;
                    tmp = leftScanner.next_token();
                }
                String previous = prevToken.sym == NodeTypes.EOF ? null
                        : document.get(prevToken.left + scanOffset, offset - scanOffset - prevToken.left).trim();

                rightScanner = new Lexer(new StringReader(rightOfSelection));
                //find the 1st token in the rightScanner, which is the next token of the cursor offset            
                nextToken = rightScanner.next_token();
                //String next= nextToken.sym == NodeTypes.EOF ? null : document.get(offset+length+nextToken.left, nextToken.right-nextToken.left).trim();
                String next = (nextToken.sym == NodeTypes.EOF || nextToken.sym == NodeTypes.END
                        || nextToken.sym == NodeTypes.LINE_COMMENT) ? null
                                : document.get(offset + length + nextToken.left, nextToken.right - nextToken.left)
                                        .trim();
                switch (event.character) {
                case '(':
                    if (!fCloseBrackets || nextToken.sym == NodeTypes.LPAREN || nextToken.sym == NodeTypes.ID
                            || next != null && next.length() > 1)
                        return;
                    break;
                case '{':
                    if (!fCloseBrackets || nextToken.sym == NodeTypes.LCURLY || nextToken.sym == NodeTypes.ID
                            || next != null && next.length() > 1)
                        return;
                    break;
                case '[':
                    if (!fCloseBrackets || nextToken.sym == NodeTypes.ID || next != null && next.length() > 1)
                        return;
                    break;

                case '\'':
                case '"':
                    if (!fCloseStrings || nextToken.sym == NodeTypes.ID || prevToken.sym == NodeTypes.ID
                            || next != null && next.length() > 1 || previous != null && previous.length() > 1
                            || previous != null && previous.length() == 1 && previous.charAt(0) == event.character)
                        return;
                    break;

                default:
                    return;
                }

                ITypedRegion partition = TextUtilities.getPartition(document, IPartitions.EGL_PARTITIONING, offset,
                        true);
                if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()))
                    return;

                if (!validateEditorInputState())
                    return;

                final char character = event.character;
                final char closingCharacter = getPeerCharacter(character);
                final StringBuffer buffer = new StringBuffer();
                buffer.append(character);
                buffer.append(closingCharacter);

                document.replace(offset, length, buffer.toString());

                BracketLevel level = new BracketLevel();
                fBracketLevelStack.push(level);

                LinkedPositionGroup group = new LinkedPositionGroup();
                group.addPosition(new LinkedPosition(document, offset + 1, 0, LinkedPositionGroup.NO_STOP));

                LinkedModeModel model = new LinkedModeModel();
                model.addLinkingListener(this);
                model.addGroup(group);
                model.forceInstall();

                level.fOffset = offset;
                level.fLength = 2;

                // set up position tracking for our magic peers
                if (fBracketLevelStack.size() == 1) {
                    document.addPositionCategory(CATEGORY);
                    document.addPositionUpdater(fUpdater);
                }
                level.fFirstPosition = new Position(offset, 1);
                level.fSecondPosition = new Position(offset + 1, 1);
                document.addPosition(CATEGORY, level.fFirstPosition);
                document.addPosition(CATEGORY, level.fSecondPosition);

                level.fUI = new EditorLinkedModeUI(model, sourceViewer);
                level.fUI.setSimpleMode(true);
                level.fUI.setExitPolicy(
                        new ExitPolicy(closingCharacter, getEscapeCharacter(closingCharacter), fBracketLevelStack));
                level.fUI.setExitPosition(sourceViewer, offset + 2, 0, Integer.MAX_VALUE);
                level.fUI.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
                level.fUI.enter();

                IRegion newSelection = level.fUI.getSelectedRegion();
                sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());

                event.doit = false;

            } catch (BadLocationException e) {
                e.printStackTrace();
                EGLLogger.log(this, e);
            } catch (BadPositionCategoryException e) {
                e.printStackTrace();
                EGLLogger.log(this, e);
            } catch (IOException e) {
                e.printStackTrace();
                EGLLogger.log(this, e);
            } catch (Exception e) {
                e.printStackTrace();
                EGLLogger.log(this, e);
            }
        }

        /*
         * @see org.eclipse.jface.text.link.ILinkedModeListener#left(org.eclipse.jface.text.link.LinkedModeModel, int)
         */
        public void left(LinkedModeModel environment, int flags) {

            final BracketLevel level = (BracketLevel) fBracketLevelStack.pop();

            if (flags != ILinkedModeListener.EXTERNAL_MODIFICATION)
                return;

            // remove brackets
            final ISourceViewer sourceViewer = getSourceViewer();
            final IDocument document = sourceViewer.getDocument();
            if (document instanceof IDocumentExtension) {
                IDocumentExtension extension = (IDocumentExtension) document;
                extension.registerPostNotificationReplace(null, new IDocumentExtension.IReplace() {

                    public void perform(IDocument d, IDocumentListener owner) {
                        if ((level.fFirstPosition.isDeleted || level.fFirstPosition.length == 0)
                                && !level.fSecondPosition.isDeleted
                                && level.fSecondPosition.offset == level.fFirstPosition.offset) {
                            try {
                                document.replace(level.fSecondPosition.offset, level.fSecondPosition.length, null);
                            } catch (BadLocationException e) {
                                e.printStackTrace();
                                EGLLogger.log(this, e);
                            }
                        }

                        if (fBracketLevelStack.size() == 0) {
                            document.removePositionUpdater(fUpdater);
                            try {
                                document.removePositionCategory(CATEGORY);
                            } catch (BadPositionCategoryException e) {
                                e.printStackTrace();
                                EGLLogger.log(this, e);
                            }
                        }
                    }
                });
            }

        }

        /*
         * @see org.eclipse.jface.text.link.ILinkedModeListener#suspend(org.eclipse.jface.text.link.LinkedModeModel)
         */
        public void suspend(LinkedModeModel environment) {
        }

        /*
         * @see org.eclipse.jface.text.link.ILinkedModeListener#resume(org.eclipse.jface.text.link.LinkedModeModel, int)
         */
        public void resume(LinkedModeModel environment, int flags) {
        }
    }

    private static char getEscapeCharacter(char character) {
        switch (character) {
        case '"':
        case '\'':
            return '\\';
        default:
            return 0;
        }
    }

    private static char getPeerCharacter(char character) {
        switch (character) {
        case '(':
            return ')';

        case ')':
            return '(';

        case '{':
            return '}';

        case '}':
            return '{';

        case '[':
            return ']';

        case ']':
            return '[';

        case '"':
            return character;

        case '\'':
            return character;

        default:
            throw new IllegalArgumentException();
        }
    }

    public boolean isPrefQuickDiffAlwaysOn() {
        if (disableRulerArea) {
            return false;
        } else {
            return super.isPrefQuickDiffAlwaysOn();
        }
    }

    public SourceViewerConfiguration getSourceViewerConfig() {
        return getSourceViewerConfiguration();
    }

    public IVerticalRuler getEditorVerticalRuler() {
        return super.getVerticalRuler();
    }

    protected void editorContextMenuAboutToShow(IMenuManager menu) {
        super.editorContextMenuAboutToShow(menu);
        addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.SELECT_ALL);
        addAction(menu, ITextEditorActionConstants.GROUP_FIND, ITextEditorActionConstants.FIND);
        addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.REDO);
        menu.addMenuListener(new IMenuListener() {

            @Override
            public void menuAboutToShow(IMenuManager menu) {
                try {
                    IContributionItem item = menu.find("org.eclipse.edt.ide.ui.file.sourceMenu");
                    if (item != null) {
                        menu.remove(item);
                    }
                } finally {
                    menu.removeMenuListener(this);
                }
            }

        });
    }

    @Override
    protected String[] collectContextMenuPreferencePages() {
        return new String[] { "org.eclipse.edt.ide.ui.editorPreferences", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.contentAssistPreferences", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.foldingPreferences", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.formatterPreferences", //$NON-NLS-1$
                "org.eclipse.ui.editors.preferencePages.Spelling", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.organizeImportsPreferencePage", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.sourceStylesPreferences", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.templatePreferences", //$NON-NLS-1$
                "org.eclipse.edt.ide.ui.ContentAssistAdvancedPreferences", //$NON-NLS-1$
        };

    }

}