/*******************************************************************************
 * Copyright (c) 2000, 2015 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.emptyList().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<Object> 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();
	}

}
