/*******************************************************************************
 * Copyright (c) 2007, 2012 Dakshinamurthy Karra, 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:
 *     Dakshinamurthy Karra (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581
 *     Piotr Maj <pm@jcake.com> - no access to template store and current selection - https://bugs.eclipse.org/bugs/show_bug.cgi?id=296439
 *******************************************************************************/
package org.eclipse.ui.texteditor.templates;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.ibm.icu.text.Collator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

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

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.templates.ContextTypeRegistry;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
import org.eclipse.jface.text.templates.persistence.TemplateStore;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.internal.texteditor.NLSUtility;
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
import org.eclipse.ui.part.Page;

import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorExtension2;
import org.eclipse.ui.texteditor.templates.TemplatePreferencePage.EditTemplateDialog;


/**
 * Abstract default implementation for {@link ITemplatesPage}.
 * <p>
 * Clients who are defining an editor may elect to provide a corresponding
 * templates page. This templates page will be presented to the user via the
 * Templates View (the user decides whether their workbench window contains this
 * view) whenever that editor is active. This class should be subclassed by
 * clients.
 * </p>
 * <p>
 * Internally, a AbstractTemplatesPage uses the template store to display different
 * categories. A link to editor mode on the templates page allows to filtering
 * of the categories to only that are supported in this context.
 * </p>
 *
 * @since 3.4
 */
public abstract class AbstractTemplatesPage extends Page implements ITemplatesPage, ITemplatesPageExtension {

	/**
	 * Sashform size
	 */
	private static final String SASH_SIZE_PREF_ID= TextEditorPlugin.PLUGIN_ID
			+ ".templates.templatesPage.sashSize"; //$NON-NLS-1$
	/**
	 * Tree columns widths
	 */
	private static final String COLUMN_NAME_WIDTH_PREF_ID= TextEditorPlugin.PLUGIN_ID
			+ ".templates.templatesPage.nameWidth"; //$NON-NLS-1$
	private static final String COLUMN_DESCRIPTION_WIDTH_PREF_ID= TextEditorPlugin.PLUGIN_ID
			+ ".templates.templatesPage.descriptionWidth"; //$NON-NLS-1$
	/**
	 * Link to editor action setting
	 */
	private static final String LINK_ACTION_PREF_ID= TextEditorPlugin.PLUGIN_ID
			+ ".templates.templatesPage.linkAction"; //$NON-NLS-1$

	/**
	 * Context expand/collapse setting prefix
	 */
	private static final String CONTEXT_COLLAPSE_PREF_ID= TextEditorPlugin.PLUGIN_ID
			+ "templates.templatesPage.context.expand."; //$NON-NLS-1$

	/**
	 * The ID for the popup menu for this templates page
	 */
	private static final String POPUP_MENU_ID= "org.eclipse.ui.texteditor.templates.PopupMenu"; //$NON-NLS-1$


	/**
	 * A post selection changed listener for the editor. Depending on the caret
	 * position updates the templates
	 */
	private final class SelectionChangedListener implements ISelectionChangedListener {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			String[] contextTypes= getEditorContextTypeIds();
			if (needUpdate(contextTypes)) {
				fCurrentContextTypeIds= contextTypes;
				updateContextTypes(fCurrentContextTypeIds);
				return;
			}
		}

		/**
		 * Check whether an update of the AbstractTemplatesPage is needed
		 *
		 * @param contextTypes the context types
		 * @return true if update is needed
		 */
		private boolean needUpdate(String[] contextTypes) {
			return fCurrentContextTypeIds == null
					|| fCurrentContextTypeIds.length != contextTypes.length
					|| contextTypeChanged(contextTypes);
		}

		/**
		 * Check whether there is any change in the context types needed
		 *
		 * @param contextTypes the context types
		 * @return true if any of the context types changed
		 */
		private boolean contextTypeChanged(String[] contextTypes) {
			for (int i= 0; i < contextTypes.length; i++) {
				if (!contextTypes[i].equals(fCurrentContextTypeIds[i]))
					return true;
			}
			return false;
		}
	}


	/**
	 * Drop support for the editor linked to this page. When a user drops a
	 * template into the active editor, the template is applied at the drop
	 * position.
	 */
	private final class EditorDropTargetListener extends DropTargetAdapter {
		@Override
		public void dragEnter(DropTargetEvent event) {
			if (!TemplatesTransfer.getInstance().isSupportedType(event.currentDataType))
				return;

			event.detail= DND.DROP_COPY;
		}

		@Override
		public void dragOperationChanged(DropTargetEvent event) {
			if (!TemplatesTransfer.getInstance().isSupportedType(event.currentDataType))
				return;

			event.detail= DND.DROP_COPY;
		}

		@Override
		public void dragOver(DropTargetEvent event) {
			if (!TemplatesTransfer.getInstance().isSupportedType(event.currentDataType))
				return;

			event.feedback |= DND.FEEDBACK_SCROLL | DND.FEEDBACK_SELECT;
			event.detail= DND.DROP_NONE;
			TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();
			if (fTextEditor instanceof ITextEditorExtension2 && ((ITextEditorExtension2)fTextEditor).isEditorInputModifiable() && selectedTemplates.length == 1 &&
					isTemplateValidAtLocation(selectedTemplates[0].getTemplate(), new Point(event.x, event.y)))
				event.detail= DND.DROP_COPY;
		}

		@Override
		public void drop(DropTargetEvent event) {
			if (!TemplatesTransfer.getInstance().isSupportedType(event.currentDataType))
				return;

			TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();
			insertTemplate(selectedTemplates[0].getTemplate());
			// The highlight of the item is removed once the drop happens -
			// restore it
			fTreeViewer.setSelection(new StructuredSelection(selectedTemplates), true);
		}

	}


	/**
	 * Comparator for the viewer. Sorts the templates by name and then
	 * description and context types by names.
	 */
	private static final class TemplateViewerComparator extends ViewerComparator {
		@Override
		public int compare(Viewer viewer, Object object1, Object object2) {
			if ((object1 instanceof TemplatePersistenceData)
					&& (object2 instanceof TemplatePersistenceData)) {
				Template left= ((TemplatePersistenceData) object1).getTemplate();
				Template right= ((TemplatePersistenceData) object2).getTemplate();
				int result= Collator.getInstance().compare(left.getName(), right.getName());
				if (result != 0)
					return result;
				return Collator.getInstance()
						.compare(left.getDescription(), right.getDescription());
			}
			if ((object1 instanceof TemplateContextType)
					&& (object2 instanceof TemplateContextType)) {
				return Collator.getInstance().compare(((TemplateContextType) object1).getName(),
						((TemplateContextType) object1).getName());
			}
			return super.compare(viewer, object1, object2);
		}

		@Override
		public boolean isSorterProperty(Object element, String property) {
			return false;
		}
	}


	/**
	 * Label provider for templates.
	 */
	private final class TemplateLabelProvider extends LabelProvider implements ITableLabelProvider {

		@Override
		public Image getColumnImage(Object element, int columnIndex) {
			if (columnIndex != 0)
				return null;
			if (element instanceof TemplateContextType)
				return TemplatesPageImages.get(TemplatesPageImages.IMG_OBJ_CONTEXT);
			return AbstractTemplatesPage.this.getImage(((TemplatePersistenceData) element).getTemplate());
		}

		@Override
		public String getColumnText(Object element, int columnIndex) {
			if (element instanceof TemplatePersistenceData)
				return getTemplateColumnText((TemplatePersistenceData) element, columnIndex);
			return getContextColumnText((TemplateContextType) element, columnIndex);
		}

		private String getTemplateColumnText(TemplatePersistenceData data, int columnIndex) {
			switch (columnIndex) {
			case 0:
				return data.getTemplate().getName();
			case 1:
				return data.getTemplate().getDescription();
			default:
				return ""; //$NON-NLS-1$
			}
		}

		private String getContextColumnText(TemplateContextType contextType, int columnIndex) {
			switch (columnIndex) {
			case 0:
				return contextType.getName();
			default:
				return ""; //$NON-NLS-1$
			}
		}
	}


	/**
	 * Content provider for templates. Provides all the enabled templates
	 * defined for this editor.
	 */
	private final class TemplatesContentProvider implements ITreeContentProvider {

		@Override
		public Object[] getChildren(Object parentElement) {
			if (parentElement instanceof TemplatePersistenceData)
				return new Object[0];
			else if (parentElement instanceof TemplateContextType) {
				TemplateContextType contextType= (TemplateContextType) parentElement;
				return getTemplates(contextType.getId());
			}
			return null;
		}

		private TemplatePersistenceData[] getTemplates(String contextId) {
			List<TemplatePersistenceData> templateList= new ArrayList<>();
			TemplatePersistenceData[] datas= getTemplateStore().getTemplateData(false);
			for (int i= 0; i < datas.length; i++) {
				if (datas[i].isEnabled() && datas[i].getTemplate().getContextTypeId().equals(contextId))
					templateList.add(datas[i]);
			}
			return templateList
					.toArray(new TemplatePersistenceData[templateList.size()]);
		}

		@Override
		public Object getParent(Object element) {
			if (element instanceof TemplatePersistenceData) {
				TemplatePersistenceData templateData= (TemplatePersistenceData) element;
				return getContextTypeRegistry().getContextType(
						templateData.getTemplate().getContextTypeId());
			}
			return null;
		}

		@Override
		public boolean hasChildren(Object parentElement) {
			if (parentElement instanceof TemplatePersistenceData)
				return false;
			else if (parentElement instanceof TemplateContextType) {
				String contextId= ((TemplateContextType) parentElement).getId();

				TemplatePersistenceData[] datas= getTemplateStore().getTemplateData(false);
				if (datas.length <= 0)
					return false;

				for (int i= 0; i < datas.length; i++) {
					if (datas[i].isEnabled() && datas[i].getTemplate().getContextTypeId().equals(contextId))
						return true;
				}
				return false;
			}
			return false;
		}

		@Override
		public Object[] getElements(Object inputElement) {
			List<TemplateContextType> contextTypes= new ArrayList<>();

			for (Iterator<TemplateContextType> iterator= getContextTypeRegistry().contextTypes(); iterator.hasNext();) {
				TemplateContextType contextType= iterator.next();
				if (!fLinkWithEditorAction.isChecked() || isActiveContext(contextType))
					contextTypes.add(contextType);
			}
			return contextTypes.toArray(new TemplateContextType[contextTypes.size()]);
		}

		private boolean isActiveContext(TemplateContextType contextType) {
			return fActiveTypes == null || fActiveTypes.contains(contextType.getId());
		}

		@Override
		public void dispose() {
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}


	/** The text editor. */
	private final ITextEditor fTextEditor;
	/** The source viewer attached to this editor. */
	private final ISourceViewer fViewer;

	/* Listener to monitor changes to template store */
	private IPropertyChangeListener fTemplateChangeListener;

	/* Control for this pagebook view */
	private SashForm fControl;

	/* Actions */
	private Action fInsertAction;
	private Action fAddAction;
	private Action fEditAction;
	private Action fRemoveAction;
	private Action fLinkWithEditorAction;
	private Action fCollapseAllAction;
	private Action fPreferencePageAction;

	/* Clipboard actions */
	private Action fPasteAction;
	private Action fCopyAction;

	/* Current active context types for the editor */
	private List<String> fActiveTypes;

	/* Preference stores */
	private IPreferenceStore fPreferenceStore;

	/* Controls */
	private Tree fTemplatesTree;
	private TreeViewer fTreeViewer;
	private Menu fContextMenu;

	/** Current selection. */
	private TemplatePersistenceData[] fSelectedTemplates= new TemplatePersistenceData[0];

	/** The pattern viewer to be used with this view. */
	private SourceViewer fPatternViewer;

	/* Cached results for avoiding processing while drag-over the editor. */
	private int fCachedOffset;
	private boolean fCachedResult;
	private Point fCachedPosition;

	/** The current context type ids. */
	private String[] fCurrentContextTypeIds;

	/** The selection changed listener to monitor the editor selections. */
	private SelectionChangedListener fSelectionChangedListener;

	/** Paste action support for the editor. */
	private IAction fEditorOldPasteAction;
	private IAction fEditorPasteAction;


	/**
	 * Creates a new templates page.
	 *
	 * @param editor the editor
	 * @param viewer the source viewer
	 */
	protected AbstractTemplatesPage(ITextEditor editor, ISourceViewer viewer) {
		Assert.isLegal(editor != null);
		Assert.isLegal(viewer != null);
		fTextEditor= editor;
		fViewer= viewer;
		setupPreferenceStore();
		setupEditorDropTarget();
		setupSelectionProvider();
		setupPasteOperation();
	}

	@Override
	public void createControl(Composite ancestor) {
		setupActions();

		fControl= new SashForm(ancestor, SWT.VERTICAL);

		createTemplateTree(fControl);
		createPatternForm(fControl);

		hookContextMenu();
		initializeDND();
		updateButtons();

		int sashSize= fPreferenceStore.getInt(SASH_SIZE_PREF_ID);
		fControl.setWeights(new int[] { sashSize, 100 - sashSize });
		fTemplateChangeListener= new IPropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent event) {
				getShell().getDisplay().asyncExec(new Runnable() {
					@Override
					public void run() {
						refresh();
					}
				});
			}
		};
		getTemplatePreferenceStore().addPropertyChangeListener(fTemplateChangeListener);
		updateContextTypes(getEditorContextTypeIds());
	}

	@Override
	public void setFocus() {
	}

	@Override
	public Control getControl() {
		return fControl;
	}

	@Override
	public void dispose() {
		ISelectionProvider selectionProvider= fViewer.getSelectionProvider();
		if (selectionProvider instanceof IPostSelectionProvider)
			((IPostSelectionProvider) selectionProvider).removePostSelectionChangedListener(fSelectionChangedListener);
		else
			selectionProvider.removeSelectionChangedListener(fSelectionChangedListener);
		fTextEditor.setAction(ITextEditorActionConstants.PASTE, fEditorOldPasteAction);
		if (fContextMenu != null && !fContextMenu.isDisposed())
			fContextMenu.dispose();
		if (fTemplateChangeListener != null)
			getTemplatePreferenceStore().removePropertyChangeListener(fTemplateChangeListener);
		super.dispose();
	}

	/**
	 * Returns the shell in which this page is displayed.
	 *
	 * @return the shell
	 */
	private Shell getShell() {
		return getSite().getShell();
	}

	/**
	 * Returns the image to be used for the given template.
	 * <p>
	 * Clients can override to provide a different image.</p>
	 *
	 * @param template the template
	 * @return the image, must not be disposed
	 */
	protected Image getImage(Template template) {
		return TemplatesPageImages.get(TemplatesPageImages.IMG_OBJ_TEMPLATE);
	}

	/**
	 * Creates and opens a dialog to edit the given template.
	 * <p
	 * Subclasses may override this method to provide a custom dialog.</p>
	 *
	 * @param template the template being edited
	 * @param edit <code>true</code> if the dialog allows editing
	 * @param isNameModifiable <code>true</code> if the template name may be modified
	 * @return the created or modified template, or <code>null</code> if the editing failed
	 */
	protected Template editTemplate(Template template, boolean edit, boolean isNameModifiable) {
		EditTemplateDialog dialog= new EditTemplateDialog(getShell(), template, edit, isNameModifiable, getContextTypeRegistry());
		if (dialog.open() == Window.OK)
			return dialog.getTemplate();
		return null;
	}

	/**
	 * Update the pattern viewer to show the current template.
	 * <p>
	 * Subclasses can extend this method to update their own pattern viewer.
	 * </p>
	 *
	 * @param template the template
	 */
	protected void updatePatternViewer(Template template) {
		String pattern= template != null ? template.getPattern() : ""; //$NON-NLS-1$
		fPatternViewer.getDocument().set(pattern);
	}

	/**
	 * Creates, configures and returns a source viewer to present the template
	 * pattern on the templates page.
	 * <p>
	 * Clients may override to provide a custom source viewer featuring e.g. syntax coloring.</p>
	 *
	 * @param parent the parent control
	 * @return a configured source viewer
	 */
	protected SourceViewer createPatternViewer(Composite parent) {
		SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.V_SCROLL | SWT.H_SCROLL);
		SourceViewerConfiguration configuration= new SourceViewerConfiguration();
		viewer.configure(configuration);
		IDocument document= new Document();
		viewer.setDocument(document);
		viewer.setEditable(false);
		return viewer;
	}

	/**
	 * Returns the pattern viewer created by createPatternViewer()
	 *
	 * @return the pattern viewer
	 */
	protected final SourceViewer getPatternViewer() {
		return fPatternViewer;
	}

	/**
	 * The caret position in the editor has moved into a new context type. It is
	 * the subclasses responsibility to see that this is called only when needed
	 * by keeping track of editor contents (eg. partitions).
	 *
	 * @param ids the ids
	 */
	private void updateContextTypes(String[] ids) {
		fActiveTypes= Arrays.asList(ids);
		if (fLinkWithEditorAction != null && fLinkWithEditorAction.isChecked())
			refresh();
	}

	/**
	 * Inserts the given template into the editor.
	 *
	 * @param template the template
	 * @param document the document
	 */
	abstract protected void insertTemplate(Template template, IDocument document);

	/**
	 * Returns the context type registry used in this page.
	 *
	 * @return the context type registry
	 */
	abstract protected ContextTypeRegistry getContextTypeRegistry();

	/**
	 * Returns the template store used in this page.
	 *
	 * @return the template store
	 * @since 3.6 public, before it was protected
	 */
	@Override
	abstract public TemplateStore getTemplateStore();

	/**
	 * Returns the preference store used to create the template store returned by
	 * {@link AbstractTemplatesPage#getTemplateStore()}.
	 *
	 * @return the preference store
	 */
	abstract protected IPreferenceStore getTemplatePreferenceStore();

	/**
	 * Returns the Template preference page id to be used by this template page.
	 *
	 * @return id the preference page if or <code>null</code> if none exists
	 */
	abstract protected String getPreferencePageId();

	/**
	 * Returns the context type ids supported at the given document offset.
	 *
	 * @param document the document
	 * @param offset the offset
	 * @return an array of supported context ids
	 */
	protected abstract String[] getContextTypeIds(IDocument document, int offset);

	/**
	 * Returns the context type ids supported at the current
	 * caret position of the editor.
	 *
	 * @return an array with the the supported context type ids
	 */
	private String[] getEditorContextTypeIds() {
		Point selectedRange=fViewer.getSelectedRange();
		int offset= selectedRange.x + selectedRange.y;
		IDocument document= fTextEditor.getDocumentProvider().getDocument(fTextEditor.getEditorInput());
		return getContextTypeIds(document, offset);
	}

	/**
	 * Checks whether the given template is valid for the document at the given
	 * offset and length.
	 *
	 * @param document the document
	 * @param template the template
	 * @param offset the offset
	 * @param length the length
	 * @return <code>true</code> if the template is valid
	 */
	protected abstract boolean isValidTemplate(IDocument document, Template template, int offset, int length);

	/**
	 * Setup the preference store
	 */
	private void setupPreferenceStore() {
		fPreferenceStore= TextEditorPlugin.getDefault().getPreferenceStore();
		fPreferenceStore.setDefault(LINK_ACTION_PREF_ID, true);
		fPreferenceStore.setDefault(SASH_SIZE_PREF_ID, 80);
	}

	/**
	 * Setup the paste operation
	 *
	 * We get the editors Paste operation and sets up a new operation that
	 * checks for the clipboard contents for {@link TemplatesTransfer} data.
	 */
	private void setupPasteOperation() {
		fEditorOldPasteAction= fTextEditor.getAction(ITextEditorActionConstants.PASTE);
		fEditorPasteAction= new Action(TemplatesMessages.TemplatesPage_paste) {
			@Override
			public void run() {
				Clipboard clipboard= new Clipboard(getShell().getDisplay());
				try {
					Template template= getTemplateFromClipboard(clipboard);
					if (template != null)
						insertTemplate(template);
					else
						fEditorOldPasteAction.run();
				} finally {
					clipboard.dispose();
				}
			}

			@Override
			public void runWithEvent(Event event) {
				run();
			}

			/**
			 * Convert the clipboard contents into a template
			 *
			 * @param clipboard the clipboard
			 * @return the template or null if contents are not valid
			 */
			private Template getTemplateFromClipboard(Clipboard clipboard) {
				TemplatePersistenceData[] contents= (TemplatePersistenceData[])clipboard
						.getContents(TemplatesTransfer.getInstance());
				if (contents != null && contents.length == 1)
					return contents[0].getTemplate();
				return null;
			}
		};
		fEditorPasteAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_PASTE);
		fTextEditor.setAction(ITextEditorActionConstants.PASTE, fEditorPasteAction);
	}

	/**
	 * Setup a selection listener to monitor the editor
	 */
	private void setupSelectionProvider() {
		ISelectionProvider selectionProvider= fViewer.getSelectionProvider();
		fSelectionChangedListener= new SelectionChangedListener();
		if (selectionProvider instanceof IPostSelectionProvider)
			((IPostSelectionProvider) selectionProvider)
					.addPostSelectionChangedListener(fSelectionChangedListener);
		else
			selectionProvider.addSelectionChangedListener(fSelectionChangedListener);
	}

	/**
	 * Setup the editor site as a drop target.
	 */
	private void setupEditorDropTarget() {
		Control control= fTextEditor.getAdapter(Control.class);
		if (control == null)
			return;

		DropTarget dropTarget= (DropTarget)control.getData(DND.DROP_TARGET_KEY);
		if (dropTarget == null)
			dropTarget= new DropTarget(control, DND.DROP_COPY);

		Transfer[] currentTransfers= dropTarget.getTransfer();
		int currentLength= currentTransfers.length;
		Transfer[] newTransfers= new Transfer[currentLength + 1];
		System.arraycopy(currentTransfers, 0, newTransfers, 0, currentLength);
		newTransfers[currentLength]= TemplatesTransfer.getInstance();
		dropTarget.setTransfer(newTransfers);

		EditorDropTargetListener editorDropTarget= new EditorDropTargetListener();
		dropTarget.addDropListener(editorDropTarget);
	}

	/**
	 * Setup the menu, context menu and toolbar actions.
	 */
	private void setupActions() {
		createActions();
		IActionBars actionBars= getSite().getActionBars();

		actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction);
		fPasteAction.setActionDefinitionId(ActionFactory.PASTE.getCommandId());
		fPasteAction.setText(TemplatesMessages.TemplatesPage_paste);
		actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction);
		fCopyAction.setActionDefinitionId(ActionFactory.COPY.getCommandId());
		fCopyAction.setText(TemplatesMessages.TemplatesPage_copy);
		fillToolbar(actionBars);
		fillMenu(actionBars);
	}

	/**
	 * Create all the actions
	 */
	private void createActions() {
		fInsertAction= new Action(TemplatesMessages.TemplatesPage_insert) {
			@Override
			public void run() {
				TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();
				insertTemplate(selectedTemplates[0].getTemplate());
			}
		};
		fInsertAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_INSERT));
		fInsertAction.setDisabledImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_DLCL_TEMPLATE_INSERT));
		fInsertAction.setToolTipText(TemplatesMessages.TemplatesPage_insert_tooltip);

		fAddAction= new Action(TemplatesMessages.TemplatesPage_new) {
			@Override
			public void run() {
				addTemplate();
			}
		};
		fAddAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_NEW));
		fAddAction.setToolTipText(TemplatesMessages.TemplatesPage_new_tooltip);

		fEditAction= new Action(TemplatesMessages.TemplatesPage_edit) {
			@Override
			public void run() {
				editTemplate();
			}
		};
		fEditAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_EDIT));
		fEditAction.setDisabledImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_DLCL_TEMPLATE_EDIT));
		fEditAction.setToolTipText(TemplatesMessages.TemplatesPage_edit_tooltip);

		fRemoveAction= new Action(TemplatesMessages.TemplatesPage_remove) {
			@Override
			public void run() {
				removeTemplates();
			}
		};
		fRemoveAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_DLCL_TEMPLATE_DELETE));
		fRemoveAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_DELETE));
		fRemoveAction.setToolTipText(TemplatesMessages.TemplatesPage_remove_tooltip);

		fLinkWithEditorAction= new Action(TemplatesMessages.TemplatesPage_link_to_editor,
				IAction.AS_CHECK_BOX) {
			@Override
			public void run() {
				fPreferenceStore.setValue(LINK_ACTION_PREF_ID, fLinkWithEditorAction.isChecked());
				refresh();
			}
		};
		fLinkWithEditorAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_LINK));
		fLinkWithEditorAction.setChecked(fPreferenceStore.getBoolean(LINK_ACTION_PREF_ID));
		fLinkWithEditorAction
				.setToolTipText(TemplatesMessages.TemplatesPage_link_to_editor_tooltip);
		fCollapseAllAction= new Action(TemplatesMessages.TemplatesPage_collapse_all) {
			@Override
			public void run() {
				fTreeViewer.collapseAll();
			}
		};
		fCollapseAllAction.setImageDescriptor(TemplatesPageImages
				.getDescriptor(TemplatesPageImages.IMG_ELCL_TEMPLATE_COLLAPSE_ALL));
		fCollapseAllAction.setToolTipText(TemplatesMessages.TemplatesPage_collapse_all_tooltip);

		if (getPreferencePageId() != null) {
			fPreferencePageAction= new Action(TemplatesMessages.TemplatesPage_preference_page) {
				@Override
				public void run() {
					showPreferencePage();
				}
			};
			fPreferencePageAction
					.setToolTipText(TemplatesMessages.TemplatesPage_preference_page_tooltip);
		}

		fPasteAction= new Action() {
			@Override
			public void run() {
				Clipboard clipboard= new Clipboard(getShell().getDisplay());
				try {
					String pattern= ((String)clipboard.getContents(TextTransfer.getInstance()));
					if (pattern != null) {
						final Template template= new Template(createTemplateName(), TemplatesMessages.TemplatesPage_paste_description, getContextTypeId(), pattern.replaceAll("\\$", "\\$\\$"), true); //$NON-NLS-1$//$NON-NLS-2$
						getShell().getDisplay().asyncExec(new Runnable() {
							@Override
							public void run() {
								addTemplate(template);
							}
						});
						return;
					}
					TemplatePersistenceData[] templates= (TemplatePersistenceData[])clipboard.getContents(TemplatesTransfer.getInstance());
					if (templates != null)
						copyTemplates(templates, getContextTypeId());
				} finally {
					clipboard.dispose();
				}

			}
		};

		fCopyAction= new Action() {
			@Override
			public void run() {
				Clipboard clipboard= new Clipboard(getShell().getDisplay());
				try {
					clipboard.setContents(new Object[] { getSelectedTemplates() }, new Transfer[] { TemplatesTransfer.getInstance() });
				} finally {
					clipboard.dispose();
				}
			}
		};
	}

	/**
	 * Inserts the given template into the editor.
	 *
	 * @param template the template
	 */
	private void insertTemplate(Template template) {
		IDocument document= fTextEditor.getDocumentProvider().getDocument(fTextEditor.getEditorInput());
		insertTemplate(template, document);
	}

	/**
	 * Fill the toolbar.
	 *
	 * @param actionBars the action bars
	 */
	private void fillToolbar(IActionBars actionBars) {
		IToolBarManager toolBarManager= actionBars.getToolBarManager();
		toolBarManager.add(fInsertAction);
		toolBarManager.add(fAddAction);
		toolBarManager.add(fEditAction);
		toolBarManager.add(fRemoveAction);

		toolBarManager.add(new Separator());

		toolBarManager.add(fLinkWithEditorAction);
		toolBarManager.add(fCollapseAllAction);
	}

	/**
	 * Fill the view menu.
	 *
	 * @param actionBars the action bars
	 */
	private void fillMenu(IActionBars actionBars) {
		IMenuManager menuManager= actionBars.getMenuManager();

		if (fPreferencePageAction != null) {
			menuManager.add(fPreferencePageAction);
			menuManager.add(new Separator());
		}

		menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	/**
	 * Fill the context menu items.
	 *
	 * @param manager the menu manager
	 */
	private void fillContextMenu(IMenuManager manager) {
		manager.add(fInsertAction);
		manager.add(new Separator());
		manager.add(fAddAction);
		manager.add(fEditAction);
		manager.add(fRemoveAction);
		manager.add(new Separator());
		manager.add(fCopyAction);
		manager.add(fPasteAction);
		// Other plug-ins can contribute there actions here
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	/**
	 * Create the tree to display templates.
	 *
	 * @param parent the parent composite
	 */
	private void createTemplateTree(Composite parent) {
		Composite treeComposite= new Composite(parent, SWT.NONE);
		GridData data= new GridData(GridData.FILL_BOTH);
		treeComposite.setLayoutData(data);

		TreeColumnLayout columnLayout= new TreeColumnLayout();
		treeComposite.setLayout(columnLayout);
		fTemplatesTree= new Tree(treeComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
				| SWT.FULL_SELECTION);
		fTemplatesTree.setHeaderVisible(true);
		fTemplatesTree.setLinesVisible(true);

		PixelConverter pixelConverter= new PixelConverter(fTemplatesTree);

		TreeColumn columnName= new TreeColumn(fTemplatesTree, SWT.NONE);
		columnName.setText(TemplatesMessages.TemplatesPage_column_name);
		int minWidth= fPreferenceStore.getInt(COLUMN_NAME_WIDTH_PREF_ID);
		if (minWidth == 0) {
			minWidth= pixelConverter.convertWidthInCharsToPixels(30);
		}
		columnLayout.setColumnData(columnName, new ColumnPixelData(minWidth, true));
		columnName.addControlListener(new ControlListener() {
			@Override
			public void controlMoved(ControlEvent e) {
			}

			@Override
			public void controlResized(ControlEvent e) {
				int nameWidth= ((TreeColumn) e.getSource()).getWidth();
				fPreferenceStore.setValue(COLUMN_NAME_WIDTH_PREF_ID, nameWidth);
			}
		});

		TreeColumn columnDescription= new TreeColumn(fTemplatesTree, SWT.NONE);
		columnDescription.setText(TemplatesMessages.TemplatesPage_column_description);
		minWidth= fPreferenceStore.getInt(COLUMN_DESCRIPTION_WIDTH_PREF_ID);
		if (minWidth == 0) {
			minWidth= pixelConverter.convertWidthInCharsToPixels(45);
		}
		columnLayout.setColumnData(columnDescription, new ColumnPixelData(minWidth, false));
		columnDescription.addControlListener(new ControlListener() {
			@Override
			public void controlMoved(ControlEvent e) {
			}

			@Override
			public void controlResized(ControlEvent e) {
				int descriptionWidth= ((TreeColumn) e.getSource()).getWidth();
				fPreferenceStore.setValue(COLUMN_DESCRIPTION_WIDTH_PREF_ID, descriptionWidth);
			}
		});

		createTreeViewer(fTemplatesTree);
	}

	/**
	 * Create the tree viewer and setup the providers.
	 *
	 * @param templatesTree the tree used to show the templates
	 */
	private void createTreeViewer(Tree templatesTree) {
		fTreeViewer= new TreeViewer(fTemplatesTree);
		fTreeViewer.setLabelProvider(new TemplateLabelProvider());
		fTreeViewer.setContentProvider(new TemplatesContentProvider());

		fTreeViewer.setComparator(new TemplateViewerComparator());
		fTreeViewer.setInput(getTemplatePreferenceStore());
		fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent e) {
				updateSelectedItems();
				TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();
				if (selectedTemplates.length > 0)
					insertTemplate(selectedTemplates[0].getTemplate());
			}
		});

		fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent e) {
				updateSelectedItems();
				updateButtons();
			}
		});
		fTreeViewer.expandAll();
	}

	/**
	 * Setup the pattern viewer.
	 *
	 * @param parent the parent composite
	 */
	private void createPatternForm(Composite parent) {
		ViewForm viewForm= new ViewForm(parent, SWT.NONE);
		viewForm.setBorderVisible(false);
		CLabel previewLabel= new CLabel(viewForm, SWT.NONE);
		previewLabel.setText(TemplatesMessages.TemplatesPage_preview);
		previewLabel.setImage(TemplatesPageImages.get(TemplatesPageImages.IMG_OBJ_PREVIEW));
		viewForm.setTopLeft(previewLabel);

		fPatternViewer= createPatternViewer(viewForm);
		viewForm.setContent(fPatternViewer.getControl());
		viewForm.addControlListener(new ControlListener() {
			@Override
			public void controlMoved(ControlEvent e) {
			}

			@Override
			public void controlResized(ControlEvent e) {
				int[] weights= fControl.getWeights();
				int sashSize= (int) (weights[0] * 100.0 / (weights[0] + weights[1]));
				fPreferenceStore.setValue(SASH_SIZE_PREF_ID, sashSize);
			}
		});
	}

	/**
	 * Hookup the context menu
	 */
	private void hookContextMenu() {
		MenuManager menuMgr= new MenuManager(POPUP_MENU_ID);
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			@Override
			public void menuAboutToShow(IMenuManager manager) {
				fillContextMenu(manager);
			}
		});
		fContextMenu= menuMgr.createContextMenu(fTreeViewer.getControl());
		fTreeViewer.getControl().setMenu(fContextMenu);
		getSite().registerContextMenu(POPUP_MENU_ID, menuMgr, fTreeViewer);
	}

	/**
	 * Check whether the template is valid for the given drop location.
	 *
	 * @param template the template
	 * @param location the drop location
	 * @return <code>true</code> if the template is valid
	 */
	private boolean isTemplateValidAtLocation(Template template, Point location) {
		StyledText textWidget= (StyledText) fTextEditor.getAdapter(Control.class);
		IDocument document= fTextEditor.getDocumentProvider().getDocument(fTextEditor.getEditorInput());
		try {
			if (location.equals(fCachedPosition))
				return fCachedResult;
			fCachedPosition= location;
			int offset= getOffset(document, textWidget, textWidget.toControl(location.x,
					location.y));
			if (fCachedOffset == offset)
				return fCachedResult;
			fCachedOffset= offset;
			if (isValidTemplate(document, template, offset, 0))
				return fCachedResult= true;
		} catch (BadLocationException e) {
		}
		return fCachedResult= false;
	}

	/**
	 * Updates the selected items.
	 */
	private void updateSelectedItems() {
		setSelectedTemplates();
		TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();

		if (selectedTemplates.length == 1)
			updatePatternViewer(selectedTemplates[0].getTemplate());
		else
			updatePatternViewer(null);
	}

	/**
	 * Shows the preference page.
	 */
	private void showPreferencePage() {
		PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageId(), null, null).open();
	}

	/**
	 * Update the state of the buttons
	 */
	private void updateButtons() {
		TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();
		fCopyAction.setEnabled(selectedTemplates.length > 0);
		fInsertAction.setEnabled(selectedTemplates.length == 1);
		fEditAction.setEnabled(selectedTemplates.length == 1);
		fRemoveAction.setEnabled(selectedTemplates.length > 0);
	}

	/**
	 * Set the selected templates
	 */
	private void setSelectedTemplates() {
		IStructuredSelection selection= (IStructuredSelection) fTreeViewer.getSelection();

		Iterator<?> it= selection.iterator();
		TemplatePersistenceData[] data= new TemplatePersistenceData[selection.size()];
		int i= 0;
		while (it.hasNext()) {
			Object o= it.next();
			if (o instanceof TemplatePersistenceData)
				data[i++]= (TemplatePersistenceData) o;
			else {
				fSelectedTemplates= new TemplatePersistenceData[0];
				return;
			}
		}
		fSelectedTemplates= data;
	}

	/**
	 * Returns the currently selected templates
	 *
	 * @return selected templates
	 * @since 3.6 public, before it was private
	 */
	@Override
	public TemplatePersistenceData[] getSelectedTemplates() {
		return fSelectedTemplates;
	}

	/**
	 * Add a template
	 */
	private void addTemplate() {
		String id= getContextTypeId();
		if (id != null) {
			Template template= new Template("", "", id, "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

			addTemplate(template);
		}
	}

	/**
	 * Returns the context type id of the selected template.
	 *
	 * @return the context type id of the selected template or the first from the
	 *         registry if no templates are selected
	 */
	private String getContextTypeId() {
		IStructuredSelection selection= (IStructuredSelection) fTreeViewer.getSelection();
		Object item;

		if (selection.size() == 0)
			return getContextTypeRegistry().contextTypes().next().getId();

		if (selection.size() == 1) {
			item= selection.getFirstElement();
			if (item instanceof TemplatePersistenceData)
				return ((TemplatePersistenceData) item).getTemplate().getContextTypeId();
			return ((TemplateContextType) item).getId();
		}
		Iterator<?> it= selection.iterator();
		String contextId= null;
		while (it.hasNext()) {
			item= it.next();
			if (contextId == null)
				contextId= getContextId(item);
			else if (!contextId.equals(getContextId(item)))
				return getContextTypeRegistry().contextTypes().next()
						.getId();
		}
		return contextId;
	}

	/**
	 * Returns the context id for the given item which is either a template or a context type.
	 *
	 * @param item the item
	 * @return the context type id
	 */
	private String getContextId(Object item) {
		String contextId;
		if (item instanceof TemplatePersistenceData)
			contextId= ((TemplatePersistenceData) item).getTemplate().getContextTypeId();
		else
			contextId= ((TemplateContextType) item).getId();
		return contextId;
	}

	/**
	 * Add a template. The dialog is filled with the values from the given template.
	 *
	 * @param template the template
	 */
	private void addTemplate(Template template) {
		Template newTemplate;
		newTemplate= editTemplate(template, false, true);
		if (newTemplate != null) {
			TemplatePersistenceData data= new TemplatePersistenceData(newTemplate, true);
			getTemplateStore().add(data);
			saveTemplateStore();
			refresh();
			fTreeViewer.setSelection(new StructuredSelection(data), true);
		}
	}

	/**
	 * Save the template store
	 */
	private void saveTemplateStore() {
		try {
			getTemplateStore().save();
		} catch (IOException e) {
			TextEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID,
					TemplatesMessages.TemplatesPage_save_error_message, e));
			MessageDialog.openError(getShell(),
					TemplatesMessages.TemplatesPage_save_error_message, e.getMessage());
		}
	}

	/**
	 * Edits the selected template.
	 */
	private void editTemplate() {
		TemplatePersistenceData selectedTemplate= getSelectedTemplates()[0];
		Template oldTemplate= selectedTemplate.getTemplate();
		Template newTemplate= editTemplate(new Template(oldTemplate), true, true);
		if (newTemplate != null) {
			if (!newTemplate.getName().equals(oldTemplate.getName())
					&& MessageDialog.openQuestion(getShell(),
							TemplatesMessages.TemplatesPage_question_create_new_title,
							TemplatesMessages.TemplatesPage_question_create_new_message)) {
				TemplatePersistenceData templateData= new TemplatePersistenceData(newTemplate,
						true);
				getTemplateStore().add(templateData);
				refresh();
				fTreeViewer.setSelection(new StructuredSelection(templateData), true);
			} else {
				selectedTemplate.setTemplate(newTemplate);
				updatePatternViewer(newTemplate);
			}
		}
		saveTemplateStore();
	}

	/**
	 * Moves the selected template from one context to another.
	 *
	 * @param templates an array of template data
	 * @param contextId the contextId
	 *
	 */
	private void moveTemplates(TemplatePersistenceData[] templates, String contextId) {
		for (int i= 0; i < templates.length; i++) {
			Template t= templates[i].getTemplate();
			templates[i].setTemplate(new Template(t.getName(), t.getDescription(), contextId, t
					.getPattern(), t.isAutoInsertable()));
		}
		saveTemplateStore();
		fTreeViewer.setSelection(new StructuredSelection(templates), true);
	}

	/**
	 * Copy the selected templates to another context
	 *
	 * @param templates an array of template data
	 * @param contextId the context id
	 *
	 */
	private void copyTemplates(TemplatePersistenceData[] templates, String contextId) {
		TemplatePersistenceData[] newTemplates= new TemplatePersistenceData[templates.length];
		for (int i= 0; i < templates.length; i++) {
			Template t= templates[i].getTemplate();
			newTemplates[i]= new TemplatePersistenceData(new Template(t.getName(), t
					.getDescription(), contextId, t.getPattern(), t.isAutoInsertable()), true);
			getTemplateStore().add(newTemplates[i]);
		}
		saveTemplateStore();
		refresh();
		fTreeViewer.setSelection(new StructuredSelection(newTemplates), true);
	}

	/**
	 * Remove one or more selected templates
	 */
	private void removeTemplates() {
		String title;
		TemplatePersistenceData[] selectedTemplates= getSelectedTemplates();
		if (selectedTemplates.length == 1)
			title= TemplatesMessages.TemplatesPage_remove_title_single;
		else
			title= TemplatesMessages.TemplatesPage_remove_title_multi;
		String message;
		if (selectedTemplates.length == 1)
			message= TemplatesMessages.TemplatesPage_remove_message_single;
		else
			message= NLSUtility.format(TemplatesMessages.TemplatesPage_remove_message_multi,
					new Object[] { Integer.valueOf(selectedTemplates.length) });
		if (!MessageDialog.openQuestion(getShell(), title, message))
			return;
		for (int i= 0; i < selectedTemplates.length; i++) {
			getTemplateStore().delete(selectedTemplates[i]);
		}
		saveTemplateStore();
		fTreeViewer.setSelection(new StructuredSelection(new Object[] {}), true);
	}

	/**
	 * Initializes drag and drop the template items
	 */
	private void initializeDND() {
		DragSourceAdapter dragListener= new DragSourceAdapter() {
			@Override
			public void dragStart(DragSourceEvent event) {
				if (getSelectedTemplates().length == 0) {
					event.doit= false;
				}
			}

			@Override
			public void dragSetData(DragSourceEvent event) {
				if (TemplatesTransfer.getInstance().isSupportedType(event.dataType)) {
					event.data= getSelectedTemplates();
				}
			}
		};
		fTreeViewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, new Transfer[] { TemplatesTransfer
				.getInstance() }, dragListener);
		DropTargetAdapter dropListener= new DropTargetAdapter() {
			Transfer textTransfer= TextTransfer.getInstance();
			Transfer templateTransfer= TemplatesTransfer.getInstance();

			@Override
			public void dragEnter(DropTargetEvent event) {
				if (event.detail == DND.DROP_DEFAULT)
					event.detail= DND.DROP_COPY;
			}

			@Override
			public void dragOperationChanged(DropTargetEvent event) {
				if (event.detail == DND.DROP_DEFAULT)
					event.detail= DND.DROP_COPY;
			}

			@Override
			public void dragOver(DropTargetEvent event) {
				event.feedback |= DND.FEEDBACK_SCROLL;
				if (event.item == null) {
					event.detail= DND.DROP_NONE;
					return;
				}
				int index= 0;
				boolean isTemplateTransfer= false;
				while (index < event.dataTypes.length) {
					if (textTransfer.isSupportedType(event.dataTypes[index])) {
						break;
					}
					if (templateTransfer.isSupportedType(event.dataTypes[index])) {
						isTemplateTransfer= true;
						break;
					}
					index++;
				}
				if (index < event.dataTypes.length) {
					event.currentDataType= event.dataTypes[index];
					if (event.detail == DND.DROP_DEFAULT || !isTemplateTransfer)
						event.detail= DND.DROP_COPY;
					return;
				}
			}

			@Override
			public void drop(DropTargetEvent event) {
				if (event.item == null)
					return;
				Object object= ((TreeItem) event.item).getData();
				final String contextId;
				if (object instanceof TemplateContextType)
					contextId= ((TemplateContextType) object).getId();
				else
					contextId= ((TemplatePersistenceData) object).getTemplate().getContextTypeId();
				if (textTransfer.isSupportedType(event.currentDataType)) {
					String text= ((String) event.data).replaceAll("\\$", "\\$\\$"); //$NON-NLS-1$ //$NON-NLS-2$
					final Template template= new Template(createTemplateName(),
							TemplatesMessages.TemplatesPage_paste_description, contextId, text,
							true);
					getShell().getDisplay().asyncExec(new Runnable() {
						@Override
						public void run() {
							addTemplate(template);
						}
					});
					return;
				}
				if (templateTransfer.isSupportedType(event.currentDataType)) {
					final TemplatePersistenceData[] templates= (TemplatePersistenceData[]) event.data;
					final int dropType= event.detail;
					getShell().getDisplay().asyncExec(new Runnable() {
						@Override
						public void run() {
							if (dropType == DND.DROP_COPY)
								copyTemplates(templates, contextId);
							else
								moveTemplates(templates, contextId);
						}
					});
				}
			}
		};
		Transfer[] transfers= new Transfer[] { TextTransfer.getInstance(),
				TemplatesTransfer.getInstance() };
		fTreeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, dropListener);
	}

	/**
	 * Create a template name.
	 *
	 * @return the created template name
	 */
	private String createTemplateName() {
		for (int i= 1; i < Integer.MAX_VALUE; i++) {
			String name= TemplatesMessages.TemplatesPage_snippet + i;
			if (getTemplateStore().findTemplate(name) == null)
				return name;
		}
		return null;
	}

	/**
	 * Stores the collapse state of a context node.
	 */
	private void storeCollapseState() {
		TreeItem[] items= fTreeViewer.getTree().getItems();
		for (int i= 0; i < items.length; i++) {
			fPreferenceStore.setValue(CONTEXT_COLLAPSE_PREF_ID
					+ ((TemplateContextType) items[i].getData()).getId(), !items[i].getExpanded());
		}
	}

	/**
	 * Refreshes the template tree contents.
	 */
	private void refresh() {
		storeCollapseState();
		fTreeViewer.getTree().setRedraw(false);
		try {
			fTreeViewer.refresh();
			TreeItem[] items= fTreeViewer.getTree().getItems();
			for (int i= 0; i < items.length; i++) {
				boolean isExpanded= !fPreferenceStore.getBoolean(CONTEXT_COLLAPSE_PREF_ID
						+ ((TemplateContextType) items[i].getData()).getId());
				if (isExpanded)
					fTreeViewer.expandToLevel(items[i].getData(), AbstractTreeViewer.ALL_LEVELS);
				else
					fTreeViewer.collapseToLevel(items[i].getData(), AbstractTreeViewer.ALL_LEVELS);
			}
		} finally {
			fTreeViewer.getTree().setRedraw(true);
		}
	}

	/**
	 * Returns the document relative offset from the text widget relative point
	 *
	 * @param document the document
	 * @param textWidget the text widget
	 * @param point the point for which to get the offset
	 * @return the offset
	 * @throws BadLocationException if the document is accessed with an invalid line
	 */
	private int getOffset(IDocument document, StyledText textWidget, Point point)
			throws BadLocationException {
		int widgetCaret= fViewer.getTextWidget().getCaretOffset();
		if (fViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 ext= (ITextViewerExtension5) fViewer;
			try {
				return ext.widgetOffset2ModelOffset(textWidget.getOffsetAtLocation(point));
			} catch (IllegalArgumentException e) {
				int docLineIndex= ext.widgetLine2ModelLine(textWidget.getLineIndex(point.y));
				String lineDelimiter= document.getLineDelimiter(docLineIndex);
				int delimLength= lineDelimiter == null ? 0 : lineDelimiter.length();
				return document.getLineOffset(docLineIndex) + document.getLineLength(docLineIndex)
						- delimLength;
			}
		}
		IRegion visible= fViewer.getVisibleRegion();
		return widgetCaret + visible.getOffset();
	}
}
