/*******************************************************************************
 * Copyright (c) 2000, 2006 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
 *******************************************************************************/
 package org.eclipse.jdt.internal.ui.dialogs;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.ProgressMonitorWrapper;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

import org.eclipse.jface.resource.ImageDescriptor;

import org.eclipse.ui.progress.UIJob;

import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;

import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.corext.util.Strings;
import org.eclipse.jdt.internal.corext.util.TypeFilter;
import org.eclipse.jdt.internal.corext.util.TypeInfo;
import org.eclipse.jdt.internal.corext.util.TypeInfoFactory;
import org.eclipse.jdt.internal.corext.util.TypeInfoFilter;
import org.eclipse.jdt.internal.corext.util.OpenTypeHistory;
import org.eclipse.jdt.internal.corext.util.UnresolvableTypeInfo;
import org.eclipse.jdt.internal.corext.util.TypeInfo.TypeInfoAdapter;

import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;

import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension;
import org.eclipse.jdt.ui.dialogs.ITypeInfoImageProvider;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.JavaUIMessages;
import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;

/**
 * A viewer to present type queried form the type history and form the
 * search engine. All viewer updating takes place in the UI thread.
 * Therefore no synchronization of the methods is necessary.
 * 
 * @since 3.1
 */
public class TypeInfoViewer {
	
	private static class SearchRequestor extends TypeNameRequestor {
		private volatile boolean fStop;
		
		private Set fHistory;

		private TypeInfoFilter fFilter;
		private TypeInfoFactory fFactory= new TypeInfoFactory();
		private List fResult;
		
		public SearchRequestor(TypeInfoFilter filter) {
			super();
			fResult= new ArrayList(2048);
			fFilter= filter;
		}
		public TypeInfo[] getResult() {
			return (TypeInfo[])fResult.toArray(new TypeInfo[fResult.size()]);
		}
		public void cancel() {
			fStop= true;
		}
		public void setHistory(Set history) {
			fHistory= history;
		}
		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
			if (fStop)
				return;
			if (TypeFilter.isFiltered(packageName, simpleTypeName))
				return;
			TypeInfo type= fFactory.create(packageName, simpleTypeName, enclosingTypeNames, modifiers, path);
			if (fHistory.contains(type))
				return;
			if (fFilter.matchesFilterExtension(type))
				fResult.add(type);
		}
	}
	
	protected static class TypeInfoComparator implements Comparator {
		private TypeInfoLabelProvider fLabelProvider;
		private TypeInfoFilter fFilter;
		public TypeInfoComparator(TypeInfoLabelProvider labelProvider, TypeInfoFilter filter) {
			fLabelProvider= labelProvider;
			fFilter= filter;
		}
	    public int compare(Object left, Object right) {
	     	TypeInfo leftInfo= (TypeInfo)left;
	     	TypeInfo rightInfo= (TypeInfo)right;
	     	int leftCategory= getCamelCaseCategory(leftInfo);
	     	int rightCategory= getCamelCaseCategory(rightInfo);
	     	if (leftCategory < rightCategory)
	     		return -1;
	     	if (leftCategory > rightCategory)
	     		return +1;
	     	int result= compareName(leftInfo.getTypeName(), rightInfo.getTypeName());
	     	if (result != 0)
	     		return result;
	     	result= compareTypeContainerName(leftInfo.getTypeContainerName(), rightInfo.getTypeContainerName());
	     	if (result != 0)
	     		return result;
	     	
	     	leftCategory= getElementTypeCategory(leftInfo);
	     	rightCategory= getElementTypeCategory(rightInfo);
	     	if (leftCategory < rightCategory)
	     		return -1;
	     	if (leftCategory > rightCategory)
	     		return +1;
	     	return compareContainerName(leftInfo, rightInfo);
	    }
		private int compareName(String leftString, String rightString) {
			int result= leftString.compareToIgnoreCase(rightString);
			if (result != 0) {
				return result;
			} else if (Strings.isLowerCase(leftString.charAt(0)) && 
				!Strings.isLowerCase(rightString.charAt(0))) {
	     		return +1;
			} else if (Strings.isLowerCase(rightString.charAt(0)) &&
	     		!Strings.isLowerCase(leftString.charAt(0))) {
	     		return -1;
			} else {
				return leftString.compareTo(rightString);
			}
		}
		private int compareTypeContainerName(String leftString, String rightString) {
			int leftLength= leftString.length();
			int rightLength= rightString.length();
			if (leftLength == 0 && rightLength > 0)
				return -1;
			if (leftLength == 0 && rightLength == 0)
				return 0;
			if (leftLength > 0 && rightLength == 0)
				return +1;
			return compareName(leftString, rightString);
		}
		private int compareContainerName(TypeInfo leftType, TypeInfo rightType) {
			return fLabelProvider.getContainerName(leftType).compareTo(
				fLabelProvider.getContainerName(rightType));
		}
		private int getCamelCaseCategory(TypeInfo type) {
			if (fFilter == null)
				return 0;
			if (!fFilter.isCamcelCasePattern())
				return 0;
			return fFilter.matchesRawNamePattern(type) ? 0 : 1;
		}
		private int getElementTypeCategory(TypeInfo type) {
			if (type.getElementType() == TypeInfo.IFILE_TYPE_INFO)
				return 0;
			if (type.getElementType() == TypeInfo.JAR_FILE_ENTRY_TYPE_INFO)
				return 1;
			return 2;
		}
	}
	
	protected static class TypeInfoLabelProvider {

		private ITypeInfoImageProvider fProviderExtension;
		private TypeInfoAdapter fAdapter= new TypeInfoAdapter();
		
		private Map fLib2Name= new HashMap();
		private String[] fInstallLocations;
		private String[] fVMNames;

		private boolean fFullyQualifyDuplicates;
		
		public TypeInfoLabelProvider(ITypeInfoImageProvider extension) {
			fProviderExtension= extension;
			List locations= new ArrayList();
			List labels= new ArrayList();
			IVMInstallType[] installs= JavaRuntime.getVMInstallTypes();
			for (int i= 0; i < installs.length; i++) {
				processVMInstallType(installs[i], locations, labels);
			}
			fInstallLocations= (String[])locations.toArray(new String[locations.size()]);
			fVMNames= (String[])labels.toArray(new String[labels.size()]);
			
		}
		public void setFullyQualifyDuplicates(boolean value) {
			fFullyQualifyDuplicates= value;
		}
		private void processVMInstallType(IVMInstallType installType, List locations, List labels) {
			if (installType != null) {
				IVMInstall[] installs= installType.getVMInstalls();
				boolean isMac= Platform.OS_MACOSX.equals(Platform.getOS());
				final String HOME_SUFFIX= "/Home"; //$NON-NLS-1$
				for (int i= 0; i < installs.length; i++) {
					String label= getFormattedLabel(installs[i].getName());
					LibraryLocation[] libLocations= installs[i].getLibraryLocations();
					if (libLocations != null) {
						processLibraryLocation(libLocations, label);
					} else {
						String filePath= installs[i].getInstallLocation().getAbsolutePath();
						// on MacOS X install locations end in an additional "/Home" segment; remove it
						if (isMac && filePath.endsWith(HOME_SUFFIX))
							filePath= filePath.substring(0, filePath.length()- HOME_SUFFIX.length() + 1);
						locations.add(filePath);
						labels.add(label);
					}
				}
			}
		}
		private void processLibraryLocation(LibraryLocation[] libLocations, String label) {
			for (int l= 0; l < libLocations.length; l++) {
				LibraryLocation location= libLocations[l];
				fLib2Name.put(location.getSystemLibraryPath().toString(), label);
			}
		}
		private String getFormattedLabel(String name) {
			return Messages.format(JavaUIMessages.TypeInfoViewer_library_name_format, name);
		}
		public String getText(Object element) {
			return ((TypeInfo)element).getTypeName();
		}
		public String getQualifiedText(TypeInfo type) {
			StringBuffer result= new StringBuffer();
			result.append(type.getTypeName());
			String containerName= type.getTypeContainerName();
			result.append(JavaElementLabels.CONCAT_STRING);
			if (containerName.length() > 0) {
				result.append(containerName);
			} else {
				result.append(JavaUIMessages.TypeInfoViewer_default_package);
			}
			return result.toString();
		}
		public String getFullyQualifiedText(TypeInfo type) {
			StringBuffer result= new StringBuffer();
			result.append(type.getTypeName());
			String containerName= type.getTypeContainerName();
			if (containerName.length() > 0) {
				result.append(JavaElementLabels.CONCAT_STRING);
				result.append(containerName);
			}
			result.append(JavaElementLabels.CONCAT_STRING);
			result.append(getContainerName(type));
			return result.toString();
		}
		public String getText(TypeInfo last, TypeInfo current, TypeInfo next) {
			StringBuffer result= new StringBuffer();
			int qualifications= 0;
			String currentTN= current.getTypeName();
			result.append(currentTN);
			String currentTCN= getTypeContainerName(current);
			if (last != null) {
				String lastTN= last.getTypeName();
				String lastTCN= getTypeContainerName(last);
				if (currentTCN.equals(lastTCN)) {
					if (currentTN.equals(lastTN)) {
						result.append(JavaElementLabels.CONCAT_STRING);
						result.append(currentTCN);
						result.append(JavaElementLabels.CONCAT_STRING);
						result.append(getContainerName(current));
						return result.toString();
					}
				} else if (currentTN.equals(lastTN)) {
					qualifications= 1;
				}
			}
			if (next != null) {
				String nextTN= next.getTypeName();
				String nextTCN= getTypeContainerName(next);
				if (currentTCN.equals(nextTCN)) {
					if (currentTN.equals(nextTN)) {
						result.append(JavaElementLabels.CONCAT_STRING);
						result.append(currentTCN);
						result.append(JavaElementLabels.CONCAT_STRING);
						result.append(getContainerName(current));
						return result.toString();
					}
				} else if (currentTN.equals(nextTN)) {
					qualifications= 1;
				}
			}
			if (qualifications > 0) {
				result.append(JavaElementLabels.CONCAT_STRING);
				result.append(currentTCN);
				if (fFullyQualifyDuplicates) {
					result.append(JavaElementLabels.CONCAT_STRING);
					result.append(getContainerName(current));
				}
			}
			return result.toString();
		}
		public String getQualificationText(TypeInfo type) {
			StringBuffer result= new StringBuffer();
			String containerName= type.getTypeContainerName();
			if (containerName.length() > 0) {
				result.append(containerName);
				result.append(JavaElementLabels.CONCAT_STRING);
			}
			result.append(getContainerName(type));
			return result.toString();
		}
		public ImageDescriptor getImageDescriptor(Object element) {
			TypeInfo type= (TypeInfo)element;
			if (fProviderExtension != null) {
				fAdapter.setInfo(type);
				ImageDescriptor descriptor= fProviderExtension.getImageDescriptor(fAdapter);
				if (descriptor != null) 
					return descriptor;
			}
			return JavaElementImageProvider.getTypeImageDescriptor(
				type.isInnerType(), false, type.getModifiers(), false);
		}
		
		private String getTypeContainerName(TypeInfo info) {
			String result= info.getTypeContainerName();
			if (result.length() > 0)
				return result;
			return JavaUIMessages.TypeInfoViewer_default_package;
		}
		
		private String getContainerName(TypeInfo type) {
			String name= type.getPackageFragmentRootName();
			for (int i= 0; i < fInstallLocations.length; i++) {
				if (name.startsWith(fInstallLocations[i])) {
					return fVMNames[i];
				}
			}
			String lib= (String)fLib2Name.get(name);
			if (lib != null)
				return lib;
			return name;
		}
	}

	private static class ProgressUpdateJob extends UIJob {
		private TypeInfoViewer fViewer;
		private boolean fStopped;
		public ProgressUpdateJob(Display display, TypeInfoViewer viewer) {
			super(display, JavaUIMessages.TypeInfoViewer_progressJob_label);
			fViewer= viewer;
		}
		public void stop() {
			fStopped= true;
			cancel();
		}
		public IStatus runInUIThread(IProgressMonitor monitor) {
			if (stopped()) 
				return new Status(IStatus.CANCEL, JavaPlugin.getPluginId(), IStatus.CANCEL, "", null); //$NON-NLS-1$
			fViewer.updateProgressMessage();
			if (!stopped())
				schedule(300);
			return new Status(IStatus.OK, JavaPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$
		}
		private boolean stopped() {
			return fStopped || fViewer.getTable().isDisposed();
		}
	}
	
	private static class ProgressMonitor extends ProgressMonitorWrapper {
		private TypeInfoViewer fViewer;
		private String fName;
		private int fTotalWork;
		private double fWorked;
		private boolean fDone;
		
		public ProgressMonitor(IProgressMonitor monitor, TypeInfoViewer viewer) {
			super(monitor);
			fViewer= viewer;
		}
		public void setTaskName(String name) {
			super.setTaskName(name);
			fName= name;
		}
		public void beginTask(String name, int totalWork) {
			super.beginTask(name, totalWork);
			if (fName == null)
				fName= name;
			fTotalWork= totalWork;
		}
		public void worked(int work) {
			super.worked(work);
			internalWorked(work);
		}
		public void done() {
			fDone= true;
			fViewer.setProgressMessage(""); //$NON-NLS-1$
			super.done();
		}
		public void internalWorked(double work) {
			fWorked= fWorked + work;
			fViewer.setProgressMessage(getMessage());
		}
		private String getMessage() {
			if (fDone) {
				return ""; //$NON-NLS-1$
			} else if (fTotalWork == 0) {
				return fName;
			} else {
				return Messages.format(
					JavaUIMessages.TypeInfoViewer_progress_label,
					new Object[] { fName, new Integer((int)((fWorked * 100) / fTotalWork)) });
			}
		}
	}

	private static abstract class AbstractJob extends Job {
		protected TypeInfoViewer fViewer;
		protected AbstractJob(String name, TypeInfoViewer viewer) {
			super(name);
			fViewer= viewer;
			setSystem(true);
		}
		protected final IStatus run(IProgressMonitor parent) {
			ProgressMonitor monitor= new ProgressMonitor(parent, fViewer);
			try {
				fViewer.scheduleProgressUpdateJob();
				return doRun(monitor);
			} finally {
				fViewer.stopProgressUpdateJob();
			}
		}
		protected abstract IStatus doRun(ProgressMonitor monitor);
	}
	
	private static abstract class AbstractSearchJob extends AbstractJob {
		private int fMode;
		
		protected int fTicket;
		protected TypeInfoLabelProvider fLabelProvider;
		
		protected TypeInfoFilter fFilter;
		protected OpenTypeHistory fHistory;
		
		protected AbstractSearchJob(int ticket, TypeInfoViewer viewer, TypeInfoFilter filter, OpenTypeHistory history, int numberOfVisibleItems, int mode) {
			super(JavaUIMessages.TypeInfoViewer_job_label, viewer);
			fMode= mode;
			fTicket= ticket;
			fViewer= viewer;
			fLabelProvider= fViewer.getLabelProvider();
			fFilter= filter;
			fHistory= history;
		}
		public void stop() {
			cancel();
		}
		protected IStatus doRun(ProgressMonitor monitor) {
			try {
				if (VIRTUAL) { 
					internalRunVirtual(monitor);
				} else {
					internalRun(monitor);
				}
			} catch (CoreException e) {
				fViewer.searchJobFailed(fTicket, e);
				return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.ERROR, JavaUIMessages.TypeInfoViewer_job_error, e);
			} catch (InterruptedException e) {
				return canceled(e, true);
			} catch (OperationCanceledException e) {
				return canceled(e, false);
			}
			fViewer.searchJobDone(fTicket);
			return ok();	
		}
		protected abstract TypeInfo[] getSearchResult(Set filteredHistory, ProgressMonitor monitor) throws CoreException;
		
		private void internalRun(ProgressMonitor monitor) throws CoreException, InterruptedException {
			if (monitor.isCanceled())
				throw new OperationCanceledException();
			
			fViewer.clear(fTicket);

			// local vars to speed up rendering
			TypeInfo last= null;
			TypeInfo type= null;
			TypeInfo next= null;
			List elements= new ArrayList();
			List imageDescriptors= new ArrayList();
			List labels= new ArrayList();
			
			Set filteredHistory= new HashSet();
			TypeInfo[] matchingTypes= fHistory.getFilteredTypeInfos(fFilter);
			if (matchingTypes.length > 0) {
				Arrays.sort(matchingTypes, new TypeInfoComparator(fLabelProvider, fFilter));
				type= matchingTypes[0];
				int i= 1;
				while(type != null) {
					next= (i == matchingTypes.length) ? null : matchingTypes[i];
					filteredHistory.add(type);
					elements.add(type);
					imageDescriptors.add(fLabelProvider.getImageDescriptor(type));
					labels.add(fLabelProvider.getText(last, type, next));
					last= type;
					type= next;
					i++;
				}
			}
			matchingTypes= null;
			fViewer.fExpectedItemCount= elements.size();
			fViewer.addHistory(fTicket, elements, imageDescriptors, labels);
			
			if ((fMode & INDEX) == 0) {
				return;
			}
			TypeInfo[] result= getSearchResult(filteredHistory, monitor);
			fViewer.fExpectedItemCount+= result.length;
			if (result.length == 0) {
				return;
			}
			if (monitor.isCanceled())
				throw new OperationCanceledException();			
			int processed= 0;
			int nextIndex= 1;
			type= result[0];
			if (filteredHistory.size() > 0) {
				fViewer.addDashLineAndUpdateLastHistoryEntry(fTicket, type);
			}
			while (true) {
				long startTime= System.currentTimeMillis();
				elements.clear();
				imageDescriptors.clear();
				labels.clear();
	            int delta = Math.min(nextIndex == 1 ? fViewer.getNumberOfVisibleItems() : 10, result.length - processed);
				if (delta == 0)
					break;
				processed= processed + delta;
				while(delta > 0) {
					next= (nextIndex == result.length) ? null : result[nextIndex];
					elements.add(type);
					labels.add(fLabelProvider.getText(last, type, next));
					imageDescriptors.add(fLabelProvider.getImageDescriptor(type));
					last= type;
					type= next;
					nextIndex++;
					delta--;
				}
				fViewer.addAll(fTicket, elements, imageDescriptors, labels);
				long sleep= 100 - (System.currentTimeMillis() - startTime);
				if (false)
					System.out.println("Sleeping for: " + sleep); //$NON-NLS-1$
				
				if (sleep > 0)
					Thread.sleep(sleep);
				
				if (monitor.isCanceled())
					throw new OperationCanceledException();
			}
		}
		private void internalRunVirtual(ProgressMonitor monitor) throws CoreException, InterruptedException {
			if (monitor.isCanceled())
				throw new OperationCanceledException();
			
			fViewer.clear(fTicket);

			TypeInfo[] matchingTypes= fHistory.getFilteredTypeInfos(fFilter);
			fViewer.setHistoryResult(fTicket, matchingTypes);
			if ((fMode & INDEX) == 0)
				return;
				
			TypeInfo[] result= getSearchResult(new HashSet(Arrays.asList(matchingTypes)), monitor);
			if (monitor.isCanceled())
				throw new OperationCanceledException();
			
			fViewer.setSearchResult(fTicket, result);
		}
		private IStatus canceled(Exception e, boolean removePendingItems) {
			fViewer.searchJobCanceled(fTicket, removePendingItems);
			return new Status(IStatus.CANCEL, JavaPlugin.getPluginId(), IStatus.CANCEL, JavaUIMessages.TypeInfoViewer_job_cancel, e);
		}
		private IStatus ok() {
			return new Status(IStatus.OK, JavaPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$
		}
	}
	
	private static class SearchEngineJob extends AbstractSearchJob {
		private IJavaSearchScope fScope;
		private int fElementKind;
		private SearchRequestor fReqestor;
		
		public SearchEngineJob(int ticket, TypeInfoViewer viewer, TypeInfoFilter filter, OpenTypeHistory history, int numberOfVisibleItems, int mode, 
				IJavaSearchScope scope, int elementKind) {
			super(ticket, viewer, filter, history, numberOfVisibleItems, mode);
			fScope= scope;
			fElementKind= elementKind;
			fReqestor= new SearchRequestor(filter);
		}
		public void stop() {
			fReqestor.cancel();
			super.stop();
		}
		protected TypeInfo[] getSearchResult(Set filteredHistory, ProgressMonitor monitor) throws CoreException {
			long start= System.currentTimeMillis();
			fReqestor.setHistory(filteredHistory);
			// consider primary working copies during searching
			SearchEngine engine= new SearchEngine((WorkingCopyOwner)null);
			String packPattern= fFilter.getPackagePattern();
			monitor.setTaskName(JavaUIMessages.TypeInfoViewer_searchJob_taskName);
			engine.searchAllTypeNames(
				packPattern == null ? null : packPattern.toCharArray(), 
				fFilter.getNamePattern().toCharArray(), 
				fFilter.getSearchFlags(), 
				fElementKind, 
				fScope, 
				fReqestor, 
				IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, 
				monitor);
			if (DEBUG)
				System.out.println("Time needed until search has finished: " + (System.currentTimeMillis() - start)); //$NON-NLS-1$
			TypeInfo[] result= fReqestor.getResult();
			Arrays.sort(result, new TypeInfoComparator(fLabelProvider, fFilter));
			if (DEBUG)
				System.out.println("Time needed until sort has finished: " + (System.currentTimeMillis() - start)); //$NON-NLS-1$
			fViewer.rememberResult(fTicket, result);
			return result;
		}
	}
	
	private static class CachedResultJob extends AbstractSearchJob {
		private TypeInfo[] fLastResult;
		public CachedResultJob(int ticket, TypeInfo[] lastResult, TypeInfoViewer viewer, TypeInfoFilter filter, OpenTypeHistory history, int numberOfVisibleItems, int mode) {
			super(ticket, viewer, filter, history, numberOfVisibleItems, mode);
			fLastResult= lastResult;
		}
		protected TypeInfo[] getSearchResult(Set filteredHistory, ProgressMonitor monitor) throws CoreException {
			List result= new ArrayList(2048);
			for (int i= 0; i < fLastResult.length; i++) {
				TypeInfo type= fLastResult[i];
				if (filteredHistory.contains(type))
					continue;
				if (fFilter.matchesCachedResult(type))
					result.add(type);
			}
			// we have to sort if the filter is a camel case filter.
			TypeInfo[] types= (TypeInfo[])result.toArray(new TypeInfo[result.size()]);
			if (fFilter.isCamcelCasePattern()) {
				Arrays.sort(types, new TypeInfoComparator(fLabelProvider, fFilter));
			}
			return types;
		}
	}
	
	private static class SyncJob extends AbstractJob {
		public SyncJob(TypeInfoViewer viewer) {
			super(JavaUIMessages.TypeInfoViewer_syncJob_label, viewer);
		}
		public void stop() {
			cancel();
		}
		protected IStatus doRun(ProgressMonitor monitor) {
			try {
				monitor.setTaskName(JavaUIMessages.TypeInfoViewer_syncJob_taskName);
				new SearchEngine().searchAllTypeNames(
					null, 
					// make sure we search a concrete name. This is faster according to Kent  
					"_______________".toCharArray(), //$NON-NLS-1$
					SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE, 
					IJavaSearchConstants.ENUM,
					SearchEngine.createWorkspaceScope(), 
					new TypeNameRequestor() {}, 
					IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, 
					monitor);
			} catch (JavaModelException e) {
				JavaPlugin.log(e);
				return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.ERROR, JavaUIMessages.TypeInfoViewer_job_error, e);
			} catch (OperationCanceledException e) {
				return new Status(IStatus.CANCEL, JavaPlugin.getPluginId(), IStatus.CANCEL, JavaUIMessages.TypeInfoViewer_job_cancel, e);
			} finally {
				fViewer.syncJobDone();
			}
			return new Status(IStatus.OK, JavaPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$
		}
	}
	
	private static class DashLine {
		private int fSeparatorWidth;
		private String fMessage;
		private int fMessageLength;
		public String getText(int width) {
			StringBuffer dashes= new StringBuffer();
			int chars= (((width - fMessageLength) / fSeparatorWidth) / 2) -2;
			for (int i= 0; i < chars; i++) {
				dashes.append(SEPARATOR);
			}
			StringBuffer result= new StringBuffer();
			result.append(dashes);
			result.append(fMessage);
			result.append(dashes);
			return result.toString();
		}
		public void initialize(GC gc) {
			fSeparatorWidth= gc.getAdvanceWidth(SEPARATOR);
			fMessage= " " + JavaUIMessages.TypeInfoViewer_separator_message + " ";  //$NON-NLS-1$ //$NON-NLS-2$
			fMessageLength= gc.textExtent(fMessage).x;
		}
	}
	
	private static class ImageManager {
		private Map fImages= new HashMap(20);
		
		public Image get(ImageDescriptor descriptor) {
			if (descriptor == null)
				descriptor= ImageDescriptor.getMissingImageDescriptor();
			
			Image result= (Image)fImages.get(descriptor);
			if (result != null)
				return result;
			result= descriptor.createImage();
			if (result != null)
				fImages.put(descriptor, result);
			return result;
		}
		
		public void dispose() {
			for (Iterator iter= fImages.values().iterator(); iter.hasNext(); ) {
				Image image= (Image)iter.next();
				image.dispose();
			}
			fImages.clear();
		}
	}
	
	private Display fDisplay;
	
	private String fProgressMessage;
	private Label fProgressLabel;
	private int fProgressCounter;
	private ProgressUpdateJob fProgressUpdateJob;
	
	private OpenTypeHistory fHistory;

	/* non virtual table */
	private int fNextElement;
	private List fItems;
	
	/* virtual table */
	private TypeInfo[] fHistoryMatches;
	private TypeInfo[] fSearchMatches;
	
	private int fNumberOfVisibleItems;
	private int fExpectedItemCount;
	private Color fDashLineColor; 
	private int fScrollbarWidth;
	private int fTableWidthDelta;
	private int fDashLineIndex= -1;
	private Image fSeparatorIcon;
	private DashLine fDashLine= new DashLine();
	
	private boolean fFullyQualifySelection;
	/* remembers the last selection to restore unqualified labels */
	private TableItem[] fLastSelection;
	private String[] fLastLabels;
	
	private TypeInfoLabelProvider fLabelProvider;
	private ImageManager fImageManager;
	
	private Table fTable;
	
	private SyncJob fSyncJob;
	
	private TypeInfoFilter fTypeInfoFilter;
	private ITypeInfoFilterExtension fFilterExtension;
	private TypeInfo[] fLastCompletedResult;
	private TypeInfoFilter fLastCompletedFilter;
	
	private int fSearchJobTicket;
	protected int fElementKind;
	protected IJavaSearchScope fSearchScope;
	
	private AbstractSearchJob fSearchJob;

	private static final int HISTORY= 1;
	private static final int INDEX= 2;
	private static final int FULL= HISTORY | INDEX;
	
	private static final char SEPARATOR= '-'; 
	
	private static final boolean DEBUG= false;	
	private static final boolean VIRTUAL= false;
	
	private static final TypeInfo[] EMTPY_TYPE_INFO_ARRAY= new TypeInfo[0];
	// only needed when in virtual table mode
	private static final TypeInfo DASH_LINE= new UnresolvableTypeInfo(null, null, null, 0, null);

	public TypeInfoViewer(Composite parent, int flags, Label progressLabel, 
			IJavaSearchScope scope, int elementKind, String initialFilter,
			ITypeInfoFilterExtension filterExtension, ITypeInfoImageProvider imageExtension) {
		Assert.isNotNull(scope);
		fDisplay= parent.getDisplay();
		fProgressLabel= progressLabel;
		fSearchScope= scope;
		fElementKind= elementKind;
		fFilterExtension= filterExtension;
		fFullyQualifySelection= (flags & SWT.MULTI) != 0;
		fTable= new Table(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.FLAT | flags | (VIRTUAL ? SWT.VIRTUAL : SWT.NONE));
		fTable.setFont(parent.getFont());
		fLabelProvider= new TypeInfoLabelProvider(imageExtension);
		fItems= new ArrayList(500);
		fTable.setHeaderVisible(false);
		addPopupMenu();
		fTable.addControlListener(new ControlAdapter() {
			public void controlResized(ControlEvent event) {
				int itemHeight= fTable.getItemHeight();
				Rectangle clientArea= fTable.getClientArea();
				fNumberOfVisibleItems= (clientArea.height / itemHeight) + 1;
			}
		});
		fTable.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.DEL) {
					deleteHistoryEntry();
				} else if (e.keyCode == SWT.ARROW_DOWN) {
					int index= fTable.getSelectionIndex();
					if (index == fDashLineIndex - 1) {
						e.doit= false;
						setTableSelection(index + 2);
					}
				} else if (e.keyCode == SWT.ARROW_UP) {
					int index= fTable.getSelectionIndex();
					if (fDashLineIndex != -1 && index == fDashLineIndex + 1) {
						e.doit= false;
						setTableSelection(index - 2);
					}
				}
			}
		});
		fTable.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (fLastSelection != null) {
					for (int i= 0; i < fLastSelection.length; i++) {
						TableItem item= fLastSelection[i];
						// could be disposed by deleting element from 
						// type info history
						if (!item.isDisposed())
							item.setText(fLastLabels[i]);
					}
				}
				TableItem[] items= fTable.getSelection();
				fLastSelection= new TableItem[items.length];
				fLastLabels= new String[items.length];
				for (int i= 0; i < items.length; i++) {
					TableItem item= items[i];
					fLastSelection[i]= item;
					fLastLabels[i]= item.getText();
					Object data= item.getData();
					if (data instanceof TypeInfo) {
						String qualifiedText= getQualifiedText((TypeInfo)data);
						if (qualifiedText.length() > fLastLabels[i].length())
							item.setText(qualifiedText);
					}
				}
			}
		});
		fTable.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				stop(true, true);
				fDashLineColor.dispose();
				fSeparatorIcon.dispose();
				fImageManager.dispose();
				if (fProgressUpdateJob != null) {
					fProgressUpdateJob.stop();
					fProgressUpdateJob= null;
				}
			}
		});
		if (VIRTUAL) {
			fHistoryMatches= EMTPY_TYPE_INFO_ARRAY;
			fSearchMatches= EMTPY_TYPE_INFO_ARRAY;
			fTable.addListener(SWT.SetData, new Listener() {
				public void handleEvent(Event event) {
					TableItem item= (TableItem)event.item;
					setData(item);
				}
			});
		}
		
		fDashLineColor= computeDashLineColor();
		fScrollbarWidth= computeScrollBarWidth();
		fTableWidthDelta= fTable.computeTrim(0, 0, 0, 0).width - fScrollbarWidth;
		fSeparatorIcon= JavaPluginImages.DESC_OBJS_TYPE_SEPARATOR.createImage(fTable.getDisplay());
		// Use a new image manager since an extension can provide its own
		// image descriptors. To avoid thread problems with SWT the registry
		// must be created in the UI thread.
		fImageManager= new ImageManager();
		
		fHistory= OpenTypeHistory.getInstance();
		if (initialFilter != null && initialFilter.length() > 0)
			fTypeInfoFilter= createTypeInfoFilter(initialFilter);
		GC gc= null;
		try {
			gc= new GC(fTable);
			gc.setFont(fTable.getFont());
			fDashLine.initialize(gc);
		} finally {
			gc.dispose();
		}
		// If we do have a type info filter then we are
		// scheduling a search job in startup. So no
		// need to sync the search indices.
		if (fTypeInfoFilter == null) {
			scheduleSyncJob();
		}
	}
	
	/* package */ void startup() {
		if (fTypeInfoFilter == null) {
			reset();
		} else {
			scheduleSearchJob(FULL);
		}
	}

	public Table getTable() {
		return fTable;
	}
	
	/* package */ TypeInfoLabelProvider getLabelProvider() {
		return fLabelProvider;
	}
	
	private int getNumberOfVisibleItems() {
		return fNumberOfVisibleItems;
	}
	
	public void setFocus() {
		fTable.setFocus();
	}
	
	
	public void setQualificationStyle(boolean value) {
		if (fFullyQualifySelection == value)
			return;
		fFullyQualifySelection= value;
		if (fLastSelection != null) {
			for (int i= 0; i < fLastSelection.length; i++) {
				TableItem item= fLastSelection[i];
				Object data= item.getData();
				if (data instanceof TypeInfo) {
					item.setText(getQualifiedText((TypeInfo)data));
				}
			}
		}
	}
	
	public TypeInfo[] getSelection() {
		TableItem[] items= fTable.getSelection();
		List result= new ArrayList(items.length);
		for (int i= 0; i < items.length; i++) {
			Object data= items[i].getData();
			if (data instanceof TypeInfo) {
				result.add(data);
			}
		}
		return (TypeInfo[])result.toArray(new TypeInfo[result.size()]);
	}
	
	public void stop() {
		stop(true, false);
	}
	
	public void stop(boolean stopSyncJob, boolean dispose) {
		if (fSyncJob != null && stopSyncJob) {
			fSyncJob.stop();
			fSyncJob= null;
		}
		if (fSearchJob != null) {
			fSearchJob.stop();
			fSearchJob= null;
		}
	}
	
	public void forceSearch() {
		stop(false, false);
		if (fTypeInfoFilter == null) {
			reset();
		} else {
			// clear last results
			fLastCompletedFilter= null;
			fLastCompletedResult= null;
			scheduleSearchJob(isSyncJobRunning() ? HISTORY : FULL);
		}
	}
	
	public void setSearchPattern(String text) {
		stop(false, false);
		if (text.length() == 0 || "*".equals(text)) { //$NON-NLS-1$
			fTypeInfoFilter= null;
			reset();
		} else {
			fTypeInfoFilter= createTypeInfoFilter(text);
			scheduleSearchJob(isSyncJobRunning() ? HISTORY : FULL);
		}
	}
	
	public void setSearchScope(IJavaSearchScope scope, boolean refresh) {
		fSearchScope= scope;
		if (!refresh)
			return;
		stop(false, false);
		fLastCompletedFilter= null;
		fLastCompletedResult= null;
		if (fTypeInfoFilter == null) {
			reset();
		} else {
			scheduleSearchJob(isSyncJobRunning() ? HISTORY : FULL);
		}
	}

	public void setFullyQualifyDuplicates(boolean value, boolean refresh) {
		fLabelProvider.setFullyQualifyDuplicates(value);
		if (!refresh)
			return;
		stop(false, false);
		if (fTypeInfoFilter == null) {
			reset();
		} else {
			scheduleSearchJob(isSyncJobRunning() ? HISTORY : FULL);
		}
	}
	
	public void reset() {
		fLastSelection= null;
		fLastLabels= null;
		fExpectedItemCount= 0;
		fDashLineIndex= -1;
		TypeInfoFilter filter= (fTypeInfoFilter != null)
			? fTypeInfoFilter
			: new TypeInfoFilter("*", fSearchScope, fElementKind, fFilterExtension); //$NON-NLS-1$
		if (VIRTUAL) {
			fHistoryMatches= fHistory.getFilteredTypeInfos(filter);
			fExpectedItemCount= fHistoryMatches.length;
			fTable.setItemCount(fHistoryMatches.length);
			// bug under windows.
			if (fHistoryMatches.length == 0) {
				fTable.redraw();
			}
			fTable.clear(0, fHistoryMatches.length - 1);
		} else {
			fNextElement= 0;
			TypeInfo[] historyItems= fHistory.getFilteredTypeInfos(filter); 
			if (historyItems.length == 0) {
				shortenTable();
				return;
			}
			fExpectedItemCount= historyItems.length;
			int lastIndex= historyItems.length - 1;
			TypeInfo last= null;
			TypeInfo type= historyItems[0];
			for (int i= 0; i < historyItems.length; i++) {
				TypeInfo next= i == lastIndex ? null : historyItems[i + 1];
				addSingleElement(type,
					fLabelProvider.getImageDescriptor(type),
					fLabelProvider.getText(last, type, next));
				last= type;
				type= next;
			}
			shortenTable();
		}
	}
	
	protected TypeInfoFilter createTypeInfoFilter(String text) {
		if ("**".equals(text)) //$NON-NLS-1$
			text= "*"; //$NON-NLS-1$
		return new TypeInfoFilter(text, fSearchScope, fElementKind, fFilterExtension);
	}
	
	private void addPopupMenu() {
		Menu menu= new Menu(fTable.getShell(), SWT.POP_UP);
		fTable.setMenu(menu);
		final MenuItem remove= new MenuItem(menu, SWT.NONE);
		remove.setText(JavaUIMessages.TypeInfoViewer_remove_from_history);
		menu.addMenuListener(new MenuAdapter() {
			public void menuShown(MenuEvent e) {
				TableItem[] selection= fTable.getSelection();
				remove.setEnabled(canEnable(selection));
			}
		});
		remove.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				deleteHistoryEntry();
			}
		});
	}
	
	private boolean canEnable(TableItem[] selection) {
		if (selection.length == 0)
			return false;
		for (int i= 0; i < selection.length; i++) {
			TableItem item= selection[i];
			Object data= item.getData();
			if (!(data instanceof TypeInfo))
				return false;
			if (!(fHistory.contains((TypeInfo)data)))
				return false; 
		}
		return true;
	}
	
	//---- History management -------------------------------------------------------
	
	private void deleteHistoryEntry() {
		int index= fTable.getSelectionIndex();
		if (index == -1)
			return;
		TableItem item= fTable.getItem(index);
		Object element= item.getData();
		if (!(element instanceof TypeInfo))
			return;
		if (fHistory.remove((TypeInfo)element) != null) {
			item.dispose();
			fItems.remove(index);
			int count= fTable.getItemCount();
			if (count > 0) {
				item= fTable.getItem(0);
				if (item.getData() instanceof DashLine) {
					item.dispose();
					fItems.remove(0);
					fDashLineIndex= -1;
					if (count > 1) {
						setTableSelection(0);
					}
				} else {
					if (index >= count) {
						index= count - 1;
					}
					setTableSelection(index);
				}
			} else {
				// send dummy selection
				fTable.notifyListeners(SWT.Selection, new Event());				
			}
		}
	}
	
	//-- Search result updating ----------------------------------------------------
	
	private void clear(int ticket) {
		syncExec(ticket, new Runnable() {
			public void run() {
				fNextElement= 0;
				fDashLineIndex= -1;
				fLastSelection= null;
				fLastLabels= null;
				fExpectedItemCount= 0;
			}
		});
	}
	
	private void rememberResult(int ticket, final TypeInfo[] result) {
		syncExec(ticket, new Runnable() {
			public void run() {
				if (fLastCompletedResult == null) {
					fLastCompletedFilter= fTypeInfoFilter;
					fLastCompletedResult= result;
				}
			}
		});
	}

	private void addHistory(int ticket, final List elements, final List imageDescriptors, final List labels) {
		addAll(ticket, elements, imageDescriptors, labels);
	}
	
	private void addAll(int ticket, final List elements, final List imageDescriptors, final List labels) {
		syncExec(ticket, new Runnable() {
			public void run() {
				int size= elements.size();
				for(int i= 0; i < size; i++) {
					addSingleElement(elements.get(i),
						(ImageDescriptor)imageDescriptors.get(i),
						(String)labels.get(i));
				}
			}
		});
	}
	
	private void addDashLineAndUpdateLastHistoryEntry(int ticket, final TypeInfo next) {
		syncExec(ticket, new Runnable() {
			public void run() {
				if (fNextElement > 0) {
					TableItem item= fTable.getItem(fNextElement - 1);
					String label= item.getText();
					String newLabel= fLabelProvider.getText(null, (TypeInfo)item.getData(), next);
					if (newLabel.length() > label.length())
						item.setText(newLabel);
					if (fLastSelection != null && fLastSelection.length > 0) {
						TableItem last= fLastSelection[fLastSelection.length - 1];
						if (last == item) {
							fLastLabels[fLastLabels.length - 1]= newLabel;
						}
					}
				}
				fDashLineIndex= fNextElement;
				addDashLine();
			}
		});
	}
	
	private void addDashLine() {
		TableItem item= null;
		if (fItems.size() > fNextElement) {
			item= (TableItem)fItems.get(fNextElement);
		} else {
			item= new TableItem(fTable, SWT.NONE);
			fItems.add(item);
		}
		fillDashLine(item);
		fNextElement++;
	}
	
	private void addSingleElement(Object element, ImageDescriptor imageDescriptor, String label) {
		TableItem item= null;
		Object old= null;
		if (fItems.size() > fNextElement) {
			item= (TableItem)fItems.get(fNextElement);
			old= item.getData();
			item.setForeground(null);
		} else {
			item= new TableItem(fTable, SWT.NONE);
			fItems.add(item);
		}
		item.setData(element);
		item.setImage(fImageManager.get(imageDescriptor));
		if (fNextElement == 0) {
			if (needsSelectionChange(old, element) || fLastSelection != null) {
				item.setText(label);
				fTable.setSelection(0);
	            fTable.notifyListeners(SWT.Selection, new Event());
			} else {
				fLastSelection= new TableItem[] { item };
				fLastLabels= new String[] { label };
			}
		} else {
			item.setText(label);
		}
		fNextElement++;
	}
	
	private boolean needsSelectionChange(Object oldElement, Object newElement) {
		int[] selected= fTable.getSelectionIndices();
		if (selected.length != 1)
			return true;
		if (selected[0] != 0)
			return true;
		if (oldElement == null)
			return true;
		return !oldElement.equals(newElement);
	}
	
	private void scheduleSearchJob(int mode) {
		fSearchJobTicket++;
		if (fLastCompletedFilter != null && fTypeInfoFilter.isSubFilter(fLastCompletedFilter.getText())) {
			fSearchJob= new CachedResultJob(fSearchJobTicket, fLastCompletedResult, this, fTypeInfoFilter, 
				fHistory, fNumberOfVisibleItems, 
				mode);
		} else {
			fLastCompletedFilter= null;
			fLastCompletedResult= null;
			fSearchJob= new SearchEngineJob(fSearchJobTicket, this, fTypeInfoFilter, 
				fHistory, fNumberOfVisibleItems, 
				mode, fSearchScope, fElementKind);
		}
		fSearchJob.schedule();
	}
	
	private void searchJobDone(int ticket) {
		syncExec(ticket, new Runnable() {
			public void run() {
				shortenTable();
				checkEmptyList();
				fSearchJob= null;
			}
		});
	}
	
	private void searchJobCanceled(int ticket, final boolean removePendingItems) {
		syncExec(ticket, new Runnable() {
			public void run() {
				if (removePendingItems) {
					shortenTable();
					checkEmptyList();
				}
				fSearchJob= null;
			}
		});
	}
	
	private synchronized void searchJobFailed(int ticket, CoreException e) {
		searchJobDone(ticket);
		JavaPlugin.log(e);
	}
	
	//-- virtual table support -------------------------------------------------------
	
	private void setHistoryResult(int ticket, final TypeInfo[] types) {
		syncExec(ticket, new Runnable() {
			public void run() {
				fExpectedItemCount= types.length;
				int lastHistoryLength= fHistoryMatches.length;
				fHistoryMatches= types;
				int length= fHistoryMatches.length + fSearchMatches.length; 
				int dash= (fHistoryMatches.length > 0 && fSearchMatches.length > 0) ? 1 : 0;
				fTable.setItemCount(length + dash);
				if (length == 0) {
					// bug under windows.
					fTable.redraw();
					return;
				} 
				int update= Math.max(lastHistoryLength, fHistoryMatches.length);
				if (update > 0) {
					fTable.clear(0, update + dash - 1);
				}
			}
		});
	}
	
	private void setSearchResult(int ticket, final TypeInfo[] types) {
		syncExec(ticket, new Runnable() {
			public void run() {
				fExpectedItemCount+= types.length;
				fSearchMatches= types;
				int length= fHistoryMatches.length + fSearchMatches.length; 
				int dash= (fHistoryMatches.length > 0 && fSearchMatches.length > 0) ? 1 : 0;
				fTable.setItemCount(length + dash);
				if (length == 0) {
					// bug under windows.
					fTable.redraw();
					return;
				}
				if (fHistoryMatches.length == 0) {
					fTable.clear(0, length + dash - 1);
				} else {
					fTable.clear(fHistoryMatches.length - 1, length + dash - 1);
				}
			}
		});
	}
	
	private void setData(TableItem item) {
		int index= fTable.indexOf(item);
		TypeInfo type= getTypeInfo(index);
		if (type == DASH_LINE) {
			item.setData(fDashLine);
			fillDashLine(item);
		} else {
			item.setData(type);
			item.setImage(fImageManager.get(fLabelProvider.getImageDescriptor(type)));
			item.setText(fLabelProvider.getText(
				getTypeInfo(index - 1), 
				type, 
				getTypeInfo(index + 1)));
			item.setForeground(null);
		}
	}
	
	private TypeInfo getTypeInfo(int index) {
		if (index < 0)
			return null;
		if (index < fHistoryMatches.length) {
			return fHistoryMatches[index];
		}
		int dash= (fHistoryMatches.length > 0 && fSearchMatches.length > 0) ? 1 : 0;
		if (index == fHistoryMatches.length && dash == 1) {
			return DASH_LINE;
		}
		index= index - fHistoryMatches.length - dash;
		if (index >= fSearchMatches.length)
			return null;
		return fSearchMatches[index];
	}
	
	//-- Sync Job updates ------------------------------------------------------------
	
	private void scheduleSyncJob() {
		fSyncJob= new SyncJob(this);
		fSyncJob.schedule();
	}
	
	private void syncJobDone() {
		syncExec(new Runnable() {
			public void run() {
				fSyncJob= null;
				if (fTypeInfoFilter != null) {
					scheduleSearchJob(FULL);
				}
			}
		});
	}

	private boolean isSyncJobRunning() {
		return fSyncJob != null;
	}
	
	//-- progress monitor updates -----------------------------------------------------
	
	private void scheduleProgressUpdateJob() {
		syncExec(new Runnable() {
			public void run() {
				if (fProgressCounter == 0) {
					clearProgressMessage();
					fProgressUpdateJob= new ProgressUpdateJob(fDisplay, TypeInfoViewer.this);
					fProgressUpdateJob.schedule(300);
				}
				fProgressCounter++;
			}
		});
	}
	
	private void stopProgressUpdateJob() {
		syncExec(new Runnable() {
			public void run() {
				fProgressCounter--;
				if (fProgressCounter == 0 && fProgressUpdateJob != null) {
					fProgressUpdateJob.stop();
					fProgressUpdateJob= null;
					clearProgressMessage();
				}
			}
		});
	}
	
	private void setProgressMessage(String message) {
		fProgressMessage= message;
	}
	
	private void clearProgressMessage() {
		fProgressMessage= ""; //$NON-NLS-1$
		fProgressLabel.setText(fProgressMessage);
	}
	
	private void updateProgressMessage() {
		fProgressLabel.setText(fProgressMessage);
	}
	
	//-- Helper methods --------------------------------------------------------------

	private void syncExec(final Runnable runnable) {
		if (fDisplay.isDisposed()) 
			return;
		fDisplay.syncExec(new Runnable() {
			public void run() {
				if (fTable.isDisposed())
					return;
				runnable.run();
			}
		});
	}
	
	private void syncExec(final int ticket, final Runnable runnable) {
		if (fDisplay.isDisposed()) 
			return;
		fDisplay.syncExec(new Runnable() {
			public void run() {
				if (fTable.isDisposed() || ticket != fSearchJobTicket)
					return;
				runnable.run();
			}
		});
	}
	
	private void fillDashLine(TableItem item) {
		Rectangle bounds= item.getImageBounds(0);
		Rectangle area= fTable.getBounds();
		boolean willHaveScrollBar= fExpectedItemCount + 1 > fNumberOfVisibleItems;
		item.setText(fDashLine.getText(area.width - bounds.x - bounds.width - fTableWidthDelta - 
			(willHaveScrollBar ? fScrollbarWidth : 0)));
		item.setImage(fSeparatorIcon);
		item.setForeground(fDashLineColor);
		item.setData(fDashLine);
	}

	private void shortenTable() {
		if (VIRTUAL)
			return;
        if (fNextElement < fItems.size()) {
            fTable.setRedraw(false);
            fTable.remove(fNextElement, fItems.size() - 1);
            fTable.setRedraw(true);
        }
		for (int i= fItems.size() - 1; i >= fNextElement; i--) {
			fItems.remove(i);
		}
	}
	
	private void checkEmptyList() {
		if (fTable.getItemCount() == 0) {
			fTable.notifyListeners(SWT.Selection, new Event());
		}
	}
	
	private void setTableSelection(int index) {
		fTable.setSelection(index);
		fTable.notifyListeners(SWT.Selection, new Event());
	}
	
	private Color computeDashLineColor() {
		Color fg= fTable.getForeground();
		int fGray= (int)(0.3*fg.getRed() + 0.59*fg.getGreen() + 0.11*fg.getBlue());
		Color bg= fTable.getBackground();
		int bGray= (int)(0.3*bg.getRed() + 0.59*bg.getGreen() + 0.11*bg.getBlue());
		int gray= (int)((fGray + bGray) * 0.66);
		return new Color(fDisplay, gray, gray, gray);
	}
	
	private int computeScrollBarWidth() {
		Composite t= new Composite(fTable.getShell(), SWT.V_SCROLL);            
		int result= t.computeTrim(0, 0, 0, 0).width;
		t.dispose();
		return result;
	}

	private String getQualifiedText(TypeInfo type) {
		return fFullyQualifySelection
			? fLabelProvider.getFullyQualifiedText(type)
			: fLabelProvider.getQualifiedText(type);
	}	
}
