/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Sebastian Davids <sdavids@gmx.de> - bug 38919
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.snippeteditor;


import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventFilter;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.debug.ui.InspectPopupDialog;
import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.eval.IEvaluationContext;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.eval.EvaluationManager;
import org.eclipse.jdt.debug.eval.IClassFileEvaluationEngine;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.debug.eval.IEvaluationResult;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.ui.JDIContentAssistPreference;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.JDISourceViewer;
import org.eclipse.jdt.internal.debug.ui.JavaDebugImages;
import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager;
import org.eclipse.jdt.internal.debug.ui.actions.DisplayAction;
import org.eclipse.jdt.internal.debug.ui.actions.EvaluateAction;
import org.eclipse.jdt.internal.debug.ui.actions.PopupInspectAction;
import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.ui.IContextMenuConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
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.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.part.EditorActionBarContributor;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.TextOperationAction;

import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;

/**
 * An editor for Java snippets.
 */
public class JavaSnippetEditor extends AbstractDecoratedTextEditor implements IDebugEventFilter, IEvaluationListener, IValueDetailListener {
	public static final String IMPORTS_CONTEXT = "SnippetEditor.imports"; //$NON-NLS-1$

	public final static int RESULT_DISPLAY= 1;
	public final static int RESULT_RUN= 2;
	public final static int RESULT_INSPECT= 3;

	private int fResultMode; // one of the RESULT_* constants

	private IJavaProject fJavaProject;
	private IEvaluationContext fEvaluationContext;
	private IDebugTarget fVM;
	private String[] fLaunchedClassPath;
	private String fLaunchedWorkingDir;
	private String fLaunchedVMArgs;
	private IVMInstall fLaunchedVM;
	private List<ISnippetStateChangedListener> fSnippetStateListeners;

	private boolean fEvaluating;
	private IJavaThread fThread;
	private boolean fStepFiltersSetting;

	private int fSnippetStart;
	private int fSnippetEnd;

	private String[] fImports= null;

	private Image fOldTitleImage= null;
	private IClassFileEvaluationEngine fEngine= null;

	/**
	 * The debug model presentation used for computing toString
	 */
	private IDebugModelPresentation fPresentation= DebugUITools.newDebugModelPresentation(JDIDebugModel.getPluginIdentifier());
	/**
	 * The result of a toString evaluation returned asynchronously by the
	 * debug model.
	 */
	private String fResult;

	/**
	 * A thread that waits to have a
	 * thread to perform an evaluation in.
	 */
	private static class WaitThread extends Thread {
		/**
		 * The display used for event dispatching.
		 */
		private Display fDisplay;

		/**
		 * Indicates whether to continue event queue dispatching.
		 */
		private volatile boolean fContinueEventDispatching = true;

		private Object fLock;
		/**
		 * Creates a "wait" thread
		 *
		 * @param display the display to be used to read and dispatch events
		 * @param lock the monitor to wait on
		 */
		private WaitThread(Display display, Object lock) {
			super("Snippet Wait Thread"); //$NON-NLS-1$
			setDaemon(true);
			fDisplay = display;
			fLock= lock;
		}
		@Override
		public void run() {
			try {
				synchronized (fLock) {
					//should be notified out of #setThread(IJavaThread)
					fLock.wait(10000);
				}
			} catch (InterruptedException e) {
			} finally {
				// Make sure that all events in the asynchronous event queue
				// are dispatched.
				fDisplay.syncExec(new Runnable() {
					@Override
					public void run() {
						// do nothing
					}
				});

				// Stop event dispatching
				fContinueEventDispatching= false;

				// Force the event loop to return from sleep () so that
				// it stops event dispatching.
				fDisplay.asyncExec(null);
			}
		}
		/**
		 * Processes events.
		 */
		protected void block() {
			if (fDisplay == Display.getCurrent()) {
				while (fContinueEventDispatching) {
					if (!fDisplay.readAndDispatch()) {
						fDisplay.sleep();
					}
				}
			}
		}
	}

	/**
	 * Listens for part activation to set scrapbook active system property
	 * for action enablement.
	 */
	private IPartListener2 fActivationListener = new IPartListener2() {

		@Override
		public void partActivated(IWorkbenchPartReference partRef) {
			if ("org.eclipse.jdt.debug.ui.SnippetEditor".equals(partRef.getId())) { //$NON-NLS-1$
				System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "true"); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "false"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void partBroughtToTop(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partClosed(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partDeactivated(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partHidden(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partInputChanged(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partOpened(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partVisible(IWorkbenchPartReference partRef) {
		}

	};

	public JavaSnippetEditor() {
		super();
		setDocumentProvider(JDIDebugUIPlugin.getDefault().getSnippetDocumentProvider());
		IPreferenceStore store = new ChainedPreferenceStore(new IPreferenceStore[] {
				PreferenceConstants.getPreferenceStore(),
				EditorsUI.getPreferenceStore()});
		setSourceViewerConfiguration(new JavaSnippetViewerConfiguration(JDIDebugUIPlugin.getDefault().getJavaTextTools(), store, this));
		fSnippetStateListeners = new ArrayList<>(4);
		setPreferenceStore(store);
		setEditorContextMenuId("#JavaSnippetEditorContext"); //$NON-NLS-1$
		setRulerContextMenuId("#JavaSnippetRulerContext"); //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
	 */
	@Override
	protected void doSetInput(IEditorInput input) throws CoreException {
		super.doSetInput(input);
		IFile file= getFile();
		if (file != null) {
			String property= file.getPersistentProperty(new QualifiedName(JDIDebugUIPlugin.getUniqueIdentifier(), IMPORTS_CONTEXT));
			if (property != null) {
				fImports = JavaDebugOptionsManager.parseList(property);
			}
		}
	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		super.init(site, input);
		site.getWorkbenchWindow().getPartService().addPartListener(fActivationListener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	@Override
	public void dispose() {
		shutDownVM();
		fPresentation.dispose();
		fSnippetStateListeners = null;
		ISourceViewer viewer = getSourceViewer();
		if(viewer != null) {
			((JDISourceViewer)viewer).dispose();
		}
		getSite().getWorkbenchWindow().getPartService().removePartListener(fActivationListener);
		super.dispose();
	}

	/**
	 * Actions for the editor popup menu
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
	 */
	@Override
	protected void createActions() {
		super.createActions();
		if (getFile() != null) {
			Action action = new TextOperationAction(SnippetMessages.getBundle(), "SnippetEditor.ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); //$NON-NLS-1$
			action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
			setAction("ContentAssistProposal", action);//$NON-NLS-1$
			setAction("ShowInPackageView", new ShowInPackageViewAction(this)); //$NON-NLS-1$
			setAction("Stop", new StopAction(this));  //$NON-NLS-1$
			setAction("SelectImports", new SelectImportsAction(this));  //$NON-NLS-1$
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
	 */
	@Override
	protected void editorContextMenuAboutToShow(IMenuManager menu) {
		super.editorContextMenuAboutToShow(menu);
		addGroup(menu, ITextEditorActionConstants.GROUP_EDIT, IContextMenuConstants.GROUP_GENERATE);
		addGroup(menu, ITextEditorActionConstants.GROUP_FIND, IContextMenuConstants.GROUP_SEARCH);
		addGroup(menu, IContextMenuConstants.GROUP_SEARCH,  IContextMenuConstants.GROUP_SHOW);
		if (getFile() != null) {
			addAction(menu, IContextMenuConstants.GROUP_SHOW, "ShowInPackageView"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Run"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Stop"); //$NON-NLS-1$
			addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "SelectImports"); //$NON-NLS-1$
		}
	}

	protected boolean isVMLaunched() {
		return fVM != null;
	}

	public boolean isEvaluating() {
		return fEvaluating;
	}

	public void evalSelection(int resultMode) {
		if (!isInJavaProject()) {
			reportNotInJavaProjectError();
			return;
		}
		if (isEvaluating()) {
			return;
		}

		checkCurrentProject();

		evaluationStarts();

		fResultMode= resultMode;
		buildAndLaunch();

		if (fVM == null) {
			evaluationEnds();
			return;
		}
		fireEvalStateChanged();

		ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection();
		String snippet= selection.getText();
		fSnippetStart= selection.getOffset();
		fSnippetEnd= fSnippetStart + selection.getLength();

		evaluate(snippet);
	}

	/**
	 * Checks if the page has been copied/moved to a different project or the project has been renamed.
	 * Updates the launch configuration template if a copy/move/rename has occurred.
	 */
	protected void checkCurrentProject() {
		IFile file= getFile();
		if (file == null) {
			return;
		}
		try {
			ILaunchConfiguration config = ScrapbookLauncher.getLaunchConfigurationTemplate(file);
			if (config != null) {
				String projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null);
				IJavaProject pro = JavaCore.create(file.getProject());
				if (!pro.getElementName().equals(projectName)) {
					//the page has been moved to a "different" project
					ScrapbookLauncher.setLaunchConfigMemento(file, null);
				}
			}
		} catch (CoreException ce) {
			JDIDebugUIPlugin.log(ce);
			ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, ce.getStatus()); //$NON-NLS-1$
			evaluationEnds();
			return;

		}
	}

	protected void buildAndLaunch() {
		IJavaProject javaProject= getJavaProject();
		if (javaProject == null) {
			return;
		}
		boolean build = !javaProject.getProject().getWorkspace().isAutoBuilding()
			|| !javaProject.hasBuildState();

		if (build) {
			if (!performIncrementalBuild()) {
				return;
			}
		}

		boolean changed= classPathHasChanged();
		if (!changed) {
			changed = workingDirHasChanged();
		}
		if (!changed) {
			changed = vmHasChanged();
		}
		if (!changed) {
			changed = vmArgsChanged();
		}
		boolean launch= fVM == null || changed;

		if (changed) {
			shutDownVM();
		}

		if (fVM == null) {
			checkMultipleEditors();
		}
		if (launch && fVM == null) {
			launchVM();
			fVM= ScrapbookLauncher.getDefault().getDebugTarget(getFile());
		}
	}

	protected boolean performIncrementalBuild() {
		IRunnableWithProgress r= new IRunnableWithProgress() {
			@Override
			public void run(IProgressMonitor pm) throws InvocationTargetException {
				try {
					getJavaProject().getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, pm);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				}
			}
		};
		try {
			PlatformUI.getWorkbench().getProgressService().run(true, false, r);
		} catch (InterruptedException e) {
			JDIDebugUIPlugin.log(e);
			evaluationEnds();
			return false;
		} catch (InvocationTargetException e) {
			JDIDebugUIPlugin.log(e);
			evaluationEnds();
			return false;
		}
		return true;
	}

	protected void checkMultipleEditors() {
		fVM= ScrapbookLauncher.getDefault().getDebugTarget(getFile());
		//multiple editors are opened on the same page
		if (fVM != null) {
			DebugPlugin.getDefault().addDebugEventFilter(this);
			try {
				IThread[] threads= fVM.getThreads();
				for (int i = 0; i < threads.length; i++) {
					IThread iThread = threads[i];
					if (iThread.isSuspended()) {
						iThread.resume();
					}
				}
			} catch (DebugException de) {
				JDIDebugUIPlugin.log(de);
			}
		}
	}

	protected void setImports(String[] imports) {
		fImports= imports;
		IFile file= getFile();
		if (file == null) {
			return;
		}
		String serialized= null;
		if (imports != null) {
			serialized= JavaDebugOptionsManager.serializeList(imports);
		}
		// persist
		try {
			file.setPersistentProperty(new QualifiedName(JDIDebugUIPlugin.getUniqueIdentifier(), IMPORTS_CONTEXT), serialized);
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
			ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.imports"), null, e.getStatus()); //$NON-NLS-1$
		}
	}

	protected String[] getImports() {
		return fImports;
	}

	protected IEvaluationContext getEvaluationContext() {
		if (fEvaluationContext == null) {
			IJavaProject project= getJavaProject();
			if (project != null) {
				fEvaluationContext= project.newEvaluationContext();
			}
		}
		if (fEvaluationContext != null) {
			if (getImports() != null) {
				fEvaluationContext.setImports(getImports());
			} else {
				fEvaluationContext.setImports(new String[]{});
			}
		}
		return fEvaluationContext;
	}

	protected IJavaProject getJavaProject() {
		if (fJavaProject == null) {
			try {
				fJavaProject = findJavaProject();
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
				showError(e.getStatus());
			}
		}
		return fJavaProject;
	}

	protected void shutDownVM() {
		DebugPlugin.getDefault().removeDebugEventFilter(this);

		// The real shut down
		IDebugTarget target= fVM;
		if (fVM != null) {
			try {
				IBreakpoint bp = ScrapbookLauncher.getDefault().getMagicBreakpoint(fVM);
				if (bp != null) {
					fVM.breakpointRemoved(bp, null);
				}
				if (getThread() != null) {
					getThread().resume();
				}

				fVM.terminate();
			} catch (DebugException e) {
				JDIDebugUIPlugin.log(e);
				ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.shutdown"), null, e.getStatus()); //$NON-NLS-1$
				return;
			}
			vmTerminated();
			ScrapbookLauncher.getDefault().cleanup(target);
		}
	}

	/**
	 * The VM has terminated, update state
	 */
	protected void vmTerminated() {
		fVM= null;
		fThread= null;
		fEvaluationContext= null;
		fLaunchedClassPath= null;
		if (fEngine != null) {
			fEngine.dispose();
		}
		fEngine= null;
		fireEvalStateChanged();
	}

	public void addSnippetStateChangedListener(ISnippetStateChangedListener listener) {
		if (fSnippetStateListeners != null && !fSnippetStateListeners.contains(listener)) {
			fSnippetStateListeners.add(listener);
		}
	}

	public void removeSnippetStateChangedListener(ISnippetStateChangedListener listener) {
		if (fSnippetStateListeners != null) {
			fSnippetStateListeners.remove(listener);
		}
	}

	protected void fireEvalStateChanged() {
		Runnable r= new Runnable() {
			@Override
			public void run() {
				Shell shell= getShell();
				if (fSnippetStateListeners != null && shell != null && !shell.isDisposed()) {
					List<ISnippetStateChangedListener> v = new ArrayList<>(fSnippetStateListeners);
					for (int i= 0; i < v.size(); i++) {
						ISnippetStateChangedListener l= v.get(i);
						l.snippetStateChanged(JavaSnippetEditor.this);
					}
				}
			}
		};
		Shell shell= getShell();
		if (shell != null) {
			getShell().getDisplay().asyncExec(r);
		}
	}

	protected void evaluate(String snippet) {
		if (getThread() == null) {
			WaitThread eThread= new WaitThread(Display.getCurrent(), this);
			eThread.start();
			eThread.block();
		}
		if (getThread() == null) {
			IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Evaluation failed: internal error - unable to obtain an execution context.", null); //$NON-NLS-1$
			ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, status); //$NON-NLS-1$
			evaluationEnds();
			return;
		}
		boolean hitBreakpoints = Platform.getPreferencesService().getBoolean(
				JDIDebugPlugin.getUniqueIdentifier(),
				JDIDebugModel.PREF_SUSPEND_FOR_BREAKPOINTS_DURING_EVALUATION,
				true,
				null);
		try {
			getEvaluationEngine().evaluate(snippet,getThread(), this, hitBreakpoints);
		} catch (DebugException e) {
			JDIDebugUIPlugin.log(e);
			ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, e.getStatus()); //$NON-NLS-1$
			evaluationEnds();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.eval.IEvaluationListener#evaluationComplete(org.eclipse.jdt.debug.eval.IEvaluationResult)
	 */
	@Override
	public void evaluationComplete(IEvaluationResult result) {
			boolean severeErrors = false;
			if (result.hasErrors()) {
				String[] errors = result.getErrorMessages();
				severeErrors = errors.length > 0;
				if (result.getException() != null) {
					showException(result.getException());
				}
				showAllErrors(errors);
			}
			IJavaValue value= result.getValue();
			if (value != null && !severeErrors) {
				switch (fResultMode) {
				case RESULT_DISPLAY:
					displayResult(value);
					break;
				case RESULT_INSPECT:
					JavaInspectExpression exp = new JavaInspectExpression(result.getSnippet().trim(), value);
					showExpression(exp);
					break;
				case RESULT_RUN:
					// no action
					break;
				}
			}
			evaluationEnds();
	}

	/**
	 * Make the expression view visible or open one
	 * if required.
	 */
	protected void showExpressionView() {
		Runnable r = new Runnable() {
			@Override
			public void run() {
				IWorkbenchPage page = JDIDebugUIPlugin.getActivePage();
				if (page != null) {
					IViewPart part = page.findView(IDebugUIConstants.ID_EXPRESSION_VIEW);
					if (part == null) {
						try {
							page.showView(IDebugUIConstants.ID_EXPRESSION_VIEW);
						} catch (PartInitException e) {
							JDIDebugUIPlugin.log(e);
							showError(e.getStatus());
						}
					} else {
						page.bringToTop(part);
					}
				}
			}
		};

		async(r);
	}

	protected void codeComplete(CompletionRequestor requestor) throws JavaModelException {
		ITextSelection selection= (ITextSelection)getSelectionProvider().getSelection();
		int start= selection.getOffset();
		String snippet= getSourceViewer().getDocument().get();
		IEvaluationContext e= getEvaluationContext();
		if (e != null) {
			e.codeComplete(snippet, start, requestor);
		}
	}

	protected IJavaElement[] codeResolve() throws JavaModelException {
		ISourceViewer viewer= getSourceViewer();
		if (viewer == null) {
			return null;
		}
		ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection();
		int start= selection.getOffset();
		int len= selection.getLength();

		String snippet= viewer.getDocument().get();
		IEvaluationContext e= getEvaluationContext();
		if (e != null) {
			return e.codeSelect(snippet, start, len);
		}
		return null;
	}

	protected void showError(IStatus status) {
		evaluationEnds();
		if (!status.isOK()) {
			ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating2"), null, status); //$NON-NLS-1$
		}
	}

	protected void showError(String message) {
		Status status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, message, null);
		showError(status);
	}

	protected void displayResult(IJavaValue result) {
		StringBuffer resultString= new StringBuffer();
		try {
			IJavaType type = result.getJavaType();
			if (type != null) {
				String sig= type.getSignature();
				if ("V".equals(sig)) { //$NON-NLS-1$
					resultString.append(SnippetMessages.getString("SnippetEditor.noreturnvalue")); //$NON-NLS-1$
				} else {
					if (sig != null) {
						resultString.append(SnippetMessages.getFormattedString("SnippetEditor.typename", result.getReferenceTypeName())); //$NON-NLS-1$
					} else {
						resultString.append(" "); //$NON-NLS-1$
					}
                    resultString.append(DisplayAction.trimDisplayResult(evaluateToString(result)));
				}
			} else {
				resultString.append(DisplayAction.trimDisplayResult(result.getValueString()));
			}
		} catch(DebugException e) {
			JDIDebugUIPlugin.log(e);
			ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.toString"), null, e.getStatus()); //$NON-NLS-1$
		}

		final String message = resultString.toString();
		Runnable r = new Runnable() {
			@Override
			public void run() {
				try {
					getSourceViewer().getDocument().replace(fSnippetEnd, 0, message);
					selectAndReveal(fSnippetEnd, message.length());
				} catch (BadLocationException e) {
				}
			}
		};
		async(r);
	}

	/**
	 * Returns the result of evaluating 'toString' on the given
	 * value.
	 *
	 * @param value object or primitive data type the 'toString'
	 *  is required for
	 * @return the result of evaluating toString
	 * @exception DebugException if an exception occurs during the
	 *  evaluation.
	 */
	protected synchronized String evaluateToString(IJavaValue value) {
		fResult= null;
		fPresentation.computeDetail(value, this);
		if (fResult == null) {
			try {
				wait(10000);
			} catch (InterruptedException e) {
				return SnippetMessages.getString("SnippetEditor.error.interrupted"); //$NON-NLS-1$
			}
		}
		return fResult;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.IValueDetailListener#detailComputed(org.eclipse.debug.core.model.IValue, java.lang.String)
	 */
	@Override
	public synchronized void detailComputed(IValue value, final String result) {
		fResult= result;
		this.notifyAll();
	}

	protected void showAllErrors(final String[] errors) {
		IDocument document = getSourceViewer().getDocument();
		String delimiter = document.getLegalLineDelimiters()[0];

		final StringBuffer errorString = new StringBuffer();
		for (int i = 0; i < errors.length; i++) {
			errorString.append(errors[i] + delimiter);
		}

		Runnable r = new Runnable() {
			@Override
			public void run() {
				try {
					getSourceViewer().getDocument().replace(fSnippetStart, 0, errorString.toString());
					selectAndReveal(fSnippetStart, errorString.length());
				} catch (BadLocationException e) {
				}
			}
		};
		async(r);
	}

	private void showExpression(final JavaInspectExpression expression) {
	    Runnable r = new Runnable() {
	        @Override
			public void run() {
	            new InspectPopupDialog(getShell(), EvaluateAction.getPopupAnchor(getSourceViewer().getTextWidget()), PopupInspectAction.ACTION_DEFININITION_ID, expression).open();
	        }
	    };
	    async(r);
	}


	protected void showException(Throwable exception) {
		if (exception instanceof DebugException) {
			DebugException de = (DebugException)exception;
			Throwable t= de.getStatus().getException();
			if (t != null) {
				// show underlying exception
				showUnderlyingException(t);
				return;
			}
		}
		ByteArrayOutputStream bos= new ByteArrayOutputStream();
		PrintStream ps= new PrintStream(bos, true);
		exception.printStackTrace(ps);

		final String message = bos.toString();
		Runnable r = new Runnable() {
			@Override
			public void run() {
				try {
					getSourceViewer().getDocument().replace(fSnippetEnd, 0, message);
					selectAndReveal(fSnippetEnd, message.length());
				} catch (BadLocationException e) {
				}
			}
		};
		async(r);
	}

	protected void showUnderlyingException(Throwable t) {
		if (t instanceof InvocationException) {
			InvocationException ie= (InvocationException)t;
			ObjectReference ref= ie.exception();
			String eName= ref.referenceType().name();
			final String message= SnippetMessages.getFormattedString("SnippetEditor.exception", eName); //$NON-NLS-1$
			Runnable r = new Runnable() {
				@Override
				public void run() {
					try {
						getSourceViewer().getDocument().replace(fSnippetEnd, 0, message);
						selectAndReveal(fSnippetEnd, message.length());
					} catch (BadLocationException e) {
					}
				}
			};
			async(r);
		} else {
			showException(t);
		}
	}

	protected IJavaProject findJavaProject() throws CoreException {
		IFile file = getFile();
		if (file != null) {
			IProject p= file.getProject();
			if (p.getNature(JavaCore.NATURE_ID) != null) {
				return JavaCore.create(p);
			}
		}
		return null;
	}

	protected boolean classPathHasChanged() {
		String[] classpath= getClassPath(getJavaProject());
		if (fLaunchedClassPath != null && !classPathsEqual(fLaunchedClassPath, classpath)) {
			MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.warning"), SnippetMessages.getString("SnippetEditor.warning.cpchange")); //$NON-NLS-2$ //$NON-NLS-1$
			return true;
		}
		return false;
	}

	protected boolean workingDirHasChanged() {
		String wd = getWorkingDirectoryAttribute();
		boolean changed = false;
		if (wd == null || fLaunchedWorkingDir == null) {
			if (wd != fLaunchedWorkingDir) {
				changed = true;
			}
		} else {
			if (!wd.equals(fLaunchedWorkingDir)) {
				changed = true;
			}
		}
		if (changed && fVM != null) {
			MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.The_working_directory_has_changed._Restarting_the_evaluation_context._2")); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return changed;
	}

	protected boolean vmArgsChanged() {
		String args = getVMArgsAttribute();
		boolean changed = false;
		if (args == null || fLaunchedVMArgs == null) {
			if (args != fLaunchedVMArgs) {
				changed = true;
			}
		} else {
			if (!args.equals(fLaunchedVMArgs)) {
				changed = true;
			}
		}
		if (changed && fVM != null) {
			MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.1")); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return changed;
	}

	protected boolean vmHasChanged() {
		IVMInstall vm = getVMInstall();
		boolean changed = false;
		if (vm == null || fLaunchedVM == null) {
			if (vm != fLaunchedVM) {
				changed = true;
			}
		} else {
			if (!vm.equals(fLaunchedVM)) {
				changed = true;
			}
		}
		if (changed && fVM != null) {
			MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.The_JRE_has_changed._Restarting_the_evaluation_context._2")); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return changed;
	}

	protected boolean classPathsEqual(String[] path1, String[] path2) {
		if (path1.length != path2.length) {
			return false;
		}
		for (int i= 0; i < path1.length; i++) {
			if (!path1[i].equals(path2[i])) {
				return false;
			}
		}
		return true;
	}

	protected synchronized void evaluationStarts() {
		if (fThread != null) {
			try {
				IThread thread = fThread;
				fThread = null;
				thread.resume();
			} catch (DebugException e) {
				JDIDebugUIPlugin.log(e);
				showException(e);
				return;
			}
		}
		fEvaluating = true;
		setTitleImage();
		fireEvalStateChanged();
		showStatus(SnippetMessages.getString("SnippetEditor.evaluating")); //$NON-NLS-1$
		getSourceViewer().setEditable(false);
	}

	/**
	 * Sets the tab image to indicate whether in the process of
	 * evaluating or not.
	 */
	protected void setTitleImage() {
		Image image=null;
		if (fEvaluating) {
			fOldTitleImage= getTitleImage();
			image= JavaDebugImages.get(JavaDebugImages.IMG_OBJS_SNIPPET_EVALUATING);
		} else {
			image= fOldTitleImage;
			fOldTitleImage= null;
		}
		if (image != null) {
			setTitleImage(image);
		}
	}

	protected void evaluationEnds() {
		Runnable r = new Runnable() {
			@Override
			public void run() {
				fEvaluating= false;
				setTitleImage();
				fireEvalStateChanged();
				showStatus(""); //$NON-NLS-1$
				getSourceViewer().setEditable(true);
			}
		};
		async(r);
	}

	protected void showStatus(String message) {
		IEditorSite site=(IEditorSite)getSite();
		EditorActionBarContributor contributor= (EditorActionBarContributor)site.getActionBarContributor();
		contributor.getActionBars().getStatusLineManager().setMessage(message);
	}

	protected String[] getClassPath(IJavaProject project) {
		try {
			return JavaRuntime.computeDefaultRuntimeClassPath(project);
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
			return new String[0];
		}
	}

	protected Shell getShell() {
		return getSite().getShell();
	}

	/**
	 * @see IDebugEventFilter#filterDebugEvents(DebugEvent[])
	 */
	@Override
	public DebugEvent[] filterDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent e = events[i];
			Object source = e.getSource();
			if (source instanceof IDebugElement) {
				IDebugElement de = (IDebugElement)source;
				if (de instanceof IDebugTarget) {
					if (de.getDebugTarget().equals(fVM)) {
						if (e.getKind() == DebugEvent.TERMINATE) {
							setThread(null);
							Runnable r = new Runnable() {
								@Override
								public void run() {
									vmTerminated();
								}
							};
							getShell().getDisplay().asyncExec(r);
						}
					}
				} else if (de instanceof IJavaThread) {
					if (e.getKind() == DebugEvent.SUSPEND) {
						IJavaThread jt = (IJavaThread)de;
						try {
							if (jt.equals(getThread()) && e.getDetail() == DebugEvent.EVALUATION) {
								return null;
							}
							IJavaStackFrame f= (IJavaStackFrame)jt.getTopStackFrame();
							if (f != null) {
							    IJavaDebugTarget target = (IJavaDebugTarget) f.getDebugTarget();
								IBreakpoint[] bps = jt.getBreakpoints();
								//last line of the eval method in ScrapbookMain1?
								int lineNumber = f.getLineNumber();
								if (e.getDetail() == DebugEvent.STEP_END && (lineNumber == 28)
									&& f.getDeclaringTypeName().equals("org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain1") //$NON-NLS-1$
									&& jt.getDebugTarget() == fVM) {
								    // restore step filters
								    target.setStepFiltersEnabled(fStepFiltersSetting);
									setThread(jt);
									return null;
								} else if (e.getDetail() == DebugEvent.BREAKPOINT &&  bps.length > 0 && bps[0].equals(ScrapbookLauncher.getDefault().getMagicBreakpoint(jt.getDebugTarget()))) {
									// locate the 'eval' method and step over
									IStackFrame[] frames = jt.getStackFrames();
									for (int j = 0; j < frames.length; j++) {
										IJavaStackFrame frame = (IJavaStackFrame)frames[j];
										if (frame.getReceivingTypeName().equals("org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain1") && frame.getName().equals("eval")) { //$NON-NLS-1$ //$NON-NLS-2$
										    // ignore step filters for this step
										    fStepFiltersSetting = target.isStepFiltersEnabled();
										    target.setStepFiltersEnabled(false);
											frame.stepOver();
											return null;
										}
									}
								}
							}
						} catch (DebugException ex) {
							JDIDebugUIPlugin.log(ex);
						}
					}
				}
			}
		}
		return events;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@Override
	protected boolean affectsTextPresentation(PropertyChangeEvent event) {
        JavaSourceViewerConfiguration sourceViewerConfiguration = (JavaSourceViewerConfiguration) getSourceViewerConfiguration();
        return sourceViewerConfiguration.affectsTextPresentation(event);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@Override
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
		JDISourceViewer isv= (JDISourceViewer) getSourceViewer();
		if (isv != null) {
			IContentAssistant assistant= isv.getContentAssistant();
			if (assistant instanceof ContentAssistant) {
				JDIContentAssistPreference.changeConfiguration((ContentAssistant) assistant, event);
			}
			SourceViewerConfiguration configuration = getSourceViewerConfiguration();
			if (configuration instanceof JavaSourceViewerConfiguration) {
				JavaSourceViewerConfiguration jsv = (JavaSourceViewerConfiguration) configuration;
				if (jsv.affectsTextPresentation(event)) {
					jsv.handlePropertyChangeEvent(event);
					isv.invalidateTextPresentation();
				}
			}
			super.handlePreferenceStoreChanged(event);
		}
	}

	protected IJavaThread getThread() {
		return fThread;
	}

	/**
	 * Sets the thread to perform any evaluations in.
	 * Notifies the WaitThread waiting on getting an evaluation thread
	 * to perform an evaluation.
	 */
	protected synchronized void setThread(IJavaThread thread) {
		fThread= thread;
		notifyAll();
	}

	protected void launchVM() {
		DebugPlugin.getDefault().addDebugEventFilter(this);
		fLaunchedClassPath = getClassPath(getJavaProject());
		fLaunchedWorkingDir = getWorkingDirectoryAttribute();
		fLaunchedVMArgs = getVMArgsAttribute();
		fLaunchedVM = getVMInstall();
		Runnable r = new Runnable() {
			@Override
			public void run() {
				ScrapbookLauncher.getDefault().launch(getFile());
			}
		};
		BusyIndicator.showWhile(getShell().getDisplay(), r);
	}

	/**
     * Return the <code>IFile</code> associated with the current
     * editor input. Will return <code>null</code> if the current
     * editor input is for an external file
     */
	public IFile getFile() {
		IEditorInput input= getEditorInput();
		return input.getAdapter(IFile.class);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#updateSelectionDependentActions()
	 */
	@Override
	protected void updateSelectionDependentActions() {
		super.updateSelectionDependentActions();
		fireEvalStateChanged();
	}

	/**
     * Terminates existing VM on a rename of the editor
 	 */
	@Override
	protected void setPartName(String title) {
		cleanupOnRenameOrMove();
		super.setPartName(title);
	}

	/**
	 * If the launch configuration has been copied, moved or
	 * renamed, shut down any running VM and clear the relevant cached information.
	 */
	protected void cleanupOnRenameOrMove() {
		if(isVMLaunched()) {
			shutDownVM();
		} else {
			fThread= null;
			fEvaluationContext= null;
			fLaunchedClassPath= null;

			if (fEngine != null) {
				fEngine.dispose();
				fEngine= null;
			}
		}
		fJavaProject= null;
	}

	/**
	 * Returns whether this editor has been opened on a resource that
	 * is in a Java project.
	 */
	protected boolean isInJavaProject() {
		try {
			return findJavaProject() != null;
		} catch (CoreException ce) {
			JDIDebugUIPlugin.log(ce);
		}
		return false;
	}

	/**
	 * Displays an error dialog indicating that evaluation
	 * cannot occur outside of a Java Project.
	 */
	protected void reportNotInJavaProjectError() {
		String projectName= null;
		IFile file= getFile();
		if (file != null) {
			IProject p= file.getProject();
			projectName= p.getName();
		}
		String message= ""; //$NON-NLS-1$
		if (projectName != null) {
			message = projectName + SnippetMessages.getString("JavaSnippetEditor._is_not_a_Java_Project._n_1"); //$NON-NLS-1$
		}
		showError(message + SnippetMessages.getString("JavaSnippetEditor.Unable_to_perform_evaluation_outside_of_a_Java_Project_2")); //$NON-NLS-1$
	}

	/**
	 * Asks the user for the workspace path
	 * of a file resource and saves the document there.
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#performSaveAs(org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	protected void performSaveAs(IProgressMonitor progressMonitor) {
		Shell shell= getSite().getShell();
		SaveAsDialog dialog= new SaveAsDialog(shell);
		dialog.open();
		IPath path= dialog.getResult();

		if (path == null) {
			if (progressMonitor != null) {
				progressMonitor.setCanceled(true);
			}
			return;
		}

		IWorkspace workspace= ResourcesPlugin.getWorkspace();
		IFile file= workspace.getRoot().getFile(path);
		final IEditorInput newInput= new FileEditorInput(file);

		WorkspaceModifyOperation op= new WorkspaceModifyOperation() {
			@Override
			public void execute(final IProgressMonitor monitor) throws CoreException {
				IDocumentProvider dp= getDocumentProvider();
				dp.saveDocument(monitor, newInput, dp.getDocument(getEditorInput()), true);
			}
		};

		boolean success= false;
		try {
			getDocumentProvider().aboutToChange(newInput);
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op);
			success= true;
		} catch (InterruptedException x) {
		} catch (InvocationTargetException x) {
			JDIDebugUIPlugin.log(x);
			String title= SnippetMessages.getString("JavaSnippetEditor.Problems_During_Save_As..._3");  //$NON-NLS-1$
			String msg= SnippetMessages.getString("JavaSnippetEditor.Save_could_not_be_completed.__4") +  x.getTargetException().getMessage(); //$NON-NLS-1$
			MessageDialog.openError(shell, title, msg);
		} finally {
			getDocumentProvider().changed(newInput);
			if (success) {
				setInput(newInput);
			}
		}

		if (progressMonitor != null) {
			progressMonitor.setCanceled(!success);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
	 */
	@Override
	public boolean isSaveAsAllowed() {
		return true;
	}

	protected IClassFileEvaluationEngine getEvaluationEngine() {
		if (fEngine == null) {
			IPath outputLocation =	getJavaProject().getProject().getWorkingLocation(JDIDebugUIPlugin.getUniqueIdentifier());
			java.io.File f = new java.io.File(outputLocation.toOSString());
			fEngine = EvaluationManager.newClassFileEvaluationEngine(getJavaProject(), (IJavaDebugTarget)getThread().getDebugTarget(), f);
		}
		if (getImports() != null) {
			fEngine.setImports(getImports());
		} else {
			fEngine.setImports(new String[]{});
		}
		return fEngine;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
	 */
	@Override
	protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
		fAnnotationAccess= getAnnotationAccess();
		fOverviewRuler= createOverviewRuler(getSharedColors());

		ISourceViewer viewer= new JDISourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles | SWT.LEFT_TO_RIGHT);

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

		return viewer;
	}

	/**
	 * Returns the working directory attribute for this scrapbook
	 */
	protected String getWorkingDirectoryAttribute() {
		IFile file= getFile();
		if (file != null) {
			try {
				return ScrapbookLauncher.getWorkingDirectoryAttribute(file);
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		}
		return null;
	}

	/**
	 * Returns the working directory attribute for this scrapbook
	 */
	protected String getVMArgsAttribute() {
		IFile file= getFile();
		if (file != null) {
			try {
				return ScrapbookLauncher.getVMArgsAttribute(file);
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		}
		return null;
	}

	/**
	 * Returns the vm install for this scrapbook
	 */
	protected IVMInstall getVMInstall() {
		IFile file= getFile();
		if (file != null) {
			try {
				return ScrapbookLauncher.getVMInstall(file);
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		}
		return null;
	}

	/**
	 * Executes the given runnable in the Display thread
	 */
	protected void async(Runnable r) {
		Control control= getVerticalRuler().getControl();
		if (!control.isDisposed()) {
			control.getDisplay().asyncExec(r);
		}
	}

	protected void showAndSelect(final String text, final int offset) {
		Runnable r = new Runnable() {
			@Override
			public void run() {
				try {
					getSourceViewer().getDocument().replace(offset, 0, text);
				} catch (BadLocationException e) {
					JDIDebugUIPlugin.log(e);
				}
				selectAndReveal(offset, text.length());
			}
		};
		async(r);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> required) {
		if (required == IShowInTargetList.class) {
			return (T) new IShowInTargetList() {
				@Override
				public String[] getShowInTargetIds() {
					return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_RES_NAV };
				}

			};
		}
		return super.getAdapter(required);
	}

}
