/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.typehierarchy;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ITypeHierarchy;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.corext.util.Messages;
import org.eclipse.dltk.internal.ui.actions.CCPActionGroup;
import org.eclipse.dltk.internal.ui.actions.CompositeActionGroup;
import org.eclipse.dltk.internal.ui.actions.NewWizardsActionGroup;
import org.eclipse.dltk.internal.ui.actions.refactoring.RefactorActionGroup;
import org.eclipse.dltk.internal.ui.editor.EditorUtility;
import org.eclipse.dltk.internal.ui.workingsets.WorkingSetFilterActionGroup;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.IContextMenuConstants;
import org.eclipse.dltk.ui.ITypeHierarchyViewPart;
import org.eclipse.dltk.ui.MembersOrderPreferenceCache;
import org.eclipse.dltk.ui.PreferenceConstants;
import org.eclipse.dltk.ui.ScriptElementLabels;
import org.eclipse.dltk.ui.actions.OpenEditorActionGroup;
import org.eclipse.dltk.ui.actions.OpenViewActionGroup;
import org.eclipse.dltk.ui.actions.SelectAllAction;
import org.eclipse.dltk.ui.util.ExceptionHandler;
import org.eclipse.dltk.ui.viewsupport.IViewPartInputProvider;
import org.eclipse.dltk.ui.viewsupport.ScriptUILabelProvider;
import org.eclipse.dltk.ui.viewsupport.SelectionProviderMediator;
import org.eclipse.dltk.ui.viewsupport.StatusBarUpdater;
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.action.ToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IBasicPropertyConstants;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;

/**
 * view showing the super types/sub types of its input.
 */
public class TypeHierarchyViewPart extends ViewPart
		implements ITypeHierarchyViewPart, IViewPartInputProvider {

	public static final int VIEW_ID_TYPE = 2;
	public static final int VIEW_ID_SUPER = 0;
	public static final int VIEW_ID_SUB = 1;

	public static final int VIEW_ORIENTATION_VERTICAL = 0;
	public static final int VIEW_ORIENTATION_HORIZONTAL = 1;
	public static final int VIEW_ORIENTATION_SINGLE = 2;
	public static final int VIEW_ORIENTATION_AUTOMATIC = 3;

	private static final String DIALOGSTORE_HIERARCHYVIEW = "TypeHierarchyViewPart.hierarchyview"; //$NON-NLS-1$
	private static final String DIALOGSTORE_VIEWORIENTATION = "TypeHierarchyViewPart.orientation"; //$NON-NLS-1$

	private static final String TAG_INPUT = "input"; //$NON-NLS-1$
	private static final String TAG_VIEW = "view"; //$NON-NLS-1$
	private static final String TAG_ORIENTATION = "orientation"; //$NON-NLS-1$
	private static final String TAG_RATIO = "ratio"; //$NON-NLS-1$
	private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$
	private static final String TAG_VERTICAL_SCROLL = "vertical_scroll"; //$NON-NLS-1$

	private static final String GROUP_FOCUS = "group.focus"; //$NON-NLS-1$

	// the selected type in the hierarchy view
	private IType fSelectedType;
	// input element or null
	private IModelElement fInputElement;

	// history of input elements. No duplicates
	private ArrayList<IModelElement> fInputHistory;

	private IMemento fMemento;
	private IDialogSettings fDialogSettings;

	private TypeHierarchyLifeCycle fHierarchyLifeCycle;
	private ITypeHierarchyLifeCycleListener fTypeHierarchyLifeCycleListener;

	private IPropertyChangeListener fPropertyChangeListener;

	private SelectionProviderMediator fSelectionProviderMediator;
	private ISelectionChangedListener fSelectionChangedListener;
	private IPartListener2 fPartListener;

	private int fCurrentOrientation;
	int fOrientation = VIEW_ORIENTATION_AUTOMATIC;
	boolean fInComputeOrientation = false;

	private boolean fLinkingEnabled;
	private boolean fSelectInEditor;

	private boolean fIsVisible;
	private boolean fNeedRefresh;
	private boolean fIsEnableMemberFilter;
	private boolean fIsRefreshRunnablePosted;

	private int fCurrentViewerIndex;
	private TypeHierarchyViewer[] fAllViewers;

	private MethodsViewer fMethodsViewer;

	private SashForm fTypeMethodsSplitter;
	private PageBook fViewerbook;
	private PageBook fPagebook;

	private Label fNoHierarchyShownLabel;
	private Label fEmptyTypesViewer;

	private ViewForm fTypeViewerViewForm;
	private ViewForm fMethodViewerViewForm;

	private CLabel fMethodViewerPaneLabel;
	private ScriptUILabelProvider fPaneLabelProvider;
	private Composite fParent;

	private ToggleViewAction[] fViewActions;
	private ToggleLinkingAction fToggleLinkingAction;
	private HistoryDropDownAction fHistoryDropDownAction;
	private ToggleOrientationAction[] fToggleOrientationActions;
	private EnableMemberFilterAction fEnableMemberFilterAction;
	private ShowQualifiedTypeNamesAction fShowQualifiedTypeNamesAction;
	private FocusOnTypeAction fFocusOnTypeAction;
	private FocusOnSelectionAction fFocusOnSelectionAction;
	private CompositeActionGroup fActionGroups;
	private SelectAllAction fSelectAllAction;

	private WorkingSetFilterActionGroup fWorkingSetActionGroup;
	private Job fRestoreStateJob;
	private IContextActivation fContextActivation;

	protected IPreferenceStore getPreferenceStore() {
		return DLTKUIPlugin.getDefault().getPreferenceStore();
	}

	public TypeHierarchyViewPart() {
		fSelectedType = null;
		fInputElement = null;
		fIsVisible = false;
		fIsRefreshRunnablePosted = false;
		fSelectInEditor = true;
		fRestoreStateJob = null;

		fHierarchyLifeCycle = new TypeHierarchyLifeCycle();
		fTypeHierarchyLifeCycleListener = (typeHierarchy,
				changedTypes) -> doTypeHierarchyChanged(typeHierarchy,
						changedTypes);
		fHierarchyLifeCycle.addChangedListener(fTypeHierarchyLifeCycleListener);

		fPropertyChangeListener = event -> doPropertyChange(event);
		// getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener
		// );

		fIsEnableMemberFilter = false;

		fInputHistory = new ArrayList<>();
		fAllViewers = null;

		fViewActions = new ToggleViewAction[] {
				new ToggleViewAction(this, VIEW_ID_TYPE),
				new ToggleViewAction(this, VIEW_ID_SUPER),
				new ToggleViewAction(this, VIEW_ID_SUB) };

		fDialogSettings = DLTKUIPlugin.getDefault().getDialogSettings();

		fHistoryDropDownAction = new HistoryDropDownAction(this);
		fHistoryDropDownAction.setEnabled(false);

		fToggleOrientationActions = new ToggleOrientationAction[] {
				new ToggleOrientationAction(this, VIEW_ORIENTATION_VERTICAL),
				new ToggleOrientationAction(this, VIEW_ORIENTATION_HORIZONTAL),
				new ToggleOrientationAction(this, VIEW_ORIENTATION_AUTOMATIC),
				new ToggleOrientationAction(this, VIEW_ORIENTATION_SINGLE) };

		fEnableMemberFilterAction = new EnableMemberFilterAction(this, false);
		fShowQualifiedTypeNamesAction = new ShowQualifiedTypeNamesAction(this,
				false);

		fFocusOnTypeAction = new FocusOnTypeAction(this);

		// TODO: DLTK: Please fix this to support
		// DLTKLanguageManager.createScriptUILabelProvider()
		fPaneLabelProvider = new ScriptUILabelProvider();

		fFocusOnSelectionAction = new FocusOnSelectionAction(this);

		fPartListener = new IPartListener2() {
			@Override
			public void partVisible(IWorkbenchPartReference ref) {
				IWorkbenchPart part = ref.getPart(false);
				if (part == TypeHierarchyViewPart.this) {
					visibilityChanged(true);
				}
			}

			@Override
			public void partHidden(IWorkbenchPartReference ref) {
				IWorkbenchPart part = ref.getPart(false);
				if (part == TypeHierarchyViewPart.this) {
					visibilityChanged(false);
				}
			}

			@Override
			public void partActivated(IWorkbenchPartReference ref) {
				IWorkbenchPart part = ref.getPart(false);
				if (part instanceof IEditorPart)
					editorActivated((IEditorPart) part);
			}

			@Override
			public void partInputChanged(IWorkbenchPartReference ref) {
				IWorkbenchPart part = ref.getPart(false);
				if (part instanceof IEditorPart)
					editorActivated((IEditorPart) part);
			}

			@Override
			public void partBroughtToTop(IWorkbenchPartReference ref) {
			}

			@Override
			public void partClosed(IWorkbenchPartReference ref) {
			}

			@Override
			public void partDeactivated(IWorkbenchPartReference ref) {
			}

			@Override
			public void partOpened(IWorkbenchPartReference ref) {
			}
		};

		fSelectionChangedListener = event -> doSelectionChanged(event);

		fLinkingEnabled = getPreferenceStore()
				.getBoolean(PreferenceConstants.LINK_TYPEHIERARCHY_TO_EDITOR);
	}

	/**
	 * Method doPropertyChange.
	 *
	 * @param event
	 */
	protected void doPropertyChange(PropertyChangeEvent event) {
		String property = event.getProperty();
		if (fMethodsViewer != null) {
			if (MembersOrderPreferenceCache
					.isMemberOrderProperty(event.getProperty())) {
				fMethodsViewer.refresh();
			}
		}
		if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE
				.equals(property)) {
			updateHierarchyViewer(true);
			updateTitle();
		}
	}

	/**
	 * Adds the entry if new. Inserted at the beginning of the history entries
	 * list.
	 *
	 * @param entry
	 *            The new entry
	 */
	private void addHistoryEntry(IModelElement entry) {
		if (fInputHistory.contains(entry)) {
			fInputHistory.remove(entry);
		}
		fInputHistory.add(0, entry);
		fHistoryDropDownAction.setEnabled(true);
	}

	private void updateHistoryEntries() {
		for (int i = fInputHistory.size() - 1; i >= 0; i--) {
			IModelElement type = fInputHistory.get(i);
			if (!type.exists()) {
				fInputHistory.remove(i);
			}
		}
		fHistoryDropDownAction.setEnabled(!fInputHistory.isEmpty());
	}

	/**
	 * Goes to the selected entry, without updating the order of history
	 * entries.
	 *
	 * @param entry
	 *            The entry to open
	 */
	public void gotoHistoryEntry(IModelElement entry) {
		if (fInputHistory.contains(entry)) {
			updateInput(entry);
		}
	}

	/**
	 * Gets all history entries.
	 *
	 * @return All history entries
	 */
	public IModelElement[] getHistoryEntries() {
		if (fInputHistory.size() > 0) {
			updateHistoryEntries();
		}
		return fInputHistory.toArray(new IModelElement[fInputHistory.size()]);
	}

	/**
	 * Sets the history entries
	 *
	 * @param elems
	 *            The history elements to set
	 */
	public void setHistoryEntries(IModelElement[] elems) {
		fInputHistory.clear();
		for (int i = 0; i < elems.length; i++) {
			fInputHistory.add(elems[i]);
		}
		updateHistoryEntries();
	}

	/**
	 * Selects an member in the methods list or in the current hierarchy.
	 *
	 * @param member
	 *            The member to select
	 */
	public void selectMember(IMember member) {
		fSelectInEditor = false;
		if (member.getElementType() != IModelElement.TYPE) {
			Control methodControl = fMethodsViewer.getControl();
			if (methodControl != null && !methodControl.isDisposed()) {
				methodControl.setFocus();
			}

			fMethodsViewer.setSelection(new StructuredSelection(member), true);
		} else {
			Control viewerControl = getCurrentViewer().getControl();
			if (viewerControl != null && !viewerControl.isDisposed()) {
				viewerControl.setFocus();
			}

			if (!member.equals(fSelectedType)) {
				getCurrentViewer().setSelection(new StructuredSelection(member),
						true);
			}
		}
		fSelectInEditor = true;
	}

	/**
	 * @return The input type
	 * @deprecated
	 */
	@Override
	@Deprecated
	public IType getInput() {
		if (fInputElement instanceof IType) {
			return (IType) fInputElement;
		}
		return null;
	}

	/**
	 * Sets the input to a new type
	 *
	 * @param type
	 *            The new input type
	 * @deprecated
	 */
	@Override
	@Deprecated
	public void setInput(IType type) {
		setInputElement(type);
	}

	/**
	 * Returns the input element of the type hierarchy. Can be of type
	 * <code>IType</code> or <code>IPackageFragment</code>
	 *
	 * @return the input element
	 */
	@Override
	public IModelElement getInputElement() {
		return fInputElement;
	}

	/**
	 * Sets the input to a new element.
	 *
	 * @param element
	 *            the input element
	 */
	@Override
	public void setInputElement(IModelElement element) {
		IMember memberToSelect = null;
		if (element != null) {
			if (element instanceof IMember) {
				if (element.getElementType() != IModelElement.TYPE) {
					memberToSelect = (IMember) element;
					element = memberToSelect.getDeclaringType();

				}
				if (element == null || !element.exists()) {
					MessageDialog.openError(getSite().getShell(),
							TypeHierarchyMessages.TypeHierarchyViewPart_error_title,
							TypeHierarchyMessages.TypeHierarchyViewPart_error_message);
					return;
				}
			} else {
				int kind = element.getElementType();
				if (kind != IModelElement.SCRIPT_PROJECT
						&& kind != IModelElement.PROJECT_FRAGMENT) {
					element = null;
					DLTKUIPlugin.logErrorMessage(
							"Invalid type hierarchy input type.");//$NON-NLS-1$
				}
			}
		}
		if (element != null && !element.equals(fInputElement)) {
			addHistoryEntry(element);
		}

		updateInput(element);
		if (memberToSelect != null) {
			selectMember(memberToSelect);
		}
	}

	/*
	 * Changes the input to a new type
	 *
	 * @param inputElement
	 */
	private void updateInput(IModelElement inputElement) {
		IModelElement prevInput = fInputElement;

		synchronized (this) {
			if (fRestoreStateJob != null) {
				fRestoreStateJob.cancel();
				try {
					fRestoreStateJob.join();
				} catch (InterruptedException e) {
					// ignore
				} finally {
					fRestoreStateJob = null;
				}
			}
		}

		// Make sure the UI got repainted before we execute a long running
		// operation. This can be removed if we refresh the hierarchy in a
		// separate thread.
		// Work-araound for http://dev.eclipse.org/bugs/show_bug.cgi?id=30881
		processOutstandingEvents();
		if (inputElement == null) {
			clearInput();
		} else {
			fInputElement = inputElement;
			try {
				fHierarchyLifeCycle.ensureRefreshedTypeHierarchy(inputElement,
						DLTKUIPlugin.getActiveWorkbenchWindow());
				// fHierarchyLifeCycle.ensureRefreshedTypeHierarchy(inputElement,
				// getSite().getWorkbenchWindow());
			} catch (InvocationTargetException e) {
				ExceptionHandler.handle(e, getSite().getShell(),
						TypeHierarchyMessages.TypeHierarchyViewPart_exception_title,
						TypeHierarchyMessages.TypeHierarchyViewPart_exception_message);
				clearInput();
				return;
			} catch (InterruptedException e) {
				return;
			}

			if (inputElement.getElementType() != IModelElement.TYPE) {
				setView(VIEW_ID_TYPE);
			}
			// turn off member filtering
			fSelectInEditor = false;
			setMemberFilter(null);
			internalSelectType(null, false); // clear selection
			fIsEnableMemberFilter = false;
			if (!inputElement.equals(prevInput)) {
				updateHierarchyViewer(true);
			}
			IType root = getSelectableType(inputElement);
			internalSelectType(root, true);
			updateMethodViewer(root);
			updateToolbarButtons();
			updateTitle();
			enableMemberFilter(false);
			fPagebook.showPage(fTypeMethodsSplitter);
			fSelectInEditor = true;
		}
	}

	private void processOutstandingEvents() {
		Display display = getDisplay();
		if (display != null && !display.isDisposed())
			display.update();
	}

	private void clearInput() {
		fInputElement = null;
		fHierarchyLifeCycle.freeHierarchy();

		updateHierarchyViewer(false);
		updateToolbarButtons();
	}

	/*
	 * @see IWorbenchPart#setFocus
	 */
	@Override
	public void setFocus() {
		fPagebook.setFocus();
	}

	/*
	 * @see IWorkbenchPart#dispose
	 */
	@Override
	public void dispose() {
		if (fContextActivation != null) {
			IContextService ctxService = getSite()
					.getService(IContextService.class);
			if (ctxService != null) {
				ctxService.deactivateContext(fContextActivation);
			}
		}
		fHierarchyLifeCycle.freeHierarchy();
		fHierarchyLifeCycle
				.removeChangedListener(fTypeHierarchyLifeCycleListener);
		fPaneLabelProvider.dispose();

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

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

		getSite().getPage().removePartListener(fPartListener);

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

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

		super.dispose();
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> key) {
		if (key == IShowInSource.class) {
			return (T) getShowInSource();
		}
		if (key == IShowInTargetList.class) {
			return (T) (IShowInTargetList) () -> new String[] {
					DLTKUIPlugin.ID_SCRIPT_EXPLORER, IPageLayout.ID_RES_NAV };
		}
		// if (key == IContextProvider.class) {
		// return JavaUIHelp.getHelpContextProvider(this,
		// IJavaHelpContextIds.TYPE_HIERARCHY_VIEW);
		// }
		return super.getAdapter(key);
	}

	private Control createTypeViewerControl(Composite parent) {
		fViewerbook = new PageBook(parent, SWT.NULL);

		KeyListener keyListener = createKeyListener();

		// Create the viewers
		TypeHierarchyViewer superTypesViewer = new SuperTypeHierarchyViewer(
				fViewerbook, fHierarchyLifeCycle, this, getPreferenceStore());
		initializeTypesViewer(superTypesViewer, keyListener,
				IContextMenuConstants.TARGET_ID_SUPERTYPES_VIEW);

		TypeHierarchyViewer subTypesViewer = new SubTypeHierarchyViewer(
				fViewerbook, fHierarchyLifeCycle, this, getPreferenceStore());
		initializeTypesViewer(subTypesViewer, keyListener,
				IContextMenuConstants.TARGET_ID_SUBTYPES_VIEW);

		TypeHierarchyViewer vajViewer = new TraditionalHierarchyViewer(
				fViewerbook, fHierarchyLifeCycle, this, getPreferenceStore());
		initializeTypesViewer(vajViewer, keyListener,
				IContextMenuConstants.TARGET_ID_HIERARCHY_VIEW);

		fAllViewers = new TypeHierarchyViewer[3];
		fAllViewers[VIEW_ID_SUPER] = superTypesViewer;
		fAllViewers[VIEW_ID_SUB] = subTypesViewer;
		fAllViewers[VIEW_ID_TYPE] = vajViewer;

		int currViewerIndex;
		try {
			currViewerIndex = fDialogSettings.getInt(DIALOGSTORE_HIERARCHYVIEW);
			if (currViewerIndex < 0 || currViewerIndex > 2) {
				currViewerIndex = VIEW_ID_TYPE;
			}
		} catch (NumberFormatException e) {
			currViewerIndex = VIEW_ID_TYPE;
		}

		fEmptyTypesViewer = new Label(fViewerbook,
				SWT.TOP | SWT.LEFT | SWT.WRAP);

		for (int i = 0; i < fAllViewers.length; i++) {
			fAllViewers[i].setInput(fAllViewers[i]);
		}

		// force the update
		fCurrentViewerIndex = -1;
		setView(currViewerIndex);

		return fViewerbook;
	}

	private KeyListener createKeyListener() {
		return new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent event) {
				if (event.stateMask == 0) {
					if (event.keyCode == SWT.F5) {
						ITypeHierarchy hierarchy = fHierarchyLifeCycle
								.getHierarchy();
						if (hierarchy != null) {
							fHierarchyLifeCycle.typeHierarchyChanged(hierarchy);
							doTypeHierarchyChangedOnViewers(null);
						}
						updateHierarchyViewer(false);
						return;
					}
				}
			}
		};
	}

	private void initializeTypesViewer(final TypeHierarchyViewer typesViewer,
			KeyListener keyListener, String cotextHelpId) {
		typesViewer.getControl().setVisible(false);
		typesViewer.getControl().addKeyListener(keyListener);
		typesViewer.initContextMenu(
				menu -> fillTypesViewerContextMenu(typesViewer, menu),
				cotextHelpId, getSite());
		typesViewer.addPostSelectionChangedListener(fSelectionChangedListener);
		typesViewer.setQualifiedTypeName(isShowQualifiedTypeNames());
		typesViewer.setWorkingSetFilter(
				fWorkingSetActionGroup.getWorkingSetFilter());
	}

	private Control createMethodViewerControl(Composite parent) {
		fMethodsViewer = new MethodsViewer(parent, fHierarchyLifeCycle, this,
				getPreferenceStore());
		fMethodsViewer.initContextMenu(
				menu -> fillMethodsViewerContextMenu(menu),
				IContextMenuConstants.TARGET_ID_MEMBERS_VIEW, getSite());
		fMethodsViewer
				.addPostSelectionChangedListener(fSelectionChangedListener);

		Control control = fMethodsViewer.getTable();
		control.addKeyListener(createKeyListener());
		control.addFocusListener(new FocusListener() {
			@Override
			public void focusGained(FocusEvent e) {
				fSelectAllAction.setEnabled(true);
			}

			@Override
			public void focusLost(FocusEvent e) {
				fSelectAllAction.setEnabled(false);
			}
		});

		return control;
	}

	// private void initDragAndDrop() {
	// for (int i= 0; i < fAllViewers.length; i++) {
	// addDragAdapters(fAllViewers[i]);
	// addDropAdapters(fAllViewers[i]);
	// }
	// addDragAdapters(fMethodsViewer);
	// fMethodsViewer.addDropSupport(DND.DROP_NONE, new Transfer[0], new
	// DropTargetAdapter());
	//
	// //DND on empty hierarchy
	// DropTarget dropTarget = new DropTarget(fPagebook, DND.DROP_MOVE |
	// DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT);
	// dropTarget.setTransfer(new Transfer[] {
	// LocalSelectionTransfer.getInstance() });
	// dropTarget.addDropListener(new TypeHierarchyTransferDropAdapter(this,
	// fAllViewers[0]));
	// }
	//
	// private void addDropAdapters(AbstractTreeViewer viewer) {
	// Transfer[] transfers= new Transfer[] {
	// LocalSelectionTransfer.getInstance() };
	// int ops= DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK |
	// DND.DROP_DEFAULT;
	//
	// TransferDropTargetListener[] dropListeners= new
	// TransferDropTargetListener[] {
	// new TypeHierarchyTransferDropAdapter(this, viewer)
	// };
	// viewer.addDropSupport(ops, transfers, new
	// DelegatingDropAdapter(dropListeners));
	// }
	//
	// private void addDragAdapters(StructuredViewer viewer) {
	// int ops= DND.DROP_COPY | DND.DROP_LINK;
	// Transfer[] transfers= new Transfer[] {
	// LocalSelectionTransfer.getInstance(), ResourceTransfer.getInstance()};
	//
	// TransferDragSourceListener[] dragListeners= new
	// TransferDragSourceListener[] {
	// new SelectionTransferDragAdapter(viewer),
	// new ResourceTransferDragAdapter(viewer)
	// };
	// viewer.addDragSupport(ops, transfers, new JdtViewerDragAdapter(viewer,
	// dragListeners));
	// }

	/**
	 * Returns the inner component in a workbench part.
	 *
	 * @see IWorkbenchPart#createPartControl(Composite)
	 */
	@Override
	public void createPartControl(Composite container) {
		fParent = container;
		addResizeListener(container);

		fPagebook = new PageBook(container, SWT.NONE);
		fWorkingSetActionGroup = new WorkingSetFilterActionGroup(getSite(),
				fPropertyChangeListener);

		// page 1 of page book (no hierarchy label)

		fNoHierarchyShownLabel = new Label(fPagebook,
				SWT.TOP + SWT.LEFT + SWT.WRAP);
		fNoHierarchyShownLabel
				.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);

		// page 2 of page book (viewers)

		fTypeMethodsSplitter = new SashForm(fPagebook, SWT.VERTICAL);
		fTypeMethodsSplitter.setVisible(false);

		fTypeViewerViewForm = new ViewForm(fTypeMethodsSplitter, SWT.NONE);

		Control typeViewerControl = createTypeViewerControl(
				fTypeViewerViewForm);
		fTypeViewerViewForm.setContent(typeViewerControl);

		fMethodViewerViewForm = new ViewForm(fTypeMethodsSplitter, SWT.NONE);
		fTypeMethodsSplitter.setWeights(new int[] { 35, 65 });

		Control methodViewerPart = createMethodViewerControl(
				fMethodViewerViewForm);
		fMethodViewerViewForm.setContent(methodViewerPart);

		fMethodViewerPaneLabel = new CLabel(fMethodViewerViewForm, SWT.NONE);
		fMethodViewerViewForm.setTopLeft(fMethodViewerPaneLabel);

		ToolBar methodViewerToolBar = new ToolBar(fMethodViewerViewForm,
				SWT.FLAT | SWT.WRAP);
		fMethodViewerViewForm.setTopCenter(methodViewerToolBar);

		// initDragAndDrop();

		MenuManager menu = new MenuManager();
		menu.add(fFocusOnTypeAction);
		fNoHierarchyShownLabel
				.setMenu(menu.createContextMenu(fNoHierarchyShownLabel));

		fPagebook.showPage(fNoHierarchyShownLabel);

		try {
			fOrientation = fDialogSettings.getInt(DIALOGSTORE_VIEWORIENTATION);
			if (fOrientation < 0 || fOrientation > 3) {
				fOrientation = VIEW_ORIENTATION_AUTOMATIC;
			}
		} catch (NumberFormatException e) {
			fOrientation = VIEW_ORIENTATION_AUTOMATIC;
		}
		// force the update
		fCurrentOrientation = -1;
		// will fill the main tool bar
		setOrientation(fOrientation);

		if (fMemento != null) { // restore state before creating action
			restoreLinkingEnabled(fMemento);
		}
		fToggleLinkingAction = new ToggleLinkingAction(this);

		// set the filter menu items
		IActionBars actionBars = getViewSite().getActionBars();
		IMenuManager viewMenu = actionBars.getMenuManager();
		for (int i = 0; i < fViewActions.length; i++) {
			ToggleViewAction action = fViewActions[i];
			viewMenu.add(action);
			action.setEnabled(false);
		}
		viewMenu.add(new Separator());

		fWorkingSetActionGroup.fillViewMenu(viewMenu);

		viewMenu.add(new Separator());

		IMenuManager layoutSubMenu = new MenuManager(
				TypeHierarchyMessages.TypeHierarchyViewPart_layout_submenu);
		viewMenu.add(layoutSubMenu);
		for (int i = 0; i < fToggleOrientationActions.length; i++) {
			layoutSubMenu.add(fToggleOrientationActions[i]);
		}
		viewMenu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		viewMenu.add(fShowQualifiedTypeNamesAction);
		viewMenu.add(fToggleLinkingAction);

		// fill the method viewer tool bar
		ToolBarManager lowertbmanager = new ToolBarManager(methodViewerToolBar);
		lowertbmanager.add(fEnableMemberFilterAction);
		lowertbmanager.add(new Separator());
		fMethodsViewer.contributeToToolBar(lowertbmanager);
		lowertbmanager.update(true);

		// selection provider
		int nHierarchyViewers = fAllViewers.length;
		StructuredViewer[] trackedViewers = new StructuredViewer[nHierarchyViewers
				+ 1];
		for (int i = 0; i < nHierarchyViewers; i++) {
			trackedViewers[i] = fAllViewers[i];
		}
		trackedViewers[nHierarchyViewers] = fMethodsViewer;
		fSelectionProviderMediator = new SelectionProviderMediator(
				trackedViewers, getCurrentViewer());
		IStatusLineManager slManager = getViewSite().getActionBars()
				.getStatusLineManager();
		fSelectionProviderMediator
				.addSelectionChangedListener(new StatusBarUpdater(slManager));

		getSite().setSelectionProvider(fSelectionProviderMediator);
		getSite().getPage().addPartListener(fPartListener);

		// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=33657
		IModelElement input = null; // determineInputElement();
		if (fMemento != null) {
			restoreState(fMemento, input);
		} else if (input != null) {
			setInputElement(input);
		} else {
			setViewerVisibility(false);
		}

		// PlatformUI.getWorkbench().getHelpSystem().setHelp(fPagebook,
		// IJavaHelpContextIds.TYPE_HIERARCHY_VIEW);

		fActionGroups = new CompositeActionGroup(
				new ActionGroup[] { new NewWizardsActionGroup(this.getSite()),
						new OpenEditorActionGroup(this),
						new OpenViewActionGroup(this), new CCPActionGroup(this),
						// new GenerateActionGroup(this),
						new RefactorActionGroup(this,
								null) /*
										 * , new DLTKSearchActionGroup(this,
										 * getLanguageToolkit())
										 */
				});

		fActionGroups.fillActionBars(actionBars);
		fSelectAllAction = new SelectAllAction(fMethodsViewer);

		actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
				fSelectAllAction);
		IContextService ctxService = getSite()
				.getService(IContextService.class);
		if (ctxService != null) {
			fContextActivation = ctxService
					.activateContext(DLTKUIPlugin.CONTEXT_VIEWS);
		}
	}

	private void addResizeListener(Composite parent) {
		parent.addControlListener(new ControlListener() {
			@Override
			public void controlMoved(ControlEvent e) {
			}

			@Override
			public void controlResized(ControlEvent e) {
				computeOrientation();
			}
		});
	}

	void computeOrientation() {
		// fix for bug: 63268 error while activating view
		// avoid recursive calls of compute orientation
		if (fInComputeOrientation) {
			return;
		}
		fInComputeOrientation = true;
		try {
			if (fOrientation != VIEW_ORIENTATION_AUTOMATIC) {
				setOrientation(fOrientation);
			} else {
				if (fOrientation == VIEW_ORIENTATION_SINGLE)
					return;
				Point size = fParent.getSize();
				if (size.x != 0 && size.y != 0) {
					if (size.x > size.y)
						setOrientation(VIEW_ORIENTATION_HORIZONTAL);
					else
						setOrientation(VIEW_ORIENTATION_VERTICAL);
				}
			}
		} finally {
			fInComputeOrientation = false;
		}
	}

	/**
	 * called from ToggleOrientationAction.
	 *
	 * @param orientation
	 *            VIEW_ORIENTATION_SINGLE, VIEW_ORIENTATION_HORIZONTAL or
	 *            VIEW_ORIENTATION_VERTICAL
	 */
	public void setOrientation(int orientation) {
		if (fCurrentOrientation != orientation) {
			boolean methodViewerNeedsUpdate = false;

			if (fMethodViewerViewForm != null
					&& !fMethodViewerViewForm.isDisposed()
					&& fTypeMethodsSplitter != null
					&& !fTypeMethodsSplitter.isDisposed()) {
				if (orientation == VIEW_ORIENTATION_SINGLE) {
					fMethodViewerViewForm.setVisible(false);
					enableMemberFilter(false);
					updateMethodViewer(null);
				} else {
					if (fCurrentOrientation == VIEW_ORIENTATION_SINGLE) {
						fMethodViewerViewForm.setVisible(true);
						methodViewerNeedsUpdate = true;
					}
					boolean horizontal = orientation == VIEW_ORIENTATION_HORIZONTAL;
					fTypeMethodsSplitter.setOrientation(
							horizontal ? SWT.HORIZONTAL : SWT.VERTICAL);
				}
				updateMainToolbar(orientation);
				fTypeMethodsSplitter.layout();
			}
			updateCheckedState();
			if (methodViewerNeedsUpdate) {
				updateMethodViewer(fSelectedType);
			}
			fDialogSettings.put(DIALOGSTORE_VIEWORIENTATION, orientation);
			fCurrentOrientation = orientation;

		}
	}

	private void updateCheckedState() {
		for (int i = 0; i < fToggleOrientationActions.length; i++) {
			fToggleOrientationActions[i]
					.setChecked(fOrientation == fToggleOrientationActions[i]
							.getOrientation());
		}
	}

	private void updateMainToolbar(int orientation) {
		IActionBars actionBars = getViewSite().getActionBars();
		IToolBarManager tbmanager = actionBars.getToolBarManager();

		if (orientation == VIEW_ORIENTATION_HORIZONTAL) {
			clearMainToolBar(tbmanager);
			ToolBar typeViewerToolBar = new ToolBar(fTypeViewerViewForm,
					SWT.FLAT | SWT.WRAP);
			fillMainToolBar(new ToolBarManager(typeViewerToolBar));
			fTypeViewerViewForm.setTopLeft(typeViewerToolBar);
		} else {
			fTypeViewerViewForm.setTopLeft(null);
			fillMainToolBar(tbmanager);
		}
	}

	private void fillMainToolBar(IToolBarManager tbmanager) {
		tbmanager.removeAll();
		for (int i = 0; i < fViewActions.length; i++) {
			tbmanager.add(fViewActions[i]);
		}
		tbmanager.add(fHistoryDropDownAction);
		tbmanager.update(false);
	}

	private void clearMainToolBar(IToolBarManager tbmanager) {
		tbmanager.removeAll();
		tbmanager.update(false);
	}

	/*
	 * Creates the context menu for the hierarchy viewers
	 */
	private void fillTypesViewerContextMenu(TypeHierarchyViewer viewer,
			IMenuManager menu) {
		DLTKUIPlugin.createStandardGroups(menu);

		menu.appendToGroup(IContextMenuConstants.GROUP_SHOW,
				new Separator(GROUP_FOCUS));
		// viewer entries
		viewer.contributeToContextMenu(menu);

		if (fFocusOnSelectionAction.canActionBeAdded())
			menu.appendToGroup(GROUP_FOCUS, fFocusOnSelectionAction);
		menu.appendToGroup(GROUP_FOCUS, fFocusOnTypeAction);

		fActionGroups.setContext(new ActionContext(
				getSite().getSelectionProvider().getSelection()));
		fActionGroups.fillContextMenu(menu);
		fActionGroups.setContext(null);
	}

	/*
	 * Creates the context menu for the method viewer
	 */
	private void fillMethodsViewerContextMenu(IMenuManager menu) {
		DLTKUIPlugin.createStandardGroups(menu);
		// viewer entries
		fMethodsViewer.contributeToContextMenu(menu);
		fActionGroups.setContext(new ActionContext(
				getSite().getSelectionProvider().getSelection()));
		fActionGroups.fillContextMenu(menu);
		fActionGroups.setContext(null);
	}

	/*
	 * Toggles between the empty viewer page and the hierarchy
	 */
	private void setViewerVisibility(boolean showHierarchy) {
		if (showHierarchy) {
			fViewerbook.showPage(getCurrentViewer().getControl());
		} else {
			fViewerbook.showPage(fEmptyTypesViewer);
		}
	}

	/*
	 * Sets the member filter. <code>null</code> disables member filtering.
	 */
	private void setMemberFilter(IMember[] memberFilter) {
		Assert.isNotNull(fAllViewers);
		for (int i = 0; i < fAllViewers.length; i++) {
			fAllViewers[i].setMemberFilter(memberFilter);
		}
	}

	private IType getSelectableType(IModelElement elem) {
		if (elem.getElementType() != IModelElement.TYPE) {
			return getCurrentViewer().getTreeRootType();
		} else {
			return (IType) elem;
		}
	}

	private void internalSelectType(IMember elem, boolean reveal) {
		TypeHierarchyViewer viewer = getCurrentViewer();
		viewer.removePostSelectionChangedListener(fSelectionChangedListener);
		viewer.setSelection(elem != null ? new StructuredSelection(elem)
				: StructuredSelection.EMPTY, reveal);
		viewer.addPostSelectionChangedListener(fSelectionChangedListener);
	}

	/*
	 * When the input changed or the hierarchy pane becomes visible,
	 * <code>updateHierarchyViewer<code> brings up the correct view and
	 * refreshes the current tree
	 */
	private void updateHierarchyViewer(final boolean doExpand) {
		if (fInputElement == null) {
			fNoHierarchyShownLabel
					.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
			fPagebook.showPage(fNoHierarchyShownLabel);
		} else {
			if (getCurrentViewer().containsElements() != null) {
				Runnable runnable = () -> {
					final TypeHierarchyViewer viewer = getCurrentViewer();
					((TypeHierarchyContentProvider) viewer.getContentProvider())
							.resetState();
					viewer.updateContent(doExpand); // refresh
				};
				BusyIndicator.showWhile(getDisplay(), runnable);
				if (!isChildVisible(fViewerbook,
						getCurrentViewer().getControl())) {
					setViewerVisibility(true);
				}
			} else {
				fEmptyTypesViewer.setText(Messages.format(
						TypeHierarchyMessages.TypeHierarchyViewPart_nodecl,
						fInputElement.getElementName()));
				setViewerVisibility(false);
			}
		}
	}

	private void updateMethodViewer(final IType input) {
		if (!fIsEnableMemberFilter
				&& fCurrentOrientation != VIEW_ORIENTATION_SINGLE) {
			if (input == fMethodsViewer.getInput()) {
				if (input != null) {
					Runnable runnable = () -> fMethodsViewer.refresh();
					BusyIndicator.showWhile(getDisplay(), runnable);
				}
			} else {
				if (input != null) {
					fMethodViewerPaneLabel
							.setText(fPaneLabelProvider.getText(input));
					fMethodViewerPaneLabel
							.setImage(fPaneLabelProvider.getImage(input));
				} else {
					fMethodViewerPaneLabel.setText(""); //$NON-NLS-1$
					fMethodViewerPaneLabel.setImage(null);
				}
				Runnable runnable = () -> fMethodsViewer.setInput(input);
				BusyIndicator.showWhile(getDisplay(), runnable);
			}
		}
	}

	protected void doSelectionChanged(SelectionChangedEvent e) {
		if (e.getSelectionProvider() == fMethodsViewer) {
			methodSelectionChanged(e.getSelection());
		} else {
			typeSelectionChanged(e.getSelection());
		}
	}

	private void methodSelectionChanged(ISelection sel) {
		if (sel instanceof IStructuredSelection) {
			List<?> selected = ((IStructuredSelection) sel).toList();
			int nSelected = selected.size();
			if (fIsEnableMemberFilter) {
				IMember[] memberFilter = null;
				if (nSelected > 0) {
					memberFilter = new IMember[nSelected];
					selected.toArray(memberFilter);
				}
				setMemberFilter(memberFilter);
				updateHierarchyViewer(true);
				updateTitle();
				internalSelectType(fSelectedType, true);
			}
			if (nSelected == 1 && fSelectInEditor) {
				revealElementInEditor(selected.get(0), fMethodsViewer);
			}
		}
	}

	private void typeSelectionChanged(ISelection sel) {
		if (sel instanceof IStructuredSelection) {
			List<?> selected = ((IStructuredSelection) sel).toList();
			int nSelected = selected.size();
			if (nSelected != 0) {
				List<IType> types = new ArrayList<>(nSelected);
				for (int i = nSelected - 1; i >= 0; i--) {
					Object elem = selected.get(i);
					if (elem instanceof IType) {
						if (!types.contains(elem)) {
							types.add((IType) elem);
						}
					} else if (elem instanceof CumulativeType.Part) {
						final CumulativeType.Part part = (CumulativeType.Part) elem;
						if (!types.contains(part.type)) {
							types.add(part.type);
						}
					}
				}
				if (types.size() == 1) {
					fSelectedType = types.get(0);
					updateMethodViewer(fSelectedType);
				} else if (types.size() == 0) {
					// method selected, no change
				}
				if (nSelected == 1 && fSelectInEditor) {
					revealElementInEditor(selected.get(0), getCurrentViewer());
				}
			} else {
				fSelectedType = null;
				updateMethodViewer(null);
			}
		}
	}

	private void revealElementInEditor(Object elem,
			StructuredViewer originViewer) {
		// only allow revealing when the type hierarchy is the active page
		// no revealing after selection events due to model changes

		if (getSite().getPage().getActivePart() != this) {
			return;
		}

		if (fSelectionProviderMediator.getViewerInFocus() != originViewer) {
			return;
		}

		IEditorPart editorPart = EditorUtility.isOpenInEditor(elem);
		if (editorPart != null && (elem instanceof IModelElement)) {
			getSite().getPage().removePartListener(fPartListener);
			getSite().getPage().bringToTop(editorPart);
			EditorUtility.revealInEditor(editorPart, (IModelElement) elem);
			getSite().getPage().addPartListener(fPartListener);
		}
	}

	private Display getDisplay() {
		if (fPagebook != null && !fPagebook.isDisposed()) {
			return fPagebook.getDisplay();
		}
		return null;
	}

	private boolean isChildVisible(Composite pb, Control child) {
		Control[] children = pb.getChildren();
		for (int i = 0; i < children.length; i++) {
			if (children[i] == child && children[i].isVisible())
				return true;
		}
		return false;
	}

	private void updateTitle() {
		String viewerTitle = getCurrentViewer().getTitle();

		String tooltip;
		String title;
		if (fInputElement != null) {
			IWorkingSet workingSet = fWorkingSetActionGroup.getWorkingSet();
			if (workingSet == null) {
				String[] args = new String[] { viewerTitle,
						ScriptElementLabels.getDefault().getElementLabel(
								fInputElement,
								ScriptElementLabels.ALL_DEFAULT) };
				title = Messages.format(
						TypeHierarchyMessages.TypeHierarchyViewPart_title,
						args);
				tooltip = Messages.format(
						TypeHierarchyMessages.TypeHierarchyViewPart_tooltip,
						args);
			} else {
				String[] args = new String[] { viewerTitle,
						ScriptElementLabels.getDefault().getElementLabel(
								fInputElement, ScriptElementLabels.ALL_DEFAULT),
						workingSet.getLabel() };
				title = Messages.format(
						TypeHierarchyMessages.TypeHierarchyViewPart_ws_title,
						args);
				tooltip = Messages.format(
						TypeHierarchyMessages.TypeHierarchyViewPart_ws_tooltip,
						args);
			}
		} else {
			title = ""; //$NON-NLS-1$
			tooltip = viewerTitle;
		}
		setContentDescription(title);
		setTitleToolTip(tooltip);
	}

	private void updateToolbarButtons() {
		boolean isType = fInputElement instanceof IType;
		for (int i = 0; i < fViewActions.length; i++) {
			ToggleViewAction action = fViewActions[i];
			if (action.getViewerIndex() == VIEW_ID_TYPE) {
				action.setEnabled(fInputElement != null);
			} else {
				action.setEnabled(isType);
			}
		}
	}

	/*
	 * Sets the current view (see view id) called from ToggleViewAction. Must be
	 * called after creation of the view part.
	 */
	public void setView(int viewerIndex) {
		Assert.isNotNull(fAllViewers);
		if (viewerIndex < fAllViewers.length
				&& fCurrentViewerIndex != viewerIndex) {
			fCurrentViewerIndex = viewerIndex;

			updateHierarchyViewer(true);
			if (fInputElement != null) {
				ISelection currSelection = getCurrentViewer().getSelection();
				if (currSelection == null || currSelection.isEmpty()) {
					internalSelectType(getSelectableType(fInputElement), false);
					currSelection = getCurrentViewer().getSelection();
				}
				if (!fIsEnableMemberFilter) {
					typeSelectionChanged(currSelection);
				}
			}
			updateTitle();

			fDialogSettings.put(DIALOGSTORE_HIERARCHYVIEW, viewerIndex);
			getCurrentViewer().getTree().setFocus();
		}
		for (int i = 0; i < fViewActions.length; i++) {
			ToggleViewAction action = fViewActions[i];
			action.setChecked(fCurrentViewerIndex == action.getViewerIndex());
		}
	}

	/**
	 * Gets the current active view index.
	 *
	 * @return The index of the current viewer
	 */
	public int getViewIndex() {
		return fCurrentViewerIndex;
	}

	private TypeHierarchyViewer getCurrentViewer() {
		return fAllViewers[fCurrentViewerIndex];
	}

	/**
	 * called from EnableMemberFilterAction. Must be called after creation of
	 * the view part.
	 *
	 * @param on
	 *            <code>true</code> to turn the member filter on
	 */
	public void enableMemberFilter(boolean on) {
		if (on != fIsEnableMemberFilter) {
			fIsEnableMemberFilter = on;
			if (!on) {
				IType methodViewerInput = (IType) fMethodsViewer.getInput();
				setMemberFilter(null);
				updateHierarchyViewer(true);
				updateTitle();

				if (methodViewerInput != null && getCurrentViewer()
						.isElementShown(methodViewerInput)) {
					// avoid that the method view changes content by selecting
					// the previous input
					internalSelectType(methodViewerInput, true);
				} else if (fSelectedType != null) {
					// choose a input that exists
					internalSelectType(fSelectedType, true);
					updateMethodViewer(fSelectedType);
				}
			} else {
				methodSelectionChanged(fMethodsViewer.getSelection());
			}
		}
		fEnableMemberFilterAction.setChecked(on);
	}

	/**
	 * called from ShowQualifiedTypeNamesAction. Must be called after creation
	 * of the view part.
	 *
	 * @param on
	 *            <code>true</code> to enable qualified type names
	 */
	public void showQualifiedTypeNames(boolean on) {
		if (fAllViewers == null) {
			return;
		}
		for (int i = 0; i < fAllViewers.length; i++) {
			fAllViewers[i].setQualifiedTypeName(on);
		}
	}

	private boolean isShowQualifiedTypeNames() {
		return fShowQualifiedTypeNamesAction.isChecked();
	}

	/**
	 * Called from ITypeHierarchyLifeCycleListener. Can be called from any
	 * thread
	 *
	 * @param typeHierarchy
	 *            Hierarchy that has changed
	 * @param changedTypes
	 *            Types in the hierarchy that have change or <code>null</code>
	 *            if the full hierarchy has changed
	 */
	protected void doTypeHierarchyChanged(
			final TypeHierarchyLifeCycle typeHierarchy,
			final IType[] changedTypes) {
		if (!fIsVisible) {
			fNeedRefresh = true;
			return;
		}
		if (fIsRefreshRunnablePosted) {
			return;
		}

		Display display = getDisplay();
		if (display != null) {
			fIsRefreshRunnablePosted = true;
			display.asyncExec(() -> {
				try {
					if (fPagebook != null && !fPagebook.isDisposed()) {
						doTypeHierarchyChangedOnViewers(changedTypes);
					}
				} finally {
					fIsRefreshRunnablePosted = false;
				}
			});
		}
	}

	protected void doTypeHierarchyChangedOnViewers(IType[] changedTypes) {
		if (fHierarchyLifeCycle.getHierarchy() == null
				|| !fHierarchyLifeCycle.getHierarchy().exists()) {
			clearInput();
		} else {
			if (changedTypes == null) {
				// hierarchy change
				try {
					fHierarchyLifeCycle.ensureRefreshedTypeHierarchy(
							fInputElement, getSite().getWorkbenchWindow());
				} catch (InvocationTargetException e) {
					ExceptionHandler.handle(e, getSite().getShell(),
							TypeHierarchyMessages.TypeHierarchyViewPart_exception_title,
							TypeHierarchyMessages.TypeHierarchyViewPart_exception_message);
					clearInput();
					return;
				} catch (InterruptedException e) {
					return;
				}
				fMethodsViewer.refresh();
				updateHierarchyViewer(false);
			} else {
				// elements in hierarchy modified
				Object methodViewerInput = fMethodsViewer.getInput();
				fMethodsViewer.refresh();
				fMethodViewerPaneLabel
						.setText(fPaneLabelProvider.getText(methodViewerInput));
				fMethodViewerPaneLabel.setImage(
						fPaneLabelProvider.getImage(methodViewerInput));
				if (getCurrentViewer().isMethodFiltering()) {
					if (changedTypes.length == 1) {
						getCurrentViewer().refresh(changedTypes[0]);
					} else {
						updateHierarchyViewer(false);
					}
				} else {
					getCurrentViewer().update(changedTypes,
							new String[] { IBasicPropertyConstants.P_TEXT,
									IBasicPropertyConstants.P_IMAGE });
				}
			}
		}
	}

	/*
	 * @see IViewPart#init
	 */
	@Override
	public void init(IViewSite site, IMemento memento)
			throws PartInitException {
		super.init(site, memento);
		fMemento = memento;
	}

	/*
	 * @see ViewPart#saveState(IMemento)
	 */
	@Override
	public void saveState(IMemento memento) {
		if (fPagebook == null) {
			// part has not been created
			if (fMemento != null) { // Keep the old state;
				memento.putMemento(fMemento);
			}
			return;
		}
		if (fInputElement != null) {
			String handleIndentifier = fInputElement.getHandleIdentifier();
			memento.putString(TAG_INPUT, handleIndentifier);
		}
		memento.putInteger(TAG_VIEW, getViewIndex());
		memento.putInteger(TAG_ORIENTATION, fOrientation);
		int weigths[] = fTypeMethodsSplitter.getWeights();
		int ratio = (weigths[0] * 1000) / (weigths[0] + weigths[1]);
		memento.putInteger(TAG_RATIO, ratio);

		ScrollBar bar = getCurrentViewer().getTree().getVerticalBar();
		int position = bar != null ? bar.getSelection() : 0;
		memento.putInteger(TAG_VERTICAL_SCROLL, position);

		IModelElement selection = toModelElement(
				((IStructuredSelection) getCurrentViewer().getSelection())
						.getFirstElement());
		if (selection != null) {
			memento.putString(TAG_SELECTION, selection.getHandleIdentifier());
		}

		fWorkingSetActionGroup.saveState(memento);

		fMethodsViewer.saveState(memento);

		saveLinkingEnabled(memento);
	}

	private void saveLinkingEnabled(IMemento memento) {
		memento.putInteger(PreferenceConstants.LINK_TYPEHIERARCHY_TO_EDITOR,
				fLinkingEnabled ? 1 : 0);
	}

	/**
	 * @param element
	 * @return
	 */
	private IModelElement toModelElement(Object element) {
		if (element instanceof IModelElement) {
			return (IModelElement) element;
		} else if (element instanceof CumulativeType) {
			return ((CumulativeType) element).getFirst();
		} else if (element instanceof CumulativeType.Part) {
			return ((CumulativeType.Part) element).type;
		}
		return null;
	}

	/*
	 * Restores the type hierarchy settings from a memento.
	 */
	private void restoreState(final IMemento memento,
			IModelElement defaultInput) {
		IModelElement input = defaultInput;
		String elementId = memento.getString(TAG_INPUT);
		if (elementId != null) {
			input = DLTKCore.create(elementId);
			if (input != null && !input.exists()) {
				input = null;
			}
		}
		if (input == null) {
			doRestoreState(memento, input);
		} else {
			final IModelElement hierarchyInput = input;

			synchronized (this) {
				String label = Messages.format(
						TypeHierarchyMessages.TypeHierarchyViewPart_restoreinput,
						hierarchyInput.getElementName());
				fNoHierarchyShownLabel.setText(label);

				fRestoreStateJob = new Job(label) {
					@Override
					protected IStatus run(IProgressMonitor monitor) {
						try {
							doRestoreInBackground(memento, hierarchyInput,
									monitor);
						} catch (ModelException e) {
							return e.getStatus();
						} catch (OperationCanceledException e) {
							return Status.CANCEL_STATUS;
						}
						return Status.OK_STATUS;
					}
				};
				fRestoreStateJob.schedule();
			}
		}
	}

	private void doRestoreInBackground(final IMemento memento,
			final IModelElement hierarchyInput, IProgressMonitor monitor)
			throws ModelException {
		fHierarchyLifeCycle.doHierarchyRefresh(hierarchyInput, monitor);
		if (!monitor.isCanceled()) {
			Display.getDefault().asyncExec(() -> {
				// running async: check first if view still exists
				if (fPagebook != null && !fPagebook.isDisposed()) {
					doRestoreState(memento, hierarchyInput);
				}
			});
		}
	}

	final void doRestoreState(IMemento memento, IModelElement input) {
		synchronized (this) {
			if (fRestoreStateJob == null) {
				return;
			}
			fRestoreStateJob = null;
		}

		fWorkingSetActionGroup.restoreState(memento);
		setInputElement(input);

		Integer viewerIndex = memento.getInteger(TAG_VIEW);
		if (viewerIndex != null) {
			setView(viewerIndex.intValue());
		}
		Integer orientation = memento.getInteger(TAG_ORIENTATION);
		if (orientation != null) {
			fOrientation = orientation.intValue();
		}
		computeOrientation();
		updateCheckedState();

		Integer ratio = memento.getInteger(TAG_RATIO);
		if (ratio != null) {
			fTypeMethodsSplitter.setWeights(
					new int[] { ratio.intValue(), 1000 - ratio.intValue() });
		}
		ScrollBar bar = getCurrentViewer().getTree().getVerticalBar();
		if (bar != null) {
			Integer vScroll = memento.getInteger(TAG_VERTICAL_SCROLL);
			if (vScroll != null) {
				bar.setSelection(vScroll.intValue());
			}
		}
		fMethodsViewer.restoreState(memento);
	}

	private void restoreLinkingEnabled(IMemento memento) {
		Integer val = memento
				.getInteger(PreferenceConstants.LINK_TYPEHIERARCHY_TO_EDITOR);
		if (val != null) {
			fLinkingEnabled = val.intValue() != 0;
		}
	}

	/**
	 * view part becomes visible
	 *
	 * @param isVisible
	 */
	protected void visibilityChanged(boolean isVisible) {
		fIsVisible = isVisible;
		if (isVisible && fNeedRefresh) {
			doTypeHierarchyChangedOnViewers(null);
		}
		fNeedRefresh = false;
	}

	/**
	 * Link selection to active editor.
	 *
	 * @param editor
	 *            The activated editor
	 */
	protected void editorActivated(IEditorPart editor) {
		if (!isLinkingEnabled()) {
			return;
		}
		if (fInputElement == null) {
			// no type hierarchy shown
			return;
		}

		IModelElement elem = editor.getEditorInput()
				.getAdapter(IModelElement.class);
		try {
			IType type = null;
			if (elem instanceof ISourceModule) {
				// Take the first type:
				IType[] allTypes = ((ISourceModule) elem).getTypes();
				if (allTypes.length > 0) {
					type = allTypes[0];
				}
			}
			if (type != null) {
				internalSelectType(type, true);
				if (getCurrentViewer().getSelection().isEmpty()) {
					updateMethodViewer(null);
				} else {
					updateMethodViewer(type);
				}
			}
		} catch (ModelException e) {
			DLTKUIPlugin.log(e);
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @seeorg.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider#
	 * getViewPartInput()
	 */
	@Override
	public Object getViewPartInput() {
		return fInputElement;
	}

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

	boolean isLinkingEnabled() {
		return fLinkingEnabled;
	}

	public void setLinkingEnabled(boolean enabled) {
		fLinkingEnabled = enabled;
		getPreferenceStore().setValue(
				PreferenceConstants.LINK_TYPEHIERARCHY_TO_EDITOR, enabled);

		if (enabled) {
			IEditorPart editor = getSite().getPage().getActiveEditor();
			if (editor != null) {
				editorActivated(editor);
			}
		}
	}

	public void clearNeededRefresh() {
		fNeedRefresh = false;
	}

}
