/*******************************************************************************
 *  Copyright (c) 2000, 2019 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
 *     QNX Software Systems - Mikhail Khodjaiants - Registers View (Bug 53640)
 *     Wind River - Pawel Piech - Drag/Drop to Expressions View (Bug 184057)
 * 	   Wind River - Pawel Piech - Busy status while updates in progress (Bug 206822)
 * 	   Wind River - Pawel Piech - NPE when closing the Variables view (Bug 213719)
 *     Wind River - Pawel Piech - Fix viewer input race condition (Bug 234908)
 *     Wind River - Anton Leherbauer - Fix selection provider (Bug 254442)
 *     Patrick Chuong (Texas Instruments) - Improve usability of the breakpoint view (Bug 238956)
 *     Patrick Chuong (Texas Instruments) and Pawel Piech (Wind River) -
 *     		Allow multiple debug views and multiple debug context providers (Bug 327263)
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.variables;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.LazyModelPresentation;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.internal.ui.VariablesViewModelPresentation;
import org.eclipse.debug.internal.ui.actions.CollapseAllAction;
import org.eclipse.debug.internal.ui.actions.ConfigureColumnsAction;
import org.eclipse.debug.internal.ui.actions.variables.ChangeVariableValueAction;
import org.eclipse.debug.internal.ui.actions.variables.ShowTypesAction;
import org.eclipse.debug.internal.ui.actions.variables.ToggleDetailPaneAction;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.internal.ui.viewers.model.VirtualFindAction;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewActionProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputRequestor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ViewerInputService;
import org.eclipse.debug.internal.ui.views.DebugModelPresentationContext;
import org.eclipse.debug.internal.ui.views.IDebugExceptionHandler;
import org.eclipse.debug.internal.ui.views.variables.details.AvailableDetailPanesAction;
import org.eclipse.debug.internal.ui.views.variables.details.DetailPaneProxy;
import org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer2;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
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.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.DoubleClickEvent;
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.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.IUpdate;

/**
 * This view shows variables and their values for a particular stack frame
 */
public class VariablesView extends AbstractDebugView implements IDebugContextListener,
	IPropertyChangeListener, IDebugExceptionHandler,
	IPerspectiveListener, IModelChangedListener,
		IViewerUpdateListener, IDetailPaneContainer2, ISaveablePart2 {

	private static final String COLLAPSE_ALL = "CollapseAll"; //$NON-NLS-1$

	/**
	 * Selection provider wrapping an exchangeable active selection provider.
	 * Sends out a selection changed event when the active selection provider changes.
	 * Forwards all selection changed events of the active selection provider.
	 */
	private static class SelectionProviderWrapper implements ISelectionProvider {
		private final ListenerList<ISelectionChangedListener> fListenerList = new ListenerList<>(ListenerList.IDENTITY);
		private final ISelectionChangedListener fListener = new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				fireSelectionChanged(event);
			}
		};
		private ISelectionProvider fActiveProvider;

		private SelectionProviderWrapper(ISelectionProvider provider) {
			setActiveProvider(provider);
		}

		private void setActiveProvider(ISelectionProvider provider) {
			if (fActiveProvider == provider || this == provider) {
				return;
			}
			if (fActiveProvider != null) {
				fActiveProvider.removeSelectionChangedListener(fListener);
			}
			if (provider != null) {
				provider.addSelectionChangedListener(fListener);
			}
			fActiveProvider = provider;
			fireSelectionChanged(new SelectionChangedEvent(this, getSelection()));
		}

		private void dispose() {
			fListenerList.clear();
			setActiveProvider(null);
		}

		private void fireSelectionChanged(SelectionChangedEvent event) {
			for (ISelectionChangedListener iSelectionChangedListener : fListenerList) {
				iSelectionChangedListener.selectionChanged(event);
			}
		}

		@Override
		public void addSelectionChangedListener(ISelectionChangedListener listener) {
			fListenerList.add(listener);
		}

		@Override
		public ISelection getSelection() {
			if (fActiveProvider != null) {
				return fActiveProvider.getSelection();
			}
			return StructuredSelection.EMPTY;
		}

		@Override
		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
			fListenerList.remove(listener);
		}

		@Override
		public void setSelection(ISelection selection) {
			if (fActiveProvider != null) {
				fActiveProvider.setSelection(selection);
			}
		}
	}

	/**
	 * The model presentation used as the label provider for the tree viewer,
	 * and also as the detail information provider for the detail pane.
	 */
	protected VariablesViewModelPresentation fModelPresentation;

	/**
	 * The UI construct that provides a sliding sash between the variables tree
	 * and the detail pane.
	 */
	private SashForm fSashForm;

	/**
	 * Composite that holds the details pane and always remains
	 */
	private Composite fDetailsAnchor;

	/**
	 * Composite that holds the separator container and detail pane control.
	 * Gets disposed/created as the layout changes.
	 */
	private Composite fDetailsComposite;

	/**
	 * Separator used when detail pane background colors of tree/detail pane are different.
	 */
	private Label fSeparator;

	/**
	 * Parent of the viewer, used to detect re-sizing for automatic layout
	 */
	private Composite fParent;

	/**
	 * Whether the detail pane has been built yet.
	 */
	private boolean fPaneBuilt = false;

	/**
	 * The detail pane that displays detailed information about the current selection
	 * @since 3.3
	 */
	private DetailPaneProxy fDetailPane;

	/**
	 * Stores whether the tree viewer was the last control to have focus in the
	 * view. Used to give focus to the correct component if the user leaves the view.
	 * @since 3.3
	 */
	private boolean fTreeHasFocus = true;

	/**
	 * Various listeners used to update the enabled state of actions and also to
	 * populate the detail pane.
	 */
	private ISelectionChangedListener fTreeSelectionChangedListener;

	/**
	 * Listener added to the control of the detail pane, allows view to keep track of which
	 * part last had focus, the tree or the detail pane.
	 */
	private Listener fDetailPaneActivatedListener;

	/**
	 * Viewer input service used to translate active debug context to viewer input.
	 */
	private ViewerInputService fInputService;

	private Map<String, IAction> fGlobalActionMap = new HashMap<>();

	/**
	 * Viewer input requester used to update the viewer once the viewer input has been
	 * resolved.
	 */
	private IViewerInputRequestor fRequester = new IViewerInputRequestor() {
		@Override
		public void viewerInputComplete(IViewerInputUpdate update) {
			if (!update.isCanceled()) {
			    viewerInputUpdateComplete(update);
			}
		}
	};

	/**
	 * These are used to initialize and persist the position of the sash that
	 * separates the tree viewer from the detail pane.
	 */
	private static final int[] DEFAULT_SASH_WEIGHTS = {13, 6};
	private int[] fLastSashWeights;
	private boolean fToggledDetailOnce;
	private String fCurrentDetailPaneOrientation = IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_HIDDEN;
	private ToggleDetailPaneAction[] fToggleDetailPaneActions;
	private ConfigureColumnsAction fConfigureColumnsAction;

    protected String PREF_STATE_MEMENTO = "pref_state_memento."; //$NON-NLS-1$

	public static final String LOGICAL_STRUCTURE_TYPE_PREFIX = "VAR_LS_"; //$NON-NLS-1$

	/**
	 * Presentation context property.
	 * @since 3.3
	 */
	public static final String PRESENTATION_SHOW_LOGICAL_STRUCTURES = "PRESENTATION_SHOW_LOGICAL_STRUCTURES"; //$NON-NLS-1$

	/**
	 * the preference name for the view part of the sash form
	 * @since 3.2
	 */
	protected static final String SASH_VIEW_PART = DebugUIPlugin.getUniqueIdentifier() + ".SASH_VIEW_PART"; //$NON-NLS-1$
	/**
	 * the preference name for the details part of the sash form
	 * @since 3.2
	 */
	protected static final String SASH_DETAILS_PART = DebugUIPlugin.getUniqueIdentifier() + ".SASH_DETAILS_PART"; //$NON-NLS-1$

	/**
	 * Sash weights for a specific detail pane type
	 */
	protected static final String DETAIL_PANE_TYPE = "DETAIL_PANE_TYPE"; //$NON-NLS-1$

    /**
     * Visits deltas to determine if details should be displayed
     */
    class Visitor implements IModelDeltaVisitor {
        /**
         * Whether to trigger details display.
         *
         * @since 3.3
         */
        private boolean fTriggerDetails = false;
		@Override
		public boolean visit(IModelDelta delta, int depth) {
			if ((delta.getFlags() & IModelDelta.CONTENT) > 0) {
				fTriggerDetails = true;
				return false;
			}
			return true;
		}

		public void reset() {
			fTriggerDetails = false;
		}

		public boolean isTriggerDetails() {
			return fTriggerDetails;
		}

    }
    /**
     * Delta visitor
     */
    private Visitor fVisitor = new Visitor();

    /**
     * Job to update details in the UI thread.
     */
    private Job fTriggerDetailsJob = new UIJob("trigger details") { //$NON-NLS-1$

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			if (monitor.isCanceled()) {
				return Status.CANCEL_STATUS;
			}
			refreshDetailPaneContents();
			return Status.OK_STATUS;
		}
	};

	/**
	 * Selection provider registered with the view site.
	 */
	private SelectionProviderWrapper fSelectionProvider;

	/**
	 * Presentation context for this view.
	 */
	private IPresentationContext fPresentationContext;

	/**
	 * Remove myself as a selection listener
	 * and preference change listener.
	 *
	 * @see IWorkbenchPart#dispose()
	 */
	@Override
	public void dispose() {

        DebugUITools.removePartDebugContextListener(getSite(), this);
		getSite().getWorkbenchWindow().removePerspectiveListener(this);
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		JFaceResources.getFontRegistry().removeListener(this);
		TreeModelViewer viewer = getVariablesViewer();
		if (viewer != null) {
			viewer.removeModelChangedListener(this);
			viewer.removeViewerUpdateListener(this);
		}
		if (fPresentationContext != null) {
		    fPresentationContext.dispose();
		    fPresentationContext = null;
		}
		if (fDetailPane != null) {
			fDetailPane.dispose();
		}
        fInputService.dispose();
        fSelectionProvider.dispose();
		super.dispose();
	}

	/**
	 * Called when the viewer input update is completed.  Unlike
	 * {@link #setViewerInput(Object)}, it allows overriding classes
	 * to examine the context for which the update was calculated.
	 *
	 * @param update Completed viewer input update.
	 */
	protected void viewerInputUpdateComplete(IViewerInputUpdate update) {
	    setViewerInput(update.getInputElement());
        updateAction(FIND_ACTION);
	}

	/**
	 * Sets the input to the viewer
	 * @param context the object context
	 */
	protected void setViewerInput(Object context) {
        if (context == null) {
            // Clear the detail pane
        	refreshDetailPaneContents();
        }

        Object current = getViewer().getInput();

        if (current == null && context == null) {
            return;
        }

        if (current != null && current.equals(context)) {
            return;
        }

        showViewer();
        getViewer().setInput(context);
        updateObjects();
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		String propertyName= event.getProperty();
		if (propertyName.equals(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR) ||
				propertyName.equals(IDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND) ||
				propertyName.equals(IDebugUIConstants.PREF_VARIABLE_TEXT_FONT)) {
			getViewer().refresh();
		}
	}

	@Override
	public Viewer createViewer(Composite parent) {
		addResizeListener(parent);
		fParent = parent;
		fTriggerDetailsJob.setSystem(true);

		// create the sash form that will contain the tree viewer & text viewer
		fSashForm = new SashForm(parent, SWT.NONE);

		getModelPresentation();
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		JFaceResources.getFontRegistry().addListener(this);

		TreeModelViewer variablesViewer = createTreeViewer(fSashForm);
		fInputService = new ViewerInputService(variablesViewer, fRequester);

		fSashForm.setMaximizedControl(variablesViewer.getControl());
		fDetailsAnchor = SWTFactory.createComposite(fSashForm, parent.getFont(), 1, 1, GridData.FILL_BOTH, 0, 0);
		fSashForm.setWeights(getLastSashWeights());

		fSelectionProvider = new SelectionProviderWrapper(variablesViewer);
		getSite().setSelectionProvider(fSelectionProvider);

		createOrientationActions(variablesViewer);
		IPreferenceStore prefStore = DebugUIPlugin.getDefault().getPreferenceStore();
		String orientation = prefStore.getString(getDetailPanePreferenceKey());
		for (int i = 0; i < fToggleDetailPaneActions.length; i++) {
			fToggleDetailPaneActions[i].setChecked(fToggleDetailPaneActions[i].getOrientation().equals(orientation));
		}

		fDetailPane = new DetailPaneProxy(this);
		fDetailPane.addProperyListener(new IPropertyListener() {
			@Override
			public void propertyChanged(Object source, int propId) {
				firePropertyChange(propId);
			}
		});
		setDetailPaneOrientation(orientation);

		IMemento memento = getMemento();
		if (memento != null) {
			variablesViewer.initState(memento);
		}

		variablesViewer.addModelChangedListener(this);
		variablesViewer.addViewerUpdateListener(this);

        initDragAndDrop(variablesViewer);

		return variablesViewer;
	}

    /**
     * Initializes the drag and/or drop adapters for this view.  Called from createViewer().
     *
     * @param viewer the viewer to add drag/drop support to.
     * @since 3.4
     */
    protected void initDragAndDrop(TreeModelViewer viewer) {
        // Drag only
        viewer.addDragSupport(DND.DROP_COPY, new Transfer[] {LocalSelectionTransfer.getTransfer()}, new SelectionDragAdapter(viewer));
    }

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		PREF_STATE_MEMENTO = PREF_STATE_MEMENTO + site.getId();
        IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
        String string = store.getString(PREF_STATE_MEMENTO);
        if(string.length() > 0) {
			try (ByteArrayInputStream bin = new ByteArrayInputStream(string.getBytes()); InputStreamReader reader = new InputStreamReader(bin);) {
        		XMLMemento stateMemento = XMLMemento.createReadRoot(reader);
        		setMemento(stateMemento);
        	} catch (WorkbenchException e) {
			} catch (IOException e1) {
			}
        }
        IMemento mem = getMemento();
        // check the weights to makes sure they are valid -- bug 154025
        setLastSashWeights(DEFAULT_SASH_WEIGHTS);
		if (mem != null) {
			int[] weights = getWeights(mem);
			if (weights != null) {
				setLastSashWeights(weights);
			}
		}
		site.getWorkbenchWindow().addPerspectiveListener(this);
    }

	/**
	 * Returns sash weights stored in the given memento or <code>null</code> if none.
	 *
	 * @param memento Memento to read sash weights from
	 * @return sash weights or <code>null</code>
	 */
	private int[] getWeights(IMemento memento) {
		Integer sw = memento.getInteger(SASH_VIEW_PART);
		if(sw != null) {
			int view = sw.intValue();
			sw = memento.getInteger(SASH_DETAILS_PART);
			if(sw != null) {
				int details = sw.intValue();
				if(view > -1 & details > -1) {
					return new int[] {view, details};
				}
			}
		}
		return null;
	}

    @Override
	public void partDeactivated(IWorkbenchPart part) {
		String id = part.getSite().getId();
		if (id.equals(getSite().getId())) {
			try (ByteArrayOutputStream bout = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(bout);) {
				XMLMemento memento = XMLMemento.createWriteRoot("VariablesViewMemento"); //$NON-NLS-1$
				saveViewerState(memento);
				memento.save(writer);

				IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
				String xmlString = bout.toString();
				store.putValue(PREF_STATE_MEMENTO, xmlString);
			} catch (IOException e) {
			}
		}
		super.partDeactivated(part);
	}

	/**
	 * Saves the current state of the viewer
	 * @param memento the memento to write the viewer state into
	 */
	public void saveViewerState(IMemento memento) {
		if (fSashForm != null && !fSashForm.isDisposed()) {
	        int[] weights = fSashForm.getWeights();
			memento.putInteger(SASH_VIEW_PART, weights[0]);
			memento.putInteger(SASH_DETAILS_PART, weights[1]);
		}
		getVariablesViewer().saveState(memento);
	}

	/**
	 * @return the pref key for the variables view details pane
	 */
	protected String getDetailPanePreferenceKey() {
		return IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_ORIENTATION;
	}

	/**
	 * Create and return the main tree viewer that displays variable.
	 * @param parent Viewer's parent control
	 * @return The created viewer.
	 */
	protected TreeModelViewer createTreeViewer(Composite parent) {

		int style = getViewerStyle();
		fPresentationContext = new DebugModelPresentationContext(getPresentationContextId(), this, fModelPresentation);
		final TreeModelViewer variablesViewer = new TreeModelViewer(parent, style, fPresentationContext);

		variablesViewer.getControl().addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				fTreeHasFocus = true;
				fSelectionProvider.setActiveProvider(variablesViewer);
				setGlobalActions();
			}

			@Override
			public void focusLost(FocusEvent e){
			    // Do not reset the selection provider with the provider proxy.
			    // This should allow toolbar actions to remain active when the view
			    // is de-activated but still visible.
			    // Bug 316850.
				clearGlobalActions();
				getViewSite().getActionBars().updateActionBars();
			}
		});
		variablesViewer.getPresentationContext().addPropertyChangeListener(
				new IPropertyChangeListener() {
					@Override
					public void propertyChange(PropertyChangeEvent event) {
						if (IPresentationContext.PROPERTY_COLUMNS.equals(event.getProperty())) {
							IAction action = getAction("ShowTypeNames"); //$NON-NLS-1$
							if (action != null) {
								action.setEnabled(event.getNewValue() == null);
							}
						}
					}
				});

		variablesViewer.addPostSelectionChangedListener(getTreeSelectionChangedListener());
		DebugUITools.addPartDebugContextListener(getSite(), this);

		return variablesViewer;
	}

	private void setGlobalActions() {
		for (Entry<String, IAction> entry : fGlobalActionMap.entrySet()) {
			String actionID = entry.getKey();
			IAction action = getOverrideAction(actionID);
			if (action == null) {
				action = entry.getValue();
			}
			setAction(actionID, action);
		}
		getViewSite().getActionBars().updateActionBars();
	}

	/**
	 * Save the global actions from action bar so they are not overridden by the
	 * detail pane.
	 */
	@Override
	protected void createContextMenu(Control menuControl) {
		super.createContextMenu(menuControl);
		IActionBars actionBars = getViewSite().getActionBars();
		if (!fGlobalActionMap.containsKey(SELECT_ALL_ACTION)) {
			setGlobalAction(IDebugView.SELECT_ALL_ACTION, actionBars.getGlobalActionHandler(SELECT_ALL_ACTION));
		}
		if (!fGlobalActionMap.containsKey(COPY_ACTION)) {
			setGlobalAction(COPY_ACTION, actionBars.getGlobalActionHandler(COPY_ACTION));
		}
		if (!fGlobalActionMap.containsKey(PASTE_ACTION)) {
			setGlobalAction(PASTE_ACTION, actionBars.getGlobalActionHandler(PASTE_ACTION));
		}
	}

	private void clearGlobalActions() {
		for (String id : fGlobalActionMap.keySet()) {
			setAction(id, null);
		}
		getViewSite().getActionBars().updateActionBars();
	}

	/**
	 * Returns the active debug context for this view based on the view's
	 * site IDs.
	 *
	 * @return Active debug context for this view.
	 *
	 * @since 3.7
	 */
	protected ISelection getDebugContext() {
	    IViewSite site = (IViewSite)getSite();
		IDebugContextService contextService = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow());
		return contextService.getActiveContext(site.getId(), site.getSecondaryId());
	}

	/**
	 * Returns the presentation context id for this view.
	 *
	 * @return context id
	 */
	protected String getPresentationContextId() {
		return IDebugUIConstants.ID_VARIABLE_VIEW;
	}

	/**
	 * Returns the presentation context secondary id for this view.
	 *
	 * @return context secondary id.
	 */
	protected String getPresentationContextSecondaryId() {
		return ((IViewSite)getSite()).getSecondaryId();
	}

	/**
	 * Returns the style bits for the viewer.
	 *
	 * @return SWT style
	 */
	protected int getViewerStyle() {
		return SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL | SWT.FULL_SELECTION;
	}

	@Override
	protected String getHelpContextId() {
		return IDebugHelpContextIds.VARIABLE_VIEW;
	}

	private void addResizeListener(Composite parent) {
		parent.addControlListener(new ControlListener() {
			@Override
			public void controlMoved(ControlEvent e) {
			}
			@Override
			public void controlResized(ControlEvent e) {
				if (IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_AUTO.equals(fCurrentDetailPaneOrientation)) {
					setDetailPaneOrientation(IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_AUTO);
				}
			}
		});
	}

	/**
	 * Returns vertical or horizontal based on view size.
	 *
	 * @return vertical or horizontal
	 */
	int computeOrientation() {
		Point size= fParent.getSize();
		if (size.x != 0 && size.y != 0) {
			if ((size.x / 3)> size.y) {
				return SWT.HORIZONTAL;
			} else {
				return SWT.VERTICAL;
			}
		}
		return SWT.HORIZONTAL;
	}

	/**
	 * Set the orientation of the details pane so that is one of:
	 * - underneath the main tree view
	 * - to the right of the main tree view
	 * - not visible
	 * @param orientation Detail pane orientation to set.
	 *
	 * @see IDebugPreferenceConstants#VARIABLES_DETAIL_PANE_AUTO
	 * @see IDebugPreferenceConstants#VARIABLES_DETAIL_PANE_HIDDEN
	 * @see IDebugPreferenceConstants#VARIABLES_DETAIL_PANE_UNDERNEATH
	 */
	public void setDetailPaneOrientation(String orientation) {
		if (!IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_AUTO.equals(orientation) && orientation.equals(fCurrentDetailPaneOrientation)) {
			return;
		}
		fCurrentDetailPaneOrientation  = orientation;
		DebugUIPlugin.getDefault().getPreferenceStore().setValue(getDetailPanePreferenceKey(), orientation);
		if (orientation.equals(IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_HIDDEN)) {
			hideDetailPane();
		} else {
			int vertOrHoriz = -1;
			if (orientation.equals(IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_AUTO)) {
				vertOrHoriz = computeOrientation();
				if (fPaneBuilt && fSashForm.getOrientation() == vertOrHoriz) {
					showDetailPane();
					return;
				}
			} else {
				vertOrHoriz = orientation.equals(IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_UNDERNEATH) ? SWT.VERTICAL : SWT.HORIZONTAL;

			}
			buildDetailPane(vertOrHoriz);
			revealTreeSelection();
		}
	}

	private void buildDetailPane(int orientation) {
		try {
			fDetailsAnchor.setRedraw(false);
			if (fDetailsComposite != null) {
				fDetailPane.dispose();
				fDetailsComposite.dispose();
			}
			fSashForm.setOrientation(orientation);
			if (orientation == SWT.VERTICAL) {
				fDetailsComposite = SWTFactory.createComposite(fDetailsAnchor, fDetailsAnchor.getFont(), 1, 1, GridData.FILL_BOTH, 0, 0);
				GridLayout layout = (GridLayout) fDetailsComposite.getLayout();
				layout.verticalSpacing = 0;
				fSeparator = new Label(fDetailsComposite, SWT.SEPARATOR| SWT.HORIZONTAL);
				fSeparator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
			} else {
				fDetailsComposite = SWTFactory.createComposite(fDetailsAnchor, fDetailsAnchor.getFont(), 2, 1, GridData.FILL_BOTH, 0, 0);
				GridLayout layout = (GridLayout) fDetailsComposite.getLayout();
				layout.horizontalSpacing = 0;
				fSeparator= new Label(fDetailsComposite, SWT.SEPARATOR | SWT.VERTICAL);
				fSeparator.setLayoutData(new GridData(SWT.TOP, SWT.FILL, false, true));
			}
			// force update so detail pane can adapt to orientation change
			showDetailPane();
		} finally {
			fDetailsAnchor.layout(true);
			fDetailsAnchor.setRedraw(true);
			fPaneBuilt = true;
		}
	}

	/**
	 * Hides the details pane
	 */
	private void hideDetailPane() {
		if (fToggledDetailOnce) {
			setLastSashWeights(fSashForm.getWeights());
		}
		fSashForm.setMaximizedControl(getViewer().getControl());
	}

	/**
	 * Shows the details pane
	 */
	private void showDetailPane() {
		fSashForm.setMaximizedControl(null);
		fSashForm.setWeights(getLastSashWeights());
		refreshDetailPaneContents();
		fToggledDetailOnce = true;
	}

	/**
	 * Make sure the currently selected item in the tree is visible.
	 */
	protected void revealTreeSelection() {
		StructuredViewer viewer = (StructuredViewer) getViewer();
		if (viewer != null) {
			ISelection selection = viewer.getSelection();
			if (selection instanceof IStructuredSelection) {
				Object selected = ((IStructuredSelection)selection).getFirstElement();
				if (selected != null) {
					viewer.reveal(selected);
				}
			}
		}
	}

	/**
	 * Return the relative weights that were in effect the last time both panes were
	 * visible in the sash form, or the default weights if:
	 * <ul>
	 * <li> both panes have not yet been made visible</li>
	 * <li> one of the values persisted before is an invalid value</li>
	 * </ul>
	 * @return The last sash weights.
	 */
	protected int[] getLastSashWeights() {
		if (fLastSashWeights == null) {
			fLastSashWeights = DEFAULT_SASH_WEIGHTS;
		}
		//check the weights to makes sure they are valid -- bug 154025
		else if(fLastSashWeights[0] < 0 || fLastSashWeights[1] < 0) {
			fLastSashWeights = DEFAULT_SASH_WEIGHTS;
		}
		return fLastSashWeights;
	}

	/**
	 * Set the current relative weights of the controls in the sash form, so that
	 * the sash form can be reset to this layout at a later time.
	 * @param weights Weight to add.
	 */
	protected void setLastSashWeights(int[] weights) {
		fLastSashWeights = weights;
	}

	@Override
	protected void createActions() {
		IAction action = new ShowTypesAction(this);
		setAction("ShowTypeNames",action); //$NON-NLS-1$

		action = new ToggleLogicalStructureAction(this);
		setAction("ToggleContentProviders", action); //$NON-NLS-1$

		action = new CollapseAllAction((TreeModelViewer)getViewer());
		setAction(COLLAPSE_ALL, action);
		IHandlerService hs = getSite().getService(IHandlerService.class);
		if (hs != null) {
			hs.activateHandler(CollapseAllHandler.COMMAND_ID, new ActionHandler(action));
		}

		action = new ChangeVariableValueAction(this);
		action.setEnabled(false);
		setAction("ChangeVariableValue", action); //$NON-NLS-1$

		action= new VirtualFindAction(getVariablesViewer());
		setGlobalAction(FIND_ACTION, action);
	}

	/**
	 * Adds the given action to the set of global actions managed by this
	 * variables view.  Global actions are cleared and reset whenever the detail
	 * pane is activated to allow the detail pane to set the actions as
	 * well.
	 *
	 * @param actionID Action ID that the given action implements.
	 * @param action Action implementation.
	 *
	 * @since 3.8
	 */
	protected void setGlobalAction(String actionID, IAction action) {
		fGlobalActionMap.put(actionID, action);
	}

	@Override
	public IAction getAction(String actionID) {
		// Check if model overrides the action. Global action overrides are
		// checked in setGlobalActions() so skip them here.
		if (!fGlobalActionMap.containsKey(actionID)) {
			IAction overrideAction = getOverrideAction(actionID);
			if (overrideAction != null) {
				return overrideAction;
			}
		}
		return super.getAction(actionID);
	}

	private IAction getOverrideAction(String actionID) {
		Viewer viewer = getViewer();
		if (viewer != null) {
			IViewActionProvider actionProvider = (IViewActionProvider) DebugPlugin.getAdapter(
					viewer.getInput(), IViewActionProvider.class);
			if (actionProvider != null) {
				IAction action = actionProvider.getAction(getPresentationContext(), actionID);
				if (action != null) {
					return action;
				}
			}
		}
		return null;
	}

	@Override
	public void updateObjects() {
		super.updateObjects();
		if (fTreeHasFocus) {
			setGlobalActions();
		}
	}

	/**
	 * Creates the actions that allow the orientation of the detail pane to be changed.
	 *
	 * @param viewer Viewer to create actions for.
	 */
	private void createOrientationActions(TreeModelViewer viewer) {
		IActionBars actionBars = getViewSite().getActionBars();
		IMenuManager viewMenu = actionBars.getMenuManager();

		fToggleDetailPaneActions = new ToggleDetailPaneAction[4];
		fToggleDetailPaneActions[0] = new ToggleDetailPaneAction(this, IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_UNDERNEATH, null);
		fToggleDetailPaneActions[1] = new ToggleDetailPaneAction(this, IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_RIGHT, null);
		fToggleDetailPaneActions[2] = new ToggleDetailPaneAction(this, IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_AUTO, null);
		fToggleDetailPaneActions[3] = new ToggleDetailPaneAction(this, IDebugPreferenceConstants.VARIABLES_DETAIL_PANE_HIDDEN, getToggleActionLabel());
		viewMenu.add(new Separator());
		final MenuManager layoutSubMenu = new MenuManager(VariablesViewMessages.VariablesView_40);
		layoutSubMenu.setRemoveAllWhenShown(true);
		layoutSubMenu.add(fToggleDetailPaneActions[0]);
		layoutSubMenu.add(fToggleDetailPaneActions[1]);
		layoutSubMenu.add(fToggleDetailPaneActions[2]);
		layoutSubMenu.add(fToggleDetailPaneActions[3]);
		viewMenu.add(layoutSubMenu);
		viewMenu.add(new Separator());

		fConfigureColumnsAction = new ConfigureColumnsAction(viewer);
		setAction("ToggleColmns", new ToggleShowColumnsAction(viewer)); //$NON-NLS-1$

		layoutSubMenu.addMenuListener(new IMenuListener() {
			@Override
			public void menuAboutToShow(IMenuManager manager) {
				layoutSubMenu.add(fToggleDetailPaneActions[0]);
				layoutSubMenu.add(fToggleDetailPaneActions[1]);
				layoutSubMenu.add(fToggleDetailPaneActions[2]);
				layoutSubMenu.add(fToggleDetailPaneActions[3]);
				layoutSubMenu.add(new Separator());
				IAction action = getAction("ToggleColmns"); //$NON-NLS-1$
				((IUpdate)action).update();
				if (action.isEnabled()) {
					layoutSubMenu.add(action);
				}
				fConfigureColumnsAction.update();
				if (fConfigureColumnsAction.isEnabled()) {
					layoutSubMenu.add(fConfigureColumnsAction);
				}
			}
		});
	}

	/**
	 * Returns the label to use for the action that toggles the view layout to be the tree viewer only (detail pane is hidden).
	 * Should be of the style '[view name] View Only'.
	 *
	 * @return action label for toggling the view layout to tree viewer only
	 */
	protected String getToggleActionLabel(){
		return VariablesViewMessages.VariablesView_41;
	}

	/**
	 * Configures the toolBar.
	 *
	 * @param tbm The toolbar that will be configured
	 */
	@Override
	protected void configureToolBar(IToolBarManager tbm) {
		tbm.add(new Separator(this.getClass().getName()));
		tbm.add(new Separator(IDebugUIConstants.RENDER_GROUP));
		tbm.add(getAction("ShowTypeNames")); //$NON-NLS-1$
		tbm.add(getAction("ToggleContentProviders")); //$NON-NLS-1$
		tbm.add(getAction(COLLAPSE_ALL));
	}

   /**
	* Adds items to the tree viewer's context menu including any extension defined
	* actions.
	*
	* @param menu The menu to add the item to.
	*/
	@Override
	protected void fillContextMenu(IMenuManager menu) {
		menu.add(new Separator(IDebugUIConstants.EMPTY_VARIABLE_GROUP));
		menu.add(new Separator(IDebugUIConstants.VARIABLE_GROUP));
		menu.add(getAction(FIND_ACTION));
		ChangeVariableValueAction changeValueAction = (ChangeVariableValueAction)getAction("ChangeVariableValue"); //$NON-NLS-1$
		if (changeValueAction.isApplicable()) {
		    menu.add(changeValueAction);
		}
		menu.add(new Separator());
		IAction action = new AvailableLogicalStructuresAction(this);
		if (action.isEnabled()) {
			menu.add(action);
		}
		action = new AvailableDetailPanesAction(this);
		if (isDetailPaneVisible() && action.isEnabled()) {
			menu.add(action);
		}
		menu.add(new Separator(IDebugUIConstants.EMPTY_RENDER_GROUP));
		menu.add(new Separator(IDebugUIConstants.EMPTY_NAVIGATION_GROUP));
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

   /**
	 * Lazily instantiate and return a selection listener that populates the detail pane,
	 * but only if the detail is currently visible.
	 *
	 * @return Created selection listener
	 */
    protected ISelectionChangedListener getTreeSelectionChangedListener() {
        if (fTreeSelectionChangedListener == null) {
            fTreeSelectionChangedListener = new ISelectionChangedListener() {
                @Override
				public void selectionChanged(final SelectionChangedEvent event) {
                    if (event.getSelectionProvider().equals(getViewer())) {
                        clearStatusLine();
                        // if the detail pane is not visible, don't waste time retrieving details
                        if (fSashForm.getMaximizedControl() == getViewer().getControl()) {
                            return;
                        }
                        refreshDetailPaneContents();
                        treeSelectionChanged(event);
                    }
                }
            };
        }
        return fTreeSelectionChangedListener;
    }

	/**
	 * Selection in the variable tree changed. Perform any updates.
	 *
	 * @param event
	 */
	protected void treeSelectionChanged(SelectionChangedEvent event) {}

	@Override
	public String getCurrentPaneID() {
		return fDetailPane.getCurrentPaneID();
	}

	@Override
	public IStructuredSelection getCurrentSelection() {
		if (getViewer() != null){
			return (IStructuredSelection)getViewer().getSelection();
		}
		return null;
	}

	@Override
	public Composite getParentComposite() {
		return fDetailsComposite;
	}

	@Override
	public IWorkbenchPartSite getWorkbenchPartSite() {
		return getSite();
	}

	@Override
	public void refreshDetailPaneContents() {
		if (isDetailPaneVisible()) {
			String currentPaneID = getCurrentPaneID();
			if (currentPaneID != null && !fSashForm.isDisposed()) {
				fLastSashWeights = fSashForm.getWeights();
			}
			fDetailPane.display(getCurrentSelection());

			// Use a grey (widget background) sash for the detail pane normally
			// If the detail pane is also grey, add a seperator line
			Control control = fDetailPane.getCurrentControl();
			if (control.getBackground().equals(fSashForm.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND))) {
				fSashForm.setBackground(fSashForm.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
				fSeparator.setVisible(true);
				fSeparator.setBackground(control.getBackground());
			} else {
				fSashForm.setBackground(fSashForm.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
				fSeparator.setVisible(false);
			}
		}
	}

	@Override
	public void paneChanged(String newPaneID) {
		if (fDetailPaneActivatedListener == null){
			fDetailPaneActivatedListener = 	new Listener() {
				@Override
				public void handleEvent(Event event) {
					fTreeHasFocus = false;
				}
			};
		}
		fDetailPane.getCurrentControl().addListener(SWT.Activate, fDetailPaneActivatedListener);
	}

	/**
	 * @return the model presentation to be used for this view
	 */
	protected IDebugModelPresentation getModelPresentation() {
		if (fModelPresentation == null) {
			fModelPresentation = new VariablesViewModelPresentation();
		}
		return fModelPresentation;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> required) {
		if (IDebugModelPresentation.class.equals(required)) {
			return (T) getModelPresentation();
		}
		else if (fDetailPane != null){
			Object adapter = fDetailPane.getAdapter(required);
			if (adapter != null) {
				return (T) adapter;
			}
		}
		return super.getAdapter(required);
	}

	/**
	 * If possible, calls the update method of the action associated with the given ID.
	 *
	 * @param actionId the ID of the action to update
	 */
	protected void updateAction(String actionId) {
		IAction action= getAction(actionId);
		if (action == null) {
			action = fGlobalActionMap.get(actionId);
		}
		if (action instanceof IUpdate) {
			((IUpdate) action).update();
		}
	}

	/**
	 * @return whether the detail pane is visible to the user
	 */
	protected boolean isDetailPaneVisible() {
		return !fToggleDetailPaneActions[3].isChecked();
	}

	@Override
	protected Control getDefaultControl() {
		return fSashForm;
	}

	@Override
	public void handleException(DebugException e) {
		showMessage(e.getMessage());
	}

	@Override
	public void debugContextChanged(DebugContextEvent event) {
		if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
			contextActivated(event.getContext());
		}
	}

	/**
	 * Updates actions and sets the viewer input when a context is activated.
	 * @param selection New selection to activate.
	 */
	protected void contextActivated(ISelection selection) {
		if (!isAvailable() || !isVisible()) {
			return;
		}
		if (selection instanceof IStructuredSelection) {
			Object source = ((IStructuredSelection)selection).getFirstElement();
			fInputService.resolveViewerInput(source);
		}
	}

	/**
	 * Delegate to the <code>DOUBLE_CLICK_ACTION</code>, if any.
	 */
	@Override
	public void doubleClick(DoubleClickEvent event) {
		IAction action = getAction(DOUBLE_CLICK_ACTION);
		if (action != null && action.isEnabled()) {
			action.run();
		} else {
			ISelection selection = getVariablesViewer().getSelection();
			if (selection instanceof TreeSelection) {
				TreeSelection ss = (TreeSelection) selection;
				if (ss.size() == 1) {
					Widget item = getVariablesViewer().findItem(ss.getPaths()[0]);
					if (item instanceof TreeItem) {
						TreeItem ti = (TreeItem) item;
						if (ti.getExpanded()) {
							ti.setExpanded(false);
						} else {
							// need to trigger proper children updates when expanding
							getVariablesViewer().expandToLevel(ss.getPaths()[0], 1);
						}
					}

				}
			}
		}
	}

	@Override
	public IDebugModelPresentation getPresentation(String id) {
		if (getViewer() instanceof StructuredViewer) {
			IDebugModelPresentation lp = getModelPresentation();
			if (lp instanceof DelegatingModelPresentation) {
				return ((DelegatingModelPresentation)lp).getPresentation(id);
			}
			if (lp instanceof LazyModelPresentation) {
				if (((LazyModelPresentation)lp).getDebugModelIdentifier().equals(id)) {
					return lp;
				}
			}
		}
		return null;
	}

	public boolean isMainViewerAvailable() {
		return isAvailable();
	}

	/**
	 * @return the presentation context of the viewer
	 */
	protected IPresentationContext getPresentationContext() {
		return getVariablesViewer().getPresentationContext();
	}

	/**
	 * Sets whether logical structures are being displayed
	 * @param flag If true, turns the logical structures on.
	 */
	public void setShowLogicalStructure(boolean flag) {
	    getPresentationContext().setProperty(PRESENTATION_SHOW_LOGICAL_STRUCTURES, Boolean.valueOf(flag));
	}

	/**
	 * Returns whether logical structures are being displayed
	 * @return Returns true if logical structures should be shown.
	 */
	public boolean isShowLogicalStructure() {
		Boolean show = (Boolean) getPresentationContext().getProperty(PRESENTATION_SHOW_LOGICAL_STRUCTURES);
		return show != null && show.booleanValue();
	}

	@Override
	protected void becomesHidden() {
        fInputService.resolveViewerInput(ViewerInputService.NULL_INPUT);
		super.becomesHidden();
	}

	@Override
	protected void becomesVisible() {
		super.becomesVisible();
		ISelection selection = getDebugContext();
		contextActivated(selection);
	}

	/**
	 * @return the tree model viewer displaying variables
	 */
	protected TreeModelViewer getVariablesViewer() {
		return (TreeModelViewer) getViewer();
	}

	/**
	 * Clears the status line of all messages and errors
	 */
	protected void clearStatusLine() {
		IStatusLineManager manager = getViewSite().getActionBars().getStatusLineManager();
		manager.setErrorMessage(null);
		manager.setMessage(null);
	}

	@Override
	public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {}

	@Override
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
		if(changeId.equals(IWorkbenchPage.CHANGE_RESET)) {
			setLastSashWeights(DEFAULT_SASH_WEIGHTS);
			fSashForm.setWeights(DEFAULT_SASH_WEIGHTS);
			fSashForm.layout(true);
		}
	}

	@Override
	public void modelChanged(IModelDelta delta, IModelProxy proxy) {
		fVisitor.reset();
		delta.accept(fVisitor);

		updateAction(FIND_ACTION);
        updateAction(COLLAPSE_ALL);
	}

	@Override
	public void updateComplete(IViewerUpdate update) {
		IStatus status = update.getStatus();
		if (!update.isCanceled()) {
			if (status != null && !status.isOK()) {
				showMessage(status.getMessage());
			} else {
				showViewer();
			}
			if (TreePath.EMPTY.equals(update.getElementPath())) {
			    updateAction(FIND_ACTION);
			    updateAction(COLLAPSE_ALL);
			}
		}
	}

	@Override
	public void updateStarted(IViewerUpdate update) {
	}

	@Override
	public synchronized void viewerUpdatesBegin() {
		fTriggerDetailsJob.cancel();
        IWorkbenchSiteProgressService progressService =
            getSite().getAdapter(IWorkbenchSiteProgressService.class);
        if (progressService != null) {
            progressService.incrementBusy();
        }
	}

	@Override
	public synchronized void viewerUpdatesComplete() {
		if (fVisitor.isTriggerDetails()) {
			fTriggerDetailsJob.schedule();
		}
        IWorkbenchSiteProgressService progressService =
            getSite().getAdapter(IWorkbenchSiteProgressService.class);
        if (progressService != null) {
            progressService.decrementBusy();
        }
	}

	@Override
	public void setFocus() {
		boolean success = false;
		if (!fTreeHasFocus && fDetailPane != null){
			success = fDetailPane.setFocus();
		}
		// Unless the detail pane successfully set focus to a control, set focus to the variables tree
		if (!success && getViewer() != null){
			getViewer().getControl().setFocus();
		}
	}

	protected ToggleDetailPaneAction getToggleDetailPaneAction(String orientation)
	{
		for (int i=0; i<fToggleDetailPaneActions.length; i++) {
			if (fToggleDetailPaneActions[i].getOrientation().equals(orientation)) {
				return fToggleDetailPaneActions[i];
			}
		}

		return null;
	}

	@Override
	public void setSelectionProvider(ISelectionProvider provider) {
		// Workaround for legacy detail pane implementations (bug 254442)
		// set selection provider wrapper again in case it got overridden by detail pane
		getSite().setSelectionProvider(fSelectionProvider);
		// change active provider
		fSelectionProvider.setActiveProvider(provider);
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		fDetailPane.doSave(monitor);
	}

	@Override
	public void doSaveAs() {
		fDetailPane.doSaveAs();
	}

	@Override
	public boolean isDirty() {
		return fDetailPane.isDirty();
	}

	@Override
	public boolean isSaveAsAllowed() {
		return fDetailPane.isSaveAsAllowed();
	}

	@Override
	public boolean isSaveOnCloseNeeded() {
		return fDetailPane.isSaveOnCloseNeeded();
	}

	@Override
	public int promptToSaveOnClose() {
		return ISaveablePart2.YES;
	}

	/**
	 * Stores the default value for the generated String that can be used as a
	 * key into a preference store based on the specified action.
	 *
	 * @param action the action to store a default value
	 * @param value the default value for action
	 *
	 */
	void storeDefaultPreference(Action action, Object value) {
		if (value instanceof Boolean) {
			getPreferenceStore().setDefault(generatePreferenceKey(action), (Boolean)value);
		} else if (value instanceof String) {
			getPreferenceStore().setDefault(generatePreferenceKey(action), (String) value);
		}
	}
}
