/*******************************************************************************
 * Copyright (c) 2006, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Eugene Kuleshov <eu@md.pp.ru> - Bug 153932 [History] Custom hyperlink detectors for comments in History view
 *     Brock Janiczak (brockj@tpg.com.au) - Bug 181899 CVS History wrongly ordered
 *******************************************************************************/

package org.eclipse.team.internal.ccvs.ui;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import org.eclipse.compare.*;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
import org.eclipse.core.resources.mapping.ResourceChangeValidator;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.revisions.Revision;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.history.*;
import org.eclipse.team.core.variants.IResourceVariant;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.core.client.Update;
import org.eclipse.team.internal.ccvs.core.filehistory.*;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.ui.actions.CVSAction;
import org.eclipse.team.internal.ccvs.ui.actions.MoveRemoteTagAction;
import org.eclipse.team.internal.ccvs.ui.operations.*;
import org.eclipse.team.internal.core.history.LocalFileRevision;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.actions.*;
import org.eclipse.team.internal.ui.history.*;
import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
import org.eclipse.team.ui.history.*;
import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
import org.eclipse.ui.*;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.progress.IProgressConstants;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;

public class CVSHistoryPage extends HistoryPage implements IAdaptable, IHistoryCompareAdapter {
	
	/* private */ ICVSFile file;
	/* private */ ICVSFile previousFile;
	/* private */ IFileRevision currentFileRevision;
	private ITypedElement fileElement;
	
	// cached for efficiency
	/* private */ CVSFileHistory cvsFileHistory;
	/* private */IFileRevision[] entries;

	/* private */CVSHistoryTableProvider historyTableProvider;

	private Composite tagAndTextComposite;
	private Composite searchComposite;
	
	/* private */TreeViewer treeViewer;
	/* private */TextViewer textViewer;
	/* private */TableViewer tagViewer;

	/* private */CompareRevisionAction compareAction;
	/* private */OpenRevisionAction openAction;
	private OpenWithMenu openWithMenu;
	
	private CVSHistoryFilterAction  cvsHistoryFilter;
	private IAction toggleTextAction;
	private IAction toggleTextWrapAction;
	private IAction toggleListAction;
	private IAction toggleFilterAction;
	private IAction toggleSearchAction;
	private TextViewerAction copyAction;
	private TextViewerAction selectAllAction;
	private Action getContentsAction;
	private Action getRevisionAction;
	private Action refreshAction;
	/**
	 * Allows copying the tag name to the clipboard
	 */
	private TableViewerAction copyTagAction;
	
	private Action tagWithExistingAction;
	private Action localMode;
	private Action remoteMode;
	private Action remoteLocalMode;
	private Action groupByDateMode;
	private Action collapseAll;
	private Action compareModeAction;
	
	private SashForm sashForm;
	private SashForm innerSashForm;
	private SashForm searchSashForm;
	
	private Image branchImage;
	private Image versionImage;

	private IDialogSettings settings;

	protected IFileRevision currentSelection;

	/* private */RefreshCVSFileHistory  refreshCVSFileHistoryJob;

	/* private */boolean shutdown = false;

	/* private */boolean localFilteredOut = false;
	/* private */boolean remoteFilteredOut = false;
	
	private HistoryResourceListener resourceListener;
	
	//toggle constants for default click action
	private boolean compareMode = false;
	
	//filter constants
	public final static int REMOTE_LOCAL_MODE = 0;
	public final static int REMOTE_MODE = 1;
	public final static int LOCAL_MODE = 2;

	// page settings keys
	private final static String SASH_WEIGHTS = "SASH_WEIGHTS"; //$NON-NLS-1$
	private final static String INNER_SASH_WEIGHTS = "INNER_SASH_WEIGHTS"; //$NON-NLS-1$
	private final static String SASH_WEIGHTS_SEPARATOR = ";"; //$NON-NLS-1$
	private final static String SORT_ORDER_KEY = "SORT_ORDER"; //$NON-NLS-1$

	// page settings section name
	private static final String CVS_HISTORY_PAGE_SECTION = CVSHistoryPage.class.getName();

	//current filter mode
	private int currentFilerMode = 0;
	
	//text field used for search
	private Text searchField;
	
	//current tag list sort order.
	private boolean sortTagsAscending;

	// listener registered on the book this page is contained
	private DisposeListener disposeListener;

	//grouping on
	private boolean groupingOn;
	private CVSHistoryFilter historyFilter;
	private CVSHistorySearchFilter searchFilter;
	private RevisionAnnotationController rulerSelectionListener;
	
	private int refreshRequest = 0;
	private DateFormat dateTimeFormat;
	private String description;
	
	public CVSHistoryPage(Object object) {
		this.file = getCVSFile(object);

		IDialogSettings viewsSettings = CVSUIPlugin.getPlugin()
				.getDialogSettings();
		settings = viewsSettings.getSection(CVS_HISTORY_PAGE_SECTION);
		if (settings == null) {
			settings = viewsSettings.addNewSection(CVS_HISTORY_PAGE_SECTION);
		}
		sortTagsAscending= settings.get(SORT_ORDER_KEY) == null || settings.getBoolean(SORT_ORDER_KEY);
	}

	/**
	 * Action to sort the tag list ascending or descending.
	 */
	final class SortTagsAction extends Action {
		
		private boolean sortAscending;
		
		public SortTagsAction(boolean sortAscending) {
			super(
				sortAscending
					? CVSUIMessages.CVSHistoryPage_SortTagsAscendingAction
					: CVSUIMessages.CVSHistoryPage_SortTagsDescendingAction,
				IAction.AS_RADIO_BUTTON);
			setChecked(sortAscending == sortTagsAscending);
			this.sortAscending = sortAscending;
		}

		@Override
		public void run() {
			sortTagsAscending = sortAscending;
			tagViewer.refresh();
		}
	}


	@Override
	public void createControl(Composite parent) {
		initializeImages();
		
		sashForm = new SashForm(parent, SWT.VERTICAL);
		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		treeViewer = createTree(sashForm);
		
		tagAndTextComposite = new Composite(sashForm, SWT.NONE);
		tagAndTextComposite.setLayout(new FillLayout());
		innerSashForm = new SashForm(tagAndTextComposite, SWT.HORIZONTAL);
		tagViewer = createTagTable(innerSashForm);
		textViewer = createText(innerSashForm);
		
		searchComposite = new Composite(sashForm, SWT.NONE);
		searchComposite.setLayout(new FillLayout());
		searchSashForm = new SashForm(searchComposite, SWT.HORIZONTAL);
		//Find field
		searchField = new Text(searchSashForm, SWT.SEARCH);
		searchField.setMessage(CVSUIMessages.CVSHistoryPage_EnterSearchTerm);
		final SearchHistoryTable searchHistoryTable = new SearchHistoryTable();
		searchField.addModifyListener(e -> Display.getDefault().timerExec(1000, searchHistoryTable));

		contributeActions();
		setViewerVisibility();

		int[] weights = loadSashWeights(SASH_WEIGHTS);
		sashForm.setWeights(weights.length == 3 ? weights : new int[] { 65, 20,
				15 });
		int[] innerWeights = loadSashWeights(INNER_SASH_WEIGHTS);
		innerSashForm.setWeights(innerWeights.length == 2 ? innerWeights
				: new int[] { 50, 50 });

		IHistoryPageSite parentSite = getHistoryPageSite();
		if (parentSite != null && parentSite instanceof DialogHistoryPageSite && treeViewer != null)
			parentSite.setSelectionProvider(treeViewer);
		
		resourceListener = new HistoryResourceListener();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener, IResourceChangeEvent.POST_CHANGE);
		
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sashForm, IHelpContextIds.RESOURCE_HISTORY_VIEW);

		disposeListener = e -> saveState();
		parent.addDisposeListener(disposeListener);
	}

	private void saveState() {
		saveSashWeights(SASH_WEIGHTS, sashForm.getWeights());
		saveSashWeights(INNER_SASH_WEIGHTS, innerSashForm.getWeights());
		historyTableProvider.saveColumnLayout();
		settings.put(SORT_ORDER_KEY, sortTagsAscending);
	}

	private int[] loadSashWeights(String key) {
		String value = settings.get(key);
		if (value == null) {
			return new int[0];
		}
		String weigths[] = value.split(SASH_WEIGHTS_SEPARATOR);
		int result[] = new int[weigths.length];
		for (int i = 0; i < weigths.length; i++) {
			try {
				result[i] = Integer.parseInt(weigths[i]);
			} catch (NumberFormatException e) {
				return new int[0];
			}
		}
		return result;
	}

	private void saveSashWeights(String key, int[] weights) {
		StringBuffer value = new StringBuffer();
		for (int i = 0; i < weights.length; i++) {
			value = value.append(weights[i] + SASH_WEIGHTS_SEPARATOR);
		}
		settings.put(key, value.toString());
	}

	private TextViewer createText(SashForm parent) {
	SourceViewer result = new SourceViewer(parent, null, null, true, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.READ_ONLY);
	result.getTextWidget().setIndent(2);
	result.configure(new TextSourceViewerConfiguration(EditorsUI.getPreferenceStore()) {
	@Override
	protected Map getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
		return Collections.singletonMap("org.eclipse.ui.DefaultTextEditor", //$NON-NLS-1$
			new IAdaptable() {
			@Override
			public <T> T getAdapter(Class<T> adapter) {
				if(adapter==IFile.class && getInput() instanceof IFile) {
					return adapter.cast(getInput());
				} else if(adapter==IFileHistory.class && getInput() instanceof IFileHistory) {
					return adapter.cast(getInput());
				}
				return Platform.getAdapterManager().getAdapter(CVSHistoryPage.this, adapter);
			}
			});
	}
	});

	result.addSelectionChangedListener(event -> copyAction.update());
	result.setTextDoubleClickStrategy(
				new DefaultTextDoubleClickStrategy(),
				IDocument.DEFAULT_CONTENT_TYPE);
		result.activatePlugins();
		return result;
	}

	private TableViewer createTagTable(SashForm parent) {
		Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
		TableViewer result = new TableViewer(table);
		TableLayout layout = new TableLayout();
		layout.addColumnData(new ColumnWeightData(100));
		table.setLayout(layout);
		result.setContentProvider(new SimpleContentProvider() {
			@Override
			public Object[] getElements(Object inputElement) {
				if (inputElement == null)
					return new Object[0];
				ITag[] tags = (ITag[]) inputElement;
				return tags;
			}
		});
		result.setLabelProvider(new LabelProvider() {
			@Override
			public Image getImage(Object element) {
				if (element == null)
					return null;
				ITag tag = (ITag) element;
				if (!(tag instanceof CVSTag))
					return null;
				
				switch (((CVSTag)tag).getType()) {
					case CVSTag.BRANCH:
					case CVSTag.HEAD:
						return branchImage;
					case CVSTag.VERSION:
						return versionImage;
				}
				return null;
			}

			@Override
			public String getText(Object element) {
				return ((ITag) element).getName();
			}
		});
		result.setComparator(new ViewerComparator() {
			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				if (!(e1 instanceof ITag) || !(e2 instanceof ITag))
					return super.compare(viewer, e1, e2);
				CVSTag tag1 = (CVSTag) e1;
				CVSTag tag2 = (CVSTag) e2;
				int type1 = tag1.getType();
				int type2 = tag2.getType();
				if (type1 != type2) {
					return type2 - type1;
				}
				if (sortTagsAscending)
					return super.compare(viewer, tag1, tag2);
				else
					return super.compare(viewer, tag2, tag1);
			}
		});
		result.addSelectionChangedListener(event -> {
			copyTagAction.setEnabled(false);
			if (event.getSelection() instanceof StructuredSelection) {
				if (((StructuredSelection) event.getSelection()).getFirstElement() != null) {
					copyTagAction.setEnabled(true);
				}
			}
			
		});
		return result;
	}

	@Override
	public void setFocus() {
		sashForm.setFocus();
		if (refreshRequest != 0) {
			refresh(refreshRequest);
			refreshRequest = 0;
		}
	}

	protected void contributeActions() {
		CVSUIPlugin plugin = CVSUIPlugin.getPlugin();

		//Refresh
		refreshAction = new Action(CVSUIMessages.HistoryView_refreshLabel, plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH_ENABLED)) {
			@Override
			public void run() {
				refresh();
			}
		};
		refreshAction.setToolTipText(CVSUIMessages.HistoryView_refresh);
		refreshAction.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH_DISABLED));
		refreshAction.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH));

		//Local Mode
		final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore();
		localMode =  new Action(CVSUIMessages.CVSHistoryPage_LocalModeAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALMODE)) {
			@Override
			public void run() {
				if (isChecked()){
					store.setValue(ICVSUIConstants.PREF_REVISION_MODE, LOCAL_MODE);
					updateFilterMode(LOCAL_MODE);
				} else
					setChecked(true);
			}
		};
		localMode.setToolTipText(CVSUIMessages.CVSHistoryPage_LocalModeTooltip);
		localMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALMODE_DISABLED));
		localMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALMODE));

		//Remote Mode
		remoteMode =  new Action(CVSUIMessages.CVSHistoryPage_RemoteModeAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE)) {
			@Override
			public void run() {
				if (isChecked()){
					store.setValue(ICVSUIConstants.PREF_REVISION_MODE, REMOTE_MODE);
					updateFilterMode(REMOTE_MODE);
				} else
					setChecked(true);
			}
		};
		remoteMode.setToolTipText(CVSUIMessages.CVSHistoryPage_RemoteModeTooltip);
		remoteMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE_DISABLED));
		remoteMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE));
		
		//Remote + Local Mode
		remoteLocalMode =  new Action(CVSUIMessages.CVSHistoryPage_CombinedModeAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE)) {
			@Override
			public void run() {
				if (isChecked()){
					store.setValue(ICVSUIConstants.PREF_REVISION_MODE, REMOTE_LOCAL_MODE);
					updateFilterMode(REMOTE_LOCAL_MODE);
				} else
					setChecked(true);
			}
		};
		remoteLocalMode.setToolTipText(CVSUIMessages.CVSHistoryPage_CombinedModeTooltip);
		remoteLocalMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE_DISABLED));
		remoteLocalMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE));
		
		//set the inital filter to both remote and local
		updateFilterMode(store.getInt(ICVSUIConstants.PREF_REVISION_MODE));
		
		//Group by Date
		groupByDateMode = new Action(CVSUIMessages.CVSHistoryPage_GroupByDate, CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY)){
			@Override
			public void run() {
				groupingOn = !groupingOn;
				store.setValue(ICVSUIConstants.PREF_GROUPBYDATE_MODE, groupingOn);
				refreshHistory(false, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
			}
		};
		groupingOn = store.getBoolean(ICVSUIConstants.PREF_GROUPBYDATE_MODE);
		groupByDateMode.setChecked(groupingOn);
		groupByDateMode.setToolTipText(CVSUIMessages.CVSHistoryPage_GroupByDate);
		groupByDateMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY));
		groupByDateMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY));
		
		//Collapse All
		collapseAll =  new Action(CVSUIMessages.CVSHistoryPage_CollapseAllAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL)) {
			@Override
			public void run() {
				treeViewer.collapseAll();
			}
		};
		collapseAll.setToolTipText(CVSUIMessages.CVSHistoryPage_CollapseAllTooltip);
		collapseAll.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL));
		collapseAll.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL));
		
		//Compare Mode Action
		compareModeAction = new Action(CVSUIMessages.CVSHistoryPage_CompareModeToggleAction,plugin.getImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW)) {
			@Override
			public void run() {
				compareMode = !compareMode;
				compareModeAction.setChecked(compareMode);
			}
		};
		compareModeAction.setToolTipText(CVSUIMessages.CVSHistoryPage_CompareModeTooltip);
		compareModeAction.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW));
		compareModeAction.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW));
		compareModeAction.setChecked(false);
		
		// Click Compare action
		compareAction = new CompareRevisionAction(CVSUIMessages.CVSHistoryPage_CompareRevisionAction, this);
		compareAction.setEnabled(!treeViewer.getSelection().isEmpty());
		treeViewer.getTree().addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				//update the current
				compareAction.setCurrentFileRevision(getCurrentFileRevision());
				compareAction.selectionChanged(treeViewer.getStructuredSelection());
			}
		});
		
		openAction = new OpenRevisionAction(CVSUIMessages.CVSHistoryPage_OpenAction, this);
		openAction.setEnabled(!treeViewer.getSelection().isEmpty());
		treeViewer.getTree().addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				openAction.selectionChanged(treeViewer.getStructuredSelection());
			}
		});
		
		// Add 'Open With...'  sub-menu
		openWithMenu = new OpenWithMenu(this);
		treeViewer.getTree().addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				openWithMenu.selectionChanged(treeViewer.getStructuredSelection());
			}
		});

		new OpenAndLinkWithEditorHelper(treeViewer) {
			@Override
			protected void open(ISelection selection, boolean activate) {
				if (getSite() != null && selection instanceof IStructuredSelection) {
					IStructuredSelection structuredSelection= (IStructuredSelection)selection;
					if (compareMode){
						StructuredSelection sel = new StructuredSelection(new Object[] {getCurrentFileRevision(), structuredSelection.getFirstElement()});
						compareAction.selectionChanged(sel);
						compareAction.run();
					} else {
						//Pass in the entire structured selection to allow for multiple editor openings
						openAction.selectionChanged(structuredSelection);
						openAction.run();
					}
				}
			}

			@Override
			protected void activate(ISelection selection) {
				int currentMode= OpenStrategy.getOpenMethod();
				try {
					OpenStrategy.setOpenMethod(OpenStrategy.DOUBLE_CLICK);
					open(selection, true);
				} finally {
					OpenStrategy.setOpenMethod(currentMode);
				}
			}

			@Override
			protected void linkToEditor(ISelection selection) {
				// XXX: Not yet implemented, see http://bugs.eclipse.org/324185
			}
		};

		getContentsAction = getContextMenuAction(CVSUIMessages.HistoryView_getContentsAction, true /* needs progress */, monitor -> {
			monitor.beginTask(null, 100);
			try {
				if(confirmOverwrite() && validateChange()) {
					IStorage currentStorage = currentSelection.getStorage(SubMonitor.convert(monitor, 50));
					InputStream in = currentStorage.getContents();
					((IFile)file.getIResource()).setContents(in, false, true, SubMonitor.convert(monitor, 50));
				}
			} catch (TeamException e) {
				throw new CoreException(e.getStatus());
			} finally {
				monitor.done();
			}
		});
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getContentsAction, IHelpContextIds.GET_FILE_CONTENTS_ACTION);

		getRevisionAction = getContextMenuAction(CVSUIMessages.HistoryView_getRevisionAction, true /* needs progress */, monitor -> {
			ICVSRemoteFile remoteFile = (ICVSRemoteFile) CVSWorkspaceRoot.getRemoteResourceFor(((CVSFileRevision) currentSelection).getCVSRemoteFile());
			try {
				if(confirmOverwrite() && validateChange()) {
					CVSTag revisionTag = new CVSTag(remoteFile.getRevision(), CVSTag.VERSION);
					
					if(CVSAction.checkForMixingTags(getHistoryPageSite().getShell(), new IResource[] {file.getIResource()}, revisionTag)) {
						new UpdateOperation(
								null,
								new IResource[] {file.getIResource()},
								new Command.LocalOption[] {Update.IGNORE_LOCAL_CHANGES},
								revisionTag)
									.run(monitor);
						
						Display.getDefault().asyncExec(() -> refresh());
					}
				}
			} catch (InvocationTargetException e1) {
				throw CVSException.wrapException(e1);
			} catch (InterruptedException e2) {
				// Cancelled by user
			}
		});
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getRevisionAction, IHelpContextIds.GET_FILE_REVISION_ACTION);

		// Override MoveRemoteTagAction to work for log entries
		final IActionDelegate tagActionDelegate = new MoveRemoteTagAction() {
			@Override
			protected ICVSResource[] getSelectedCVSResources() {
				ICVSResource[] resources = super.getSelectedCVSResources();
				if (resources == null || resources.length == 0) {
					ArrayList logEntrieFiles = null;
					IStructuredSelection selection = getSelection();
					if (!selection.isEmpty()) {
						logEntrieFiles = new ArrayList();
						Iterator elements = selection.iterator();
						while (elements.hasNext()) {
							Object next = elements.next();
							if (next instanceof CVSFileRevision) {
								logEntrieFiles.add(((CVSFileRevision)next).getCVSRemoteFile());
								continue;
							}
							if (next instanceof IAdaptable) {
								IAdaptable a = (IAdaptable) next;
								Object adapter = a.getAdapter(ICVSResource.class);
								if (adapter instanceof ICVSResource) {
									logEntrieFiles.add(((ILogEntry)adapter).getRemoteFile());
									continue;
								}
							}
						}
					}
					if (logEntrieFiles != null && !logEntrieFiles.isEmpty()) {
						return (ICVSResource[])logEntrieFiles.toArray(new ICVSResource[logEntrieFiles.size()]);
					}
				}
				return resources;
			}
			/*
			 * Override the creation of the tag operation in order to support
			 * the refresh of the view after the tag operation completes
			 */
			@Override
			protected ITagOperation createTagOperation() {
				return new TagInRepositoryOperation(getTargetPart(), getSelectedRemoteResources()) {
					@Override
					public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
						super.execute(monitor);
						Display.getDefault().asyncExec(() -> {
							if( ! wasCancelled()) {
								refresh();
							}
						});
					};
				};
			}
		};
		tagWithExistingAction = getContextMenuAction(CVSUIMessages.HistoryView_tagWithExistingAction, false /* no progress */, monitor -> {
			tagActionDelegate.selectionChanged(tagWithExistingAction, treeViewer.getSelection());
			tagActionDelegate.run(tagWithExistingAction);
		});
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getRevisionAction, IHelpContextIds.TAG_WITH_EXISTING_ACTION);
		
		// Toggle text visible action
		toggleTextAction = new Action(TeamUIMessages.GenericHistoryView_ShowCommentViewer) {
			@Override
			public void run() {
				setViewerVisibility();
				store.setValue(ICVSUIConstants.PREF_SHOW_COMMENTS, toggleTextAction.isChecked());
			}
		};
		toggleTextAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_SHOW_COMMENTS));
		//PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleTextAction, IHelpContextIds.SHOW_COMMENT_IN_HISTORY_ACTION);

		// Toggle wrap comments action
		toggleTextWrapAction = new Action(TeamUIMessages.GenericHistoryView_WrapComments) {
			@Override
			public void run() {
				setViewerVisibility();
				store.setValue(ICVSUIConstants.PREF_WRAP_COMMENTS, toggleTextWrapAction.isChecked());
			}
		};
		toggleTextWrapAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_WRAP_COMMENTS));
		//PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleTextWrapAction, IHelpContextIds.SHOW_TAGS_IN_HISTORY_ACTION);

		// Toggle list visible action
		toggleListAction = new Action(TeamUIMessages.GenericHistoryView_ShowTagViewer) {
			@Override
			public void run() {
				setViewerVisibility();
				store.setValue(ICVSUIConstants.PREF_SHOW_TAGS, toggleListAction.isChecked());
			}
		};
		toggleListAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_SHOW_TAGS));
		//PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleListAction, IHelpContextIds.SHOW_TAGS_IN_HISTORY_ACTION);

		//Toggle search field
		toggleSearchAction= new Action(CVSUIMessages.CVSHistoryPage_ShowSearchField) {
			@Override
			public void run() {
				setViewerVisibility();
				store.setValue(ICVSUIConstants.PREF_SHOW_SEARCH, toggleSearchAction.isChecked());
				if (!toggleSearchAction.isChecked()){
					if (searchFilter != null)
						treeViewer.removeFilter(searchFilter);
				} else {
					searchField.setMessage(CVSUIMessages.CVSHistoryPage_EnterSearchTerm);
					searchField.selectAll();
					searchField.setFocus();
				}
			}
		};
		toggleSearchAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_SHOW_SEARCH));
		//PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleListAction, IHelpContextIds.SHOW_TAGS_IN_HISTORY_ACTION);
		
		toggleFilterAction = new Action(CVSUIMessages.CVSHistoryPage_NoFilter){
			@Override
			public void run(){
				if (historyFilter != null)
					treeViewer.removeFilter(historyFilter);
					historyFilter = null;
					String old = CVSHistoryPage.this.description;
					CVSHistoryPage.this.description = null;
					CVSHistoryPage.this.firePropertyChange(CVSHistoryPage.this, P_NAME, old, getName());
					toggleFilterAction.setEnabled(false);
			}
		};
		toggleFilterAction.setEnabled(historyFilter != null);
		
		//Create the filter action
		cvsHistoryFilter = new CVSHistoryFilterAction(this);
		cvsHistoryFilter.setText(CVSUIMessages.CVSHistoryPage_FilterOn);
		cvsHistoryFilter.init(treeViewer);
		cvsHistoryFilter.setToolTipText(CVSUIMessages.CVSHistoryPage_FilterHistoryTooltip);
		cvsHistoryFilter.setImageDescriptor(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_FILTER_HISTORY));
		
		//Contribute actions to popup menu
		MenuManager menuMgr = new MenuManager();
		Menu menu = menuMgr.createContextMenu(treeViewer.getTree());
		menuMgr.addMenuListener(menuMgr1 -> fillTableMenu(menuMgr1));
		menuMgr.setRemoveAllWhenShown(true);
		treeViewer.getTree().setMenu(menu);
		//Don't add the object contribution menu items if this page is hosted in a dialog
		IHistoryPageSite parentSite = getHistoryPageSite();
		if (!parentSite.isModal()) {
			IWorkbenchPart part = parentSite.getPart();
			if (part != null) {
				IWorkbenchPartSite workbenchPartSite = part.getSite();
				workbenchPartSite.registerContextMenu(menuMgr, treeViewer);
			}
			IPageSite pageSite = parentSite.getWorkbenchPageSite();
			if (pageSite != null) {
				IActionBars actionBars = pageSite.getActionBars();
				// Contribute toggle text visible to the toolbar drop-down
				IMenuManager actionBarsMenu = actionBars.getMenuManager();
				if (actionBarsMenu != null){
					actionBarsMenu.add(toggleTextWrapAction);
					actionBarsMenu.add(new Separator());
					actionBarsMenu.add(toggleTextAction);
					actionBarsMenu.add(toggleListAction);
					actionBarsMenu.add(new Separator());
					actionBarsMenu.add(toggleSearchAction);
					actionBarsMenu.add(new Separator());
					actionBarsMenu.add(cvsHistoryFilter);
					actionBarsMenu.add(toggleFilterAction);
				}
				// Create actions for the text editor
				copyAction = new TextViewerAction(textViewer, ITextOperationTarget.COPY);
				copyAction.setText(CVSUIMessages.HistoryView_copy);
				actionBars.setGlobalActionHandler(ITextEditorActionConstants.COPY, copyAction);
				
				selectAllAction = new TextViewerAction(textViewer, ITextOperationTarget.SELECT_ALL);
				selectAllAction.setText(CVSUIMessages.HistoryView_selectAll);
				actionBars.setGlobalActionHandler(ITextEditorActionConstants.SELECT_ALL, selectAllAction);
				
				copyTagAction = new TableViewerAction(tagViewer);
				copyTagAction.setText(CVSUIMessages.HistoryView_copy);
				copyTagAction.setEnabled(false);
				
				actionBars.updateActionBars();
			}
		}
		
		
		
		//Create the local tool bar
		IToolBarManager tbm = parentSite.getToolBarManager();
		if (tbm != null) {
			String fileNameQualifier = getFileNameQualifier();
			//Add groups
			tbm.add(new Separator(fileNameQualifier + "grouping"));	//$NON-NLS-1$
			tbm.appendToGroup(fileNameQualifier+"grouping", groupByDateMode); //$NON-NLS-1$
			tbm.add(new Separator(fileNameQualifier+"modes"));	//$NON-NLS-1$
			tbm.appendToGroup(fileNameQualifier+"modes", remoteLocalMode); //$NON-NLS-1$
			tbm.appendToGroup(fileNameQualifier+"modes", localMode); //$NON-NLS-1$
			tbm.appendToGroup(fileNameQualifier+"modes", remoteMode); //$NON-NLS-1$
			tbm.add(new Separator(fileNameQualifier+"collapse")); //$NON-NLS-1$
			tbm.appendToGroup(fileNameQualifier+"collapse", collapseAll); //$NON-NLS-1$
			if (!parentSite.isModal()) {
				//don't bother adding the compare mode toolbar button if in
				//a dialog; you can only compare from dialogs
				tbm.appendToGroup(fileNameQualifier+"collapse", compareModeAction);  //$NON-NLS-1$
			}
			tbm.update(false);
		}

		menuMgr = new MenuManager();
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(menuMgr1 -> fillTextMenu(menuMgr1));
		StyledText text = textViewer.getTextWidget();
		menu = menuMgr.createContextMenu(text);
		text.setMenu(menu);
		
		menuMgr = new MenuManager();
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(menuMgr1 -> fillTagMenu(menuMgr1));
		menu = menuMgr.createContextMenu(tagViewer.getControl());
		tagViewer.getControl().setMenu(menu);
	}

	private String getFileNameQualifier() {
		//Just append the current system time to generate a unique group name
		return Long.toString(System.currentTimeMillis());
	}

	private boolean isLocalHistoryFilteredOut() {
		return localFilteredOut;
	}
	
	private boolean isRemoteHistoryFilteredOut(){
		return remoteFilteredOut;
	}
	
	/* private */ void fillTableMenu(IMenuManager manager) {
		// file actions go first (view file)
		IHistoryPageSite parentSite = getHistoryPageSite();
		manager.add(new Separator(IWorkbenchActionConstants.GROUP_FILE));
		
		if (file != null && !parentSite.isModal()){
			manager.add(openAction);
			
			MenuManager openWithSubmenu = new MenuManager(
					CVSUIMessages.CVSHistoryPage_OpenWithMenu);
			openWithSubmenu.add(openWithMenu);
			manager.add(openWithSubmenu);
			
			manager.add(compareAction);
			manager.add(new Separator("openCompare")); //$NON-NLS-1$
		}
		if (file != null &&
			!(file instanceof RemoteFile)) {
			// Add the "Add to Workspace" action if 1 revision is selected.
			ISelection sel = treeViewer.getSelection();
			if (!sel.isEmpty()) {
				if (sel instanceof IStructuredSelection) {
					IStructuredSelection tempSelection = (IStructuredSelection) sel;
					if (tempSelection.size() == 1) {
						manager.add(getContentsAction);
						if (!(tempSelection.getFirstElement() instanceof LocalFileRevision)) {
							manager.add(getRevisionAction);
							manager.add(new Separator());
							if (!parentSite.isModal())
								manager.add(tagWithExistingAction);
						}
					}
				}
			}
		}
		
		if (!parentSite.isModal()){
			manager.add(new Separator("additions")); //$NON-NLS-1$
			manager.add(refreshAction);
			manager.add(new Separator("additions-end")); //$NON-NLS-1$
		}
	}

	private void fillTextMenu(IMenuManager manager) {
		manager.add(copyAction);
		manager.add(selectAllAction);
	}
	
	private void fillTagMenu(IMenuManager manager) {
		manager.add(copyTagAction);
		manager.add(new Separator());
		manager.add(new SortTagsAction(true));
		manager.add(new SortTagsAction(false));
	}

	/**
	 * Creates the group that displays lists of the available repositories and
	 * team streams.
	 * 
	 * @param the
	 *            parent composite to contain the group
	 * @return the group control
	 */
	protected TreeViewer createTree(Composite parent) {

		historyTableProvider = new CVSHistoryTableProvider();
		TreeViewer viewer = historyTableProvider.createTree(parent);

		viewer.setContentProvider(new ITreeContentProvider() {
			@Override
			public Object[] getElements(Object inputElement) {

				// The entries of already been fetch so return them
				if (entries != null)
					return entries;
				
				if (!(inputElement instanceof IFileHistory) &&
					!(inputElement instanceof AbstractHistoryCategory[]))
					return new Object[0];

				if (inputElement instanceof AbstractHistoryCategory[]){
					return (AbstractHistoryCategory[]) inputElement;
				}
				
				final IFileHistory fileHistory = (IFileHistory) inputElement;
				entries = fileHistory.getFileRevisions();
				
				return entries;
			}

			@Override
			public void dispose() {
			}

			@Override
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
				entries = null;
			}

			@Override
			public Object[] getChildren(Object parentElement) {
				if (parentElement instanceof AbstractHistoryCategory){
					return ((AbstractHistoryCategory) parentElement).getRevisions();
				}
				
				return null;
			}

			@Override
			public Object getParent(Object element) {
				return null;
			}

			@Override
			public boolean hasChildren(Object element) {
				if (element instanceof AbstractHistoryCategory){
					IFileRevision[] revs = ((AbstractHistoryCategory) element).getRevisions();
					if (revs != null)
						return revs.length > 0;
				}
				return false;
			}
		});

		viewer.addSelectionChangedListener(event -> {
			ISelection selection = event.getSelection();
			if (selection == null || !(selection instanceof IStructuredSelection)) {
				textViewer.setDocument(new Document("")); //$NON-NLS-1$
				tagViewer.setInput(null);
				setStatusLineMessage(null);
				return;
			}
			IStructuredSelection ss = (IStructuredSelection)selection;
			if (ss.size() != 1) {
				textViewer.setDocument(new Document("")); //$NON-NLS-1$
				tagViewer.setInput(null);
				setStatusLineMessage(null);
				return;
			}
			Object o = ss.getFirstElement();
			if (o instanceof AbstractHistoryCategory){
				textViewer.setDocument(new Document("")); //$NON-NLS-1$
				tagViewer.setInput(null);
				setStatusLineMessage(null);
				return;
			}
			IFileRevision entry = (IFileRevision)o;
			textViewer.setDocument(new Document(entry.getComment()));
			tagViewer.setInput(entry.getTags());
			setStatusLineMessage(CVSHistoryTableProvider.getCommentAsSingleLine(entry));
		});

		return viewer;
	}

	private Action getContextMenuAction(String title, final boolean needsProgressDialog, final IWorkspaceRunnable action) {
		return new Action(title) {
			@Override
			public void run() {
				try {
					if (file == null) return;
					ISelection selection = treeViewer.getSelection();
					if (!(selection instanceof IStructuredSelection)) return;
					IStructuredSelection ss = (IStructuredSelection)selection;
					Object o = ss.getFirstElement();
					
					if (o instanceof AbstractHistoryCategory)
						return;
					
					currentSelection = (IFileRevision)o;
					if(needsProgressDialog) {
						PlatformUI.getWorkbench().getProgressService().run(true, true, monitor -> {
							try {
								action.run(monitor);
							} catch (CoreException e) {
								throw new InvocationTargetException(e);
							}
						});
					} else {
						try {
							action.run(null);
						} catch (CoreException e) {
							throw new InvocationTargetException(e);
						}
					}
				} catch (InvocationTargetException e) {
					IHistoryPageSite parentSite = getHistoryPageSite();
					CVSUIPlugin.openError(parentSite.getShell(), null, null, e, CVSUIPlugin.LOG_NONTEAM_EXCEPTIONS);
				} catch (InterruptedException e) {
					// Do nothing
				}
			}
			
			@Override
			public boolean isEnabled() {
				ISelection selection = treeViewer.getSelection();
				if (!(selection instanceof IStructuredSelection)) return false;
				IStructuredSelection ss = (IStructuredSelection)selection;
				if(ss.size() != 1) return false;
				return true;
			}
		};
	}

	private boolean confirmOverwrite() {
		if (file!=null && file.getIResource().exists()) {
			try {
				if(file.isModified(null)) {
					String title = CVSUIMessages.HistoryView_overwriteTitle;
					String msg = CVSUIMessages.HistoryView_overwriteMsg;
					IHistoryPageSite parentSite = getHistoryPageSite();
					final MessageDialog dialog = new MessageDialog(parentSite.getShell(), title, null, msg, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.CANCEL_LABEL }, 0);
					final int[] result = new int[1];
					parentSite.getShell().getDisplay().syncExec(() -> result[0] = dialog.open());
					if (result[0] != 0) {
						// cancel
						return false;
					}
				}
			} catch(CVSException e) {
				CVSUIPlugin.log(e);
			}
		}
		return true;
	}
	
	private boolean validateChange(){
		if (file!=null && file.getIResource().exists()) {
			IResourceChangeDescriptionFactory factory = ResourceChangeValidator.getValidator().createDeltaFactory();
			factory.change((IFile) file.getIResource());
			return IDE.promptToConfirm(getHistoryPageSite().getShell(), CVSUIMessages.CVSHistoryPage_ValidateChangeTitle, NLS.bind(CVSUIMessages.CVSHistoryPage_ValidateChangeMessage, new String[]{file.getName()}), factory.getDelta(), new String[0], true /* syncExec */);
		}
		
		return false;
	}

	/*
	 * Refresh the view by refetching the log entries for the remote file
	 */
	@Override
	public void refresh() {
		refresh(CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
	}
	
	public void refresh(int refreshFlags) {
		printDebugInfo("CVSHistoryPage#refresh", (IFile)(previousFile != null ? previousFile.getIResource() : null), cvsFileHistory, new Throwable()); //$NON-NLS-1$
		//refetch revisions, not a select only job
		// TODO
		refreshHistory(true, false, refreshFlags);
	}

	private void refreshHistory(boolean refetch, boolean selectOnly, int refreshFlags) {
		if (refreshCVSFileHistoryJob.getState() != Job.NONE){
			RefreshCVSFileHistory oldJob = refreshCVSFileHistoryJob;
			oldJob.cancel();
			refreshCVSFileHistoryJob = new RefreshCVSFileHistory(this);
			refreshCVSFileHistoryJob.setLocalFileRevision(oldJob.localFileRevision);
			refreshCVSFileHistoryJob.setSelectLocal(oldJob.useLocalSelect);
			refetch = true;
			selectOnly = false;
			refreshFlags = CVSFileHistory.REFRESH_ALL;
			printDebugInfo("CVSHistoryPage#refreshHistory, cancel old job", (IFile)(previousFile != null ? previousFile.getIResource() : null), cvsFileHistory, null); //$NON-NLS-1$
		}
		refreshCVSFileHistoryJob.setFileHistory(cvsFileHistory);
		IResource resource = previousFile.getIResource();
		if (resource != null){
			IResource workspaceFile = ResourcesPlugin.getWorkspace().getRoot().findMember(resource.getFullPath());
			refreshCVSFileHistoryJob.setWorkspaceFile((IFile) workspaceFile);
		}
		//if we need to refetch it's not a select only job and vice versa
		refreshCVSFileHistoryJob.setSelectOnly(selectOnly);
		refreshCVSFileHistoryJob.setRefetchHistory(refetch);
		refreshCVSFileHistoryJob.setIncludeLocals(!isLocalHistoryFilteredOut());
		refreshCVSFileHistoryJob.setIncludeRemote(!isRemoteHistoryFilteredOut());
		refreshCVSFileHistoryJob.setGrouping(groupingOn);
		refreshCVSFileHistoryJob.setRefreshFlags(refreshFlags);
		IHistoryPageSite parentSite = getHistoryPageSite();
		printDebugInfo("CVSHistoryPage#refreshHistory, about to schedule RefreshCVSFileHistoryJob", (IFile)resource, cvsFileHistory, null); //$NON-NLS-1$
		Utils.schedule(refreshCVSFileHistoryJob, getWorkbenchSite(parentSite));
	}

	private IWorkbenchPartSite getWorkbenchSite(IHistoryPageSite parentSite) {
		IWorkbenchPart part = parentSite.getPart();
		if (part != null)
			return part.getSite();
		return null;
	}

	/**
	 * Select the revision in the receiver.
	 */
	public void selectRevision(String revision) {
		IFileRevision entry = null;
		entry = getFileRevision(revision);
	
		if (entry != null) {
			IStructuredSelection selection = new StructuredSelection(entry);
			treeViewer.getTree().setRedraw(false);
			treeViewer.setSelection(selection, true);
			treeViewer.getTree().setRedraw(true);
		} else {
			//nothing to select so clear selection
			treeViewer.getTree().deselectAll();
		}
	}
	
	private IFileRevision getFileRevision(String revision) {
		if (entries != null) {
			for (int i = 0; i < entries.length; i++) {
				if (entries[i].getContentIdentifier().equals(revision)) {
					return entries[i];
				}
			}
		} else if (cvsFileHistory != null) {
			return cvsFileHistory.getFileRevision(revision);
		}
		return null;
	}
	
	/**
	 * Select the local revision in the receiver. Local revisions are differentiated by their
	 * timestamps.
	 */
	public void selectLocalRevision(long timeStamp){
		IFileRevision entry = null;
		if (entries != null) {
			for (int i = 0; i < entries.length; i++) {
				if (entries[i].getTimestamp() == timeStamp) {
					entry = entries[i];
					break;
				}
			}
		}else if (cvsFileHistory != null) {
			IFileRevision[] tempEntries = cvsFileHistory.getFileRevisions();
			for (int i = 0; i < tempEntries.length; i++) {
				if (tempEntries[i].getTimestamp() == timeStamp) {
					entry = tempEntries[i];
					break;
				}
			}
		}
	
		if (entry != null) {
			IStructuredSelection selection = new StructuredSelection(entry);
			treeViewer.getTree().setRedraw(false);
			treeViewer.setSelection(selection, true);
			treeViewer.getTree().setRedraw(true);
		} else {
			//nothing to select so clear selection
			treeViewer.getTree().deselectAll();
		}
	}
	
	protected static ICVSFile getCVSFile(Object object) {
		// First, adapt to IResource and ensure mapped to CVS
		IResource resource = Adapters.adapt(object, IResource.class);
		if (resource instanceof IFile) {
			RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject());
			if (provider instanceof CVSTeamProvider)
				return CVSWorkspaceRoot.getCVSFileFor((IFile) resource);
			return null;
		}
		// Second, try ICVSFile
		ICVSFile remoteFile = Adapters.adapt(object, ICVSFile.class);
		if (remoteFile != null) {
			return remoteFile;
		}
		// Next, try ICVSResource
		ICVSResource remote = Adapters.adapt(object, ICVSResource.class);
		if (remote instanceof RemoteFile) {
			return (ICVSFile)remote;
		}
		// Next, try IResourceVariant
		IResourceVariant variant = Adapters.adapt(object, IResourceVariant.class);
		if (variant instanceof RemoteFile) {
			return (ICVSFile)remote;
		}
		// Finally, try IFileRevision
		IFileRevision revision = Adapters.adapt(object, IFileRevision.class);
		if (revision instanceof CVSFileRevision) {
			return ((CVSFileRevision)revision).getCVSRemoteFile();
		}
		
		return null;
	}

	/* private */void setViewerVisibility() {
		boolean showText = toggleTextAction.isChecked();
		boolean showList = toggleListAction.isChecked();
		boolean showSearch = toggleSearchAction.isChecked();
		
		//check to see if this page is being shown in a dialog, in which case
		//don't show the text and list panes
		IHistoryPageSite parentSite = getHistoryPageSite();
		if (parentSite.isModal()){
			showText = false;
			showList = false;
		}

		
		if (showText && showList && showSearch) {
			//tree + tag + text + search
			tagAndTextComposite.setVisible(true);
			searchComposite.setVisible(true);
			sashForm.setWeights(new int[] {60, 25, 15});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(null);
			searchSashForm.setMaximizedControl(null);
		} else if (showText && showSearch) {
			//tree + text + search
			tagAndTextComposite.setVisible(true);
			searchComposite.setVisible(true);
			sashForm.setWeights(new int[] {60, 25, 15});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(textViewer.getTextWidget());
			searchSashForm.setMaximizedControl(searchField);
		} else if (showList && showSearch) {
			//tree + tag + search
			tagAndTextComposite.setVisible(true);
			searchComposite.setVisible(true);
			sashForm.setWeights(new int[] {60, 25, 15});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(tagViewer.getTable());
			searchSashForm.setMaximizedControl(searchField);
		} else if (showSearch){
			//tree + search
			tagAndTextComposite.setVisible(false);
			searchComposite.setVisible(true);
			sashForm.setWeights(new int[] {85, 0, 15});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(null);
			searchSashForm.setMaximizedControl(searchField);
		} else if (showText && showList) {
			//tree + tag + text
			tagAndTextComposite.setVisible(true);
			searchComposite.setVisible(false);
			sashForm.setWeights(new int[] {70, 30, 0});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(null);
			searchSashForm.setMaximizedControl(searchField);
		} else if (showText) {
			//tree + text
			tagAndTextComposite.setVisible(true);
			searchComposite.setVisible(false);
			sashForm.setWeights(new int[] {70, 30, 0});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(textViewer.getTextWidget());
		} else if (showList) {
			//tree + tag
			tagAndTextComposite.setVisible(true);
			searchComposite.setVisible(false);
			sashForm.setWeights(new int[] {70, 30, 0});
			sashForm.setMaximizedControl(null);
			innerSashForm.setMaximizedControl(tagViewer.getTable());
		} else {
			//tree
			tagAndTextComposite.setVisible(false);
			searchComposite.setVisible(false);
			sashForm.setMaximizedControl(treeViewer.getControl());
		}

		boolean wrapText = toggleTextWrapAction.isChecked();
		textViewer.getTextWidget().setWordWrap(wrapText);
	}

	private void initializeImages() {
		CVSUIPlugin plugin = CVSUIPlugin.getPlugin();
		versionImage = plugin.getImageDescriptor(ICVSUIConstants.IMG_PROJECT_VERSION).createImage();
		branchImage = plugin.getImageDescriptor(ICVSUIConstants.IMG_TAG).createImage();
	}
	
	@Override
	public void dispose() {
		shutdown = true;
		
		
		if (!sashForm.isDisposed() && !innerSashForm.isDisposed()) {
			saveState(); // called when switching pages
			if (disposeListener != null){
				sashForm.getParent().removeDisposeListener(disposeListener);
				disposeListener = null;
			}
		}

		if (resourceListener != null){
			ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener);
			resourceListener = null;
		}
		
		if (branchImage != null) {
			branchImage.dispose();
			branchImage = null;
		}
		if (versionImage != null) {
			versionImage.dispose();
			versionImage = null;
		}
		if (rulerSelectionListener != null) {
			rulerSelectionListener.dispose();
			rulerSelectionListener= null;
		}
		
		//Cancel any incoming
		if (refreshCVSFileHistoryJob != null) {
			if (refreshCVSFileHistoryJob.getState() != Job.NONE) {
				refreshCVSFileHistoryJob.cancel();
			}
		}

		super.dispose();
	}

	public IFileRevision getCurrentFileRevision() {
		if (currentFileRevision != null)
			return currentFileRevision;

		if (file != null) {
			try {
				//Case 1 : file is remote
				if (file instanceof RemoteFile) {
					RemoteFile remote = (RemoteFile) file;
					currentFileRevision = cvsFileHistory.getFileRevision(remote.getContentIdentifier());
					//remote.getContents(monitor);
					//currentFileRevision = new CVSFileRevision(remote.getLogEntry(monitor));
					return currentFileRevision;
				}
				//Case 2 : file is local
				//if (file.isModified(monitor)) {
				//file has been modified locally
				IFile localFile = (IFile) file.getIResource();
				if (localFile != null) {
					//make sure that there's actually a resource associated with the file
					currentFileRevision = new LocalFileRevision(localFile);
				} else {
					//no local version exists
					if (file.getSyncInfo() != null) {
						currentFileRevision = cvsFileHistory.getFileRevision(file.getSyncInfo().getRevision());
					}
				}
				return currentFileRevision;
			} catch (CVSException e) {
			}
		}

		return null;
	}
	
	private final class CVSRevisionAnnotationController extends
			RevisionAnnotationController {
		public CVSRevisionAnnotationController(IWorkbenchPage page, IFile file) {
			super(page, file, treeViewer);
		}

		public CVSRevisionAnnotationController(IWorkbenchPage page, IStorageEditorInput editorInput) {
			super(page, editorInput, treeViewer);
		}

		@Override
		protected Object getHistoryEntry(Revision selected) {
			return CVSHistoryPage.this.getFileRevision(selected.getId());
		}
	}


	private final class SearchHistoryTable implements Runnable {
		@Override
		public void run() {
			String searchString = searchField.getText();
			if (searchString.equals("") || //$NON-NLS-1$
				searchString.equals(CVSUIMessages.CVSHistoryPage_EnterSearchTerm)) {
				if (searchFilter != null)
					treeViewer.removeFilter(searchFilter);
				return;
			}
			

			if (searchFilter != null)
				treeViewer.removeFilter(searchFilter);

			searchFilter = new CVSHistorySearchFilter(searchString);

			if (historyFilter != null)
				treeViewer.removeFilter(historyFilter);

			treeViewer.addFilter(searchFilter);
		}
	}


	private class RefreshCVSFileHistory extends Job {
		private final static int NUMBER_OF_CATEGORIES = 4;
		
		private CVSFileHistory fileHistory;
		private AbstractHistoryCategory[] categories;
		private boolean grouping;
		private Object[] elementsToExpand;
		private boolean revisionsFound;
		private IFile workspaceFile;
		private CVSHistoryPage page;
		private boolean selectOnly;
		private boolean useLocalSelect;
		
		private CVSLocalFileRevision localFileRevision;

		private int refreshFlags = CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE;
		
		public RefreshCVSFileHistory(CVSHistoryPage page) {
			super(CVSUIMessages.HistoryView_fetchHistoryJob);
			this.page = page;
		}
		
		public void setWorkspaceFile(IFile workspaceFile) {
			this.workspaceFile = workspaceFile;
		}

		public void setIncludeLocals(boolean flag) {
			if (fileHistory != null)
				fileHistory.includeLocalRevisions(flag);
		}
		
		public void setIncludeRemote(boolean flag){
			if (fileHistory != null)
				fileHistory.includeRemoteRevisions(flag);
		}

		public void setRefetchHistory(boolean refetch) {
			if (fileHistory != null)
				fileHistory.setRefetchRevisions(refetch);
		}

		public void setFileHistory(CVSFileHistory fileHistory) {
			this.fileHistory = fileHistory;
		}
	
		public void setGrouping (boolean value){
			this.grouping = value;
		}
		
		public void setSelectOnly(boolean select) {
			this.selectOnly = select;
		}

		public void setSelectLocal(boolean localSelect) {
			this.useLocalSelect = localSelect;
		}

		public void setLocalFileRevision(CVSLocalFileRevision localRev){
			this.localFileRevision = localRev;
		}
		
		@Override
		public IStatus run(IProgressMonitor monitor)  {
			final int cachedRefreshFlags = refreshFlags;
			final boolean cachedSelectOnly= selectOnly;
			IStatus status = Status.OK_STATUS;
			printDebugInfo("RefreshCVSFileHistory#run started for", workspaceFile, fileHistory, null); //$NON-NLS-1$
			if (fileHistory != null && !shutdown) {
				printDebugInfo("RefreshCVSFileHistory#run checkpoint 1", workspaceFile, fileHistory, null); //$NON-NLS-1$

				//If fileHistory terminates in a bad way, try to fetch the local
				//revisions only
				boolean localFetched = false;
				boolean needsUpdate = true;
				if (!fileHistory.isInitialized()
						&& fileHistory.isIncludeLocal()
						&& (cachedRefreshFlags & CVSFileHistory.REFRESH_REMOTE) > 0) {
					// If this is the first refresh, show the local history before hitting the server
					try {
						printDebugInfo("RefreshCVSFileHistory#run checkpoint 2", workspaceFile, fileHistory, null); //$NON-NLS-1$
						fileHistory.refresh(CVSFileHistory.REFRESH_LOCAL, monitor);
						updateTable(cachedSelectOnly);
						localFetched = true;
						needsUpdate = false;
					} catch (TeamException e) {
						// Ignore and try the full refresh
						printDebugInfo("RefreshCVSFileHistory#run encountered an exception(1)", workspaceFile, fileHistory, e); //$NON-NLS-1$
					}
				}
				try {
					printDebugInfo("RefreshCVSFileHistory#run checkpoint 3", workspaceFile, fileHistory, null); //$NON-NLS-1$
					fileHistory.refresh(cachedRefreshFlags, monitor);
					needsUpdate = true;
				} catch (OperationCanceledException ex) {
					printDebugInfo("RefreshCVSFileHistory#run OperationCanceledException", workspaceFile, fileHistory, ex); //$NON-NLS-1$
					throw ex;
				} catch (TeamException ex) {
					printDebugInfo("RefreshCVSFileHistory#run encountered an exception(2)", workspaceFile, fileHistory, ex); //$NON-NLS-1$
					if (!localFetched) {
						try {
							fileHistory.refresh(CVSFileHistory.REFRESH_LOCAL, monitor);
							needsUpdate = true;
						} catch (TeamException e) {
							// Ignore and allow the original exception to go through
							printDebugInfo("RefreshCVSFileHistory#run encountered an exception(3)", workspaceFile, fileHistory, e); //$NON-NLS-1$
						}
					}
					status = new CVSStatus(ex.getStatus().getSeverity(), ex.getStatus().getCode(), ex.getMessage(), ex);
				}
				if (needsUpdate) {
					printDebugInfo("RefreshCVSFileHistory#run checkpoint 4", workspaceFile, fileHistory, null); //$NON-NLS-1$
					updateTable(cachedSelectOnly);
				}
			}

			if (status != Status.OK_STATUS ) {
				this.setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
				this.setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE);
			}
			printDebugInfo("RefreshCVSFileHistory#run finished, status: " + status, workspaceFile, fileHistory, null); //$NON-NLS-1$
			return status;
		}

		private void updateTable(final boolean selectOnly) {
			if (grouping)
				revisionsFound = sortRevisions();
			
			Utils.asyncExec((Runnable) () -> {
				printDebugInfo("RefreshCVSFileHistory#updateTable, in asyncExec", workspaceFile, cvsFileHistory, null); //$NON-NLS-1$
				treeViewer.refresh();
				historyTableProvider.setFile(fileHistory, workspaceFile);
				//historyTableProvider.setWorkspaceFile(workspaceFile);
				if (!selectOnly){
					if (grouping) {
						mapExpandedElements(treeViewer.getExpandedElements());
						treeViewer.getTree().setLinesVisible(revisionsFound);
						treeViewer.getTree().setRedraw(false);
						printDebugInfo("RefreshCVSFileHistory#updateTable, setInput:grouping", workspaceFile, cvsFileHistory, null); //$NON-NLS-1$
						treeViewer.setInput(categories);
						//if user is switching modes and already has expanded elements
						//selected try to expand those, else expand all
						if (elementsToExpand.length > 0)
							treeViewer.setExpandedElements(elementsToExpand);
						else {
							treeViewer.expandAll();
							Object[] el = treeViewer.getExpandedElements();
							if (el != null && el.length > 0) {
								treeViewer.setSelection(new StructuredSelection(el[0]));
								treeViewer.getTree().deselectAll();
							}
						}
						treeViewer.getTree().setRedraw(true);
					} else {
						if (fileHistory.getFileRevisions().length > 0) {
							treeViewer.getTree().setLinesVisible(true);
							printDebugInfo("RefreshCVSFileHistory#updateTable, setInput:no grouping", workspaceFile, cvsFileHistory, null); //$NON-NLS-1$
							treeViewer.setInput(fileHistory);
						} else {
							categories = new AbstractHistoryCategory[] {getErrorMessage()};
							treeViewer.getTree().setLinesVisible(false);
							treeViewer.setInput(categories);
						}
					}
				}
				//Update the history (if it exists) to reflect the new
				//counts
				if (historyFilter != null){
					CVSHistoryFilter tempFilter = new CVSHistoryFilter(historyFilter.branchName, historyFilter.author, historyFilter.comment, historyFilter.fromDate, historyFilter.toDate, historyFilter.isOr);
					showFilter(tempFilter);
				}
				
				//Select the current file if we didn't have to refetch the history
				if (file != null){
					try {
						if (useLocalSelect){
							page.selectLocalRevision(localFileRevision.getTimestamp());
						} else {
							byte[] syncBytes = file.getSyncBytes();
							if (syncBytes != null) {
								String workspaceRevision = ResourceSyncInfo.getRevision(syncBytes);
								page.selectRevision(workspaceRevision);
							}
						}
					} catch (CVSException e){
					}
				}
			}, treeViewer);
		}

		private void mapExpandedElements(Object[] expandedElements) {
			//store the names of the currently expanded categories in a map
			HashMap elementMap = new HashMap();
			for (int i=0; i<expandedElements.length; i++){
				elementMap.put(((DateHistoryCategory)expandedElements[i]).getName(), null);
			}
			
			//Go through the new categories and keep track of the previously expanded ones
			ArrayList expandable = new ArrayList();
			for (int i = 0; i<categories.length; i++){
				//check to see if this category is currently expanded
				if (elementMap.containsKey(categories[i].getName())){
					expandable.add(categories[i]);
				}
			}
			
			elementsToExpand = new Object[expandable.size()];
			elementsToExpand = expandable.toArray(new Object[expandable.size()]);
		}

		private boolean sortRevisions() {
			IFileRevision[] fileRevision = fileHistory.getFileRevisions();
			
			//Create the 4 categories
			DateHistoryCategory[] tempCategories = new DateHistoryCategory[NUMBER_OF_CATEGORIES];
			//Get a calendar instance initialized to the current time
			Calendar currentCal = Calendar.getInstance();
			tempCategories[0] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Today, currentCal, null);
			//Get yesterday
			Calendar yesterdayCal = Calendar.getInstance();
			yesterdayCal.roll(Calendar.DAY_OF_YEAR, -1);
			tempCategories[1] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Yesterday, yesterdayCal, null);
			//Get this month
			Calendar monthCal = Calendar.getInstance();
			monthCal.set(Calendar.DAY_OF_MONTH, 1);
			tempCategories[2] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_ThisMonth, monthCal, yesterdayCal);
			//Everything before this month is previous
			tempCategories[3] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Previous, null, monthCal);
		
			ArrayList finalCategories = new ArrayList();
			for (int i = 0; i<NUMBER_OF_CATEGORIES; i++){
				tempCategories[i].collectFileRevisions(fileRevision, false);
				if (tempCategories[i].hasRevisions())
					finalCategories.add(tempCategories[i]);
			}
			
			//Assume that some revisions have been found
			boolean revisionsFound = true;
			
			if (finalCategories.size() == 0){
				//no revisions found for the current mode, so add a message category
				finalCategories.add(getErrorMessage());
				revisionsFound = false;
			}
			
			categories = (AbstractHistoryCategory[])finalCategories.toArray(new AbstractHistoryCategory[finalCategories.size()]);
			return revisionsFound;
		}
		
		private MessageHistoryCategory getErrorMessage(){
			String message = ""; //$NON-NLS-1$
			switch(currentFilerMode){
				case LOCAL_MODE:
				message = CVSUIMessages.CVSHistoryPage_LocalModeTooltip;
				break;
				
				case REMOTE_MODE:
				message = CVSUIMessages.CVSHistoryPage_RemoteModeTooltip;
				break;
				
				case REMOTE_LOCAL_MODE:
				message = CVSUIMessages.CVSHistoryPage_NoRevisions;
				break;
			}
		
			MessageHistoryCategory messageCategory = new MessageHistoryCategory(NLS.bind(CVSUIMessages.CVSHistoryPage_NoRevisionsForMode, new String[] { message }));
			return messageCategory;
		}

		public void setRefreshFlags(int refreshFlags) {
			this.refreshFlags = refreshFlags;
		}

	
		
	}
	
	
	/**
	 * A default content provider to prevent subclasses from
	 * having to implement methods they don't need.
	 */
	private class SimpleContentProvider implements IStructuredContentProvider {

		/**
		 * SimpleContentProvider constructor.
		 */
		public SimpleContentProvider() {
			super();
		}

		@Override
		public void dispose() {
		}

		@Override
		public Object[] getElements(Object element) {
			return new Object[0];
		}

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

	private class HistoryResourceListener implements IResourceChangeListener {
		@Override
		public void resourceChanged(IResourceChangeEvent event) {
			IResourceDelta root = event.getDelta();
			//Safety check for non-managed files that are added with the CVSHistoryPage
			//in view
			if (file == null ||	file.getIResource() == null)
				return;
			
			IResourceDelta resourceDelta = root.findMember(((IFile)file.getIResource()).getFullPath());
			if (resourceDelta != null){
				String revision = getRevision();
				final boolean hasRevision = cvsFileHistory.getFileRevision(revision) != null;
				Display.getDefault().asyncExec(() -> {
					if (treeViewer.getControl().isDisposed())
						return;
					if (treeViewer.getControl().isVisible()) {
						if (hasRevision)
							refresh(CVSFileHistory.REFRESH_LOCAL);
						else
							refresh();
					} else {
						refreshRequest = hasRevision ? CVSFileHistory.REFRESH_LOCAL : CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE;
					}
				});
			}
		}

		private String getRevision() {
			try {
				byte[] syncBytes = file.getSyncBytes();
				if (syncBytes != null && !ResourceSyncInfo.isAddition(syncBytes)) {
					return ResourceSyncInfo.getRevision(syncBytes);
				}
			} catch (CVSException e) {
				// Ignore the errors
			}
			return null;
		}
	}
		
	@Override
	public Control getControl() {
		return sashForm;
	}

	@Override
	public boolean isValidInput(Object object) {
		return getCVSFile(object) != null;
	}

	@Override
	public String getName() {
		if (description != null)
			return description;
		if (file != null)
			return file.getName();
		
		return ""; //$NON-NLS-1$
	}
	
	/**
	 * Returns the path of the file currently being shown in the CVS History Page.
	 * @return an IPath or <code>null</code> if the file is null
	 */
	public IPath getFilePath() {
		if (file != null)
			return file.getIResource().getFullPath();
		
		return null;
	}

	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if(adapter == IHistoryCompareAdapter.class) {
			return adapter.cast(this);
		}
		return null;
	}

	@Override
	public ICompareInput getCompareInput(Object object) {
		if (object instanceof IFileRevision){
			IFileRevision selectedFileRevision = (IFileRevision)object;
			if (fileElement == null)
				fileElement = SaveableCompareEditorInput.createFileElement((IFile) file.getIResource());
			FileRevisionTypedElement right = new FileRevisionTypedElement(selectedFileRevision, getLocalEncoding());
			DiffNode node = new DiffNode(fileElement, right);
			return node;
		}
		return null;
	}

	private String getLocalEncoding() {
		IResource resource = file.getIResource();
		if (resource instanceof IFile) {
			IFile file = (IFile) resource;
			try {
				return file.getCharset();
			} catch (CoreException e) {
				CVSUIPlugin.log(e);
			}
		}
		return null;
	}

	public void setClickAction(boolean compare) {
		//toggleCompareAction is going to switch the mode
		//so make sure that we're in the appropriate mode before
		compareMode = !compare;
		compareModeAction.run();
	}

	@Override
	public void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) {
		initLabels(input, configuration);
		// TODO: pre-fetch contents
	}
	
	private void initLabels(ICompareInput input, CompareConfiguration cc) {
		String leftLabel = getFileRevisionLabel(input.getLeft(), cc);
		cc.setLeftLabel(leftLabel);
		String rightLabel = getFileRevisionLabel(input.getRight(), cc);
		cc.setRightLabel(rightLabel);
	}

	private String getFileRevisionLabel(ITypedElement element, CompareConfiguration cc) {
		String label = null;

		if (element instanceof IEditableContent) {
			//current revision
			if (element instanceof IModificationDate) {
				IModificationDate md = (IModificationDate) element;
				Date dateFromLong = new Date(md.getModificationDate());
				label = NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_workspace, new Object[]{ element.getName(), getDateTimeFormat().format(dateFromLong)});
			} else {
				label = element.getName();
			}
			return label;

		} else if (element instanceof FileRevisionTypedElement) {
			Object fileObject = ((FileRevisionTypedElement) element).getFileRevision();

			if (fileObject instanceof LocalFileRevision) {
				try {
					IStorage storage = ((LocalFileRevision) fileObject).getStorage(new NullProgressMonitor());
					if (Adapters.adapt(storage, IFileState.class) != null) {
						//local revision
						label = NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_localRevision, new Object[]{element.getName(), ((FileRevisionTypedElement) element).getTimestamp()});
					}
				} catch (CoreException e) {
				}
			} else {
				label = NLS.bind(
						TeamUIMessages.CompareFileRevisionEditorInput_repository,
						new Object[]{
								element.getName(),
								((FileRevisionTypedElement) element).getContentIdentifier(),
								((FileRevisionTypedElement) element).getAuthor()
								});
			}
		}
		return label;
	}
	
	private synchronized DateFormat getDateTimeFormat() {
		if (dateTimeFormat == null)
			dateTimeFormat = DateFormat.getDateTimeInstance();
		return dateTimeFormat;
	}

	@Override
	public String getDescription() {
		try {
			if (file != null)
				return file.getRepositoryRelativePath();
		} catch (CVSException e) {
			// Ignore
		}
		return null;
	}

	@Override
	public boolean inputSet() {
		//reset currentFileRevision
		currentFileRevision = null;
		Object inputObj = getInput();
	
		ICVSFile cvsFile = getCVSFile(inputObj);
		if (cvsFile == null)
			return false;
		
		this.file = cvsFile;
		fileElement = null;

		// if this input is the same as the last, we don't need to cancel
		// the current job
		boolean needRefresh = checkPreviousInput();
		printDebugInfo("CVSHistoryPage#inputSet, needRefresh = " + needRefresh, (IFile)cvsFile.getIResource(), cvsFileHistory, null); //$NON-NLS-1$
		if (refreshCVSFileHistoryJob != null) {
			if (!needRefresh && refreshCVSFileHistoryJob.getState() != Job.NONE) {
				// let the old job finish
				printDebugInfo("CVSHistoryPage#inputSet, the old job is still running", (IFile)cvsFile.getIResource(), cvsFileHistory, null); //$NON-NLS-1$
				return true;
			} else {
				// cancel the old job and continue
				printDebugInfo("CVSHistoryPage#inputSet, cancel the old job", (IFile)cvsFile.getIResource(), cvsFileHistory, null); //$NON-NLS-1$
				refreshCVSFileHistoryJob.cancel();
			}
		}
		
		refreshCVSFileHistoryJob = new RefreshCVSFileHistory(this);
		
		//if the input is a local file revision, pass it to the refresh job to
		//allow the refresh job to use it to match the time stamp of the local
		//files displayed in the history page
		if (inputObj instanceof CVSLocalFileRevision){
			refreshCVSFileHistoryJob.setLocalFileRevision((CVSLocalFileRevision) inputObj);
		} else if (inputObj instanceof IFile) {
			refreshCVSFileHistoryJob.setLocalFileRevision(new CVSLocalFileRevision((IFile) inputObj));
		}
		//let the refresh job know which flavour of select to use (ie. select CVSFileRevisions
		//or CVSLocalFileRevision)
		refreshCVSFileHistoryJob.setSelectLocal(inputObj instanceof CVSLocalFileRevision || inputObj instanceof IFile);
		
		
		//If the file history doesn't need to be refreshed, we can just
		//use the previous input file history
		if (needRefresh){
			cvsFileHistory = new CVSFileHistory(cvsFile);
			//fetch both local and remote revisions the first time around
			cvsFileHistory.includeLocalRevisions(true);
			//blank current input only after we're sure that we have a file
			//to fetch history for
			this.treeViewer.setInput(null);
			
			linkWithEditor();
		}
		
		//always refresh the history if the input gets set - in which
		//case set the selectOnly to false
		refreshHistory(needRefresh, !needRefresh, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
		
		if (toggleSearchAction!= null && toggleSearchAction.isChecked()){
			searchField.selectAll();
		}
		
		return true;
	}
	

	
	/**
	 * @param page the workbench page that view and editor are contained in
	 * @param editor the editor to link to the history view
	 * @param historyView the history view to link to the editor
	 */
	public void linkWithEditor() {
		if (rulerSelectionListener != null) {
			rulerSelectionListener.dispose();
			rulerSelectionListener= null;
		}

		if (!getHistoryPageSite().isModal()) {
			IResource resource = file.getIResource();
			if (resource instanceof IFile) {
				IFile file = (IFile) resource;
				rulerSelectionListener= new CVSRevisionAnnotationController(getHistoryPageSite().getWorkbenchPageSite().getPage(), file);
			} else {
				Object input = getInput();
				if (input instanceof IStorageEditorInput) {
					IStorageEditorInput editorInput = (IStorageEditorInput) input;
					rulerSelectionListener= new CVSRevisionAnnotationController(getHistoryPageSite().getWorkbenchPageSite().getPage(), editorInput);
				}
			}
		}
	}
	
	/*
	 * Check to see if we need to refresh the input; if the previous file
	 * that was being shown
	 */
	private boolean checkPreviousInput() {
		
		if (previousFile != null){
			try {
				if (isSameRemote(file, previousFile)
					&& (isSameLocalFile(file, previousFile)
							|| (!isLocal(file) && isLocal(previousFile)))) {
					return false;
				}
			} catch (CVSException e) {
			}
		}
		
		//set previous file to current file
		previousFile = file;
		return true;
	}

	private boolean isLocal(ICVSFile file) {
		return file.getIResource() != null;
	}

	private boolean isSameLocalFile(ICVSFile file, ICVSFile previousFile) {
		IResource r1 = file.getIResource();
		IResource r2 = previousFile.getIResource();
		return r1 != null && r2 != null && r1.equals(r2);
	}

	private boolean isSameRemote(ICVSFile file, ICVSFile previousFile) throws CVSException {
		String path = file.getRepositoryRelativePath();
		String previousPath = previousFile.getRepositoryRelativePath();
		
		//Could be comparing two local files with no remotes
		if (path == null && previousPath == null)
			return true;
		
		return (path != null && previousPath != null && path.equals(previousPath) && isSameRepository(file.getParent(), previousFile.getParent()));
	}


	private boolean isSameRepository(ICVSFolder parent1, ICVSFolder parent2) {
		try {
			FolderSyncInfo info1 = parent1.getFolderSyncInfo();
			FolderSyncInfo info2 = parent2.getFolderSyncInfo();
			return (info1 != null && info2 != null && info1.getRemoteLocation().equals(info2.getRemoteLocation()));
		} catch (CVSException e) {
			// Ignore
		}
		return false;
	}

	private void updateFilterMode(int mode) {
		currentFilerMode=mode;
		switch(mode){
			case LOCAL_MODE:
				localFilteredOut = false;
				remoteFilteredOut = true;
				localMode.setChecked(true);
				remoteMode.setChecked(false);
				remoteLocalMode.setChecked(false);
				break;

			case REMOTE_MODE:
				localFilteredOut = true;
				remoteFilteredOut = false;
				localMode.setChecked(false);
				remoteMode.setChecked(true);
				remoteLocalMode.setChecked(false);
				break;

			case REMOTE_LOCAL_MODE:
				localFilteredOut = false;
				remoteFilteredOut = false;
				localMode.setChecked(false);
				remoteMode.setChecked(false);
				remoteLocalMode.setChecked(true);
				break;
		}

		//the refresh job gets created once the input is set
		//don't bother trying to refresh any history until the input has been set
		if (refreshCVSFileHistoryJob != null){
			//don't refetch, but not a select only job (ie. have to get the
			//existing revisions corresponding to the mode change)
			refreshHistory(false, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
		}
	}

	public TreeViewer getTreeViewer() {
		return treeViewer;
	}

	public void showFilter(CVSHistoryFilter filter) {
		if (historyFilter != null)
			treeViewer.removeFilter(historyFilter);
		
		historyFilter = filter;
		int before = cvsFileHistory.getFileRevisions().length;
		treeViewer.addFilter(historyFilter);
		IHistoryPageSite historyPageSite =getHistoryPageSite();
		if (historyPageSite instanceof WorkbenchHistoryPageSite){
			IWorkbenchPart part = ((WorkbenchHistoryPageSite) historyPageSite).getPart();
			if (part instanceof GenericHistoryView){
				String revisions = NLS.bind(CVSUIMessages.CVSHistoryPage_FilterOnMessage, new Object[]{Integer.valueOf(historyFilter.getMatchCount()),Integer.valueOf(before)});
				String old = getName();
				description = NLS.bind(CVSUIMessages.CVSHistoryPage_FilterDescription, new Object[]{file.getName(), revisions});
				CVSHistoryPage.this.firePropertyChange(CVSHistoryPage.this, P_NAME, old, getName());
			}
		}
		toggleFilterAction.setEnabled(true);
	}
	
	/*
	 * Sets the filter mode for the page.
	 * param flag	LOCAL_MODE, REMOTE_MODE, REMOTE_LOCAL_MODE
	 */
	public void setMode(int flag){
		switch(flag){
			case LOCAL_MODE:
				localMode.setChecked(true);
				localMode.run();
				break;
			
			case REMOTE_MODE:
				remoteMode.setChecked(true);
				remoteMode.run();
				break;
				
			case REMOTE_LOCAL_MODE:
				remoteLocalMode.setChecked(true);
				remoteLocalMode.run();
				break;
		}
		
		//refetch revisions, not a select only job
		refreshHistory(true, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
	}

	/**
	 * Save any changes that are buffered in the pages typed element.
	 * @param monitor a progress monitor.
	 * @throws CoreException
	 */
	public void saveChanges(IProgressMonitor monitor) throws CoreException {
		if (fileElement instanceof LocalResourceTypedElement) {
			LocalResourceTypedElement element = (LocalResourceTypedElement) fileElement;
			element.commit(monitor);
		}
	}

	private void setStatusLineMessage(String message) {
		IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite();
		if (workbenchPageSite != null) {
			workbenchPageSite.getActionBars().getStatusLineManager().setMessage(message);
		}
	}

	private static void printDebugInfo(String message, IFile file, CVSFileHistory history, Throwable t) {
		if (!Policy.DEBUG_HISTORY)
			return;
		String time= new SimpleDateFormat("m:ss.SSS").format(new Date(System.currentTimeMillis())); //$NON-NLS-1$
		String fileName= file != null ? file.getName() : "<workspaceFile == null>"; //$NON-NLS-1$
		String fileHistoryID= history != null ? history.toString() : "<fileHistory == null>"; //$NON-NLS-1$
		int i= fileHistoryID.indexOf('@');
		if (i != -1)
			fileHistoryID= fileHistoryID.substring(i);
		System.out.println(time + ": " + fileName + ", " + fileHistoryID + ": " + message); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		if (t != null)
			t.printStackTrace();
	}
}
