/*******************************************************************************
 * Copyright (c) 2005, 2007 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
 *******************************************************************************/
package org.eclipse.team.tests.ccvs.ui;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.internal.resources.mapping.ShallowContainer;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.ModelProvider;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceMappingContext;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.diff.provider.Diff;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.mapping.IResourceDiffTree;
import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.core.mapping.provider.SynchronizationContext;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.subscribers.SubscriberMergeContext;
import org.eclipse.team.core.subscribers.SubscriberScopeManager;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.ccvs.core.CVSCompareSubscriber;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSMergeSubscriber;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.CVSWorkspaceSubscriber;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.ui.mappings.CompareSubscriberContext;
import org.eclipse.team.internal.ccvs.ui.mappings.MergeSubscriberContext;
import org.eclipse.team.internal.ccvs.ui.mappings.ModelCompareParticipant;
import org.eclipse.team.internal.ccvs.ui.mappings.ModelMergeParticipant;
import org.eclipse.team.internal.ccvs.ui.mappings.WorkspaceModelParticipant;
import org.eclipse.team.internal.ccvs.ui.mappings.WorkspaceSubscriberContext;
import org.eclipse.team.internal.ccvs.ui.wizards.CommitWizard;
import org.eclipse.team.internal.core.mapping.SyncInfoToDiffConverter;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.mapping.ModelSynchronizePage;
import org.eclipse.team.internal.ui.mapping.ResourceMarkAsMergedHandler;
import org.eclipse.team.internal.ui.mapping.ResourceMergeHandler;
import org.eclipse.team.internal.ui.synchronize.IRefreshEvent;
import org.eclipse.team.internal.ui.synchronize.IRefreshSubscriberListener;
import org.eclipse.team.internal.ui.synchronize.RefreshModelParticipantJob;
import org.eclipse.team.internal.ui.synchronize.RefreshParticipantJob;
import org.eclipse.team.internal.ui.synchronize.SynchronizeView;
import org.eclipse.team.tests.ccvs.core.CVSTestSetup;
import org.eclipse.team.ui.TeamUI;
import org.eclipse.team.ui.synchronize.ISynchronizeManager;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipantReference;
import org.eclipse.team.ui.synchronize.ISynchronizeView;
import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.part.IPage;
import org.junit.Assert;

import junit.framework.AssertionFailedError;

public class ModelParticipantSyncInfoSource extends ParticipantSyncInfoSource {

	public class ZeroDepthContainer extends PlatformObject {
		private IContainer container;
		public ZeroDepthContainer(IContainer container) {
			this.container = container;
		}
		public IContainer getResource() {
			return container;
		}
		public boolean equals(Object obj) {
			if (obj == this)
				return true;
			if (obj instanceof ShallowContainer) {
				ZeroDepthContainer other = (ZeroDepthContainer) obj;
				return other.getResource().equals(getResource());
			}
			return false;
		}
		public int hashCode() {
			return getResource().hashCode();
		}
		public Object getAdapter(Class adapter) {
			if (adapter == IResource.class || adapter == IContainer.class)
				return container;
			return super.getAdapter(adapter);
		}
	}
	
	public class ZeroDepthResourceMapping extends ResourceMapping {
		private final ZeroDepthContainer container;
		public ZeroDepthResourceMapping(ZeroDepthContainer container) {
			this.container = container;
		}
		public Object getModelObject() {
			return container;
		}
		public String getModelProviderId() {
			return ModelProvider.RESOURCE_MODEL_PROVIDER_ID;
		}
		public IProject[] getProjects() {
			return new IProject[] { container.getResource().getProject() };
		}
		public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) {
			return new ResourceTraversal[] { new ResourceTraversal(new IResource[] { container.getResource() }, IResource.DEPTH_ZERO, IResource.NONE)};
		}
		public boolean contains(ResourceMapping mapping) {
			if (mapping.getModelProviderId().equals(this.getModelProviderId())) {
				Object object = mapping.getModelObject();
				IResource resource = container.getResource();
				// A shallow mapping only contains direct file children or equal shallow containers
				if (object instanceof ShallowContainer) {
					ZeroDepthContainer sc = (ZeroDepthContainer) object;
					return sc.getResource().equals(resource);
				}
				if (object instanceof IResource) {
					IResource other = (IResource) object;
					return other.equals(resource);
				}
			}
			return false;
		}
	}
	
	public static ModelSynchronizeParticipant getParticipant(Subscriber subscriber) {
		// show the sync view
		ISynchronizeParticipantReference[] participants = TeamUI.getSynchronizeManager().getSynchronizeParticipants();
		for (int i = 0; i < participants.length; i++) {
			ISynchronizeParticipant participant;
			try {
				participant = participants[i].getParticipant();
			} catch (TeamException e) {
				return null;
			}
			if (participant instanceof ModelSynchronizeParticipant) {
				ModelSynchronizeParticipant msp = (ModelSynchronizeParticipant) participant;
				ISynchronizationContext context = msp.getContext();
				if (context instanceof SubscriberMergeContext) {
					SubscriberMergeContext smc = (SubscriberMergeContext) context;
					if (smc.getSubscriber().equals(subscriber))
							return msp;
				}
			}
		}
		return null;
	}
	
	public void assertSyncEquals(String message, Subscriber subscriber, IResource resource, int syncKind) throws CoreException {
		assertDiffKindEquals(message, subscriber, resource, SyncInfoToDiffConverter.asDiffFlags(syncKind));	
	}
	
	protected IDiff getDiff(Subscriber subscriber, IResource resource) throws CoreException {
		waitForCollectionToFinish(subscriber);
		IDiff subscriberDiff =  subscriber.getDiff(resource);
		IDiff contextDiff = getContextDiff(subscriber, resource);
		assertDiffsEqual(subscriber, subscriberDiff, contextDiff);
		return contextDiff;
	}
	
	public void refresh(Subscriber subscriber, IResource[] resources) throws TeamException {
		RefreshParticipantJob job = new RefreshModelParticipantJob(getParticipant(subscriber), "Refresh", "Refresh", Utils.getResourceMappings(resources), new IRefreshSubscriberListener() {
			public void refreshStarted(IRefreshEvent event) {
				// Do nothing
			}
		
			public IWorkbenchAction refreshDone(IRefreshEvent event) {
				// Do nothing
				return null;
			}
		});
		job.schedule();
		waitForCollectionToFinish(subscriber);
		assertViewMatchesModel(subscriber);
	}
	
	public void waitForCollectionToFinish(Subscriber subscriber) {
		ModelSynchronizeParticipant family = getParticipant(subscriber);
		if (family == null) {
			while (waitUntilFamilyDone(subscriber)) {
				// just keep looping until we no longer wait for any jobs
			}
		} else {
			while (waitUntilFamilyDone(subscriber) 
					|| waitUntilFamilyDone(family)
					|| waitUntilFamilyDone(family.getContext())
					|| waitUntilFamilyDone(family.getContext().getScope())
					|| waitUntilFamilyDone(((SynchronizationContext)family.getContext()).getScopeManager())) {
				// just keep looping until we no longer wait for any jobs
			}
		}
	}

	private boolean waitUntilFamilyDone(Object family) {
		if (family == null)
			return false;
		Job[] jobs = Job.getJobManager().find(family);
		boolean waited = false;
		for (int i = 0; i < jobs.length; i++) {
			Job job = jobs[i];
			while (job.getState() != Job.NONE) {
				waited = true;
				while (Display.getCurrent().readAndDispatch()) {}
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// Ignore
				}
			}
		}
		return waited;
	}

	private void assertDiffsEqual(Subscriber subscriber, IDiff subscriberDiff, IDiff contextDiff) throws CoreException {
		if (subscriberDiff == null && contextDiff == null)
			return;
		if (subscriberDiff == null && contextDiff != null) {
			Assert.fail("Subscriber contains no change for "
					+ ResourceDiffTree.getResourceFor(contextDiff).getFullPath().toString()
					+ " but the context contains: "
					+ contextDiff.toDiffString());
		}
		if (subscriberDiff != null && contextDiff == null) {
			if (subscriber instanceof CVSCompareSubscriber) {
				// The compare context filters out nodes whose contents are equal
				if (localContentsMatchRemote(subscriberDiff))
					return;
			}
			Assert.fail("Subscriber contains change: "
					+ subscriberDiff.toDiffString()
					+ " for "
					+ ResourceDiffTree.getResourceFor(subscriberDiff).getFullPath().toString()
					+ " but the context has no change");
		}
		int subscriberStatus = ((Diff)subscriberDiff).getStatus();
		int contextStatus = ((Diff)subscriberDiff).getStatus();
		if (subscriberStatus != contextStatus) {
			Assert.fail("Subscriber contains change: "
					+ subscriberDiff.toDiffString()
					+ " for "
					+ ResourceDiffTree.getResourceFor(contextDiff).getFullPath().toString()
					+ " but the context contains: "
					+ contextDiff.toDiffString());
		}
	}

	private boolean localContentsMatchRemote(IDiff subscriberDiff) throws CoreException {
		IResource resource = ResourceDiffTree.getResourceFor(subscriberDiff);
		if (resource instanceof IFile) {
			IFile file = (IFile) resource;
			IFileRevision remote = SyncInfoToDiffConverter.getRemote(subscriberDiff);
			return compareContent(file.getContents(), remote.getStorage(DEFAULT_MONITOR).getContents());
		}
		return false;
	}

	/**
	 * Returns a boolean value indicating whether or not the contents
	 * of the given streams are considered to be equal. Closes both input streams.
	 */
	public boolean compareContent(InputStream a, InputStream b) {
		int c, d;
		if (a == null && b == null)
			return true;
		try {
			if (a == null || b == null)
				return false;
			while ((c = a.read()) == (d = b.read()) && (c != -1 && d != -1)) {
				//body not needed
			}
			return (c == -1 && d == -1);
		} catch (IOException e) {
			return false;
		} finally {
			try {
				if (a != null)
					a.close();
			} catch (IOException e) {
				// ignore
			}
			try {
				if (b != null)
					b.close();
			} catch (IOException e) {
				// ignore
			}
		}
	}
	
	private IDiff getContextDiff(Subscriber subscriber, IResource resource) {
		ModelSynchronizeParticipant p = getParticipant(subscriber);
		return p.getContext().getDiffTree().getDiff(resource);
	}

	protected SyncInfo getSyncInfo(Subscriber subscriber, IResource resource) throws TeamException {
		try {
			IDiff diff = getDiff(subscriber, resource);
			return getConverter(subscriber).asSyncInfo(diff, subscriber.getResourceComparator());
		} catch (CoreException e) {
			throw TeamException.asTeamException(e);
		}
	}
	
	protected void assertProjectRemoved(Subscriber subscriber, IProject project) {
		super.assertProjectRemoved(subscriber, project);
		waitForCollectionToFinish(subscriber);
		ModelSynchronizeParticipant participant = getParticipant(subscriber);
		IResourceDiffTree tree = participant.getContext().getDiffTree();
		if (tree.members(project).length > 0) {
			throw new AssertionFailedError("The diff tree still contains resources from the deleted project " + project.getName());	
		}
	}
	
	private ISynchronizationScopeManager createScopeManager(IResource resource, Subscriber subscriber) {
		return new SubscriberScopeManager(subscriber.getName(), 
				new ResourceMapping[] { Utils.getResourceMapping(resource) }, subscriber, true);
	}
	
	private ISynchronizationScopeManager createWorkspaceScopeManager() {
		CVSWorkspaceSubscriber workspaceSubscriber = CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber();
		try {
			ModelProvider workspaceModel = ModelProvider.getModelProviderDescriptor(ModelProvider.RESOURCE_MODEL_PROVIDER_ID).getModelProvider();
			return new SubscriberScopeManager(workspaceSubscriber.getName(), 
					new ResourceMapping[] { Utils.getResourceMapping(workspaceModel) }, workspaceSubscriber, true);
		} catch (CoreException e) {
			Assert.fail(e.getMessage());
		}
		return null;
	}
	
	public CVSMergeSubscriber createMergeSubscriber(IProject project, CVSTag root, CVSTag branch) {
		CVSMergeSubscriber mergeSubscriber = super.createMergeSubscriber(project, root, branch);
		ModelSynchronizeParticipant participant = new ModelMergeParticipant(MergeSubscriberContext.createContext(createScopeManager(project, mergeSubscriber), mergeSubscriber));
		showParticipant(participant);
		return mergeSubscriber;
	}

	public Subscriber createWorkspaceSubscriber() throws TeamException {
		ISynchronizeManager synchronizeManager = TeamUI.getSynchronizeManager();
		ISynchronizeParticipantReference[] participants = synchronizeManager.get(WorkspaceModelParticipant.ID);
		if (participants.length > 0) {
			Subscriber subscriber = ((SubscriberMergeContext)((WorkspaceModelParticipant)participants[0].getParticipant()).getContext()).getSubscriber();
			waitForCollectionToFinish(subscriber);
			return subscriber;
		}
		WorkspaceModelParticipant participant = new WorkspaceModelParticipant(WorkspaceSubscriberContext.createContext(createWorkspaceScopeManager(), ISynchronizationContext.THREE_WAY));
		showParticipant(participant);
		Subscriber subscriber = super.createWorkspaceSubscriber();
		refresh(subscriber, subscriber.roots());
		return subscriber;
	}

	public CVSCompareSubscriber createCompareSubscriber(IResource resource, CVSTag tag) {
		CVSCompareSubscriber s = super.createCompareSubscriber(resource, tag);
		ModelSynchronizeParticipant participant = new ModelCompareParticipant(CompareSubscriberContext.createContext(createScopeManager(resource, s), s));
		showParticipant(participant);
		return s;
	}
	
	public void disposeSubscriber(Subscriber subscriber) {
		ISynchronizeParticipant participant = getParticipant(subscriber);
		ISynchronizeManager synchronizeManager = TeamUI.getSynchronizeManager();
		synchronizeManager.removeSynchronizeParticipants(new ISynchronizeParticipant[] {participant});
	}
	
	public void mergeResources(Subscriber subscriber, IResource[] resources, boolean allowOverwrite) throws TeamException {
		// Try a merge first
		internalMergeResources(subscriber, resources, false);
		if (allowOverwrite) {
			internalMergeResources(subscriber, resources, true);
			try {
				assertInSync(subscriber, resources);
			} catch (CoreException e) {
				throw TeamException.asTeamException(e);
			}
		}
	}

	private void assertInSync(Subscriber subscriber, IResource[] resources) throws CoreException {
		waitForCollectionToFinish(subscriber);
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			assertSyncEquals("merge failed", subscriber, resource, SyncInfo.IN_SYNC);
		}
		
	}

	private void internalMergeResources(Subscriber subscriber, IResource[] resources, final boolean allowOverwrite) throws TeamException {
		ResourceMergeHandler handler = new ResourceMergeHandler(getConfiguration(subscriber), allowOverwrite) {
			protected boolean promptToConfirm() {
				return true;
			}
			protected void promptForNoChanges() {
				// Do nothing
			}
		};
		handler.updateEnablement(new StructuredSelection(asResourceMappings(resources)));
		try {
			handler.execute(new ExecutionEvent(null, Collections.EMPTY_MAP, null, null));
		} catch (ExecutionException e) {
			throw new TeamException("Error running merge", e);
		}
		waitForCollectionToFinish(subscriber);
	}

	public void markAsMerged(Subscriber subscriber, IResource[] resources) throws InvocationTargetException, InterruptedException, TeamException {
		ResourceMarkAsMergedHandler handler = new ResourceMarkAsMergedHandler(getConfiguration(subscriber));
		handler.updateEnablement(new StructuredSelection(resources));
		try {
			handler.execute(new ExecutionEvent(null, Collections.EMPTY_MAP, null, null));
		} catch (ExecutionException e) {
			throw new TeamException("Error running markAsMerged", e);
		}
		waitForCollectionToFinish(subscriber);
	}
	
	public void updateResources(Subscriber subscriber, IResource[] resources) throws CoreException {
		mergeResources(subscriber, resources, false);
	}
	
	public void overrideAndUpdateResources(Subscriber subscriber, boolean shouldPrompt, IResource[] resources) throws CoreException {
		mergeResources(subscriber, resources, true);
	}
	
	public void commitResources(Subscriber subscriber, IResource[] resources) throws CoreException {
		try {
			new CommitWizard.AddAndCommitOperation(null, 
					getChangedFiles(subscriber, resources),
					getNewResources(subscriber, resources), "").run(DEFAULT_MONITOR);
		} catch (InvocationTargetException e) {
			throw CVSException.wrapException(e);
		} catch (InterruptedException e) {
			Assert.fail();
		}
	}

	private IResource[] getChangedFiles(Subscriber subscriber, IResource[] resources) throws CoreException {
		List result = new ArrayList();
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if (resource.getType() == IResource.FILE) {
				IDiff diff = subscriber.getDiff(resource);
				if (diff != null)
					result.add(resource);
			}
		}
		return (IResource[]) result.toArray(new IResource[result.size()]);
	}
	
	private IResource[] getNewResources(Subscriber subscriber, IResource[] resources) throws CoreException {
		List result = new ArrayList();
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			IDiff diff = subscriber.getDiff(resource);
			if (diff instanceof IThreeWayDiff) {
				IThreeWayDiff twd = (IThreeWayDiff) diff;
				if (twd.getKind() == IDiff.ADD && twd.getDirection() == IThreeWayDiff.OUTGOING) {
					if (!CVSWorkspaceRoot.getCVSResourceFor(resource).isManaged()) {
						result.add(resource);
					}
				}
			}
		}
		return (IResource[]) result.toArray(new IResource[result.size()]);
	}

	private ResourceMapping[] asResourceMappings(IResource[] resources) {
		List result = new ArrayList();
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if (resource.getType() == IResource.FILE) {
				result.add(Utils.getResourceMapping(resource));
			} else {
				result.add(new ZeroDepthResourceMapping(new ZeroDepthContainer((IContainer)resource)));
			}
		}
		return (ResourceMapping[]) result.toArray(new ResourceMapping[result.size()]);
	}

	public void overrideAndCommitResources(Subscriber subscriber, IResource[] resources) throws CoreException {
		try {
			markAsMerged(subscriber, resources);
		} catch (InvocationTargetException e) {
			throw CVSException.wrapException(e);
		} catch (InterruptedException e) {
			Assert.fail("unexpected interrupt");
		}
		commitResources(subscriber, resources);
	}
	
	public ISynchronizePageConfiguration getConfiguration(Subscriber subscriber) {
		ModelSynchronizePage page = getPage(subscriber);
		return page.getConfiguration();
	}

	private ModelSynchronizePage getPage(Subscriber subscriber) {
        try {
            ModelSynchronizeParticipant participant = getParticipant(subscriber);
            if (participant == null)
            	throw new AssertionFailedError("The participant for " + subscriber.getName() + " could not be retrieved");
            IWorkbenchPage activePage = TeamUIPlugin.getActivePage();
            ISynchronizeView view = (ISynchronizeView)activePage.showView(ISynchronizeView.VIEW_ID);
            IPage page = ((SynchronizeView)view).getPage(participant);
            if (page instanceof ModelSynchronizePage) {
            	ModelSynchronizePage subscriberPage = (ModelSynchronizePage)page;
            	return subscriberPage;
            }
        } catch (PartInitException e) {
            throw new AssertionFailedError("Cannot show sync view in active page");
        }
        throw new AssertionFailedError("The page for " + subscriber.getName() + " could not be retrieved");
	}
	
	public void assertViewMatchesModel(Subscriber subscriber) {
		waitForCollectionToFinish(subscriber);
		TreeItem[] rootItems = getTreeItems(subscriber);
		ModelSynchronizeParticipant p = getParticipant(subscriber);
		ResourceDiffTree tree = (ResourceDiffTree)p.getContext().getDiffTree();
		ResourceDiffTree copy = new ResourceDiffTree();
		IDiff[] diffs = tree.getDiffs();
		for (int i = 0; i < diffs.length; i++) {
			IDiff diff = diffs[i];
			copy.add(diff);
		}
		assertTreeMatchesDiffs(rootItems, copy);
	}
	
    private void assertTreeMatchesDiffs(TreeItem[] rootItems, ResourceDiffTree copy) {
		assertItemsInDiffTree(rootItems, copy);
		if (!copy.isEmpty()) {
			new AssertionFailedError("Viewer is not showing all diffs");
		}
	}

	private void assertItemsInDiffTree(TreeItem[] items, ResourceDiffTree copy) {
        if (items == null || items.length == 0) {
            return;
        }
        for (int i = 0; i < items.length; i++) {
			TreeItem item = items[i];
			assertItemInTree(item, copy);
		}
		
	}

	private void assertItemInTree(TreeItem item, ResourceDiffTree copy) {
		Object element = item.getData();
		if (element instanceof IResource) {
			IResource resource = (IResource) element;
			if (copy.getDiff(resource) != null) {
				copy.remove(resource);
			} else if (copy.getChildren(resource.getFullPath()).length == 0) {
				// When running in the suites, we want to avoid intermittent failures so we only flag errors that would result in lost changes
				if (CVSTestSetup.FAIL_ON_BAD_DIFF) {
					throw new AssertionFailedError("Resource" + resource.getFullPath() + " is in the view but not in the diff tree");
				} else {
					System.out.println("Resource" + resource.getFullPath() + " is in the view but not in the diff tree");
					new Exception().printStackTrace();
					return;
				}
				
			}
			assertItemsInDiffTree(item.getItems(), copy);
		}
	}

	private TreeItem[] getTreeItems(Subscriber subscriber) {
    	ModelSynchronizePage page = getPage(subscriber);
        Viewer v = page.getViewer();
        if (v instanceof TreeViewer) {
            TreeViewer treeViewer = (TreeViewer)v;
            treeViewer.expandAll();
            Tree t = (treeViewer).getTree();
            return t.getItems();
        }
        throw new AssertionFailedError("The tree for " + subscriber.getName() + " could not be retrieved");
    }
	
}
