/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ListenerList;

import org.eclipse.core.resources.IResource;

import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.OpenAndLinkWithEditorHelper;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.model.WorkbenchAdapter;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.IUpdate;

import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.formatter.CodeFormatter;

import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

import org.eclipse.jdt.ui.JavaElementComparator;
import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
import org.eclipse.jdt.ui.actions.CCPActionGroup;
import org.eclipse.jdt.ui.actions.CustomFiltersActionGroup;
import org.eclipse.jdt.ui.actions.GenerateActionGroup;
import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
import org.eclipse.jdt.ui.actions.JavaSearchActionGroup;
import org.eclipse.jdt.ui.actions.JdtActionConstants;
import org.eclipse.jdt.ui.actions.MemberFilterActionGroup;
import org.eclipse.jdt.ui.actions.OpenViewActionGroup;
import org.eclipse.jdt.ui.actions.RefactorActionGroup;
import org.eclipse.jdt.ui.actions.SelectionDispatchAction;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.actions.AbstractToggleLinkingAction;
import org.eclipse.jdt.internal.ui.actions.CategoryFilterActionGroup;
import org.eclipse.jdt.internal.ui.actions.CollapseAllAction;
import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
import org.eclipse.jdt.internal.ui.dnd.JdtViewerDragSupport;
import org.eclipse.jdt.internal.ui.dnd.JdtViewerDropSupport;
import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
import org.eclipse.jdt.internal.ui.preferences.formatter.FormatterProfileManager;
import org.eclipse.jdt.internal.ui.util.ElementValidator;
import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
import org.eclipse.jdt.internal.ui.viewsupport.SourcePositionComparator;
import org.eclipse.jdt.internal.ui.viewsupport.StatusBarUpdater;


/**
 * The content outline page of the Java editor. The viewer implements a proprietary
 * update mechanism based on Java model deltas. It does not react on domain changes.
 * It is specified to show the content of ICompilationUnits and IClassFiles.
 * Publishes its context menu under <code>JavaPlugin.getDefault().getPluginId() + ".outline"</code>.
 */
public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdaptable , IPostSelectionProvider {

			static Object[] NO_CHILDREN= new Object[0];

			/**
			 * The element change listener of the java outline viewer.
			 * @see IElementChangedListener
			 */
			protected class ElementChangedListener implements IElementChangedListener {

				@Override
				public void elementChanged(final ElementChangedEvent e) {

					if (getControl() == null)
						return;

					Display d= getControl().getDisplay();
					if (d != null) {
						d.asyncExec(() -> {
							ICompilationUnit cu= (ICompilationUnit) fInput;
							IJavaElement base= cu;
							if (fTopLevelTypeOnly) {
								base= cu.findPrimaryType();
								if (base == null) {
									if (fOutlineViewer != null)
										fOutlineViewer.refresh(true);
									return;
								}
							}
							IJavaElementDelta delta= findElement(base, e.getDelta());
							if (delta != null && fOutlineViewer != null) {
								fOutlineViewer.reconcile(delta);
							}
						});
					}
				}

				private boolean isPossibleStructuralChange(IJavaElementDelta cuDelta) {
					if (cuDelta.getKind() != IJavaElementDelta.CHANGED) {
						return true; // add or remove
					}
					int flags= cuDelta.getFlags();
					if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
						return true;
					}
					return (flags & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_FINE_GRAINED)) == IJavaElementDelta.F_CONTENT;
				}

				protected IJavaElementDelta findElement(IJavaElement unit, IJavaElementDelta delta) {

					if (delta == null || unit == null)
						return null;

					IJavaElement element= delta.getElement();

					if (unit.equals(element)) {
						if (isPossibleStructuralChange(delta)) {
							return delta;
						}
						return null;
					}


					if (element.getElementType() > IJavaElement.CLASS_FILE)
						return null;

					IJavaElementDelta[] children= delta.getAffectedChildren();
					if (children == null || children.length == 0)
						return null;

					for (IJavaElementDelta child : children) {
						IJavaElementDelta d= findElement(unit, child);
						if (d != null)
							return d;
					}

					return null;
				}
			}

			static class NoClassElement extends WorkbenchAdapter implements IAdaptable {
				/*
				 * @see java.lang.Object#toString()
				 */
				@Override
				public String toString() {
					return JavaEditorMessages.JavaOutlinePage_error_NoTopLevelType;
				}

				@Override
				@SuppressWarnings("unchecked")
				public <T> T getAdapter(Class<T> clas) {
					if (clas == IWorkbenchAdapter.class)
						return (T) this;
					return null;
				}
			}

			/**
			 * Content provider for the children of an ICompilationUnit or
			 * an IClassFile
			 * @see ITreeContentProvider
			 */
			protected class ChildrenProvider implements ITreeContentProvider {

				private Object[] NO_CLASS= new Object[] {new NoClassElement()};
				private ElementChangedListener fListener;

				protected boolean matches(IJavaElement element) {
					if (element.getElementType() == IJavaElement.METHOD) {
						String name= element.getElementName();
						return (name != null && name.indexOf('<') >= 0);
					}
					return false;
				}

				protected IJavaElement[] filter(IJavaElement[] children) {
					boolean initializers= false;
					for (IJavaElement child : children) {
						if (matches(child)) {
							initializers= true;
							break;
						}
					}

					if (!initializers)
						return children;

					ArrayList<IJavaElement> v= new ArrayList<>();
					for (IJavaElement child : children) {
						if (matches(child)) {
							continue;
						}
						v.add(child);
					}

					return v.toArray(new IJavaElement[v.size()]);
				}

				@Override
				public Object[] getChildren(Object parent) {
					if (parent instanceof IParent) {
						IParent c= (IParent) parent;
						try {
							return filter(c.getChildren());
						} catch (JavaModelException x) {
							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
							// don't log NotExist exceptions as this is a valid case
							// since we might have been posted and the element
							// removed in the meantime.
							if (JavaPlugin.isDebug() || !x.isDoesNotExist())
								JavaPlugin.log(x);
						}
					}
					return NO_CHILDREN;
				}

				@Override
				public Object[] getElements(Object parent) {
					if (fTopLevelTypeOnly) {
						if (parent instanceof ITypeRoot) {
							try {
								IType type= ((ITypeRoot) parent).findPrimaryType();
								return type != null ? type.getChildren() : NO_CLASS;
							} catch (JavaModelException e) {
								JavaPlugin.log(e);
							}
						}
					}
					return getChildren(parent);
				}

				@Override
				public Object getParent(Object child) {
					if (child instanceof IJavaElement) {
						IJavaElement e= (IJavaElement) child;
						return e.getParent();
					}
					return null;
				}

				@Override
				public boolean hasChildren(Object parent) {
					if (parent instanceof IParent) {
						IParent c= (IParent) parent;
						try {
							IJavaElement[] children= filter(c.getChildren());
							return (children != null && children.length > 0);
						} catch (JavaModelException x) {
							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
							// don't log NotExist exceptions as this is a valid case
							// since we might have been posted and the element
							// removed in the meantime.
							if (JavaPlugin.isDebug() || !x.isDoesNotExist())
								JavaPlugin.log(x);
						}
					}
					return false;
				}

				@Override
				public void dispose() {
					if (fListener != null) {
						JavaCore.removeElementChangedListener(fListener);
						fListener= null;
					}
				}

				/*
				 * @see IContentProvider#inputChanged(Viewer, Object, Object)
				 */
				@Override
				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
					boolean isCU= (newInput instanceof ICompilationUnit);

					if (isCU && fListener == null) {
						fListener= new ElementChangedListener();
						JavaCore.addElementChangedListener(fListener);
					} else if (!isCU && fListener != null) {
						JavaCore.removeElementChangedListener(fListener);
						fListener= null;
					}
				}
			}

			/**
			 * The tree viewer used for displaying the outline.
			 *
			 * @see TreeViewer
			 */
			protected class JavaOutlineViewer extends TreeViewer {

				public JavaOutlineViewer(Tree tree) {
					super(tree);
					setAutoExpandLevel(ALL_LEVELS);
					setUseHashlookup(true);
				}

				/**
				 * Investigates the given element change event and if affected
				 * incrementally updates the Java outline.
				 *
				 * @param delta the Java element delta used to reconcile the Java outline
				 */
				public void reconcile(IJavaElementDelta delta) {
					refresh(true);
				}

				/*
				 * @see TreeViewer#internalExpandToLevel
				 */
				@Override
				protected void internalExpandToLevel(Widget node, int level) {
					if (node instanceof Item) {
						Item i= (Item) node;
						if (i.getData() instanceof IJavaElement) {
							IJavaElement je= (IJavaElement) i.getData();
							if (je.getElementType() == IJavaElement.IMPORT_CONTAINER || isInnerType(je)) {
								setExpanded(i, false);
						return;
							}
						}
					}
					super.internalExpandToLevel(node, level);
				}

				/*
				 * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object)
				 */
				@Override
				public boolean isExpandable(Object element) {
					if (hasFilters()) {
						return getFilteredChildren(element).length > 0;
					}
					return super.isExpandable(element);
				}

				/*
				 * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
				 */
				@Override
				protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
					Object input= getInput();
					if (event instanceof ProblemsLabelChangedEvent) {
						ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event;
						if (e.isMarkerChange() && input instanceof ICompilationUnit) {
							return; // marker changes can be ignored
						}
					}
					// look if the underlying resource changed
					Object[] changed= event.getElements();
					if (changed != null) {
						IResource resource= getUnderlyingResource();
						if (resource != null) {
							for (Object c : changed) {
								if (c != null && c.equals(resource)) {
									// change event to a full refresh
									event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource());
									break;
								}
							}
						}
					}
					super.handleLabelProviderChanged(event);
				}

				private IResource getUnderlyingResource() {
					Object input= getInput();
					if (input instanceof ICompilationUnit) {
						ICompilationUnit cu= (ICompilationUnit) input;
						cu= cu.getPrimary();
						return cu.getResource();
					} else if (input instanceof IClassFile) {
						return ((IClassFile) input).getResource();
					}
					return null;
				}

			}


			class LexicalSortingAction extends Action {

				private JavaElementComparator fComparator= new JavaElementComparator();
				private SourcePositionComparator fSourcePositonComparator= new SourcePositionComparator();

				public LexicalSortingAction() {
					super();
					PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LEXICAL_SORTING_OUTLINE_ACTION);
					setText(JavaEditorMessages.JavaOutlinePage_Sort_label);
					JavaPluginImages.setLocalImageDescriptors(this, "alphab_sort_co.png"); //$NON-NLS-1$
					setToolTipText(JavaEditorMessages.JavaOutlinePage_Sort_tooltip);
					setDescription(JavaEditorMessages.JavaOutlinePage_Sort_description);

					boolean checked= JavaPlugin.getDefault().getPreferenceStore().getBoolean("LexicalSortingAction.isChecked"); //$NON-NLS-1$
					valueChanged(checked, false);
				}

				@Override
				public void run() {
					valueChanged(isChecked(), true);
				}

				private void valueChanged(final boolean on, boolean store) {
					setChecked(on);
					BusyIndicator.showWhile(fOutlineViewer.getControl().getDisplay(), () -> {
						if (on) {
							fOutlineViewer.setComparator(fComparator);
							fDropSupport.setFeedbackEnabled(false);
						} else {
							fOutlineViewer.setComparator(fSourcePositonComparator);
							fDropSupport.setFeedbackEnabled(true);
						}
					});

					if (store)
						JavaPlugin.getDefault().getPreferenceStore().setValue("LexicalSortingAction.isChecked", on); //$NON-NLS-1$
				}
			}

		class ClassOnlyAction extends Action {

			public ClassOnlyAction() {
				super();
				PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GO_INTO_TOP_LEVEL_TYPE_ACTION);
				setText(JavaEditorMessages.JavaOutlinePage_GoIntoTopLevelType_label);
				setToolTipText(JavaEditorMessages.JavaOutlinePage_GoIntoTopLevelType_tooltip);
				setDescription(JavaEditorMessages.JavaOutlinePage_GoIntoTopLevelType_description);
				JavaPluginImages.setLocalImageDescriptors(this, "gointo_toplevel_type.png"); //$NON-NLS-1$

				IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
				boolean showclass= preferenceStore.getBoolean("GoIntoTopLevelTypeAction.isChecked"); //$NON-NLS-1$
				setTopLevelTypeOnly(showclass);
			}

			/*
			 * @see org.eclipse.jface.action.Action#run()
			 */
			@Override
			public void run() {
				setTopLevelTypeOnly(!fTopLevelTypeOnly);
			}

			private void setTopLevelTypeOnly(boolean show) {
				fTopLevelTypeOnly= show;
				setChecked(show);
				fOutlineViewer.refresh(false);

				IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
				preferenceStore.setValue("GoIntoTopLevelTypeAction.isChecked", show); //$NON-NLS-1$
			}
		}

		/**
		 * This action toggles whether this Java Outline page links
		 * its selection to the active editor.
		 *
		 * @since 3.0
		 */
		public class ToggleLinkingAction extends AbstractToggleLinkingAction {

			/**
			 * Constructs a new action.
			 */
			public ToggleLinkingAction() {
				boolean isLinkingEnabled= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE);
				setChecked(isLinkingEnabled);
				fOpenAndLinkWithEditorHelper.setLinkWithEditor(isLinkingEnabled);
			}

			/**
			 * Runs the action.
			 */
			@Override
			public void run() {
				final boolean isChecked= isChecked();
				PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, isChecked);
				if (isChecked && fEditor != null)
					fEditor.synchronizeOutlinePage(fEditor.computeHighlightRangeSourceReference(), false);
				fOpenAndLinkWithEditorHelper.setLinkWithEditor(isChecked);
			}

		}

		/**
		 * Empty selection provider.
		 *
		 * @since 3.2
		 */
		private static final class EmptySelectionProvider implements ISelectionProvider {
			@Override
			public void addSelectionChangedListener(ISelectionChangedListener listener) {
			}
			@Override
			public ISelection getSelection() {
				return StructuredSelection.EMPTY;
			}
			@Override
			public void removeSelectionChangedListener(ISelectionChangedListener listener) {
			}
			@Override
			public void setSelection(ISelection selection) {
			}
		}



	/**
	 * Formats the code associated with the elements selected in the Outline view. The action
	 * requires that the selection provided by the site's selection provider is of type
	 * {@link IStructuredSelection}
	 *
	 * @since 3.7
	 */
	private class FormatElementAction extends SelectionDispatchAction {

		/**
		 * Creates a new <code>FormatViewElementAction</code>.
		 *
		 * @param site the site providing context information for this action
		 */
		FormatElementAction(IPageSite site) {
			super(site);
		}

		/**
		 * Executes the action based on the Structured Selection. This formats the non-overlapping
		 * element(s) that have been selected in the view.
		 *
		 * @param selection the current selection
		 */
		@Override
		public void run(IStructuredSelection selection) {
			ICompilationUnit compilationUnit= (ICompilationUnit)((IJavaElement)selection.getFirstElement()).getAncestor(IJavaElement.COMPILATION_UNIT);
			if (ElementValidator.check(compilationUnit, getShell(), JavaEditorMessages.JavaEditor_FormatElementDialog_label, fEditor != null)) {
				JavaSourceViewer javaSourceViewer= (JavaSourceViewer)fEditor.getViewer();
				javaSourceViewer.rememberSelection();
				javaSourceViewer.setRedraw(false);
				try {
					IDocument document= javaSourceViewer.getDocument();
					IRegion[] regions= getOrderedRegionsForNonOverlappingElements(selection, document);
					Map<String, String> formatterSettings= FormatterProfileManager.getProjectSettings(compilationUnit.getJavaProject());
					String content= compilationUnit.getBuffer().getContents();
					String lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
					int kind = (JavaModelUtil.isModuleInfo(compilationUnit) ? CodeFormatter.K_MODULE_INFO : CodeFormatter.K_COMPILATION_UNIT) | CodeFormatter.F_INCLUDE_COMMENTS;

					TextEdit edit= CodeFormatterUtil.reformat(kind, content, regions, 0, lineDelimiter, formatterSettings);
					edit.apply(javaSourceViewer.getDocument());

				} catch (CoreException | MalformedTreeException | BadLocationException e) {
					JavaPlugin.log(e);
				} finally {
					javaSourceViewer.setRedraw(true);
					javaSourceViewer.restoreSelection();
				}
			}
		}

		/**
		 * Parses the selections for non-overlapping elements and returns their source regions
		 * ordered by their offsets.
		 *
		 * @param selection the selected elements
		 * @param document the document containing the selected elements
		 * @return the array of ordered source regions
		 */
		private IRegion[] getOrderedRegionsForNonOverlappingElements(IStructuredSelection selection, IDocument document) {
			List<?> allElements= selection.toList();
			Iterator<?> iterator= selection.iterator();
			ArrayList<IRegion> regions= new ArrayList<>(selection.size());
			while (iterator.hasNext()) {
				Object element= iterator.next();
				if (!isElementOverlapping((IJavaElement)element, allElements)) {
					regions.add(getElementRegion(element, document));
				}
			}
			Comparator<IRegion> comparator= (region0, region1) -> {
				int region1Offset= region0.getOffset();
				int region2Offset= region1.getOffset();
				if (region1Offset > region2Offset)
					return 1;
				else if (region1Offset == region2Offset)
					return 0;
				else
					return -1;
			};
			Collections.sort(regions, comparator);
			Object[] sortedObjects= regions.toArray();
			IRegion[] sortedRegions= new Region[sortedObjects.length];
			System.arraycopy(sortedObjects, 0, sortedRegions, 0, sortedObjects.length);
			return sortedRegions;
		}

		/**
		 * Calculates the region of the element. The start is at beginning of its first line if from
		 * the source start to the beginning of the line is all whitespace.
		 *
		 * @param element the element whose regions is to be calculated
		 * @param document the document containing the element whose region is to be calculated
		 * @return the region for the element
		 */
		private Region getElementRegion(Object element, IDocument document) {
			try {
				ISourceRange sourceRange= ((ISourceReference)element).getSourceRange();
				int sourceOffset= sourceRange.getOffset();
				int beginningOfWSOffset= sourceOffset - 1;
				int lineAtSourceOffset= document.getLineOfOffset(sourceOffset);
				while (beginningOfWSOffset >= 0 && Character.isWhitespace(document.getChar(beginningOfWSOffset)) && lineAtSourceOffset == document.getLineOfOffset(beginningOfWSOffset)) {
					beginningOfWSOffset--;
				}
				beginningOfWSOffset++;
				int sourceLength= sourceRange.getLength() + (sourceOffset - beginningOfWSOffset);
				if (lineAtSourceOffset != document.getLineOfOffset(beginningOfWSOffset))
					return new Region(document.getLineOffset(lineAtSourceOffset), sourceLength);
				else
					return new Region(beginningOfWSOffset, sourceLength);
			} catch (JavaModelException | BadLocationException e) {
				JavaPlugin.log(e);
			}
			return null;
		}

		/**
		 * Checks if element has an enclosing parent among other selected elements.
		 *
		 * @param element the element to be checked for overlap against all elements
		 * @param allElements the list of all elements
		 * @return <code>true</code> if the element has a parent in the list of all elements
		 */
		private boolean isElementOverlapping(IJavaElement element, List<?> allElements) {
			element= element.getParent();
			while (element != null) {
				if (element instanceof ISourceReference) {
					if (allElements.contains(element))
						return true;
				} else {
					return false;
				}
				element= element.getParent();
			}
			return false;
		}

		/**
		 * Notifies the action of a change in the Selection.
		 *
		 * @param selection the new Structured Selection
		 */
		@Override
		public void selectionChanged(IStructuredSelection selection) {
			setEnabled(fEditor.isEditorInputModifiable());
		}
	}



	/** A flag to show contents of top level type only */
	private boolean fTopLevelTypeOnly;

	private IJavaElement fInput;
	private String fContextMenuID;
	private Menu fMenu;
	private JavaOutlineViewer fOutlineViewer;
	private JavaEditor fEditor;

	private MemberFilterActionGroup fMemberFilterActionGroup;

	private ListenerList<ISelectionChangedListener> fSelectionChangedListeners= new ListenerList<>(ListenerList.IDENTITY);
	private ListenerList<ISelectionChangedListener> fPostSelectionChangedListeners= new ListenerList<>(ListenerList.IDENTITY);
	private Hashtable<String, IAction> fActions= new Hashtable<>();

	private TogglePresentationAction fTogglePresentation;

	private ToggleLinkingAction fToggleLinkingAction;

	/**
	 * Action for Collapse All.
	 *
	 * @since 3.7
	 */
	private CollapseAllAction fCollapseAllAction;

	/**
	 * Action for Format Element
	 *
	 * @since 3.7
	 */
	private FormatElementAction fFormatElement;

	private CompositeActionGroup fActionGroups;

	private IPropertyChangeListener fPropertyChangeListener;
	/**
	 * Custom filter action group.
	 * @since 3.0
	 */
	private CustomFiltersActionGroup fCustomFiltersActionGroup;
	/**
	 * Category filter action group.
	 * @since 3.2
	 */
	private CategoryFilterActionGroup fCategoryFilterActionGroup;

	private JdtViewerDropSupport fDropSupport;

	/**
	 * Helper to open and activate editors.
	 * @since 3.5
	 */
	private OpenAndLinkWithEditorHelper fOpenAndLinkWithEditorHelper;


	public JavaOutlinePage(String contextMenuID, JavaEditor editor) {
		super();

		Assert.isNotNull(editor);

		fContextMenuID= contextMenuID;
		fEditor= editor;

		fTogglePresentation= new TogglePresentationAction();
		fTogglePresentation.setEditor(editor);

		fPropertyChangeListener= this::doPropertyChange;
		JavaPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener);
	}

	/*
	 * @see org.eclipse.ui.part.Page#init(org.eclipse.ui.part.IPageSite)
	 */
	@Override
	public void init(IPageSite pageSite) {
		super.init(pageSite);
	}

	private void doPropertyChange(PropertyChangeEvent event) {
		if (fOutlineViewer != null) {
			if (MembersOrderPreferenceCache.isMemberOrderProperty(event.getProperty())) {
				fOutlineViewer.refresh(false);
			}
		}
	}

	/*
	 * @see ISelectionProvider#addSelectionChangedListener(ISelectionChangedListener)
	 */
	@Override
	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		if (fOutlineViewer != null)
			fOutlineViewer.addSelectionChangedListener(listener);
		else
			fSelectionChangedListeners.add(listener);
	}

	/*
	 * @see ISelectionProvider#removeSelectionChangedListener(ISelectionChangedListener)
	 */
	@Override
	public void removeSelectionChangedListener(ISelectionChangedListener listener) {
		if (fOutlineViewer != null)
			fOutlineViewer.removeSelectionChangedListener(listener);
		else
			fSelectionChangedListeners.remove(listener);
	}

	/*
	 * @see ISelectionProvider#setSelection(ISelection)
	 */
	@Override
	public void setSelection(ISelection selection) {
		if (fOutlineViewer != null)
			fOutlineViewer.setSelection(selection);
	}

	/*
	 * @see ISelectionProvider#getSelection()
	 */
	@Override
	public ISelection getSelection() {
		if (fOutlineViewer == null)
			return StructuredSelection.EMPTY;
		return fOutlineViewer.getSelection();
	}

	/*
	 * @see org.eclipse.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 */
	@Override
	public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
		if (fOutlineViewer != null)
			fOutlineViewer.addPostSelectionChangedListener(listener);
		else
			fPostSelectionChangedListeners.add(listener);
	}

	/*
	 * @see org.eclipse.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 */
	@Override
	public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
		if (fOutlineViewer != null)
			fOutlineViewer.removePostSelectionChangedListener(listener);
		else
			fPostSelectionChangedListeners.remove(listener);
	}

	private void registerToolbarActions(IActionBars actionBars) {
		IToolBarManager toolBarManager= actionBars.getToolBarManager();

		fCollapseAllAction= new CollapseAllAction(fOutlineViewer);
		fCollapseAllAction.setActionDefinitionId(CollapseAllHandler.COMMAND_ID);
		toolBarManager.add(fCollapseAllAction);

		toolBarManager.add(new LexicalSortingAction());

		fMemberFilterActionGroup= new MemberFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage"); //$NON-NLS-1$
		fMemberFilterActionGroup.contributeToToolBar(toolBarManager);

		fCustomFiltersActionGroup.fillActionBars(actionBars);

		IMenuManager viewMenuManager= actionBars.getMenuManager();
		viewMenuManager.add(new Separator("EndFilterGroup")); //$NON-NLS-1$

		fToggleLinkingAction= new ToggleLinkingAction();
		fToggleLinkingAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR);
		viewMenuManager.add(new ClassOnlyAction());
		viewMenuManager.add(fToggleLinkingAction);

		fCategoryFilterActionGroup= new CategoryFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage", new IJavaElement[] {fInput}); //$NON-NLS-1$
		fCategoryFilterActionGroup.contributeToViewMenu(viewMenuManager);
	}

	/*
	 * @see IPage#createControl
	 */
	@Override
	public void createControl(Composite parent) {

		Tree tree= new Tree(parent, SWT.MULTI);

		AppearanceAwareLabelProvider lprovider= new AppearanceAwareLabelProvider(
			AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS |  JavaElementLabels.F_APP_TYPE_SIGNATURE | JavaElementLabels.ALL_CATEGORY,
			AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS
		);

		fOutlineViewer= new JavaOutlineViewer(tree);
		initDragAndDrop();
		fOutlineViewer.setContentProvider(new ChildrenProvider());
		fOutlineViewer.setLabelProvider(new DecoratingJavaLabelProvider(lprovider));

		for (ISelectionChangedListener listener : fSelectionChangedListeners) {
			fSelectionChangedListeners.remove(listener);
			fOutlineViewer.addSelectionChangedListener(listener);
		}

		for (ISelectionChangedListener listener : fPostSelectionChangedListeners) {
			fPostSelectionChangedListeners.remove(listener);
			fOutlineViewer.addPostSelectionChangedListener(listener);
		}

		MenuManager manager= new MenuManager(fContextMenuID, fContextMenuID);
		manager.setRemoveAllWhenShown(true);
		manager.addMenuListener(this::contextMenuAboutToShow);
		fMenu= manager.createContextMenu(tree);
		tree.setMenu(fMenu);

		IPageSite site= getSite();
		site.registerContextMenu(JavaPlugin.getPluginId() + ".outline", manager, fOutlineViewer); //$NON-NLS-1$

		updateSelectionProvider(site);

		// we must create the groups after we have set the selection provider to the site
		fActionGroups= new CompositeActionGroup(new ActionGroup[] {
				new OpenViewActionGroup(this),
				new CCPActionGroup(this),
				new GenerateActionGroup(this),
				new RefactorActionGroup(this),
				new JavaSearchActionGroup(this)});

		// register global actions
		IActionBars actionBars= site.getActionBars();
		actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, fEditor.getAction(ITextEditorActionConstants.UNDO));
		actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, fEditor.getAction(ITextEditorActionConstants.REDO));

		IAction action= fEditor.getAction(ITextEditorActionConstants.NEXT);
		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION, action);
		actionBars.setGlobalActionHandler(ITextEditorActionConstants.NEXT, action);
		action= fEditor.getAction(ITextEditorActionConstants.PREVIOUS);
		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION, action);
		actionBars.setGlobalActionHandler(ITextEditorActionConstants.PREVIOUS, action);

		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);

		fActionGroups.fillActionBars(actionBars);

		fFormatElement= new FormatElementAction(site);
		fFormatElement.setActionDefinitionId(IJavaEditorActionDefinitionIds.QUICK_FORMAT);
		site.getSelectionProvider().addSelectionChangedListener(fFormatElement);
		actionBars.setGlobalActionHandler(JdtActionConstants.FORMAT_ELEMENT, fFormatElement);

		IStatusLineManager statusLineManager= actionBars.getStatusLineManager();
		if (statusLineManager != null) {
			StatusBarUpdater updater= new StatusBarUpdater(statusLineManager);
			fOutlineViewer.addPostSelectionChangedListener(updater);
		}
		// Custom filter group
		fCustomFiltersActionGroup= new CustomFiltersActionGroup("org.eclipse.jdt.ui.JavaOutlinePage", fOutlineViewer); //$NON-NLS-1$

		fOpenAndLinkWithEditorHelper= new OpenAndLinkWithEditorHelper(fOutlineViewer) {

			@Override
			protected void activate(ISelection selection) {
				fEditor.doSelectionChanged(selection);
				getSite().getPage().activate(fEditor);
			}

			@Override
			protected void linkToEditor(ISelection selection) {
				fEditor.doSelectionChanged(selection);

			}

			@Override
			protected void open(ISelection selection, boolean activate) {
				fEditor.doSelectionChanged(selection);
				if (activate)
					getSite().getPage().activate(fEditor);
			}

		};

		registerToolbarActions(actionBars);

		IHandlerService handlerService= site.getService(IHandlerService.class);
		handlerService.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, new ActionHandler(fToggleLinkingAction));
		handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, new ActionHandler(fCollapseAllAction));


		fOutlineViewer.setInput(fInput);
	}

	/*
	 * @since 3.2
	 */
	private void updateSelectionProvider(IPageSite site) {
		ISelectionProvider provider= fOutlineViewer;
		if (fInput != null) {
			ICompilationUnit cu= (ICompilationUnit)fInput.getAncestor(IJavaElement.COMPILATION_UNIT);
			if (cu != null && !JavaModelUtil.isPrimary(cu))
				provider= new EmptySelectionProvider();
		}
		site.setSelectionProvider(provider);
	}

	@Override
	public void dispose() {

		if (fEditor == null)
			return;

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

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

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


		fEditor.outlinePageClosed();
		fEditor= null;

		fSelectionChangedListeners.clear();
		fSelectionChangedListeners= null;
		getSite().getSelectionProvider().removeSelectionChangedListener(fFormatElement);

		fPostSelectionChangedListeners.clear();
		fPostSelectionChangedListeners= null;

		if (fPropertyChangeListener != null) {
			JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
			fPropertyChangeListener= null;
		}

		if (fMenu != null && !fMenu.isDisposed()) {
			fMenu.dispose();
			fMenu= null;
		}

		if (fActionGroups != null)
			fActionGroups.dispose();

		fTogglePresentation.setEditor(null);

		fOutlineViewer= null;

		super.dispose();
	}

	@Override
	public Control getControl() {
		if (fOutlineViewer != null)
			return fOutlineViewer.getControl();
		return null;
	}

	public void setInput(IJavaElement inputElement) {
		fInput= inputElement;
		if (fOutlineViewer != null) {
			fOutlineViewer.setInput(fInput);
			updateSelectionProvider(getSite());
		}
		if (fCategoryFilterActionGroup != null)
			fCategoryFilterActionGroup.setInput(new IJavaElement[] {fInput});
	}

	public void select(ISourceReference reference) {
		if (fOutlineViewer != null) {

			ISelection s= fOutlineViewer.getSelection();
			if (s instanceof IStructuredSelection) {
				IStructuredSelection ss= (IStructuredSelection) s;
				List<?> elements= ss.toList();
				if (!elements.contains(reference)) {
					s= (reference == null ? StructuredSelection.EMPTY : new StructuredSelection(reference));
					fOutlineViewer.setSelection(s, true);
				}
			}
		}
	}

	public void setAction(String actionID, IAction action) {
		Assert.isNotNull(actionID);
		if (action == null)
			fActions.remove(actionID);
		else
			fActions.put(actionID, action);
	}

	public IAction getAction(String actionID) {
		Assert.isNotNull(actionID);
		return fActions.get(actionID);
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(Class<T> key) {
		if (key == IShowInSource.class) {
			return (T) getShowInSource();
		}
		if (key == IShowInTargetList.class) {
			return (T) (IShowInTargetList) () -> new String[] { JavaUI.ID_PACKAGES };
		}
		if (key == IShowInTarget.class) {
			return (T) getShowInTarget();
		}

		return null;
	}

	/**
	 * Convenience method to add the action installed under the given actionID to the
	 * specified group of the menu.
	 *
	 * @param menu		the menu manager
	 * @param group		the group to which to add the action
	 * @param actionID	the ID of the new action
	 */
	protected void addAction(IMenuManager menu, String group, String actionID) {
		IAction action= getAction(actionID);
		if (action != null) {
			if (action instanceof IUpdate)
				((IUpdate) action).update();

			if (action.isEnabled()) {
		 		IMenuManager subMenu= menu.findMenuUsingPath(group);
		 		if (subMenu != null)
		 			subMenu.add(action);
		 		else
		 			menu.appendToGroup(group, action);
			}
		}
	}

	protected void contextMenuAboutToShow(IMenuManager menu) {

		JavaPlugin.createStandardGroups(menu);

		IStructuredSelection selection= (IStructuredSelection)getSelection();
		fActionGroups.setContext(new ActionContext(selection));
		fActionGroups.fillContextMenu(menu);
	}

	/*
	 * @see Page#setFocus()
	 */
	@Override
	public void setFocus() {
		if (fOutlineViewer != null)
			fOutlineViewer.getControl().setFocus();
	}

	/**
	 * Checks whether a given Java element is an inner type.
	 *
	 * @param element the java element
	 * @return <code>true</code> iff the given element is an inner type
	 */
	private boolean isInnerType(IJavaElement element) {

		if (element != null && element.getElementType() == IJavaElement.TYPE) {
			IType type= (IType)element;
			try {
				return type.isMember();
			} catch (JavaModelException e) {
				IJavaElement parent= type.getParent();
				if (parent != null) {
					int parentElementType= parent.getElementType();
					return (parentElementType != IJavaElement.COMPILATION_UNIT && parentElementType != IJavaElement.CLASS_FILE);
				}
			}
		}

		return false;
	}

	/**
	 * Returns the <code>IShowInSource</code> for this view.
	 *
	 * @return the {@link IShowInSource}
	 */
	protected IShowInSource getShowInSource() {
		return () -> new ShowInContext(
			null,
			getSite().getSelectionProvider().getSelection());
	}

	/**
	 * Returns the <code>IShowInTarget</code> for this view.
	 *
	 * @return the {@link IShowInTarget}
	 */
	protected IShowInTarget getShowInTarget() {
		return context -> {
			ISelection sel= context.getSelection();
			if (sel instanceof ITextSelection) {
				ITextSelection tsel= (ITextSelection) sel;
				int offset= tsel.getOffset();
				IJavaElement element= fEditor.getElementAt(offset);
				if (element != null) {
					setSelection(new StructuredSelection(element));
					return true;
				}
			} else if (sel instanceof IStructuredSelection) {
				setSelection(sel);
				return true;
			}
			return false;
		};
	}

	private void initDragAndDrop() {
		fDropSupport= new JdtViewerDropSupport(fOutlineViewer);
		fDropSupport.start();

		new JdtViewerDragSupport(fOutlineViewer).start();
	}

	/**
	 * Returns whether only the contents of the top level type is to be shown.
	 *
	 * @return <code>true</code> if only the contents of the top level type is to be shown.
	 * @since 3.3
	 */
	protected final boolean isTopLevelTypeOnly() {
		return fTopLevelTypeOnly;
	}

	/**
	 * Returns the <code>JavaOutlineViewer</code> of this view.
	 *
	 * @return the {@link JavaOutlineViewer}
	 * @since 3.3
	 */
	protected final JavaOutlineViewer getOutlineViewer() {
		return fOutlineViewer;
	}
}
