/*******************************************************************************
 * Copyright (c) 2010 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.wst.sse.ui.contentassist;

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

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistEvent;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionListener;
import org.eclipse.jface.text.contentassist.ICompletionListenerExtension;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistantExtension2;
import org.eclipse.jface.text.contentassist.IContentAssistantExtension3;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.IReleasable;
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.contentassist.CompletionProposalCategory;
import org.eclipse.wst.sse.ui.internal.contentassist.CompletionProposalComputerRegistry;
import org.eclipse.wst.sse.ui.internal.contentassist.CompletionProposoalCatigoriesConfigurationRegistry;
import org.eclipse.wst.sse.ui.internal.contentassist.CompoundContentAssistProcessor;
import org.eclipse.wst.sse.ui.internal.contentassist.ContextInformationValidator;
import org.eclipse.wst.sse.ui.internal.contentassist.OptionalMessageDialog;
import org.eclipse.wst.sse.ui.preferences.ICompletionProposalCategoriesConfigurationReader;
import org.eclipse.wst.sse.ui.preferences.ICompletionProposalCategoriesConfigurationWriter;


/**
 * <p>A content assist processor that aggregates the proposals of the
 * {@link org.eclipse.wst.sse.ui.contentassist.ICompletionProposalComputer}s contributed via the
 * <code>org.eclipse.wst.sse.ui.completionProposal</code> extension point.</p>
 * <p>
 * Extenders may extend:
 * <ul>
 * <li>{@link #propertyChange(PropertyChangeEvent)}to react to property change events
 * that occur in the {@link IPreferenceStore} given to the constructor in case the behavior
 * of the processor needs to change according to user preferences</li>
 * <li>{@link #getCompletionProposalAutoActivationCharacters()}</li>
 * <li>{@link #getContextInformationAutoActivationCharacters()}</li>
 * <li>{@link #filterAndSortProposals(List, IProgressMonitor, CompletionProposalInvocationContext)}
 * to add sorting and filtering</li>
 * <li>{@link #filterAndSortContextInformation(List, IProgressMonitor)} to add sorting and filtering</li>
 * <li>{@link #createProgressMonitor()} to change the way progress is reported</li>
 * <li>{@link #createContext(ITextViewer, int)} to provide the context object
 * passed to the computers</li>
 * <li>{@link #getContextInformationValidator()} to add context validation (needed if any
 * contexts are provided)</li>
 * <li>{@link #getErrorMessage()} to change error reporting</li>
 * </ul>
 * </p>
 * 
 * @base org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor
 */
public class StructuredContentAssistProcessor implements IContentAssistProcessor, IPropertyChangeListener, IReleasable {

	/** Legacy editor configuration extension point. */
	private static final String CONTENT_ASSIST_PROCESSOR_EXTENDED_ID = "contentassistprocessor"; //$NON-NLS-1$

	/** Content assist processors added through the now legacy editor configuration extension point */
	private List fLegacyExtendedContentAssistProcessors;
	
	/**
	 * Dialog settings key for the "all categories are disabled" warning dialog. See
	 * {@link OptionalMessageDialog}.
	 */
	private static final String PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY= "EmptyDefaultAssistCategory"; //$NON-NLS-1$

	/**
	 * Used to sort categories by their page order so they are cycled in the correct order
	 */
	private final Comparator PAGE_ORDER_COMPARATOR = new Comparator() {
		public int compare(Object o1, Object o2) {
			CompletionProposalCategory d1= (CompletionProposalCategory) o1;
			CompletionProposalCategory d2= (CompletionProposalCategory) o2;

			return d1.getPageSortRank(fContentTypeID) - d2.getPageSortRank(fContentTypeID);
		}
	};
	
	/**
	 * Used to sort categories by their default page order so they are
	 * ordered correctly on the default page
	 */
	private final Comparator DEFAULT_PAGE_ORDER_COMPARATOR = new Comparator() {
		public int compare(Object o1, Object o2) {
			CompletionProposalCategory d1= (CompletionProposalCategory) o1;
			CompletionProposalCategory d2= (CompletionProposalCategory) o2;

			return d1.getDefaultPageSortRank(fContentTypeID) - d2.getDefaultPageSortRank(fContentTypeID);
		}
	};

	/** List of {@link CompletionProposalCategory}s supported by this processor */
	private List fCategories;
	
	/** content type ID this processor is associated with */
	String fContentTypeID;
	
	/** partition type ID this processor is associated with */
	private final String fPartitionTypeID;
	
	/** Content assistant used for giving the user status messages and listening to completion results*/
	private ContentAssistant fAssistant;

	/* cycling stuff */
	private int fRepetition= -1;
	private List fCategoryIteration = null;
	private String fIterationGesture = null;
	private int fNumberOfComputedResults = 0;
	private String fErrorMessage;
	
	/** Optionally specified preference store for listening to property change events */
	private IPreferenceStore fPreferenceStore;
	
	/** The viewer this processor is associated with */
	private ITextViewer fViewer;

	/**
	 * the {@link ITextInputListener} used to set the content type when
	 * a document is set for this processors associated viewer.
	 */
	private ITextInputListener fTextInputListener;

	private CompletionListener fCompletionListener;
	
	/** the context information validator for this processor */
	private IContextInformationValidator fContextInformationValidator;
	
	/**
	 * <p>Create a new content assist processor for a specific partition type. 
	 * The content type will be determined when a document is set on the viewer</p>
	 * 
	 * <p>If the given {@link IPreferenceStore} is not <code>null</code> then this
	 * processor will be registered as a {@link IPropertyChangeListener} on the given store
	 * so that implementers of this class can change the way the processor acts based on
	 * user preferences</p>
	 * 
	 * @param assistant {@link ContentAssistant} to use
	 * @param partitionTypeID the partition type this processor is for
	 * @param viewer {@link ITextViewer} this processor is acting in
	 * @param preferenceStore This processor will be registered as a {@link IPropertyChangeListener}
	 * on this store and the processor itself will take care of removing itself as a listener, if
	 * <code>null</code> then will not be registered as a {@link IPropertyChangeListener}
	 */
	public StructuredContentAssistProcessor(ContentAssistant assistant, String partitionTypeID,
			ITextViewer viewer, IPreferenceStore preferenceStore) {
		
		Assert.isNotNull(partitionTypeID);
		Assert.isNotNull(assistant);
		
		//be sure the registry has been loaded, none blocking
		CompletionProposalComputerRegistry.getDefault().initialize();
		
		//register on the preference store
		this.fPreferenceStore = preferenceStore;
		if(this.fPreferenceStore != null) {
			this.fPreferenceStore.addPropertyChangeListener(this);
		}
		
		//The content type can not be determined until a document has been set
		this.fContentTypeID = null;
		this.fViewer = viewer;
		if(viewer != null) {
			this.fTextInputListener = new TextInputListener();
			viewer.addTextInputListener(this.fTextInputListener);
		
			if(viewer.getDocument() != null) {
				/* it is highly unlike the document has already been set, but check
				 * just for sanity
				 */
				this.fTextInputListener.inputDocumentChanged(null, viewer.getDocument());
			}
		}
		
		//set the associated partition type
		this.fPartitionTypeID = partitionTypeID;
		
		//add completion listener
		fAssistant = assistant;
		fCompletionListener = new CompletionListener();
		fAssistant.addCompletionListener(fCompletionListener);
		
		//lazy load these to speed up initial editor opening
		fLegacyExtendedContentAssistProcessors = null;
		fCategories = null;
	}

	/**
	 * <p>Collect the proposals using the extension points</p>
	 * 
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
	 */
	public final ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
		clearState();

		IProgressMonitor monitor= createProgressMonitor();
		monitor.beginTask(SSEUIMessages.ContentAssist_computing_proposals, getProposalCategories().size() + 1);

		CompletionProposalInvocationContext context = createContext(viewer, offset);

		monitor.subTask(SSEUIMessages.ContentAssist_collecting_proposals);
		List proposals = collectProposals(viewer, offset, monitor, context);

		monitor.subTask(SSEUIMessages.ContentAssist_sorting_proposals);
		List filtered = filterAndSortProposals(proposals, monitor, context);
		fNumberOfComputedResults= filtered.size();

		ICompletionProposal[] result= (ICompletionProposal[]) filtered.toArray(new ICompletionProposal[filtered.size()]);
		monitor.done();

		return result;
	}

	/**
	 * <p>Collect the context information using the extension points</p>
	 * 
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
	 */
	public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
		clearState();

		IProgressMonitor monitor= createProgressMonitor();
		monitor.beginTask(SSEUIMessages.ContentAssist_computing_contexts, getProposalCategories().size() + 1);

		monitor.subTask(SSEUIMessages.ContentAssist_collecting_contexts);
		List proposals= collectContextInformation(viewer, offset, monitor);

		monitor.subTask(SSEUIMessages.ContentAssist_sorting_contexts);
		List filtered= filterAndSortContextInformation(proposals, monitor);
		fNumberOfComputedResults= filtered.size();

		IContextInformation[] result= (IContextInformation[]) filtered.toArray(new IContextInformation[filtered.size()]);
		monitor.done();
		return result;
	}

	/**
	 * <p>Default implementation is to return <code>null</code></p>
	 * <p>Extenders may override</p>
	 * 
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
	 */
	public char[] getCompletionProposalAutoActivationCharacters() {
		return null;
	}

	/**
	 * <p>Default implementation is to return <code>null</code></p>
	 * <p>Extenders may override</p>
	 * 
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
	 */
	public char[] getContextInformationAutoActivationCharacters() {
		return null;
	}

	/**
	 * <p>Extenders may override this function to change error reporting</p>
	 * 
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
	 */
	public String getErrorMessage() {
		if (fErrorMessage != null)
			return fErrorMessage;
		if (fNumberOfComputedResults > 0)
			return null;
		return SSEUIMessages.ContentAssist_no_completions;
	}

	/**
	 * @see org.eclipse.wst.sse.ui.contentassist.StructuredContentAssistProcessor#getContextInformationValidator()
	 */
	public IContextInformationValidator getContextInformationValidator() {
		if (this.fContextInformationValidator == null) {
			this.fContextInformationValidator = new ContextInformationValidator();
		}
		return this.fContextInformationValidator;
	}
	
	/**
	 * <p>Extenders may override, but should always be sure to call the super implementation</p>
	 * 
	 * @see org.eclipse.wst.sse.ui.internal.IReleasable#release()
	 */
	public void release() {
		if(this.fPreferenceStore != null) {
			this.fPreferenceStore.removePropertyChangeListener(this);
			this.fPreferenceStore = null;
		}
		
		if(this.fViewer != null) {
			this.fViewer.removeTextInputListener(this.fTextInputListener);
			this.fViewer = null;
		}
		if (this.fAssistant != null) {
			this.fAssistant.removeCompletionListener(fCompletionListener);
			this.fAssistant = null;
		}
	}
	
	/**
	 * <p>Intended to be overridden by extenders wishing to change the behavior
	 * of the processor based on user preferences from the store optionally 
	 * associated with this processor.  If no store was given to the constructor
	 * when creating this assistant then this method will never be invoked.</p>
	 * 
	 * <p>The default implementation does not react to the events in any way</p>
	 * 
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
	}
	
	/**
	 * <p>Filters and sorts the proposals. The passed list may be modified
	 * and returned, or a new list may be created and returned.</p>
	 * 
	 * <p>The default implementation does not do any sorting or filtering.</p>
	 * <p>Extenders may override this function.</p>
	 *
	 * @param proposals the list of collected proposals (element type:
	 *        {@link ICompletionProposal})
	 * @param monitor a progress monitor
	 * @param context TODO
	 * @return the list of filtered and sorted proposals, ready for
	 *         display (element type: {@link ICompletionProposal})
	 */
	protected List filterAndSortProposals(List proposals, IProgressMonitor monitor, CompletionProposalInvocationContext context) {
		return proposals;
	}
	
	/**
	 * <p>Filters and sorts the context information objects. The passed
	 * list may be modified and returned, or a new list may be created
	 * and returned.</p>
	 * 
	 * <p>The default implementation does not do any sorting or filtering</p>
	 * <p>Extenders may override this method</p>
	 *
	 * @param contexts the list of collected proposals (element type:
	 *        {@link IContextInformation})
	 * @param monitor a progress monitor
	 * @return the list of filtered and sorted proposals, ready for
	 *         display (element type: {@link IContextInformation})
	 */
	protected List filterAndSortContextInformation(List contexts, IProgressMonitor monitor) {
		return contexts;
	}

	/**
	 * <p>Creates a progress monitor.</p>
	 * <p>The default implementation creates a {@link NullProgressMonitor}.</p>
	 *
	 * <p>Extenders may override this method</p>
	 *
	 * @return a progress monitor
	 */
	protected IProgressMonitor createProgressMonitor() {
		return new NullProgressMonitor();
	}

	/**
	 * <p>Creates the context that is passed to the completion proposal
	 * computers.</p>
	 * 
	 * <p>Extenders may override this method</p>
	 *
	 * @param viewer the viewer that content assist is invoked on
	 * @param offset the content assist offset
	 * @return the context to be passed to the computers
	 */
	protected CompletionProposalInvocationContext createContext(ITextViewer viewer, int offset) {
		return new CompletionProposalInvocationContext(viewer, offset);
	}
	
	/**
	 * @return the associated preference store
	 */
	protected IPreferenceStore getPreferenceStore() {
		return this.fPreferenceStore;
	}
	
	/**
	 * Clears the state
	 */
	private void clearState() {
		fErrorMessage=null;
		fNumberOfComputedResults= 0;
	}

	/**
	 * <p>Collects the proposals from the extensions.</p>
	 *
	 * @param viewer the text viewer
	 * @param offset the offset
	 * @param monitor the progress monitor
	 * @param context the code assist invocation context
	 * @return the list of proposals
	 */
	private List collectProposals(ITextViewer viewer, int offset, IProgressMonitor monitor, CompletionProposalInvocationContext context) {
		List proposals = new ArrayList();
		List categories = getCategories();
		for (Iterator it = categories.iterator(); it.hasNext();) {
			CompletionProposalCategory cat = (CompletionProposalCategory) it.next();
			List computed = cat.computeCompletionProposals(context, this.fContentTypeID, this.fPartitionTypeID, new SubProgressMonitor(monitor, 1));
			proposals.addAll(computed);
			if (fErrorMessage == null) {
				fErrorMessage= cat.getErrorMessage();
			}
		}
		
		// if default page
		// Deal with adding in proposals from processors added through the legacy extension
		if (isFirstPage() && getLegacyExtendedContentAssistProcessors() != null &&
				!getLegacyExtendedContentAssistProcessors().isEmpty()) {
			
			Iterator iter = getLegacyExtendedContentAssistProcessors().iterator();
			while (iter.hasNext()) {
				IContentAssistProcessor legacyProcessor = (IContentAssistProcessor) iter.next();
				ICompletionProposal[] legacyComputed = legacyProcessor.computeCompletionProposals(viewer, offset);
				proposals.addAll(Arrays.asList(legacyComputed));
			}
		}
		
		return proposals;
	}
	
	/**
	 * <p>Collects the context information from the extensions.</p>
	 * 
	 * @param viewer
	 * @param offset
	 * @param monitor
	 * @return
	 */
	private List collectContextInformation(ITextViewer viewer, int offset, IProgressMonitor monitor) {
		List proposals = new ArrayList();
		CompletionProposalInvocationContext context= createContext(viewer, offset);

		List providers= getCategories();
		for (Iterator it= providers.iterator(); it.hasNext();) {
			CompletionProposalCategory cat= (CompletionProposalCategory) it.next();
			List computed= cat.computeContextInformation(context, this.fContentTypeID, this.fPartitionTypeID, new SubProgressMonitor(monitor, 1));
			proposals.addAll(computed);
			if (fErrorMessage == null) {
				fErrorMessage= cat.getErrorMessage();
			}
		}
		
		// Deal with adding in contexts from processors added through the legacy extension
		if (getLegacyExtendedContentAssistProcessors() != null &&
				!getLegacyExtendedContentAssistProcessors().isEmpty()) {
			
			Iterator iter = getLegacyExtendedContentAssistProcessors().iterator();
			while (iter.hasNext()) {
				IContentAssistProcessor legacyProcessor = (IContentAssistProcessor) iter.next();
				IContextInformation[] legacyComputed = legacyProcessor.computeContextInformation(viewer, offset);
				if(legacyComputed != null) {
					proposals.addAll(Arrays.asList(legacyComputed));
				}
			}
		}

		return proposals;
	}

	/**
	 * @return the next set of categories
	 */
	private List getCategories() {
		List categories;
		if (fCategoryIteration == null) {
			categories =  getProposalCategories();
		} else {
			int iteration= fRepetition % fCategoryIteration.size();
			fAssistant.setStatusMessage(createIterationMessage());
			fAssistant.setEmptyMessage(createEmptyMessage());
			fRepetition++;
	
			categories = (List) fCategoryIteration.get(iteration);
		}
		
		return categories;
	}

	/**
	 *  This may show the warning dialog if all categories are disabled
	 */
	private void resetCategoryIteration() {
		fCategoryIteration = getCategoryIteration();
	}

	/**
	 * @return {@link List} of {@link List}s of {@link CompletionProposalCategory}s, this is
	 * the ordered list of the completion categories to cycle through
	 */
	private List getCategoryIteration() {
		List sequence= new ArrayList();
		sequence.add(getDefaultCategories());
		for (Iterator it= getSortedOwnPageCategories().iterator(); it.hasNext();) {
			CompletionProposalCategory cat= (CompletionProposalCategory) it.next();
			sequence.add(Collections.singletonList(cat));
		}
		return sequence;
	}

	/**
	 * @return the sorted categories for the default page
	 */
	private List getDefaultCategories() {
		// default mix - enable all included computers
		List included= getDefaultCategoriesUnchecked();

		if (included.size() == 0 && CompletionProposalComputerRegistry.getDefault().hasUninstalledComputers()) {
			if (informUserAboutEmptyDefaultCategory()) {
				// preferences were restored - recompute the default categories
				included= getDefaultCategoriesUnchecked();
			}
			CompletionProposalComputerRegistry.getDefault().resetUnistalledComputers();
		}
		
		Collections.sort(included, DEFAULT_PAGE_ORDER_COMPARATOR);

		return included;
	}

	/**
	 * <p>Gets the default categories with no error checking.</p>
	 * 
	 * @return the default {@link CompletionProposalCategory}s
	 */
	private List getDefaultCategoriesUnchecked() {
		List included = new ArrayList();
		for (Iterator it = getProposalCategories().iterator(); it.hasNext();) {
			CompletionProposalCategory category = (CompletionProposalCategory) it.next();
			if (category.isIncludedOnDefaultPage(this.fContentTypeID) && category.hasComputers(fContentTypeID, fPartitionTypeID))
				included.add(category);
		}
		return included;
	}

	/**
	 * <p>Informs the user about the fact that there are no enabled categories in the default content
	 * assist set and shows a link to the preferences.</p>
	 *
	 * @return  <code>true</code> if the default should be restored
	 */
	private boolean informUserAboutEmptyDefaultCategory() {
		/*If warn about empty default category and there are associated properties for this
		 * processors content type and those properties have an associated properties page then
		 * display warning message to user.
		 */
		ICompletionProposalCategoriesConfigurationReader properties = CompletionProposoalCatigoriesConfigurationRegistry.getDefault().getReadableConfiguration(this.fContentTypeID);
		if (OptionalMessageDialog.isDialogEnabled(PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY) &&
				properties instanceof ICompletionProposalCategoriesConfigurationWriter  &&
				((ICompletionProposalCategoriesConfigurationWriter)properties).hasAssociatedPropertiesPage()) {
			
			ICompletionProposalCategoriesConfigurationWriter propertiesExtension = (ICompletionProposalCategoriesConfigurationWriter)properties;
			
			final Shell shell= SSEUIPlugin.getActiveWorkbenchShell();
			String title= SSEUIMessages.ContentAssist_all_disabled_title;
			String message= SSEUIMessages.ContentAssist_all_disabled_message;
			// see PreferencePage#createControl for the 'defaults' label
			final String restoreButtonLabel= JFaceResources.getString("defaults"); //$NON-NLS-1$
			final String linkMessage= NLS.bind(SSEUIMessages.ContentAssist_all_disabled_preference_link, LegacyActionTools.removeMnemonics(restoreButtonLabel));
			final int restoreId= IDialogConstants.CLIENT_ID + 10;
			final int settingsId= IDialogConstants.CLIENT_ID + 11;
			final OptionalMessageDialog dialog= new OptionalMessageDialog(PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY, shell, title, null /* default image */, message, MessageDialog.WARNING, new String[] { restoreButtonLabel, IDialogConstants.CLOSE_LABEL }, 1) {
				/*
				 * @see org.eclipse.jdt.internal.ui.dialogs.OptionalMessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite)
				 */
				protected Control createCustomArea(Composite composite) {
					// wrap link and checkbox in one composite without space
					Composite parent= new Composite(composite, SWT.NONE);
					GridLayout layout= new GridLayout();
					layout.marginHeight= 0;
					layout.marginWidth= 0;
					layout.verticalSpacing= 0;
					parent.setLayout(layout);

					Composite linkComposite= new Composite(parent, SWT.NONE);
					layout= new GridLayout();
					layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
					layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
					layout.horizontalSpacing= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
					linkComposite.setLayout(layout);

	        		Link link= new Link(linkComposite, SWT.NONE);
	        		link.setText(linkMessage);
	        		link.addSelectionListener(new SelectionAdapter() {
	        			public void widgetSelected(SelectionEvent e) {
	        				setReturnCode(settingsId);
	        				close();
	        			}
	        		});
	        		GridData gridData= new GridData(SWT.FILL, SWT.BEGINNING, true, false);
	        		gridData.widthHint= this.getMinimumMessageWidth();
					link.setLayoutData(gridData);

					// create checkbox and "don't show this message" prompt
					super.createCustomArea(parent);

					return parent;
	        	}

				/*
				 * @see org.eclipse.jface.dialogs.MessageDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
				 */
				protected void createButtonsForButtonBar(Composite parent) {
			        Button[] buttons= new Button[2];
					buttons[0]= createButton(parent, restoreId, restoreButtonLabel, false);
			        buttons[1]= createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
			        setButtons(buttons);
				}
	        };
	        int returnValue = dialog.open();
	        
	        //based on user actions either reset defaults or open preference dialog
	        if (restoreId == returnValue || settingsId == returnValue) {
	        	if (restoreId == returnValue) {
	        		propertiesExtension.loadDefaults();
	        		propertiesExtension.saveConfiguration();
	        	}
	        	if (settingsId == returnValue) {
					PreferencesUtil.createPreferenceDialogOn(shell,
							propertiesExtension.getPropertiesPageID(), null, null).open();
	        	}
	        	
	        	return true;
	        }
		}
		return false;
	}

	/**
	 * @return a sorted {@link List} of {@link CompletionProposalCategory}s that
	 * should be displayed on their own content assist page
	 */
	private List getSortedOwnPageCategories() {
		ArrayList sorted= new ArrayList();
		for (Iterator it= getProposalCategories().iterator(); it.hasNext();) {
			CompletionProposalCategory category= (CompletionProposalCategory) it.next();
			if (category.isDisplayedOnOwnPage(this.fContentTypeID) && 
					category.hasComputers(fContentTypeID, fPartitionTypeID)) {
				
				sorted.add(category);
			}
		}
		Collections.sort(sorted, PAGE_ORDER_COMPARATOR);
		return sorted;
	}

	/**
	 * @return a user message describing that there are no content assist suggestions for the current page
	 */
	private String createEmptyMessage() {
		return NLS.bind(SSEUIMessages.ContentAssist_no_message, new String[]{getCategoryLabel(fRepetition)});
	}

	/**
	 * @return user message describing what the next page of content assist holds
	 */
	private String createIterationMessage() {
		return NLS.bind(SSEUIMessages.ContentAssist_toggle_affordance_update_message,
				new String[]{ getCategoryLabel(fRepetition), fIterationGesture, getCategoryLabel(fRepetition + 1) });
	}

	/**
	 * @param repetition which category to get the label for
	 * @return the label of the category
	 */
	private String getCategoryLabel(int repetition) {
		int iteration= (fCategoryIteration != null ? repetition % fCategoryIteration.size() : 0);
		if (iteration == 0)
			return SSEUIMessages.ContentAssist_defaultProposalCategory_title;
		return ((CompletionProposalCategory) ((List) fCategoryIteration.get(iteration)).get(0)).getDisplayName();
	}

	/**
	 * @return {@link String} representing the user command to iterate to the next page
	 */
	private String getIterationGesture() {
		TriggerSequence binding= getIterationBinding();
		return binding != null ?
				NLS.bind(SSEUIMessages.ContentAssist_press, new Object[] { binding.format() })
				: SSEUIMessages.ContentAssist_click;
	}

	/**
	 * @return {@link KeySequence} used by user to iterate to the next page
	 */
	private KeySequence getIterationBinding() {
	    final IBindingService bindingSvc= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
		TriggerSequence binding= bindingSvc.getBestActiveBindingFor(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		if (binding instanceof KeySequence)
			return (KeySequence) binding;
		return null;
    }
	
	/**
	 * @return <code>true</code> if displaying first page, <code>false</code> otherwise
	 */
	private boolean isFirstPage() {
		return fCategoryIteration == null || fCategoryIteration.size() == 1 || fRepetition % fCategoryIteration.size() == 1;
	}
	
	/**
	 * <p><b>NOTE: </b>This method should be used over accessing the
	 * {@link #fLegacyExtendedContentAssistProcessors} field directly so as to
	 * facilitate the lazy initialization of the field.</p>
	 * 
	 * @return the legacy extended content assist processors
	 */
	private List getLegacyExtendedContentAssistProcessors() {
		if(fLegacyExtendedContentAssistProcessors == null) {
			fLegacyExtendedContentAssistProcessors =
				ExtendedConfigurationBuilder.getInstance().getConfigurations(
						CONTENT_ASSIST_PROCESSOR_EXTENDED_ID, fPartitionTypeID);
		}
		
		return fLegacyExtendedContentAssistProcessors;
	}
	
	/**
	 * <p><b>NOTE: </b>This method should be used over accessing the {@link #fCategories}
	 * field directly so as to facilitate the lazy initialization of the field.</p>
	 * 
	 * @return the categories associated with the content type this processor is associated with
	 */
	private List getProposalCategories() {
		if(fCategories == null) {
			fCategories =
				CompletionProposalComputerRegistry.getDefault().getProposalCategories(fContentTypeID);
		}
		
		return fCategories;
	}
	
	/**
	 * The completion listener class for this processor.
	 */
	private final class CompletionListener implements ICompletionListener, ICompletionListenerExtension {
		/**
		 * @see org.eclipse.jface.text.contentassist.ICompletionListener#assistSessionStarted(org.eclipse.jface.text.contentassist.ContentAssistEvent)
		 */
		public void assistSessionStarted(ContentAssistEvent event) {
			if (event.processor == StructuredContentAssistProcessor.this ||
					(event.processor instanceof CompoundContentAssistProcessor &&
							((CompoundContentAssistProcessor)event.processor).containsProcessor(StructuredContentAssistProcessor.this))) {
				
				fIterationGesture= getIterationGesture();
				KeySequence binding= getIterationBinding();
	
				// This may show the warning dialog if all categories are disabled
				resetCategoryIteration();
				for (Iterator it= StructuredContentAssistProcessor.this.getProposalCategories().iterator(); it.hasNext();) {
					CompletionProposalCategory cat= (CompletionProposalCategory) it.next();
					cat.sessionStarted();
				}
	
				fRepetition= 0;
				if (event.assistant instanceof IContentAssistantExtension2) {
					IContentAssistantExtension2 extension= (IContentAssistantExtension2) event.assistant;
	
					if (fCategoryIteration.size() == 1) {
						extension.setRepeatedInvocationMode(false);
						extension.setShowEmptyList(false);
					} else {
						extension.setRepeatedInvocationMode(true);
						extension.setStatusLineVisible(true);
						extension.setStatusMessage(createIterationMessage());
						extension.setShowEmptyList(true);
						if (extension instanceof IContentAssistantExtension3) {
							IContentAssistantExtension3 ext3= (IContentAssistantExtension3) extension;
							((ContentAssistant) ext3).setRepeatedInvocationTrigger(binding);
						}
					}
				}
			}
		}

		/**
		 * @see org.eclipse.jface.text.contentassist.ICompletionListener#assistSessionEnded(org.eclipse.jface.text.contentassist.ContentAssistEvent)
		 */
		public void assistSessionEnded(ContentAssistEvent event) {
			if (event.processor == StructuredContentAssistProcessor.this ||	(event.processor instanceof CompoundContentAssistProcessor && ((CompoundContentAssistProcessor)event.processor).containsProcessor(StructuredContentAssistProcessor.this))) {
				for (Iterator it= StructuredContentAssistProcessor.this.getProposalCategories().iterator(); it.hasNext();) {
					CompletionProposalCategory cat= (CompletionProposalCategory) it.next();
					cat.sessionEnded();
				}
	
				fCategoryIteration= null;
				fRepetition= -1;
				fIterationGesture= null;
				if (event.assistant instanceof IContentAssistantExtension2) {
					IContentAssistantExtension2 extension= (IContentAssistantExtension2) event.assistant;
					extension.setShowEmptyList(false);
					extension.setRepeatedInvocationMode(false);
					extension.setStatusLineVisible(false);
					if (extension instanceof IContentAssistantExtension3) {
						IContentAssistantExtension3 ext3= (IContentAssistantExtension3) extension;
						((ContentAssistant) ext3).setRepeatedInvocationTrigger(null);
					}
				}
			}
		}

		/**
		 * @see org.eclipse.jface.text.contentassist.ICompletionListener#selectionChanged(org.eclipse.jface.text.contentassist.ICompletionProposal, boolean)
		 */
		public void selectionChanged(ICompletionProposal proposal, boolean smartToggle) {
			//ignore
		}

		/**
		 * @see org.eclipse.jface.text.contentassist.ICompletionListenerExtension#assistSessionRestarted(org.eclipse.jface.text.contentassist.ContentAssistEvent)
		 */
		public void assistSessionRestarted(ContentAssistEvent event) {
			fRepetition= 0;
		}
	}
	
	/**
	 * 
	 */
	private class TextInputListener implements ITextInputListener {

		/**
		 * <p>Set the content type based on the new document if it has not already been
		 * set yet.</p>
		 * 
		 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
		 */
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			if(fContentTypeID == null) {
				if(newInput instanceof IStructuredDocument) {
					IStructuredModel model = null;
					try {
						model = StructuredModelManager.getModelManager().getModelForRead((IStructuredDocument)newInput);
						if(model != null) {
							fContentTypeID = model.getContentTypeIdentifier();
						}
					} finally {
						if(model != null) {
							model.releaseFromRead();
						}
					}
				}
			}
		}
		
		/**
		 * <p>Ignored</p>
		 * 
		 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
		 */
		public void inputDocumentAboutToBeChanged(IDocument oldInput,
				IDocument newInput) {
			//ignore
		}
	}
}
