/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Michael Fraenkel (fraenkel@us.ibm.com) - contributed a fix for:
 *       o New search view sets incorrect title
 *         (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=60966)
 *******************************************************************************/
package org.eclipse.search.internal.ui;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionGroup;

import org.eclipse.search.internal.ui.util.FileLabelProvider;
import org.eclipse.search.ui.IActionGroupFactory;
import org.eclipse.search.ui.IContextMenuConstants;
import org.eclipse.search.ui.IContextMenuContributor;
import org.eclipse.search.ui.ISearchResultViewEntry;
import org.eclipse.search.ui.SearchUI;


/**
 * A special viewer to present search results. The viewer implements an
 * optimized adding and removing strategy. Furthermore it manages
 * contributions for search result types. For example the viewer's context
 * menu differs if the search result has been generated by a text or
 * a java search.
 * @deprecated old search
 */
@Deprecated
public class SearchResultViewer extends TableViewer {

	private SearchResultView fOuterPart;
	private ShowNextResultAction fShowNextResultAction;
	private ShowPreviousResultAction fShowPreviousResultAction;
	private GotoMarkerAction fGotoMarkerActionProxy;
	private SearchAgainAction fSearchAgainAction;
	private RemoveResultAction fRemoveSelectedMatchesAction;
	private RemoveAllResultsAction fRemoveAllResultsAction;
	private SortDropDownAction fSortDropDownAction;
	private SearchDropDownAction fSearchDropDownAction;
	private CopyToClipboardAction fCopyToClipboardAction;
	private int fMarkerToShow;
	private boolean fHandleSelectionChangedEvents= true;
	private ISelection fLastSelection;
	private boolean fCurrentMatchRemoved= false;
	private Color fPotentialMatchFgColor;
	private ActionGroup fActionGroup;
	private IContextMenuContributor fContextMenuContributor;
	private IAction fGotoMarkerAction;

	private ResourceToItemsMapper fResourceToItemsMapper;
	private String fCurrentPageId= null;

	public SearchResultViewer(SearchResultView outerPart, Composite parent) {
		super(new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));

		fResourceToItemsMapper= new ResourceToItemsMapper(this);

		fOuterPart= outerPart;
		Assert.isNotNull(fOuterPart);

		if (SearchPreferencePage.arePotentialMatchesEmphasized())
			fPotentialMatchFgColor= new Color(SearchPlugin.getActiveWorkbenchShell().getDisplay(), SearchPreferencePage.getPotentialMatchForegroundColor());

		setUseHashlookup(true);
		setContentProvider(new ArrayContentProvider());

		ILabelProvider labelProvider= new SearchResultLabelProvider(new FileLabelProvider(FileLabelProvider.SHOW_LABEL));
		setLabelProvider(labelProvider);

		Search currentSearch= SearchManager.getDefault().getCurrentSearch();
		boolean hasSearch= currentSearch != null;
		boolean hasSearchOperation= currentSearch != null && currentSearch.getOperation() != null;

		fShowNextResultAction= new ShowNextResultAction(this);
		fShowNextResultAction.setEnabled(false);
		fShowPreviousResultAction= new ShowPreviousResultAction(this);
		fShowPreviousResultAction.setEnabled(false);
		fGotoMarkerActionProxy= new GotoMarkerAction(this);
		fGotoMarkerActionProxy.setEnabled(false);
		fRemoveSelectedMatchesAction= new RemoveResultAction(this, false);
		fRemoveSelectedMatchesAction.setEnabled(false);
		fRemoveAllResultsAction= new RemoveAllResultsAction();
		fRemoveAllResultsAction.setEnabled(false);
		fSearchAgainAction= new SearchAgainAction();
		fSearchAgainAction.setEnabled(hasSearchOperation);
		fSortDropDownAction = new SortDropDownAction(this);
		fSortDropDownAction.setEnabled(getItemCount() > 0);
		fSearchDropDownAction= new SearchDropDownAction();
		fSearchDropDownAction.setEnabled(hasSearch);
		fCopyToClipboardAction= new CopyToClipboardAction(this);

		addSelectionChangedListener(
			new ISelectionChangedListener() {
				@Override
				public void selectionChanged(SelectionChangedEvent event) {
					if (fLastSelection == null || !fLastSelection.equals(event.getSelection())) {
						fLastSelection= event.getSelection();
						handleSelectionChanged();
					}
				}
			}
		);

		addOpenListener(new IOpenListener() {
			@Override
			public void open(OpenEvent event) {
				showResult();
			}
		});

		MenuManager menuMgr= new MenuManager("#PopUp"); //$NON-NLS-1$
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(
			new IMenuListener() {
				@Override
				public void menuAboutToShow(IMenuManager mgr) {
					SearchPlugin.createStandardGroups(mgr);
					fillContextMenu(mgr);
				}
			});
		Menu menu= menuMgr.createContextMenu(getTable());
		getTable().setMenu(menu);

		// Register menu
		fOuterPart.getSite().registerContextMenu(menuMgr, this);

		IActionBars actionBars= fOuterPart.getViewSite().getActionBars();
		if (actionBars != null) {
			actionBars.setGlobalActionHandler(ActionFactory.NEXT.getId(), fShowNextResultAction);
			actionBars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), fShowPreviousResultAction);
		}

		fOuterPart.getSite().setSelectionProvider(this);
	}

	void init() {
		Search search= SearchManager.getDefault().getCurrentSearch();
		if (search != null) {
			setGotoMarkerAction(search.getGotoMarkerAction());
			setContextMenuTarget(search.getContextMenuContributor());
			setActionGroupFactory(null);
			setActionGroupFactory(search.getActionGroupFactory());
			setPageId(search.getPageId());
			setInput(search.getResults());
		}
	}

	@Override
	protected void doUpdateItem(Widget item, Object element, boolean fullMap) {
		super.doUpdateItem(item, element, fullMap);
		if (((SearchResultViewEntry)element).isPotentialMatch()) {
			TableItem ti = (TableItem) item;
			ti.setForeground(fPotentialMatchFgColor);
		}
	}

	private void handleSelectionChanged() {
		int selectionCount= getSelectedEntriesCount();
		boolean hasSingleSelection= selectionCount == 1;
		boolean hasElements= getItemCount() > 0;
		fShowNextResultAction.setEnabled(hasSingleSelection || (hasElements && selectionCount == 0));
		fShowPreviousResultAction.setEnabled(hasSingleSelection || (hasElements && selectionCount == 0));
		fGotoMarkerActionProxy.setEnabled(hasSingleSelection);
		fRemoveSelectedMatchesAction.setEnabled(selectionCount > 0);

		if (fHandleSelectionChangedEvents) {
			fMarkerToShow= -1;
			fCurrentMatchRemoved= false;
		} else
			fHandleSelectionChangedEvents= true;

		updateStatusLine();
	}

	void updateStatusLine() {
		boolean hasSingleSelection= getSelectedEntriesCount() == 1;
		String location= ""; //$NON-NLS-1$
		if (hasSingleSelection) {
			ISearchResultViewEntry entry= (ISearchResultViewEntry)getTable().getItem(getTable().getSelectionIndex()).getData();
			IPath path= entry.getResource().getFullPath();
			if (path != null)
				location= path.makeRelative().toString();
		}
		setStatusLineMessage(location);
	}

	void enableActions() {
		/*
		 * Note: The check before each set operation reduces flickering
		 */
		boolean state= getItemCount() > 0;
		if (state != fShowNextResultAction.isEnabled())
			fShowNextResultAction.setEnabled(state);
		if (state != fShowPreviousResultAction.isEnabled())
			fShowPreviousResultAction.setEnabled(state);
		if (state != fSortDropDownAction.isEnabled())
			fSortDropDownAction.setEnabled(state);
		if (state != fRemoveAllResultsAction.isEnabled())
			fRemoveAllResultsAction.setEnabled(state);

		Search currentSearch= SearchManager.getDefault().getCurrentSearch();
		state= currentSearch != null;
		boolean operationState= currentSearch != null && currentSearch.getOperation() != null;
		if (state != fSearchDropDownAction.isEnabled())
			fSearchDropDownAction.setEnabled(state);
		if (operationState != fSearchAgainAction.isEnabled())
			fSearchAgainAction.setEnabled(operationState);

		state= !getSelection().isEmpty();
		if (state != fGotoMarkerActionProxy.isEnabled())
			fGotoMarkerActionProxy.setEnabled(state);
		if (state != fRemoveSelectedMatchesAction.isEnabled())
			fRemoveSelectedMatchesAction.setEnabled(state);
	}


	@Override
	protected void inputChanged(Object input, Object oldInput) {
		fLastSelection= null;
		getTable().removeAll();
		super.inputChanged(input, oldInput);
		fMarkerToShow= -1;
		fCurrentMatchRemoved= false;
		updateTitle();
		enableActions();
		if (getItemCount() > 0)
			selectResult(0);

		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), SearchPlugin.getDefault().getSearchViewHelpContextId());
	}

	protected int getSelectedEntriesCount() {
		ISelection s= getSelection();
		if (s == null || s.isEmpty() || !(s instanceof IStructuredSelection))
			return 0;
		IStructuredSelection selection= (IStructuredSelection)s;
		return selection.size();
	}

	//--- Contribution management -----------------------------------------------


	protected boolean enableRemoveMatchMenuItem() {
		if (getSelectedEntriesCount() != 1)
			return false;
		Table table= getTable();
		int index= table.getSelectionIndex();
		SearchResultViewEntry entry= null;
		if (index > -1)
			entry= (SearchResultViewEntry)table.getItem(index).getData();
		return (entry != null && entry.getMatchCount() > 1);

	}

	void fillContextMenu(IMenuManager menu) {
		ISelection selection= getSelection();

		if (fActionGroup != null) {
			ActionContext context= new ActionContext(selection);
			context.setInput(getInput());
			fActionGroup.setContext(context);
			fActionGroup.fillContextMenu(menu);
			fActionGroup.setContext(null);
		}

		if (fContextMenuContributor != null)
			fContextMenuContributor.fill(menu, this);

		if (!selection.isEmpty()) {
			menu.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, fCopyToClipboardAction);
			menu.appendToGroup(IContextMenuConstants.GROUP_GOTO, fGotoMarkerActionProxy);
			if (enableRemoveMatchMenuItem())
				menu.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, new RemoveMatchAction(this));
			menu.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, new RemoveResultAction(this, true));

			if (isPotentialMatchSelected())
				menu.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, new RemovePotentialMatchesAction(fOuterPart.getViewSite()));
		}

		// If we have elements
		if (getItemCount() > 0)
			menu.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, new RemoveAllResultsAction());

		menu.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, fSearchAgainAction);
		if (getItemCount() > 0) {
			fSortDropDownAction= fSortDropDownAction.renew();
			if (fSortDropDownAction.getSorterCount() > 1)
				menu.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, fSortDropDownAction);
		}
	}

	private boolean isPotentialMatchSelected() {
		if (getSelectedEntriesCount() == 0)
			return false;

		Iterator iter= Collections.EMPTY_LIST.iterator();
		ISelection selection= getSelection();
		if (selection instanceof IStructuredSelection)
			iter= ((IStructuredSelection)selection).iterator();

		while (iter.hasNext()) {
			Object entry= iter.next();
			if (entry instanceof ISearchResultViewEntry) {
				IMarker marker= ((ISearchResultViewEntry)entry).getSelectedMarker();
				if (marker != null && marker.getAttribute(SearchUI.POTENTIAL_MATCH, false))
					return true;
			}
		}

		return false;
	}

	IAction getGotoMarkerAction() {
		// null as return value is covered (no action will take place)
		return fGotoMarkerAction;
	}

	void setGotoMarkerAction(IAction gotoMarkerAction) {
		fGotoMarkerAction= gotoMarkerAction;
	}


	void setContextMenuTarget(IContextMenuContributor contributor) {
		fContextMenuContributor= contributor;
	}

	void setActionGroupFactory(IActionGroupFactory groupFactory) {
		IActionBars actionBars= fOuterPart.getViewSite().getActionBars();
		if (fActionGroup != null) {
			fActionGroup.dispose();
			fActionGroup= null;
		}

		if (groupFactory != null) {
			fActionGroup= groupFactory.createActionGroup(fOuterPart);
			if (actionBars != null)
				fActionGroup.fillActionBars(actionBars);
		}
		if (actionBars != null)
			actionBars.updateActionBars();
	}

	void setPageId(String pageId) {
		if (fCurrentPageId != null && fCurrentPageId.equals(pageId))
			return;

		fCurrentPageId= pageId;
		ILabelProvider labelProvider= fOuterPart.getLabelProvider(pageId);
		if (labelProvider != null)
			internalSetLabelProvider(labelProvider);
		fSortDropDownAction.setPageId(pageId);
	}

	void fillToolBar(IToolBarManager tbm) {
		tbm.add(fShowNextResultAction);
		tbm.add(fShowPreviousResultAction);
//		tbm.add(fGotoMarkerAction); see bug 15275
		tbm.add(fRemoveSelectedMatchesAction);
		tbm.add(fRemoveAllResultsAction);
		tbm.add(new Separator());
		tbm.add(new OpenSearchDialogAction());
		tbm.add(fSearchDropDownAction);

		// need to hook F5 to table
		getTable().addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if (e.keyCode == SWT.F5) {
					fSearchAgainAction.run();
					return;	// performance
				}
				if (e.character == SWT.DEL) {
					new RemoveResultAction(SearchResultViewer.this, true).run();
					return; // performance
				}
			}
		});
	}

	int getItemCount() {
		return SearchManager.getDefault().getCurrentItemCount();
	}

	void internalSetLabelProvider(ILabelProvider provider) {
		setLabelProvider(new SearchResultLabelProvider(provider));
	}

	/**
	 * Makes the first marker of the current result entry
	 * visible in an editor. If no result
	 * is visible, this method does nothing.
	 */
	public void showResult() {
		Table table= getTable();
		if (!canDoShowResult(table))
			return;


		int index= table.getSelectionIndex();
		if (index < 0)
			return;
		SearchResultViewEntry entry= (SearchResultViewEntry)getTable().getItem(index).getData();


		fMarkerToShow= 0;
		fCurrentMatchRemoved= false;
		entry.setSelectedMarkerIndex(0);
		openCurrentSelection();
	}


	/**
	 * Makes the next result (marker) visible in an editor. If no result
	 * is visible, this method makes the first result visible.
	 */
	public void showNextResult() {
		Table table= getTable();
		if (!canDoShowResult(table))
			return;

		int index= table.getSelectionIndex();
		SearchResultViewEntry entry= null;
		if (index > -1)
			entry= (SearchResultViewEntry)table.getItem(index).getData();

		if (fCurrentMatchRemoved)
			fCurrentMatchRemoved= false;
		else
			fMarkerToShow++;
		if (entry == null || fMarkerToShow >= entry.getMatchCount()) {
			// move selection
			if (index == -1) {
				index= 0;
			} else {
				index++;
				if (index >= table.getItemCount())
					index= 0;
			}
			fMarkerToShow= 0;
			entry= (SearchResultViewEntry)getTable().getItem(index).getData();
			selectResult(index);
		}
		entry.setSelectedMarkerIndex(fMarkerToShow);
		openCurrentSelection();
		updateStatusLine();
	}


	/**
	 * Makes the previous result (marker) visible. If there isn't any
	 * visible result, this method makes the last result visible.
	 */
	public void showPreviousResult() {
		fCurrentMatchRemoved= false;
		Table table= getTable();
		if (!canDoShowResult(table))
			return;

		int index= table.getSelectionIndex();
		SearchResultViewEntry entry;


		fMarkerToShow--;
		if (fMarkerToShow >= 0)
			entry= (SearchResultViewEntry)getTable().getItem(getTable().getSelectionIndex()).getData();
		else {
			// move selection
			int count= table.getItemCount();
			if (index == -1) {
				index= count - 1;
			} else {
				index--;
				if (index < 0)
					index= count - 1;
			}
			entry= (SearchResultViewEntry)getTable().getItem(index).getData();
			fMarkerToShow= entry.getMatchCount() - 1;
			selectResult(index);
		}
		entry.setSelectedMarkerIndex(fMarkerToShow);
		openCurrentSelection();
		updateStatusLine();
	}

	private boolean canDoShowResult(Table table) {
		if (table == null || getItemCount() == 0)
			return false;
		return true;
	}

	private void selectResult(int index) {
		fHandleSelectionChangedEvents= false;
		Object element= getElementAt(index);
		if (element != null)
			setSelection(new StructuredSelection(getElementAt(index)), true);
		else
			setSelection(StructuredSelection.EMPTY);
	}

	private void openCurrentSelection() {
		IAction action= getGotoMarkerAction();
		if (action != null)
			action.run();
	}

	/**
	 * Updates the foreground color for potential matches.
	 */
	void updatedPotentialMatchFgColor() {
		if (fPotentialMatchFgColor != null)
			fPotentialMatchFgColor.dispose();
		fPotentialMatchFgColor= null;
		if (SearchPreferencePage.arePotentialMatchesEmphasized())
			fPotentialMatchFgColor= new Color(SearchPlugin.getActiveWorkbenchShell().getDisplay(), SearchPreferencePage.getPotentialMatchForegroundColor());
		refresh();
	}

	/**
	 * Update the title
	 */
	protected void updateTitle() {
		boolean hasCurrentSearch= SearchManager.getDefault().getCurrentSearch() != null;
		String title;
		if (hasCurrentSearch) {
			String description= SearchManager.getDefault().getCurrentSearch().getFullDescription();
			title= Messages.format(SearchMessages.SearchResultView_titleWithDescription, description);
		} else
			title= SearchMessages.SearchResultView_title;
		if (title == null || !title.equals(fOuterPart.getContentDescription()))
			fOuterPart.setContentDescription(title);
	}

	/**
	 * Clear the title
	 */
	protected void clearTitle() {
		String title= SearchMessages.SearchResultView_title;
		if (!title.equals(fOuterPart.getContentDescription()))
			fOuterPart.setContentDescription(title);
	}

	/**
	 * Sets the message text to be displayed on the status line.
	 * The image on the status line is cleared.
	 * @param message the message
	 */
	private void setStatusLineMessage(String message) {
		fOuterPart.getViewSite().getActionBars().getStatusLineManager().setMessage(message);
	}


	@Override
	protected void handleDispose(DisposeEvent event) {
		fLastSelection= null;
		Menu menu= getTable().getMenu();
		if (menu != null)
			menu.dispose();
		if (fPotentialMatchFgColor != null)
			fPotentialMatchFgColor.dispose();
		if (fActionGroup != null) {
			fActionGroup.dispose();
			fActionGroup= null;
		}
		super.handleDispose(event);
	}

	//--- Change event handling -------------------------------------------------

	/**
	 * Handle a single add.
	 * @param entry the entry to add
	 */
	protected void handleAddMatch(ISearchResultViewEntry entry) {
		insert(entry, -1);
	}

	/**
	 * Handle a single remove.
	 * @param entry the entry to remove
	 */
	protected void handleRemoveMatch(ISearchResultViewEntry entry) {
		Widget item= findItem(entry);
		if (entry.getMatchCount() == 0)
			remove(entry);
		else
			updateItem(item, entry);
		updateStatusLine();
	}

	/**
	 * Handle remove all.
	 */
	protected void handleRemoveAll() {
		setContextMenuTarget(null);
		setActionGroupFactory(null);
		setInput(null);
	}

	/**
	 * Handle an update of an entry.
	 * 
	 * @param entry the entry
	 * @param matchRemoved <code>true</code> if a match got removed
	 */
	protected void handleUpdateMatch(ISearchResultViewEntry entry, boolean matchRemoved) {
		Widget item= findItem(entry);
		updateItem(item, entry);
		if (matchRemoved && getSelectionFromWidget().contains(entry))
			fCurrentMatchRemoved= true;
	}

	//--- Persistency -------------------------------------------------

	void restoreState(IMemento memento) {
		fSortDropDownAction.restoreState(memento);
	}

	void saveState(IMemento memento) {
		fSortDropDownAction.saveState(memento);
	}

	@Override
	protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
		Object[] changed= event.getElements();
		if (changed != null && !fResourceToItemsMapper.isEmpty()) {
			ArrayList others= new ArrayList(changed.length);
			for (int i= 0; i < changed.length; i++) {
				Object curr= changed[i];
				if (curr instanceof IResource)
					fResourceToItemsMapper.resourceChanged((IResource) curr);
				else if (curr instanceof IAdaptable) {
					IResource resource= ((IAdaptable)curr).getAdapter(IResource.class);
					if (resource != null)
						fResourceToItemsMapper.resourceChanged(resource);
				} else
					others.add(curr);
			}
			if (others.isEmpty()) {
				return;
			}
			event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource(), others.toArray());
		}
		super.handleLabelProviderChanged(event);
	}

	@Override
	protected void mapElement(Object element, Widget item) {
		super.mapElement(element, item);
		if (item instanceof Item) {
			fResourceToItemsMapper.addToMap(element, (Item)item);
		}
	}

	@Override
	protected void unmapElement(Object element, Widget item) {
		if (item instanceof Item) {
			fResourceToItemsMapper.removeFromMap(element, (Item)item);
		}
		super.unmapElement(element, item);
	}

	@Override
	protected void unmapAllElements() {
		fResourceToItemsMapper.clearMap();
		super.unmapAllElements();
	}

	@Override
	protected void internalRefresh(Object element, boolean updateLabels) {
		// see bug 44891
		getTable().setRedraw(false);
		super.internalRefresh(element, updateLabels);
		getTable().setRedraw(true);
	}

	void handleAllSearchesRemoved() {
		setContextMenuTarget(null);
		setActionGroupFactory(null);
		setInput(null);
		fSearchDropDownAction.clear();
	}

}
