/*******************************************************************************
 * Copyright (c) 2004, 2009 Tasktop Technologies and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Trace Mew - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.sandbox.ui.views;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlExtension;
import org.eclipse.jface.text.IInformationControlExtension2;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.AbstractContextListener;
import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionContext;
import org.eclipse.mylyn.context.core.IInteractionElement;
import org.eclipse.mylyn.context.core.IInteractionRelation;
import org.eclipse.mylyn.context.ui.ContextUi;
import org.eclipse.mylyn.internal.context.core.AbstractRelationProvider;
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
import org.eclipse.mylyn.internal.context.ui.ContextUiPlugin;
import org.eclipse.mylyn.internal.context.ui.DoiOrderSorter;
import org.eclipse.mylyn.internal.context.ui.views.QuickOutlinePatternAndInterestFilter;
import org.eclipse.mylyn.internal.sandbox.ui.DelegatingContextLabelProvider;
import org.eclipse.mylyn.internal.sandbox.ui.SandboxUiImages;
import org.eclipse.mylyn.internal.sandbox.ui.SandboxUiPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.misc.StringMatcher;

/**
 * Derived from {@link QuickOutlinePopupDialog}
 * 
 * @author Tracy Mew
 */
public class RelatedElementsPopupDialog extends PopupDialog implements IInformationControl,
		IInformationControlExtension, IInformationControlExtension2, DisposeListener {

	public static final String ID = "org.eclipse.mylyn.context.ui.navigator.context.related";

	private TreeViewer viewer;

	private Text fFilterText;

	private StringMatcher fStringMatcher;

	private QuickOutlinePatternAndInterestFilter namePatternFilter;

	private final DelegatingContextLabelProvider labelProvider = new DelegatingContextLabelProvider();

	private final DegreeZeroAction zero = new DegreeZeroAction();

	private final DegreeOneAction one = new DegreeOneAction();

	private final DegreeTwoAction two = new DegreeTwoAction();

	private final DegreeThreeAction three = new DegreeThreeAction();

	private final DegreeFourAction four = new DegreeFourAction();

	private final DegreeFiveAction five = new DegreeFiveAction();

	private int degree = 2;

	public RelatedElementsPopupDialog(Shell parent, int shellStyle) {
		super(parent, shellStyle, true, true, true, true, true, null, "Context Search");
		ContextCore.getContextManager().addListener(REFRESH_UPDATE_LISTENER);
		for (AbstractRelationProvider provider : ContextCorePlugin.getDefault().getRelationProviders()) {
			provider.setEnabled(true);
		}
		create();
	}

	/**
	 * For testing.
	 */
	private boolean syncExecForTesting = true;

	private final AbstractContextListener REFRESH_UPDATE_LISTENER = new AbstractContextListener() {

		@Override
		public void interestChanged(List<IInteractionElement> nodes) {
			refresh(nodes.get(nodes.size() - 1), false);
		}

		@Override
		public void contextActivated(IInteractionContext taskscape) {
			refreshRelatedElements();
			refresh(null, true);
		}

		@Override
		public void contextDeactivated(IInteractionContext taskscape) {
			refresh(null, true);
		}

		@Override
		public void contextCleared(IInteractionContext context) {
			refresh(null, true);
		}

		@Override
		public void landmarkAdded(IInteractionElement node) {
			refresh(null, true);
		}

		@Override
		public void landmarkRemoved(IInteractionElement node) {
			refresh(null, true);
		}

		// TODO move this somewhere?
//		public void relationsChanged(IInteractionElement node) {
//			refresh(node, true);
//		}

		@Override
		public void elementsDeleted(List<IInteractionElement> elements) {
			refresh(null, true);
		}
	};

	@Override
	protected Control createDialogArea(Composite parent) {
		createViewer(parent);
		createUIListenersTreeViewer();
		addDisposeListener(this);

		return viewer.getControl();
	}

	private void createViewer(Composite parent) {
		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);

		viewer.setUseHashlookup(true);

		viewer.setContentProvider(new ContextContentProvider(viewer.getTree(), parent.getShell(), true));

		viewer.setLabelProvider(new DecoratingLabelProvider(labelProvider, PlatformUI.getWorkbench()
				.getDecoratorManager()
				.getLabelDecorator()));

		viewer.setSorter(new DoiOrderSorter());

		try {
			viewer.getControl().setRedraw(false);
			viewer.setInput(getShell());
		} finally {
			refreshRelatedElements();
			viewer.getControl().setRedraw(true);
		}
	}

	private void createUIListenersTreeViewer() {
		final Tree tree = viewer.getTree();
		tree.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				if (e.character == 0x1B) {
					// Dispose on ESC key press
					dispose();
				}
			}

			public void keyReleased(KeyEvent e) {
				// ignore
			}
		});

		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				handleTreeViewerMouseUp(tree, e);
			}
		});

		tree.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				// ignore
			}

			public void widgetDefaultSelected(SelectionEvent e) {
				gotoSelectedElement();
			}
		});
	}

	private void handleTreeViewerMouseUp(final Tree tree, MouseEvent e) {
		if ((tree.getSelectionCount() < 1) || (e.button != 1) || (tree.equals(e.getSource()) == false)) {
			return;
		}
		// Selection is made in the selection changed listener
		Object object = tree.getItem(new Point(e.x, e.y));
		TreeItem selection = tree.getSelection()[0];
		if (selection.equals(object)) {
			gotoSelectedElement();
		}
	}

	private void gotoSelectedElement() {
		Object selectedElement = getSelectedElement();
		if (selectedElement == null) {
			return;
		}
		IInteractionElement node = null;
		if (selectedElement instanceof IInteractionElement) {
			node = (IInteractionElement) selectedElement;
		} else if (!(selectedElement instanceof IInteractionRelation)) {
			AbstractContextStructureBridge bridge = ContextCore.getStructureBridge(selectedElement);
			String handle = bridge.getHandleIdentifier(selectedElement);
			node = ContextCore.getContextManager().getElement(handle);
		}
		if (node != null) {
			ContextUi.getUiBridge(node.getContentType()).open(node);
		}
		dispose();
	}

	private Object getSelectedElement() {
		if (viewer == null) {
			return null;
		}
		return ((IStructuredSelection) viewer.getSelection()).getFirstElement();
	}

	public void addDisposeListener(DisposeListener listener) {
		getShell().addDisposeListener(listener);
	}

	public void addFocusListener(FocusListener listener) {
		getShell().addFocusListener(listener);
	}

	public Point computeSizeHint() {
		// Note that it already has the persisted size if persisting is enabled.
		return getShell().getSize();
	}

	public boolean isFocusControl() {
		if (viewer.getControl().isFocusControl() || fFilterText.isFocusControl()) {
			return true;
		}
		return false;
	}

	public void removeDisposeListener(DisposeListener listener) {
		getShell().removeDisposeListener(listener);
	}

	public void removeFocusListener(FocusListener listener) {
		getShell().removeFocusListener(listener);
	}

	public void setBackgroundColor(Color background) {
		applyBackgroundColor(background, getContents());
	}

	public void setFocus() {
		viewer.refresh();
		viewer.getControl().setFocus();
		fFilterText.setFocus();
		getShell().forceFocus();
	}

	public void setForegroundColor(Color foreground) {
		applyForegroundColor(foreground, getContents());
	}

	public void setInformation(String information) {
		// See IInformationControlExtension2
	}

	public void setLocation(Point location) {
		/*
		 * If the location is persisted, it gets managed by PopupDialog - fine. Otherwise, the location is
		 * computed in Window#getInitialLocation, which will center it in the parent shell / main
		 * monitor, which is wrong for two reasons:
		 * - we want to center over the editor / subject control, not the parent shell
		 * - the center is computed via the initalSize, which may be also wrong since the size may 
		 *   have been updated since via min/max sizing of AbstractInformationControlManager.
		 * In that case, override the location with the one computed by the manager. Note that
		 * the call to constrainShellSize in PopupDialog.open will still ensure that the shell is
		 * entirely visible.
		 */
		if (getPersistLocation() == false || getDialogSettings() == null) {
			getShell().setLocation(location);
		}
	}

	public void setSize(int width, int height) {
		getShell().setSize(width, height);
	}

	public void setSizeConstraints(int maxWidth, int maxHeight) {
		// Ignore
	}

	public void setVisible(boolean visible) {
		if (visible) {
			open();
		} else {
			saveDialogBounds(getShell());
			getShell().setVisible(false);
		}
	}

	public boolean hasContents() {
		if ((viewer == null) || (viewer.getInput() == null)) {
			return false;
		}
		return true;
	}

	public void setInput(Object input) {
		// Input comes from PDESourceInfoProvider.getInformation2()
		// The input should be a model object of some sort
		// Turn it into a structured selection and set the selection in the tree
		if (input != null) {
			viewer.setSelection(new StructuredSelection(input));
		}
	}

	public void widgetDisposed(DisposeEvent e) {
		// Note: We do not reuse the dialog
		viewer = null;
		fFilterText = null;
	}

	@Override
	protected Control createTitleControl(Composite parent) {
		// Applies only to dialog title - not body.  See createDialogArea
		// Create the text widget
		createUIWidgetFilterText(parent);
		// Add listeners to the text widget
		createUIListenersFilterText();
		// Return the text widget
		return fFilterText;
	}

	private void createUIWidgetFilterText(Composite parent) {
		// Create the widget
		fFilterText = new Text(parent, SWT.NONE);
		// Set the font 
		GC gc = new GC(parent);
		gc.setFont(parent.getFont());
		FontMetrics fontMetrics = gc.getFontMetrics();
		gc.dispose();
		// Create the layout
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		data.heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 1);
		data.horizontalAlignment = GridData.FILL;
		data.verticalAlignment = GridData.CENTER;
		fFilterText.setLayoutData(data);
	}

	private void createUIListenersFilterText() {
		fFilterText.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == 0x0D) {
					// Return key was pressed
					gotoSelectedElement();
				} else if (e.keyCode == SWT.ARROW_DOWN) {
					// Down key was pressed
					viewer.getTree().setFocus();
				} else if (e.keyCode == SWT.ARROW_UP) {
					// Up key was pressed
					viewer.getTree().setFocus();
				} else if (e.character == 0x1B) {
					// Escape key was pressed
					dispose();
				}
			}

			public void keyReleased(KeyEvent e) {
				// NO-OP
			}
		});
		// Handle text modify events
		fFilterText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = ((Text) e.widget).getText();
				int length = text.length();
				if (length > 0) {
					// Append a '*' pattern to the end of the text value if it
					// does not have one already
					if (text.charAt(length - 1) != '*') {
						text = text + '*';
					}
					// Prepend a '*' pattern to the beginning of the text value
					// if it does not have one already
					if (text.charAt(0) != '*') {
						text = '*' + text;
					}
				}
				// Set and update the pattern
				setMatcherString(text, true);
			}
		});
	}

	/**
	 * Sets the patterns to filter out for the receiver.
	 * <p>
	 * The following characters have special meaning: ? => any character * => any string
	 * </p>
	 * 
	 * @param pattern
	 *            the pattern
	 * @param update
	 *            <code>true</code> if the viewer should be updated
	 */
	private void setMatcherString(String pattern, boolean update) {
		if (pattern.length() == 0) {
			fStringMatcher = null;
		} else {
			fStringMatcher = new StringMatcher(pattern, true, false);
		}
		// Update the name pattern filter on the tree viewer
		namePatternFilter.setStringMatcher(fStringMatcher);
		// Update the tree viewer according to the pattern
		if (update) {
			stringMatcherUpdated();
		}
	}

	/**
	 * The string matcher has been modified. The default implementation refreshes the view and selects the first matched
	 * element
	 */
	private void stringMatcherUpdated() {
		// Refresh the tree viewer to re-filter
		viewer.getControl().setRedraw(false);
		viewer.refresh();
		viewer.expandAll();
		selectFirstMatch();
		viewer.getControl().setRedraw(true);
	}

	/**
	 * Selects the first element in the tree which matches the current filter pattern.
	 */
	private void selectFirstMatch() {
		Tree tree = viewer.getTree();
		Object element = findFirstMatchToPattern(tree.getItems());
		if (element != null) {
			viewer.setSelection(new StructuredSelection(element), true);
		} else {
			viewer.setSelection(StructuredSelection.EMPTY);
		}
	}

	/**
	 * @param items
	 * @return
	 */
	private Object findFirstMatchToPattern(TreeItem[] items) {
		// Match the string pattern against labels
		ILabelProvider labelProvider = (ILabelProvider) viewer.getLabelProvider();
		// Process each item in the tree
		for (TreeItem item : items) {
			Object element = item.getData();
			// Return the first element if no pattern is set
			if (fStringMatcher == null) {
				return element;
			}
			// Return the element if it matches the pattern
			if (element != null) {
				String label = labelProvider.getText(element);
				if (fStringMatcher.match(label)) {
					return element;
				}
			}
			// Recursively check the elements children for a match
			element = findFirstMatchToPattern(item.getItems());
			// Return the child element match if found
			if (element != null) {
				return element;
			}
		}
		// No match found
		return null;
	}

	/**
	 * fix for bug 109235
	 * 
	 * @param node
	 * @param updateLabels
	 */
	void refresh(final IInteractionElement node, final boolean updateLabels) {
		if (!syncExecForTesting) { // for testing
			// if (viewer != null && !viewer.getTree().isDisposed()) {
			// internalRefresh(node, updateLabels);
			// }
			PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
				public void run() {
					try {
						internalRefresh(node, updateLabels);
					} catch (Throwable t) {
						StatusHandler.log(new Status(IStatus.WARNING, SandboxUiPlugin.ID_PLUGIN,
								"Context search refresh failed", t));
					}
				}
			});
		} else {
			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
				public void run() {
					try {
						internalRefresh(node, updateLabels);
					} catch (Throwable t) {
						StatusHandler.log(new Status(IStatus.WARNING, SandboxUiPlugin.ID_PLUGIN,
								"Context search refresh failed", t));
					}
				}
			});
		}

	}

	private void internalRefresh(final IInteractionElement node, boolean updateLabels) {
		Object toRefresh = null;
		if (node != null) {
			AbstractContextStructureBridge bridge = ContextCore.getStructureBridge(node.getContentType());
			toRefresh = bridge.getObjectForHandle(node.getHandleIdentifier());
		}
		if (viewer != null && !viewer.getTree().isDisposed()) {
			viewer.getControl().setRedraw(false);
			if (toRefresh != null && containsNode(viewer.getTree(), toRefresh)) {
				viewer.refresh(toRefresh, updateLabels);
			} else if (node == null) {
				viewer.refresh();
			}
			viewer.expandAll();
			viewer.getControl().setRedraw(true);
		}
	}

	private boolean containsNode(Tree tree, Object object) {
		boolean contains = false;
		for (int i = 0; i < tree.getItems().length; i++) {
			TreeItem item = tree.getItems()[i];
			if (object.equals(item.getData())) {
				contains = true;
			}
		}
		return contains;
	}

	public void refreshRelatedElements() {
		try {
			for (AbstractRelationProvider provider : ContextCorePlugin.getDefault().getRelationProviders()) {
				List<AbstractRelationProvider> providerList = new ArrayList<AbstractRelationProvider>();
				providerList.add(provider);
				updateDegreesOfSeparation(providerList, provider.getCurrentDegreeOfSeparation());
			}
		} catch (Throwable t) {
			StatusHandler.log(new Status(IStatus.WARNING, SandboxUiPlugin.ID_PLUGIN,
					"Could not refresh related elements", t));
		}
	}

	public void updateDegreesOfSeparation(Collection<AbstractRelationProvider> providers, int degreeOfSeparation) {
		for (AbstractRelationProvider provider : providers) {
			updateDegreeOfSeparation(provider, degreeOfSeparation);
		}
	}

	public void updateDegreeOfSeparation(AbstractRelationProvider provider, int degreeOfSeparation) {
		ContextCorePlugin.getContextManager().resetLandmarkRelationshipsOfKind(provider.getId());
		ContextUiPlugin.getDefault().getPreferenceStore().setValue(provider.getGenericId(), degreeOfSeparation);
		provider.setDegreeOfSeparation(degreeOfSeparation);
		for (IInteractionElement element : ContextCore.getContextManager().getActiveContext().getInteresting()) {
			if (element.getInterest().isLandmark()) {
				provider.landmarkAdded(element);
			}
		}
	}

	@Override
	protected void fillDialogMenu(IMenuManager dialogMenu) {
		MenuManager degMenu = new MenuManager("Degree of Separation");
		degMenu.add(zero);
		degMenu.add(one);
		degMenu.add(two);
		degMenu.add(three);
		degMenu.add(four);
		degMenu.add(five);
		check(getDegree());
		dialogMenu.add(degMenu);
		dialogMenu.add(new Separator());

		IAction qualifyElements = new ShowQualifiedNamesAction(this);
		dialogMenu.add(qualifyElements);
		dialogMenu.add(new Separator());

		super.fillDialogMenu(dialogMenu);
	}

	public void setQualifiedNameMode(boolean qualifiedNameMode) {
		DelegatingContextLabelProvider.setQualifyNamesMode(qualifiedNameMode);
		refresh(null, true);
	}

	private class DegreeZeroAction extends Action {
		DegreeZeroAction() {
			super(JFaceResources.getString("0: Disabled"), //$NON-NLS-1$
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			check(0);
			refreshAction(0);

		}
	}

	private class DegreeOneAction extends Action {
		DegreeOneAction() {
			super(JFaceResources.getString("1: Landmark Resources"), //$NON-NLS-1$
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			check(1);
			refreshAction(1);
		}
	}

	private class DegreeTwoAction extends Action {
		DegreeTwoAction() {
			super(JFaceResources.getString("2: Interesting Resources"), //$NON-NLS-1$
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			check(2);
			refreshAction(2);
		}
	}

	private class DegreeThreeAction extends Action {
		DegreeThreeAction() {
			super(JFaceResources.getString("3: Interesting Projects"), //$NON-NLS-1$
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			check(3);
			refreshAction(3);
		}
	}

	private class DegreeFourAction extends Action {
		DegreeFourAction() {
			super(JFaceResources.getString("4: Project Dependencies"), //$NON-NLS-1$
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			check(4);
			refreshAction(4);
		}
	}

	private class DegreeFiveAction extends Action {
		DegreeFiveAction() {
			super(JFaceResources.getString("5: Entire Workspace (slow)"), //$NON-NLS-1$
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			check(5);
			refreshAction(5);
		}
	}

	private void refreshAction(int degOfSep) {
		try {
			for (AbstractRelationProvider provider : ContextCorePlugin.getDefault().getRelationProviders()) {
				List<AbstractRelationProvider> providerList = new ArrayList<AbstractRelationProvider>();
				providerList.add(provider);

				if (provider.getCurrentDegreeOfSeparation() != degOfSep) {
					updateDegreesOfSeparation(providerList, degOfSep);
					degree = provider.getCurrentDegreeOfSeparation();
				}
			}

		} catch (Throwable t) {
			StatusHandler.log(new Status(IStatus.WARNING, SandboxUiPlugin.ID_PLUGIN,
					"Could not refresh related elements", t));
		}
	}

	private int getDegree() {
		for (AbstractRelationProvider provider : ContextCorePlugin.getDefault().getRelationProviders()) {
			degree = provider.getCurrentDegreeOfSeparation();
			break;
		}
		return degree;
	}

	private void check(int degree) {
		zero.setChecked(false);
		one.setChecked(false);
		two.setChecked(false);
		three.setChecked(false);
		four.setChecked(false);
		five.setChecked(false);
		switch (degree) {
		case 0:
			zero.setChecked(true);
			break;
		case 1:
			one.setChecked(true);
			break;
		case 2:
			two.setChecked(true);
			break;
		case 3:
			three.setChecked(true);
			break;
		case 4:
			four.setChecked(true);
			break;
		default:
			five.setChecked(true);
		}
	}

	private class ShowQualifiedNamesAction extends Action {

		public static final String LABEL = "Qualify Member Names";

		public static final String ID = "org.eclipse.mylyn.ui.views.elements.qualify";

		private final RelatedElementsPopupDialog dialog;

		public ShowQualifiedNamesAction(RelatedElementsPopupDialog dialog) {
			super(LABEL, IAction.AS_CHECK_BOX);
			this.dialog = dialog;
			setId(ID);
			setText(LABEL);
			setToolTipText(LABEL);
			setImageDescriptor(SandboxUiImages.QUALIFY_NAMES);
			update(ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(ID));
		}

		public void update(boolean on) {
			dialog.setQualifiedNameMode(on);
			setChecked(on);
			ContextUiPlugin.getDefault().getPreferenceStore().setValue(ID, on);
		}

		@Override
		public void run() {
			update(!ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(ID));
		}
	}

	/**
	 * Set to false for testing
	 */
	public void setSyncExecForTesting(boolean asyncRefreshMode) {
		this.syncExecForTesting = asyncRefreshMode;
	}

	public void dispose() {
		ContextCore.getContextManager().removeListener(REFRESH_UPDATE_LISTENER);
		super.close();
	}

	@Override
	protected Point getInitialSize() {
		return new Point(400, 500);
	}

}
