/*******************************************************************************
 * 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.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 final 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 final List fCategories;
	
	/** content type ID this processor is associated with */
	private 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 final 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;
	
	/**
	 * <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);
		
		//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;
		
		//get the completion categories
		fCategories = CompletionProposalComputerRegistry.getDefault().getProposalCategories();
		fAssistant = assistant;
		fAssistant.addCompletionListener(new CompletionListener());
		
		//get the processors added by the legacy extension
		fLegacyExtendedContentAssistProcessors =
			ExtendedConfigurationBuilder.getInstance().getConfigurations(
					CONTENT_ASSIST_PROCESSOR_EXTENDED_ID, this.fPartitionTypeID);
	}

	/**
	 * <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, fCategories.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, fCategories.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.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
	 */
	public IContextInformationValidator getContextInformationValidator() {
		return null;
	}
	
	/**
	 * <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;
		}
	}
	
	/**
	 * <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() && this.fLegacyExtendedContentAssistProcessors != null && !fLegacyExtendedContentAssistProcessors.isEmpty()) {
			Iterator iter = fLegacyExtendedContentAssistProcessors.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();
			}
		}
		
		// if default page
		// Deal with adding in contexts from processors added through the legacy extension
		if (getIteration() == 0 && this.fLegacyExtendedContentAssistProcessors != null && !fLegacyExtendedContentAssistProcessors.isEmpty()) {
			Iterator iter = fLegacyExtendedContentAssistProcessors.iterator();
			while (iter.hasNext()) {
				IContentAssistProcessor legacyProcessor = (IContentAssistProcessor) iter.next();
				IContextInformation[] legacyComputed = legacyProcessor.computeContextInformation(viewer, offset);
				proposals.addAll(Arrays.asList(legacyComputed));
			}
		}

		return proposals;
	}

	/**
	 * @return the next set of categories
	 */
	private List getCategories() {
		List categories;
		if (fCategoryIteration == null) {
			categories =  fCategories;
		} 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 = fCategories.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= fCategories.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= repetition % fCategoryIteration.size();
		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 the page that should be displayed next to the user
	 */
	private int getIteration() {
		return fRepetition % fCategoryIteration.size();
	}
	
	/**
	 * @return <code>true</code> if displaying first page, <code>false</code> otherwise
	 */
	private boolean isFirstPage() {
		return fCategoryIteration.size() == 1 || fRepetition % fCategoryIteration.size() == 1;
	}
	
	/**
	 * 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= fCategories.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) {
				for (Iterator it= fCategories.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
		}
	}
}
