/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=116454
 *     Marcel Bruch, bruch@cs.tu-darmstadt.de - [content assist] Allow to re-sort proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=350991
 *     Terry Parker, tparker@google.com - Protect against poorly behaved completion proposers - http://bugs.eclipse.org/429925
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 493649
 *     Mickael Istria (Red Hat Inc.) - [251156] Allow multiple contentAssitProviders internally & inheritance
 *******************************************************************************/
package org.eclipse.jface.text.contentassist;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.osgi.util.TextProcessor;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Control;
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.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;

import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.contentassist.IContentAssistSubjectControl;
import org.eclipse.jface.internal.text.InformationControlReplacer;
import org.eclipse.jface.internal.text.TableOwnerDrawSupport;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.util.Util;
import org.eclipse.jface.viewers.StyledString;

import org.eclipse.jface.text.AbstractInformationControlManager;
import org.eclipse.jface.text.AbstractInformationControlManager.Anchor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IEditingSupport;
import org.eclipse.jface.text.IEditingSupportRegistry;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.IRewriteTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.TextUtilities;


/**
 * This class is used to present proposals to the user. If additional
 * information exists for a proposal, then selecting that proposal
 * will result in the information being displayed in a secondary
 * window.
 *
 * @see org.eclipse.jface.text.contentassist.ICompletionProposal
 * @see org.eclipse.jface.text.contentassist.AdditionalInfoController
 */
class CompletionProposalPopup implements IContentAssistListener {

	/**
	 * Completion proposal selection handler.
	 *
	 * @since 3.4
	 */
	final class ProposalSelectionHandler extends AbstractHandler {

		/**
		 * Selection operation codes.
		 */
		static final int SELECT_NEXT= 1;
		static final int SELECT_PREVIOUS= 2;


		private final int fOperationCode;

		/**
		 * Creates a new selection handler.
		 *
		 * @param operationCode the operation code
		 * @since 3.4
		 */
		public ProposalSelectionHandler(int operationCode) {
			Assert.isLegal(operationCode == SELECT_NEXT || operationCode == SELECT_PREVIOUS);
			fOperationCode= operationCode;
		}

		@Override
		public Object execute(ExecutionEvent event) throws ExecutionException {
			int itemCount= fProposalTable.getItemCount();
			int selectionIndex= fProposalTable.getSelectionIndex();
			switch (fOperationCode) {
			case SELECT_NEXT:
				selectionIndex+= 1;
				if (selectionIndex > itemCount - 1)
					selectionIndex= 0;
				break;
			case SELECT_PREVIOUS:
				selectionIndex-= 1;
				if (selectionIndex < 0)
					selectionIndex= itemCount - 1;
				break;
			default:
				break;
			}
			selectProposal(selectionIndex, false);
			return null;
		}

	}


	/**
	 * The empty proposal displayed if there is nothing else to show.
	 *
	 * @since 3.2
	 */
	private static final class EmptyProposal implements ICompletionProposal, ICompletionProposalExtension {

		String fDisplayString;
		int fOffset;
		@Override
		public void apply(IDocument document) {
		}

		@Override
		public Point getSelection(IDocument document) {
			return new Point(fOffset, 0);
		}

		@Override
		public IContextInformation getContextInformation() {
			return null;
		}

		@Override
		public Image getImage() {
			return null;
		}

		@Override
		public String getDisplayString() {
			return fDisplayString;
		}

		@Override
		public String getAdditionalProposalInfo() {
			return null;
		}

		@Override
		public void apply(IDocument document, char trigger, int offset) {
		}

		@Override
		public boolean isValidFor(IDocument document, int offset) {
			return false;
		}

		@Override
		public char[] getTriggerCharacters() {
			return null;
		}

		@Override
		public int getContextInformationPosition() {
			return -1;
		}
	}

	final class ProposalSelectionListener implements KeyListener {
		@Override
		public void keyPressed(KeyEvent e) {
			if (!Helper.okToUse(fProposalShell))
				return;

			if (e.character == 0 && e.keyCode == SWT.CTRL) {
				// http://dev.eclipse.org/bugs/show_bug.cgi?id=34754
				int index= fProposalTable.getSelectionIndex();
				if (index >= 0)
					selectProposal(index, true);
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
			if (!Helper.okToUse(fProposalShell))
				return;

			if (e.character == 0 && e.keyCode == SWT.CTRL) {
				// http://dev.eclipse.org/bugs/show_bug.cgi?id=34754
				int index= fProposalTable.getSelectionIndex();
				if (index >= 0)
					selectProposal(index, false);
			}
		}
	}

	private final class CommandKeyListener extends KeyAdapter {
		private final KeySequence fCommandSequence;

		private CommandKeyListener(KeySequence keySequence) {
			fCommandSequence= keySequence;
		}

		@Override
		public void keyPressed(KeyEvent e) {
			if (!Helper.okToUse(fProposalShell))
				return;

			int accelerator= SWTKeySupport.convertEventToUnmodifiedAccelerator(e);
			KeySequence sequence= KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator));
			if (sequence.equals(fCommandSequence))
				if (fContentAssistant.isPrefixCompletionEnabled())
					incrementalComplete();
				else
					showProposals(false);

		}
	}


	/** The associated text viewer. */
	ITextViewer fViewer;
	/** The associated content assistant. */
	final ContentAssistant fContentAssistant;
	/** The used additional info controller, or <code>null</code> if none. */
	private final AdditionalInfoController fAdditionalInfoController;
	/** The closing strategy for this completion proposal popup. */
	private final PopupCloser fPopupCloser= new PopupCloser();
	/** The popup shell. */
	Shell fProposalShell;
	/** The proposal table. */
	private Table fProposalTable;
	/** Indicates whether a completion proposal is being inserted. */
	private boolean fInserting= false;
	/** The key listener to control navigation. */
	ProposalSelectionListener fKeyListener;
	/** List of document events used for filtering proposals. */
	private final List<DocumentEvent> fDocumentEvents= new ArrayList<>();
	/** Listener filling the document event queue. */
	private IDocumentListener fDocumentListener;
	/** The filter list of proposals. */
	List<ICompletionProposal> fFilteredProposals;
	/** The computed list of proposals. */
	List<ICompletionProposal> fComputedProposals;
	/** The offset for which the proposals have been computed. */
	int fInvocationOffset;
	/** The offset for which the computed proposals have been filtered. */
	int fFilterOffset;
	/**
	 * The most recently selected proposal.
	 * @since 3.0
	 */
	private ICompletionProposal fLastProposal;
	/**
	 * The content assist subject control.
	 * This replaces <code>fViewer</code>
	 *
	 * @since 3.0
	 */
	IContentAssistSubjectControl fContentAssistSubjectControl;
	/**
	 * The content assist subject control adapter.
	 * This replaces <code>fViewer</code>
	 *
	 * @since 3.0
	 */
	final ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter;
	/**
	 * Remembers the size for this completion proposal popup.
	 * @since 3.0
	 */
	private Point fSize;
	/**
	 * Editor helper that communicates that the completion proposal popup may
	 * have focus while the 'logical focus' is still with the editor.
	 * @since 3.1
	 */
	private IEditingSupport fFocusHelper;
	/**
	 * Set to true by {@link #computeFilteredProposals(int, DocumentEvent)} if
	 * the returned proposals are a subset of {@link #fFilteredProposals},
	 * <code>false</code> if not.
	 * @since 3.1
	 */
	private boolean fIsFilteredSubset;
	/**
	 * The filter runnable.
	 *
	 * @since 3.1.1
	 */
	private final Runnable fFilterRunnable= new Runnable() {
		@Override
		public void run() {
			if (!fIsFilterPending)
				return;

			fIsFilterPending= false;

			if (!Helper.okToUse(fContentAssistSubjectControlAdapter.getControl()))
				return;

			int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
			List<ICompletionProposal> proposals= null;
			DocumentEvent event= null;
			try {
				if (offset > -1) {
					event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents);
					proposals= computeFilteredProposals(offset, event);
				}
			} catch (BadLocationException x) {
			} finally {
				fDocumentEvents.clear();
			}
			fFilterOffset= offset;

			if (proposals != null && proposals.size() > 0)
				setProposals(proposals, fIsFilteredSubset);
			else {
				hide();
				if (fContentAssistant.isAutoActivation() && offset > 0 && event != null) {
					try {
						char charBeforeOffset= event.getDocument().getChar(offset - 1);
						if (fContentAssistant.isAutoActivationTriggerChar(charBeforeOffset)) {
							fContentAssistant.fireSessionBeginEvent(true);
							showProposals(true);
						}
					} catch (BadLocationException e) {
					}
				}
			}
		}
	};
	/**
	 * <code>true</code> if <code>fFilterRunnable</code> has been
	 * posted, <code>false</code> if not.
	 *
	 * @since 3.1.1
	 */
	private boolean fIsFilterPending= false;
	/**
	 * The info message at the bottom of the popup, or <code>null</code> for no popup (if
	 * ContentAssistant does not provide one).
	 *
	 * @since 3.2
	 */
	private Label fMessageText;
	/**
	 * The font used for <code>fMessageText</code> or null; dispose when done.
	 *
	 * @since 3.2
	 */
	private Font fMessageTextFont;
	/**
	 * The most recent completion offset (used to determine repeated invocation)
	 *
	 * @since 3.2
	 */
	int fLastCompletionOffset;
	/**
	 * The (reusable) empty proposal.
	 *
	 * @since 3.2
	 */
	private final EmptyProposal fEmptyProposal= new EmptyProposal();
	/**
	 * The text for the empty proposal, or <code>null</code> to use the default text.
	 *
	 * @since 3.2
	 */
	private String fEmptyMessage= null;
	/**
	 * Tells whether colored labels support is enabled.
	 * Only valid while the popup is active.
	 *
	 * @since 3.4
	 */
	private boolean fIsColoredLabelsSupportEnabled= false;

	/**
	 * The sorter to be used for sorting the proposals or <code>null</code> if no sorting is
	 * requested.
	 *
	 * @since 3.8
	 */
	ICompletionProposalSorter fSorter;

	/**
	 * Set to true by {@link #computeProposals(int)} when initial sorting is performed on the
	 * computed proposals using {@link #fSorter}.
	 *
	 * @since 3.11
	 */
	boolean fIsInitialSort;

	/**
	 * Creates a new completion proposal popup for the given elements.
	 *
	 * @param contentAssistant the content assistant feeding this popup
	 * @param viewer the viewer on top of which this popup appears
	 * @param infoController the information control collaborating with this popup, or <code>null</code>
	 * @since 2.0
	 */
	public CompletionProposalPopup(ContentAssistant contentAssistant, ITextViewer viewer, AdditionalInfoController infoController) {
		fContentAssistant= contentAssistant;
		fViewer= viewer;
		fAdditionalInfoController= infoController;
		fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer);
	}

	/**
	 * Creates a new completion proposal popup for the given elements.
	 *
	 * @param contentAssistant the content assistant feeding this popup
	 * @param contentAssistSubjectControl the content assist subject control on top of which this popup appears
	 * @param infoController the information control collaborating with this popup, or <code>null</code>
	 * @since 3.0
	 */
	public CompletionProposalPopup(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl, AdditionalInfoController infoController) {
		fContentAssistant= contentAssistant;
		fContentAssistSubjectControl= contentAssistSubjectControl;
		fAdditionalInfoController= infoController;
		fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl);
	}

	/**
	 * Computes and presents completion proposals. The flag indicates whether this call has
	 * be made out of an auto activation context.
	 *
	 * @param autoActivated <code>true</code> if auto activation context
	 * @return an error message or <code>null</code> in case of no error
	 */
	public String showProposals(final boolean autoActivated) {

		if (fKeyListener == null)
			fKeyListener= new ProposalSelectionListener();

		final Control control= fContentAssistSubjectControlAdapter.getControl();

		if (!Helper.okToUse(fProposalShell) && control != null && !control.isDisposed()) {
			// add the listener before computing the proposals so we don't move the caret
			// when the user types fast.
			fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);

			BusyIndicator.showWhile(control.getDisplay(), () -> {

				fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
				fFilterOffset= fInvocationOffset;
				fLastCompletionOffset= fFilterOffset;
				fComputedProposals= computeProposals(fInvocationOffset);

				int count= (fComputedProposals == null ? 0 : fComputedProposals.size());
				if (count == 0 && hideWhenNoProposals(autoActivated))
					return;

				if (count == 1 && !autoActivated && canAutoInsert(fComputedProposals.get(0))) {
					insertProposal(fComputedProposals.get(0), (char) 0, 0, fInvocationOffset);
					hide();
				} else {
					createProposalSelector();
					setProposals(fComputedProposals, false);
					displayProposals();
				}
			});
		} else {
			fLastCompletionOffset= fFilterOffset;
			handleRepeatedInvocation();
		}

		return getErrorMessage();
	}

	/**
	 * Hides the popup and returns <code>true</code> if the popup is configured
	 * to never display an empty list. Returns <code>false</code> otherwise.
	 *
	 * @param autoActivated whether the invocation was auto-activated
	 * @return <code>false</code> if an empty list should be displayed, <code>true</code> otherwise
	 * @since 3.2
	 */
	boolean hideWhenNoProposals(boolean autoActivated) {
		if (autoActivated || !fContentAssistant.isShowEmptyList()) {
			if (!autoActivated) {
				Control control= fContentAssistSubjectControlAdapter.getControl();
				if (control != null && !control.isDisposed())
					control.getDisplay().beep();
			}
			hide();
			return true;
		}
		return false;
	}

	/**
	 * If content assist is set up to handle cycling, then the proposals are recomputed. Otherwise,
	 * nothing happens.
	 *
	 * @since 3.2
	 */
	void handleRepeatedInvocation() {
		if (fContentAssistant.isRepeatedInvocationMode()) {
			fComputedProposals= computeProposals(fFilterOffset);
			setProposals(fComputedProposals, false);
		}
	}

	/**
	 * Returns the completion proposals available at the given offset of the viewer's document.
	 * Delegates the work to the content assistant. Sorts the computed proposals if sorting is
	 * requested with {@link #fSorter}.
	 *
	 * @param offset the offset
	 * @return the completion proposals available at this offset, never null
	 */
	List<ICompletionProposal> computeProposals(int offset) {
		ICompletionProposal[] completionProposals;
		if (fContentAssistSubjectControl != null) {
			completionProposals= fContentAssistant.computeCompletionProposals(fContentAssistSubjectControl, offset);
		} else {
			completionProposals= fContentAssistant.computeCompletionProposals(fViewer, offset);
		}
		if (completionProposals == null) {
			return Collections.emptyList();
		}
		List<ICompletionProposal> proposals= Arrays.asList(completionProposals);
		if (fSorter != null) {
			sortProposals(proposals);
			fIsInitialSort= true;
		}
		return proposals;
	}

	/**
	 * Returns the error message.
	 *
	 * @return the error message
	 */
	String getErrorMessage() {
		return fContentAssistant.getErrorMessage();
	}

	/**
	 * Creates the proposal selector.
	 */
	void createProposalSelector() {
		if (Helper.okToUse(fProposalShell))
			return;

		Control control= fContentAssistSubjectControlAdapter.getControl();
		fProposalShell= new Shell(control.getShell(), SWT.ON_TOP | SWT.RESIZE );
		fProposalShell.setFont(JFaceResources.getDefaultFont());
		fProposalTable= new Table(fProposalShell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL);

		Listener listener= new Listener() {
			@Override
			public void handleEvent(Event event) {
				handleSetData(event);
			}
		};
		fProposalTable.addListener(SWT.SetData, listener);

		fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled();
		if (fIsColoredLabelsSupportEnabled)
			TableOwnerDrawSupport.install(fProposalTable);

		fProposalTable.setLocation(0, 0);
		if (fAdditionalInfoController != null)
			fAdditionalInfoController.setSizeConstraints(50, 10, true, true);

		GridLayout layout= new GridLayout();
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		layout.verticalSpacing= 1;
		fProposalShell.setLayout(layout);

		if (fContentAssistant.isStatusLineVisible()) {
			createMessageText();
		}

		GridData data= new GridData(GridData.FILL_BOTH);

		Point size= fContentAssistant.restoreCompletionProposalPopupSize();
		if (size != null) {
			fProposalTable.setLayoutData(data);
			fProposalShell.setSize(size);
		} else {
			int height= fProposalTable.getItemHeight() * 15;
			// use golden ratio as default aspect ratio
			final double aspectRatio= (1 + Math.sqrt(5)) / 2;
			int width= (int) (height * aspectRatio);

			// Make sure our bounds still fit to the screen
			Monitor monitor= Util.getClosestMonitor(fProposalShell.getDisplay(), getLocation());
			Rectangle bounds= monitor.getClientArea();
			width= Math.min(width, bounds.width / 4);
			height= Math.min(height, bounds.height / 4);

			Rectangle trim= fProposalTable.computeTrim(0, 0, width, height);
			data.heightHint= trim.height;
			data.widthHint= trim.width;
			fProposalTable.setLayoutData(data);
			fProposalShell.pack();
		}
		fContentAssistant.addToLayout(this, fProposalShell, ContentAssistant.LayoutManager.LAYOUT_PROPOSAL_SELECTOR, fContentAssistant.getSelectionOffset());

		fProposalShell.addControlListener(new ControlListener() {

			@Override
			public void controlMoved(ControlEvent e) {}

			@Override
			public void controlResized(ControlEvent e) {
				if (fAdditionalInfoController != null) {
					// reset the cached resize constraints
					fAdditionalInfoController.setSizeConstraints(50, 10, true, false);
					fAdditionalInfoController.hideInformationControl();
					fAdditionalInfoController.handleTableSelectionChanged();
				}

				fSize= fProposalShell.getSize();
			}
		});

		Color background= getBackgroundColor(control);
		if (background == null) {
			background= JFaceColors.getInformationViewerBackgroundColor(Display.getDefault());
		}

		Color foreground= getForegroundColor(control);
		if (foreground == null) {
			foreground= JFaceColors.getInformationViewerBackgroundColor(Display.getDefault());
		}

		fProposalShell.setBackground(background);
		fProposalTable.setBackground(background);
		fProposalTable.setForeground(foreground);

		fProposalTable.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				insertSelectedProposalWithMask(e.stateMask);
			}
		});

		fPopupCloser.install(fContentAssistant, fProposalTable, fAdditionalInfoController);

		fProposalShell.addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent e) {
				unregister(); // but don't dispose the shell, since we're being called from its disposal event!
			}
		});

		fProposalTable.setHeaderVisible(false);

		addCommandSupport(fProposalTable);
	}

	/**
	 * Returns the minimal required height for the proposal, may return 0 if the popup has not been
	 * created yet.
	 *
	 * @return the minimal height
	 * @since 3.3
	 */
	int getMinimalHeight() {
		int height= 0;
		if (Helper.okToUse(fProposalTable)) {
			int items= fProposalTable.getItemHeight() * 10;
			Rectangle trim= fProposalTable.computeTrim(0, 0, SWT.DEFAULT, items);
			height= trim.height;
		}
		if (Helper.okToUse(fMessageText))
			height+= fMessageText.getSize().y + 1;
		return height;
	}

	/**
	 * Adds command support to the given control.
	 *
	 * @param control the control to watch for focus
	 * @since 3.2
	 */
    private void addCommandSupport(final Control control) {
    	final KeySequence commandSequence= fContentAssistant.getRepeatedInvocationKeySequence();
    	if (commandSequence != null && !commandSequence.isEmpty() && fContentAssistant.isRepeatedInvocationMode()) {
    		control.addFocusListener(new FocusListener() {
    			private CommandKeyListener fCommandKeyListener;
    			@Override
				public void focusGained(FocusEvent e) {
    				if (Helper.okToUse(control)) {
    					if (fCommandKeyListener == null) {
    						fCommandKeyListener= new CommandKeyListener(commandSequence);
    						fProposalTable.addKeyListener(fCommandKeyListener);
    					}
    				}
    			}
    			@Override
				public void focusLost(FocusEvent e) {
    				if (fCommandKeyListener != null) {
    					control.removeKeyListener(fCommandKeyListener);
    					fCommandKeyListener= null;
    				}
    			}
    		});
    	}
    	if (fAdditionalInfoController != null) {
	    	control.addFocusListener(new FocusListener() {
	    		private TraverseListener fTraverseListener;
	    		@Override
				public void focusGained(FocusEvent e) {
	    			if (Helper.okToUse(control)) {
	    				if (fTraverseListener == null) {
							fTraverseListener= new TraverseListener() {
								@Override
								public void keyTraversed(TraverseEvent event) {
									if (event.detail == SWT.TRAVERSE_TAB_NEXT) {
										IInformationControl iControl= fAdditionalInfoController.getCurrentInformationControl2();
										if (fAdditionalInfoController.getInternalAccessor().canReplace(iControl)) {
											fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true);
											event.doit= false;
										}
									}
								}
							};
	    					fProposalTable.addTraverseListener(fTraverseListener);
	    				}
	    			}
	    		}
	    		@Override
				public void focusLost(FocusEvent e) {
	    			if (fTraverseListener != null) {
	    				control.removeTraverseListener(fTraverseListener);
	    				fTraverseListener= null;
	    			}
	    		}
	    	});
    	}
    }

	/**
	 * Returns the background color to use.
	 *
	 * @param control the control to get the display from
	 * @return the background color
	 * @since 3.2
	 */
	private Color getBackgroundColor(Control control) {
		Color c= fContentAssistant.getProposalSelectorBackground();
		if (c == null)
			c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_BACKGROUND_COLOR);
		return c;
	}

	/**
	 * Returns the foreground color to use.
	 *
	 * @param control the control to get the display from
	 * @return the foreground color
	 * @since 3.2
	 */
	private Color getForegroundColor(Control control) {
		Color c= fContentAssistant.getProposalSelectorForeground();
		if (c == null)
			c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR);
		return c;
	}

	/**
	 * Creates the caption line under the proposal table.
	 *
	 * @since 3.2
	 */
	private void createMessageText() {
		if (fMessageText == null) {
			fMessageText= new Label(fProposalShell, SWT.RIGHT);
			GridData textData= new GridData(SWT.FILL, SWT.BOTTOM, true, false);
			fMessageText.setLayoutData(textData);
			fMessageText.setText(fContentAssistant.getStatusMessage() + " "); //$NON-NLS-1$
			if (fMessageTextFont == null) {
				Font font= fMessageText.getFont();
				Display display= fProposalShell.getDisplay();
				FontData[] fontDatas= font.getFontData();
				for (FontData fontData : fontDatas)
					fontData.setHeight(fontData.getHeight() * 9 / 10);
				fMessageTextFont= new Font(display, fontDatas);
			}
			fMessageText.setFont(fMessageTextFont);
			fMessageText.setBackground(getBackgroundColor(fProposalShell));
			fMessageText.setForeground(getForegroundColor(fProposalShell));

			if (fContentAssistant.isRepeatedInvocationMode()) {
				fMessageText.setCursor(fProposalShell.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
				fMessageText.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseUp(MouseEvent e) {
						fLastCompletionOffset= fFilterOffset;
						fProposalTable.setFocus();
						handleRepeatedInvocation();
					}

					@Override
					public void mouseDown(MouseEvent e) {
					}
				});
			}
		}
	}

	/*
	 * @since 3.1
	 */
	private void handleSetData(Event event) {
		TableItem item= (TableItem) event.item;
		int index= fProposalTable.indexOf(item);

		if (0 <= index && index < fFilteredProposals.size()) {
			ICompletionProposal current= fFilteredProposals.get(index);

			String displayString;
			StyleRange[] styleRanges= null;
			Image image= null;
			try {
				if (fIsColoredLabelsSupportEnabled && current instanceof ICompletionProposalExtension7 && Helper.okToUse(fProposalShell)) {
					BoldStylerProvider boldStylerProvider= fContentAssistant.getBoldStylerProvider();
					if (boldStylerProvider == null) {
						boldStylerProvider= new BoldStylerProvider(fProposalShell.getFont());
						fContentAssistant.setBoldStylerProvider(boldStylerProvider);
					}
					StyledString styledString= ((ICompletionProposalExtension7) current).getStyledDisplayString(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset,
							boldStylerProvider);
					displayString= styledString.getString();
					styleRanges= styledString.getStyleRanges();
				} else if (fIsColoredLabelsSupportEnabled && current instanceof ICompletionProposalExtension6) {
					StyledString styledString= ((ICompletionProposalExtension6) current).getStyledDisplayString();
					displayString= styledString.getString();
					styleRanges= styledString.getStyleRanges();
				} else {
					displayString= current.getDisplayString();
				}
			} catch (RuntimeException e) {
				// On failures to retrieve the proposal's text, insert a dummy entry and log the error.
				displayString= JFaceTextMessages.getString("CompletionProposalPopup.error_retrieving_proposal"); //$NON-NLS-1$

				String PLUGIN_ID= "org.eclipse.jface.text"; //$NON-NLS-1$
				ILog log= Platform.getLog(Platform.getBundle(PLUGIN_ID));
				log.log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, JFaceTextMessages.getString("CompletionProposalPopup.unexpected_error"), e)); //$NON-NLS-1$
			}

			try {
				image= current.getImage();
			} catch (RuntimeException e) {
				// If we are unable to retrieve the proposal's image, leave it blank.
			}

			item.setText(displayString);
			if (fIsColoredLabelsSupportEnabled)
				TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges);

			item.setImage(image);
			item.setData(current);
		} else {
			// this should not happen, but does on win32
		}
	}

	/**
	 * Returns the proposal selected in the proposal selector.
	 *
	 * @return the selected proposal
	 * @since 2.0
	 */
	private ICompletionProposal getSelectedProposal() {
		/* Make sure that there is no filter runnable pending.
		 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=31427
		 */
		if (fIsFilterPending)
			fFilterRunnable.run();

		// filter runnable may have hidden the proposals
		if (!Helper.okToUse(fProposalTable))
			return null;

		int i= fProposalTable.getSelectionIndex();
		if (fFilteredProposals == null || i < 0 || i >= fFilteredProposals.size())
			return null;
		return fFilteredProposals.get(i);
	}

	/**
	 * Takes the selected proposal and applies it.
	 *
	 * @param stateMask the state mask
	 * @since 3.2
	 */
	private void insertSelectedProposalWithMask(int stateMask) {
		ICompletionProposal p= getSelectedProposal();
		hide();
		if (p != null)
			insertProposal(p, (char) 0, stateMask, fContentAssistSubjectControlAdapter.getSelectedRange().x);
	}

	/**
	 * Applies the given proposal at the given offset. The given character is the
	 * one that triggered the insertion of this proposal.
	 *
	 * @param p the completion proposal
	 * @param trigger the trigger character
	 * @param stateMask the state mask
	 * @param offset the offset
	 * @since 2.1
	 */
	void insertProposal(ICompletionProposal p, char trigger, int stateMask, final int offset) {

		fInserting= true;
		IRewriteTarget target= null;
		IEditingSupport helper= new IEditingSupport() {

			@Override
			public boolean isOriginator(DocumentEvent event, IRegion focus) {
				return focus.getOffset() <= offset && focus.getOffset() + focus.getLength() >= offset;
			}

			@Override
			public boolean ownsFocusShell() {
				return false;
			}

		};

		try {

			IDocument document= fContentAssistSubjectControlAdapter.getDocument();

			if (fViewer instanceof ITextViewerExtension) {
				ITextViewerExtension extension= (ITextViewerExtension) fViewer;
				target= extension.getRewriteTarget();
			}

			if (target != null)
				target.beginCompoundChange();

			if (fViewer instanceof IEditingSupportRegistry) {
				IEditingSupportRegistry registry= (IEditingSupportRegistry) fViewer;
				registry.register(helper);
			}


			if (p instanceof ICompletionProposalExtension2 && fViewer != null) {
				ICompletionProposalExtension2 e= (ICompletionProposalExtension2) p;
				e.apply(fViewer, trigger, stateMask, offset);
			} else if (p instanceof ICompletionProposalExtension) {
				ICompletionProposalExtension e= (ICompletionProposalExtension) p;
				e.apply(document, trigger, offset);
			} else {
				p.apply(document);
			}
			fireAppliedEvent(p);

			Point selection= p.getSelection(document);
			if (selection != null) {
				fContentAssistSubjectControlAdapter.setSelectedRange(selection.x, selection.y);
				fContentAssistSubjectControlAdapter.revealRange(selection.x, selection.y);
			}

			IContextInformation info= p.getContextInformation();
			if (info != null) {

				int contextInformationOffset;
				if (p instanceof ICompletionProposalExtension) {
					ICompletionProposalExtension e= (ICompletionProposalExtension) p;
					contextInformationOffset= e.getContextInformationPosition();
				} else {
					if (selection == null)
						selection= fContentAssistSubjectControlAdapter.getSelectedRange();
					contextInformationOffset= selection.x + selection.y;
				}

				fContentAssistant.showContextInformation(info, contextInformationOffset);
			} else
				fContentAssistant.showContextInformation(null, -1);


		} finally {
			if (target != null)
				target.endCompoundChange();

			if (fViewer instanceof IEditingSupportRegistry) {
				IEditingSupportRegistry registry= (IEditingSupportRegistry) fViewer;
				registry.unregister(helper);
			}
			fInserting= false;
		}
	}

	/**
	 * Returns whether this popup has the focus.
	 *
	 * @return <code>true</code> if the popup has the focus
	 */
	public boolean hasFocus() {
		if (Helper.okToUse(fProposalShell)) {
			if ((fProposalShell.getDisplay().getActiveShell() == fProposalShell))
				return true;
			/*
			 * We have to delegate this query to the additional info controller
			 * as well, since the content assistant is the widget token owner
			 * and its closer does not know that the additional info control can
			 * now also take focus.
			 */
			if (fAdditionalInfoController != null) {
				IInformationControl informationControl= fAdditionalInfoController.getCurrentInformationControl2();
				if (informationControl != null && informationControl.isFocusControl())
					return true;
				InformationControlReplacer replacer= fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer();
				if (replacer != null) {
					informationControl= replacer.getCurrentInformationControl2();
					if (informationControl != null && informationControl.isFocusControl())
						return true;
				}
			}
		}

		return false;
	}

	/**
	 * Hides this popup.
	 */
	public void hide() {

		unregister();

		if (fViewer instanceof IEditingSupportRegistry) {
			IEditingSupportRegistry registry= (IEditingSupportRegistry) fViewer;
			registry.unregister(fFocusHelper);
		}

		if (Helper.okToUse(fProposalShell)) {

			fContentAssistant.removeContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR);

			fPopupCloser.uninstall();
			fProposalShell.setVisible(false);
			fProposalShell.dispose();
			fProposalShell= null;
		}

		if (fMessageTextFont != null) {
			fMessageTextFont.dispose();
			fMessageTextFont= null;
		}

		if (fMessageText != null) {
			fMessageText= null;
		}

		fEmptyMessage= null;

		fLastCompletionOffset= -1;

		fContentAssistant.fireSessionEndEvent();
	}

	/**
	 * Unregister this completion proposal popup.
	 *
	 * @since 3.0
	 */
	private void unregister() {
		if (fDocumentListener != null) {
			IDocument document= fContentAssistSubjectControlAdapter.getDocument();
			if (document != null)
				document.removeDocumentListener(fDocumentListener);
			fDocumentListener= null;
		}
		fDocumentEvents.clear();

		if (fKeyListener != null && fContentAssistSubjectControlAdapter.getControl() != null && !fContentAssistSubjectControlAdapter.getControl().isDisposed()) {
			fContentAssistSubjectControlAdapter.removeKeyListener(fKeyListener);
			fKeyListener= null;
		}

		if (fLastProposal != null) {
			if (fLastProposal instanceof ICompletionProposalExtension2 && fViewer != null) {
				ICompletionProposalExtension2 extension= (ICompletionProposalExtension2) fLastProposal;
				extension.unselected(fViewer);
			}
			fLastProposal= null;
		}

		fFilteredProposals= null;
		fComputedProposals= null;

		fContentAssistant.possibleCompletionsClosed();
	}

	/**
	 *Returns whether this popup is active. It is active if the proposal selector is visible.
	 *
	 * @return <code>true</code> if this popup is active
	 */
	public boolean isActive() {
		return fProposalShell != null && !fProposalShell.isDisposed();
	}

	/**
	 * Initializes the proposal selector with these given proposals. If a proposal sorter is
	 * configured, the given proposals are sorted before.
	 *
	 * @param proposals the proposals
	 * @param isFilteredSubset if <code>true</code>, the proposal table is
	 *        not cleared, but the proposals that are not in the passed array
	 *        are removed from the displayed set
	 */
	void setProposals(List<ICompletionProposal> proposals, boolean isFilteredSubset) {
		List<ICompletionProposal> oldProposals= fFilteredProposals;
		ICompletionProposal oldProposal= getSelectedProposal(); // may trigger filtering and a reentrant call to setProposals()
		if (oldProposals != fFilteredProposals) // reentrant call was first - abort
			return;

		if (Helper.okToUse(fProposalTable)) {
			if (oldProposal instanceof ICompletionProposalExtension2 && fViewer != null)
				((ICompletionProposalExtension2) oldProposal).unselected(fViewer);

			if (proposals == null || proposals.isEmpty()) {
				fEmptyProposal.fOffset= fFilterOffset;
				fEmptyProposal.fDisplayString= fEmptyMessage != null ? fEmptyMessage : JFaceTextMessages.getString("CompletionProposalPopup.no_proposals"); //$NON-NLS-1$
				proposals= Collections.singletonList(fEmptyProposal);
			}

			if (fSorter != null && !fIsInitialSort) {
				sortProposals(proposals);
			}
			fIsInitialSort= false;

			fFilteredProposals= proposals;
			final int newLen= proposals.size();

			fProposalTable.clearAll();
			fProposalTable.setItemCount(newLen);

			Point currentLocation= fProposalShell.getLocation();
			Point newLocation= getLocation();
			if ((newLocation.x < currentLocation.x && newLocation.y == currentLocation.y) || newLocation.y < currentLocation.y)
				fProposalShell.setLocation(newLocation);

			selectProposal(0, false);
		}
	}

	/**
	 * Returns the graphical location at which this popup should be made visible.
	 *
	 * @return the location of this popup
	 */
	private Point getLocation() {
		int caret= fContentAssistSubjectControlAdapter.getCaretOffset();
		Rectangle location= fContentAssistant.getLayoutManager().computeBoundsBelowAbove(fProposalShell, fSize == null ? fProposalShell.getSize() : fSize, caret, this);
		return Geometry.getLocation(location);
	}

	/**
	 * Returns the size of this completion proposal popup.
	 *
	 * @return a Point containing the size
	 * @since 3.0
	 */
	Point getSize() {
		return fSize;
	}

	/**
	 * Displays this popup and install the additional info controller, so that additional info
	 * is displayed when a proposal is selected and additional info is available.
	 */
	void displayProposals() {

		if (!Helper.okToUse(fProposalShell) ||  !Helper.okToUse(fProposalTable))
			return;

		if (fContentAssistant.addContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR)) {

			ensureDocumentListenerInstalled();

			if (fFocusHelper == null) {
				fFocusHelper= new IEditingSupport() {

					@Override
					public boolean isOriginator(DocumentEvent event, IRegion focus) {
						return false; // this helper just covers the focus change to the proposal shell, no remote editions
					}

					@Override
					public boolean ownsFocusShell() {
						return true;
					}

				};
			}
			if (fViewer instanceof IEditingSupportRegistry) {
				IEditingSupportRegistry registry= (IEditingSupportRegistry) fViewer;
				registry.register(fFocusHelper);
			}


			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=52646
			 * on GTK, setVisible and such may run the event loop
			 * (see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=47511)
			 * Since the user may have already canceled the popup or selected
			 * an entry (ESC or RETURN), we have to double check whether
			 * the table is still okToUse. See comments below
			 */
			fProposalShell.setVisible(true); // may run event loop on GTK
			// transfer focus since no verify key listener can be attached
			if (!fContentAssistSubjectControlAdapter.supportsVerifyKeyListener() && Helper.okToUse(fProposalShell))
				fProposalShell.setFocus(); // may run event loop on GTK ??

			if (fAdditionalInfoController != null && Helper.okToUse(fProposalTable)) {
				fAdditionalInfoController.install(fProposalTable);
				fAdditionalInfoController.handleTableSelectionChanged();
			}
		} else
			hide();
	}

	/**
	 * Installs the document listener if not already done.
	 *
	 * @since 3.2
	 */
	void ensureDocumentListenerInstalled() {
		if (fDocumentListener == null) {
			fDocumentListener=  new IDocumentListener()  {
				@Override
				public void documentAboutToBeChanged(DocumentEvent event) {
					if (!fInserting)
						fDocumentEvents.add(event);
				}

				@Override
				public void documentChanged(DocumentEvent event) {
					if (!fInserting)
						filterProposals();
				}
			};
			IDocument document= fContentAssistSubjectControlAdapter.getDocument();
			if (document != null)
				document.addDocumentListener(fDocumentListener);
		}
	}

	@Override
	public boolean verifyKey(VerifyEvent e) {
		if (!Helper.okToUse(fProposalShell))
			return true;

		char key= e.character;
		if (key == 0) {
			int newSelection= fProposalTable.getSelectionIndex();
			int visibleRows= (fProposalTable.getSize().y / fProposalTable.getItemHeight()) - 1;
			int itemCount= fProposalTable.getItemCount();
			switch (e.keyCode) {

				case SWT.ARROW_LEFT :
				case SWT.ARROW_RIGHT :
					filterProposals();
					return true;

				case SWT.ARROW_UP :
					newSelection -= 1;
					if (newSelection < 0)
						newSelection= itemCount - 1;
					break;

				case SWT.ARROW_DOWN :
					newSelection += 1;
					if (newSelection > itemCount - 1)
						newSelection= 0;
					break;

				case SWT.PAGE_DOWN :
					newSelection += visibleRows;
					if (newSelection >= itemCount)
						newSelection= itemCount - 1;
					break;

				case SWT.PAGE_UP :
					newSelection -= visibleRows;
					if (newSelection < 0)
						newSelection= 0;
					break;

				case SWT.HOME :
					newSelection= 0;
					break;

				case SWT.END :
					newSelection= itemCount - 1;
					break;

				default :
					if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1 && e.keyCode != SWT.MOD2 && e.keyCode != SWT.MOD3 && e.keyCode != SWT.MOD4)
						hide();
					return true;
			}

			selectProposal(newSelection, (e.stateMask & SWT.CTRL) != 0);

			e.doit= false;
			return false;

		}

		// key != 0
		switch (key) {
			case 0x1B: // Esc
				e.doit= false;
				hide();
				break;

			case '\n': // Ctrl-Enter on w2k
			case '\r': // Enter
				e.doit= false;
				insertSelectedProposalWithMask(e.stateMask);
				break;

			case '\t':
				e.doit= false;
				fProposalShell.setFocus();
				return false;

			default:
				if (fContentAssistant.isCompletionProposalTriggerCharsEnabled()) {
					ICompletionProposal p= getSelectedProposal();
					if (p instanceof ICompletionProposalExtension) {
						ICompletionProposalExtension t= (ICompletionProposalExtension) p;
						char[] triggers= t.getTriggerCharacters();
						if (contains(triggers, key)) {
							e.doit= false;
							hide();
							insertProposal(p, key, e.stateMask, fContentAssistSubjectControlAdapter.getSelectedRange().x);
						}
					}
				}
		}

		return true;
	}

	/**
	 * Selects the entry with the given index in the proposal selector and feeds
	 * the selection to the additional info controller.
	 *
	 * @param index the index in the list
	 * @param smartToggle <code>true</code> if the smart toggle key has been pressed
	 * @since 2.1
	 */
	private void selectProposal(int index, boolean smartToggle) {

		ICompletionProposal oldProposal= getSelectedProposal();
		if (oldProposal instanceof ICompletionProposalExtension2 && fViewer != null)
			((ICompletionProposalExtension2) oldProposal).unselected(fViewer);

		if (fFilteredProposals == null) {
			fireSelectionEvent(null, smartToggle);
			return;
		}

		ICompletionProposal proposal= fFilteredProposals.get(index);
		if (proposal instanceof ICompletionProposalExtension2 && fViewer != null)
			((ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle);

		fireSelectionEvent(proposal, smartToggle);

		fLastProposal= proposal;

		fProposalTable.setSelection(index);
		fProposalTable.showSelection();
		if (fAdditionalInfoController != null)
			fAdditionalInfoController.handleTableSelectionChanged();
	}

	/**
	 * Fires a selection event, see {@link ICompletionListener}.
	 *
	 * @param proposal the selected proposal, possibly <code>null</code>
	 * @param smartToggle true if the smart toggle is on
	 * @since 3.2
	 */
	private void fireSelectionEvent(ICompletionProposal proposal, boolean smartToggle) {
		fContentAssistant.fireSelectionEvent(proposal, smartToggle);
	}

	/**
	 * Fires an event after applying the given proposal, see {@link ICompletionListenerExtension2}.
	 *
	 * @param proposal the applied proposal
	 * @since 3.8
	 */
	private void fireAppliedEvent(ICompletionProposal proposal) {
		fContentAssistant.fireAppliedEvent(proposal);
	}

	/**
	 * Returns whether the given character is contained in the given array of characters.
	 *
	 * @param characters the list of characters
	 * @param c the character to look for in the list
	 * @return <code>true</code> if character belongs to the list
	 * @since 2.0
	 */
	private boolean contains(char[] characters, char c) {

		if (characters == null)
			return false;

		for (char character : characters) {
			if (c == character)
				return true;
		}

		return false;
	}

	@Override
	public void processEvent(VerifyEvent e) {
	}

	/**
	 * Filters the displayed proposal based on the given cursor position and the
	 * offset of the original invocation of the content assistant.
	 */
	void filterProposals() {
		if (!fIsFilterPending) {
			fIsFilterPending= true;
			Control control= fContentAssistSubjectControlAdapter.getControl();
			control.getDisplay().asyncExec(fFilterRunnable);
		}
	}

	/**
	 * Computes the subset of already computed proposals that are still valid for
	 * the given offset.
	 *
	 * @param offset the offset
	 * @param event the merged document event
	 * @return the set of filtered proposals
	 * @since 3.0
	 */
	List<ICompletionProposal> computeFilteredProposals(int offset, DocumentEvent event) {

		if (offset == fInvocationOffset && event == null) {
			fIsFilteredSubset= false;
			return fComputedProposals;
		}

		if (offset < fInvocationOffset) {
			fIsFilteredSubset= false;
			fInvocationOffset= offset;
			fContentAssistant.fireSessionRestartEvent();
			fComputedProposals= computeProposals(fInvocationOffset);
			return fComputedProposals;
		}

		List<ICompletionProposal> proposals;
		if (offset < fFilterOffset) {
			proposals= fComputedProposals;
			fIsFilteredSubset= false;
		} else {
			proposals= fFilteredProposals;
			fIsFilteredSubset= true;
		}

		if (proposals == null) {
			fIsFilteredSubset= false;
			return null;
		}

		IDocument document= fContentAssistSubjectControlAdapter.getDocument();
		int length= proposals.size();
		List<ICompletionProposal> filtered= new ArrayList<>(length);
		for (ICompletionProposal proposal : proposals) {

			if (proposal instanceof ICompletionProposalExtension2) {

				ICompletionProposalExtension2 p= (ICompletionProposalExtension2) proposal;
				try {
					if (p.validate(document, offset, event))
						filtered.add(proposal);
				} catch (RuntimeException e) {
					// Make sure that poorly behaved completion proposers do not break filtering.
				}
			} else if (proposal instanceof ICompletionProposalExtension) {

				ICompletionProposalExtension p= (ICompletionProposalExtension) proposal;
				try {
					if (p.isValidFor(document, offset))
						filtered.add(proposal);
				} catch (RuntimeException e) {
					// Make sure that poorly behaved completion proposers do not break filtering.
				}
			} else {
				// restore original behavior
				fIsFilteredSubset= false;
				fInvocationOffset= offset;
				fContentAssistant.fireSessionRestartEvent();
				fComputedProposals= computeProposals(fInvocationOffset);
				return fComputedProposals;
			}
		}

		return filtered;
	}

	/**
	 * Requests the proposal shell to take focus.
	 *
	 * @since 3.0
	 */
	public void setFocus() {
		if (Helper.okToUse(fProposalShell)) {
			fProposalShell.setFocus();
		}
	}

	/**
	 * Returns <code>true</code> if <code>proposal</code> should be auto-inserted,
	 * <code>false</code> otherwise.
	 *
	 * @param proposal the single proposal that might be automatically inserted
	 * @return <code>true</code> if <code>proposal</code> can be inserted automatically,
	 *         <code>false</code> otherwise
	 * @since 3.1
	 */
	boolean canAutoInsert(ICompletionProposal proposal) {
		if (fContentAssistant.isAutoInserting()) {
			if (proposal instanceof ICompletionProposalExtension4) {
				ICompletionProposalExtension4 ext= (ICompletionProposalExtension4) proposal;
				return ext.isAutoInsertable();
			}
			return true; // default behavior before ICompletionProposalExtension4 was introduced
		}
		return false;
	}

	/**
	 * Completes the common prefix of all proposals directly in the code. If no
	 * common prefix can be found, the proposal popup is shown.
	 *
	 * @return an error message if completion failed.
	 * @since 3.0
	 */
	public String incrementalComplete() {
		if (Helper.okToUse(fProposalShell) && fFilteredProposals != null) {
			if (fLastCompletionOffset == fFilterOffset) {
				handleRepeatedInvocation();
			} else {
				fLastCompletionOffset= fFilterOffset;
				completeCommonPrefix();
			}
		} else {
			final Control control= fContentAssistSubjectControlAdapter.getControl();

			if (fKeyListener == null)
				fKeyListener= new ProposalSelectionListener();

			if (!Helper.okToUse(fProposalShell) && !control.isDisposed())
				fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);

			BusyIndicator.showWhile(control.getDisplay(), () -> {

				fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
				fFilterOffset= fInvocationOffset;
				fLastCompletionOffset= fFilterOffset;
				fFilteredProposals= computeProposals(fInvocationOffset);

				int count= (fFilteredProposals == null ? 0 : fFilteredProposals.size());
				if (count == 0 && hideWhenNoProposals(false))
					return;

				if (count == 1 && canAutoInsert(fFilteredProposals.get(0))) {
					insertProposal(fFilteredProposals.get(0), (char) 0, 0, fInvocationOffset);
					hide();
				} else {
					ensureDocumentListenerInstalled();
					if (count > 0 && completeCommonPrefix())
						hide();
					else {
						fComputedProposals= fFilteredProposals;
						createProposalSelector();
						setProposals(fComputedProposals, false);
						displayProposals();
					}
				}
			});
		}
		return getErrorMessage();
	}

	/**
	 * Acts upon <code>fFilteredProposals</code>: if there is just one valid
	 * proposal, it is inserted, otherwise, the common prefix of all proposals
	 * is inserted into the document. If there is no common prefix, nothing
	 * happens and <code>false</code> is returned.
	 *
	 * @return <code>true</code> if a single proposal was inserted and the
	 *         selector can be closed, <code>false</code> otherwise
	 * @since 3.0
	 */
	boolean completeCommonPrefix() {

		// 0: insert single proposals
		if (fFilteredProposals.size() == 1) {
			if (canAutoInsert(fFilteredProposals.get(0))) {
				insertProposal(fFilteredProposals.get(0), (char) 0, 0, fFilterOffset);
				hide();
				return true;
			}
			return false;
		}

		// 1: extract pre- and postfix from all remaining proposals
		IDocument document= fContentAssistSubjectControlAdapter.getDocument();

		// contains the common postfix in the case that there are any proposals matching our LHS
		StringBuilder rightCasePostfix= null;
		List<ICompletionProposal> rightCase= new ArrayList<>();

		boolean isWrongCaseMatch= false;

		// the prefix of all case insensitive matches. This differs from the document
		// contents and will be replaced.
		CharSequence wrongCasePrefix= null;
		int wrongCasePrefixStart= 0;
		// contains the common postfix of all case-insensitive matches
		StringBuilder wrongCasePostfix= null;
		List<ICompletionProposal> wrongCase= new ArrayList<>();

		boolean hasMixedProposals= hasMixedProposals();
		for (int i= 0; i < fFilteredProposals.size(); i++) {
			ICompletionProposal proposal= fFilteredProposals.get(i);

			if (!(proposal instanceof ICompletionProposalExtension3))
				return false;

			int start= ((ICompletionProposalExtension3)proposal).getPrefixCompletionStart(document, fFilterOffset);
			CharSequence insertion= ((ICompletionProposalExtension3)proposal).getPrefixCompletionText(document, fFilterOffset);
			if (insertion == null)
				insertion= TextProcessor.deprocess(proposal.getDisplayString());
			try {
				int prefixLength= fFilterOffset - start;
				int relativeCompletionOffset= Math.min(insertion.length(), prefixLength);
				String prefix= document.get(start, prefixLength);
				if (!isWrongCaseMatch && insertion.toString().startsWith(prefix) && !hasMixedProposals) {
					isWrongCaseMatch= false;
					rightCase.add(proposal);
					CharSequence newPostfix= insertion.subSequence(relativeCompletionOffset, insertion.length());
					if (rightCasePostfix == null)
						rightCasePostfix= new StringBuilder(newPostfix.toString());
					else
						truncatePostfix(rightCasePostfix, newPostfix, false);
				} else if (i == 0 || isWrongCaseMatch) {
					String insertionStrLowerCase= insertion.toString().toLowerCase();
					String prefixLowerCase= prefix.toLowerCase();
					boolean isSubstringMatch= !insertionStrLowerCase.startsWith(prefixLowerCase) && insertionStrLowerCase.contains(prefixLowerCase);

					CharSequence newPrefix;
					if (isSubstringMatch) {
						int subStrStart= insertionStrLowerCase.indexOf(prefixLowerCase);
						newPrefix= insertion.subSequence(subStrStart, subStrStart + relativeCompletionOffset);
					} else {
						newPrefix= insertion.subSequence(0, relativeCompletionOffset);
					}
					if (isPrefixCompatible(wrongCasePrefix, wrongCasePrefixStart, newPrefix, start, document, hasMixedProposals)) {
						isWrongCaseMatch= true;
						if (insertionStrLowerCase.isEmpty()) {
							newPrefix= prefix;
						}
						if (wrongCasePrefix == null || !hasMixedProposals || !wrongCasePrefix.toString().equalsIgnoreCase(newPrefix.toString())) {
							wrongCasePrefix= newPrefix; // ignore casing when there are mixed proposals - don't update if newPrefix differs only in case
						}
						wrongCasePrefixStart= start;
						CharSequence newPostfix;
						if (isSubstringMatch) {
							int subStrStart= insertionStrLowerCase.indexOf(prefixLowerCase);
							newPostfix= insertion.subSequence(subStrStart + prefixLength, insertion.length());
						} else {
							newPostfix= insertion.subSequence(relativeCompletionOffset, insertion.length());
						}
						if (wrongCasePostfix == null)
							wrongCasePostfix= new StringBuilder(newPostfix.toString());
						else
							truncatePostfix(wrongCasePostfix, newPostfix, hasMixedProposals);
						wrongCase.add(proposal);
					} else {
						return false;
					}
				} else
					return false;
			} catch (BadLocationException e2) {
				// bail out silently
				return false;
			}

			if (rightCasePostfix != null && rightCasePostfix.length() == 0 && rightCase.size() > 1)
				return false;
		}

		// 2: replace single proposals

		if (rightCase.size() == 1) {
			ICompletionProposal proposal= rightCase.get(0);
			if (canAutoInsert(proposal) && rightCasePostfix.length() > 0) {
				insertProposal(proposal, (char) 0, 0, fInvocationOffset);
				hide();
				return true;
			}
			return false;
		} else if (isWrongCaseMatch && wrongCase.size() == 1) {
			ICompletionProposal proposal= wrongCase.get(0);
			if (canAutoInsert(proposal)) {
				insertProposal(proposal, (char) 0, 0, fInvocationOffset);
				hide();
			return true;
			}
			return false;
		}

		// 3: replace post- / prefixes

		CharSequence prefix;
		if (isWrongCaseMatch)
			prefix= wrongCasePrefix;
		else
			prefix= "";  //$NON-NLS-1$

		CharSequence postfix;
		if (isWrongCaseMatch)
			postfix= wrongCasePostfix;
		else
			postfix= rightCasePostfix;

		if (prefix == null || postfix == null)
			return false;

		try {
			// 4: check if parts of the postfix are already in the document
			int to= Math.min(document.getLength(), fFilterOffset + postfix.length());
			StringBuilder inDocument= new StringBuilder(document.get(fFilterOffset, to - fFilterOffset));
			truncatePostfix(inDocument, postfix, hasMixedProposals);

			// 5: replace and reveal
			document.replace(fFilterOffset - prefix.length(), prefix.length() + inDocument.length(), prefix.toString() + postfix.toString());

			fContentAssistSubjectControlAdapter.setSelectedRange(fFilterOffset + postfix.length(), 0);
			fContentAssistSubjectControlAdapter.revealRange(fFilterOffset + postfix.length(), 0);
			fFilterOffset+= postfix.length();
			fLastCompletionOffset= fFilterOffset;

			return false;
		} catch (BadLocationException e) {
			// ignore and return false
			return false;
		}
	}

	/**
	 * Checks if {@link #fFilteredProposals} list contains proposals based on different rules
	 * (prefix and substring match rules). While extracting the common prefix, if substring
	 * proposals are also present along with prefix proposals (i.e. <code>fFilteredProposals</code>
	 * list has mixed proposals) then casing of substring matches is ignored for the computation of
	 * common prefix.
	 *
	 * @return <code>true</code> if <code>fFilteredProposals</code> list contains proposals based on
	 *         different rules
	 */
	private boolean hasMixedProposals() {
		IDocument document= fContentAssistSubjectControlAdapter.getDocument();
		boolean hasSubstringMatch= false;
		boolean hasPrefixMatch= false;
		for (ICompletionProposal proposal : fFilteredProposals) {
			if (!(proposal instanceof ICompletionProposalExtension3))
				return false;

			int start= ((ICompletionProposalExtension3) proposal).getPrefixCompletionStart(document, fFilterOffset);
			CharSequence insertion= ((ICompletionProposalExtension3) proposal).getPrefixCompletionText(document, fFilterOffset);
			if (insertion == null) {
				insertion= TextProcessor.deprocess(proposal.getDisplayString());
			}
			int prefixLength= fFilterOffset - start;
			try {
				String prefix= document.get(start, prefixLength);
				String insertionString= insertion.toString();
				if (insertionString.isEmpty() || insertionString.toLowerCase().startsWith(prefix.toLowerCase())) {
					hasPrefixMatch= true;
				} else if (insertionString.toLowerCase().contains(prefix.toLowerCase())) {
					hasSubstringMatch= true;
				}
			} catch (BadLocationException e) {
				return false;
			}
			if (hasPrefixMatch && hasSubstringMatch) {
				return true;
			}
		}
		return false;
	}

	/*
	 * @since 3.1
	 */
	private boolean isPrefixCompatible(CharSequence oneSequence, int oneOffset, CharSequence twoSequence, int twoOffset, IDocument document, boolean ignoreCase) throws BadLocationException {
		if (oneSequence == null || twoSequence == null)
			return true;

		int min= Math.min(oneOffset, twoOffset);
		int oneEnd= oneOffset + oneSequence.length();
		int twoEnd= twoOffset + twoSequence.length();

		String one= document.get(oneOffset, min - oneOffset) + oneSequence + document.get(oneEnd, Math.min(fFilterOffset, fFilterOffset - oneEnd));
		String two= document.get(twoOffset, min - twoOffset) + twoSequence + document.get(twoEnd, Math.min(fFilterOffset, fFilterOffset - twoEnd));

		return ignoreCase ? one.equalsIgnoreCase(two) : one.equals(two);
	}

	/**
	 * Truncates <code>buffer</code> to the common prefix of <code>buffer</code>
	 * and <code>sequence</code>.
	 *
	 * @param buffer the common postfix to truncate
	 * @param sequence the characters to truncate with
	 * @param ignoreCase <code>true</code> to ignore case while comparing
	 */
	private void truncatePostfix(StringBuilder buffer, CharSequence sequence, boolean ignoreCase) {
		// find common prefix
		int min= Math.min(buffer.length(), sequence.length());
		for (int c= 0; c < min; c++) {
			boolean matches;
			if (ignoreCase) {
				matches= Character.toUpperCase(sequence.charAt(c)) == Character.toUpperCase(buffer.charAt(c));
			} else {
				matches= sequence.charAt(c) == buffer.charAt(c);
			}
			if (!matches) {
				buffer.delete(c, buffer.length());
				return;
			}
		}

		// all equal up to minimum
		buffer.delete(min, buffer.length());
	}

	/**
	 * Sets the message for the repetition affordance text at the bottom of the proposal. Only has
	 * an effect if {@link ContentAssistant#isRepeatedInvocationMode()} returns <code>true</code>.
	 *
	 * @param message the new caption
	 * @since 3.2
	 */
	void setMessage(String message) {
		Assert.isNotNull(message);
		if (isActive() && fMessageText != null && !fMessageText.isDisposed())
			fMessageText.setText(message + " "); //$NON-NLS-1$
	}

	/**
	 * Sets the text to be displayed if no proposals are available. Only has an effect if
	 * {@link ContentAssistant#isShowEmptyList()} returns <code>true</code>.
	 *
	 * @param message the empty message
	 * @since 3.2
	 */
	void setEmptyMessage(String message) {
		Assert.isNotNull(message);
		fEmptyMessage= message;
	}

	/**
	 * Enables or disables showing of the caption line. See also {@link #setMessage(String)}.
	 *
	 * @param show <code>true</code> if the status line is visible
	 * @since 3.2
	 */
	public void setStatusLineVisible(boolean show) {
		if (!isActive() || show == (fMessageText != null && !fMessageText.isDisposed()))
			return; // nothing to do

		if (show) {
			createMessageText();
		} else {
			fMessageText.dispose();
			fMessageText= null;
		}
		fProposalShell.layout();
	}

	/**
	 * Informs the popup that it is being placed above the caret line instead of below.
	 *
	 * @param above <code>true</code> if the location of the popup is above the caret line, <code>false</code> if it is below
	 * @since 3.3
	 */
	void switchedPositionToAbove(boolean above) {
		if (fAdditionalInfoController != null) {
			fAdditionalInfoController.setFallbackAnchors(new Anchor[] {
					AbstractInformationControlManager.ANCHOR_RIGHT,
					AbstractInformationControlManager.ANCHOR_LEFT,
					above ? AbstractInformationControlManager.ANCHOR_TOP : AbstractInformationControlManager.ANCHOR_BOTTOM
			});
		}
	}

	/**
	 * Returns a new proposal selection handler.
	 *
	 * @param operationCode the operation code
	 * @return the handler
	 * @since 3.4
	 */
	IHandler createProposalSelectionHandler(int operationCode) {
		return new ProposalSelectionHandler(operationCode);
	}

	/**
	 * Sets the proposal sorter.
	 *
	 * @param sorter the sorter to be used, or <code>null</code> if no sorting is requested
	 * @since 3.8
	 * @see ContentAssistant#setSorter(ICompletionProposalSorter)
	 */
	public void setSorter(ICompletionProposalSorter sorter) {
		fSorter= sorter;
	}

	/**
	 * Sorts the given proposal array.
	 *
	 * @param proposals the new proposals to display in the popup window
	 * @throws NullPointerException if no sorter has been set
	 * @since 3.8
	 */
	void sortProposals(final List<ICompletionProposal> proposals) {
		proposals.sort(fSorter::compare);
	}
}
