/*******************************************************************************
 *  Copyright (c) 2004, 2017 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
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *     Sergey Prigogin (Google) - [464072] Refresh on Access ignored during text search
 *******************************************************************************/
package org.eclipse.core.tests.resources;

import java.io.*;
import java.nio.charset.StandardCharsets;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.preferences.EclipsePreferences;
import org.eclipse.core.internal.resources.CharsetDeltaJob;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;

public class CharsetTest extends ResourceTest {

	private final class JobChangeAdapterExtension extends JobChangeAdapter {
		private IStatus result;

		public JobChangeAdapterExtension() {
		}

		@Override
		public void done(IJobChangeEvent event) {
			if (event.getJob().belongsTo(CharsetDeltaJob.FAMILY_CHARSET_DELTA)) {
				this.result = event.getResult();
			}
		}

		IStatus getResult() {
			return this.result;
		}
	}

	public class CharsetVerifier extends ResourceDeltaVerifier {
		final static int IGNORE_BACKGROUND_THREAD = 0x02;
		final static int IGNORE_CREATION_THREAD = 0x01;
		private final Thread creationThread = Thread.currentThread();
		private final int flags;

		CharsetVerifier(int flags) {
			this.flags = flags;
		}

		@Override
		void internalVerifyDelta(IResourceDelta delta) {
			// do NOT ignore any changes to project preferences only to .project
			IPath path = delta.getFullPath();
			if (path.segmentCount() == 2 && path.segment(1).equals(".project")) {
				return;
			}
			super.internalVerifyDelta(delta);
		}

		private boolean isSet(int mask) {
			return (mask & flags) == mask;
		}

		@Override
		public synchronized void resourceChanged(IResourceChangeEvent e) {
			// to make testing easier, we allow events from the main or other thread to be ignored
			if (isSet(IGNORE_BACKGROUND_THREAD) && Thread.currentThread() != creationThread) {
				return;
			}
			if (isSet(IGNORE_CREATION_THREAD) && Thread.currentThread() == creationThread) {
				return;
			}
			super.resourceChanged(e);
			this.notify();
		}

		public synchronized boolean waitForEvent(long limit) {
			if (hasBeenNotified()) {
				return true;
			}
			try {
				this.wait(limit);
			} catch (InterruptedException e) {
				// ignore
			}
			return hasBeenNotified();
		}
	}

	static final String SAMPLE_SPECIFIC_XML = "<?xml version=\"1.0\"?><org.eclipse.core.tests.resources.anotherXML/>";
	private static final String SAMPLE_XML_DEFAULT_ENCODING = "<?xml version=\"1.0\"?><org.eclipse.core.resources.tests.root/>";
	static final String SAMPLE_XML_ISO_8859_1_ENCODING = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><org.eclipse.core.resources.tests.root/>";
	static final String SAMPLE_XML_US_ASCII_ENCODING = "<?xml version=\"1.0\" encoding=\"US-ASCII\"?><org.eclipse.core.resources.tests.root/>";

	static final String SAMPLE_DERIVED_ENCODING_TO_FALSE_REGULAR_PREFS = "#Mon Nov 15 17:54:11 CET 2010\n" + ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS + "=false\neclipse.preferences.version=1";
	static final String SAMPLE_DERIVED_ENCODING_AFTER_FALSE_REGULAR_PREFS[] = new String[] {ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS + "=false", "encoding//b1/a.txt=UTF-8", "eclipse.preferences.version=1"};

	static final String SAMPLE_DERIVED_ENCODING_TO_TRUE_REGULAR_PREFS = "#Mon Nov 15 17:54:11 CET 2010\n" + ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS + "=true\nencoding//b1/a.txt=UTF-8\neclipse.preferences.version=1";
	static final String SAMPLE_DERIVED_ENCODING_AFTER_TRUE_REGULAR_PREFS[] = new String[] {ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS + "=true", "eclipse.preferences.version=1"};
	static final String SAMPLE_DERIVED_ENCODING_AFTER_TRUE_DERIVED_PREFS[] = new String[] {"encoding//b1/a.txt=UTF-8", "eclipse.preferences.version=1"};

	private String savedWorkspaceCharset;

	public static Test suite() {
		//		TestSuite suite = new TestSuite();
		//		suite.addTest(new CharsetTest("testFileCreation"));
		//		suite.addTest(new CharsetTest("testPrefsFileCreation"));
		//		return suite;
		//		return new CharsetTest("testMovingProject");

		return new TestSuite(CharsetTest.class);

		//    // cause the same test to run several times to catch a timing problem
		//		TestSuite suite = new TestSuite();
		//		for (int i = 0; i < 1000; i++)
		//			suite.addTest(new CharsetTest("testDeltasFile"));
		//		return suite;
	}

	public CharsetTest(String name) {
		super(name);
	}

	/**
	 * See bug 67606.
	 *
	 * TODO enable when bug is fixed
	 */
	public void _testBug67606() throws CoreException {
		IWorkspace workspace = getWorkspace();
		final IProject project = workspace.getRoot().getProject("MyProject");
		try {
			final IFile file = project.getFile("file.txt");
			ensureExistsInWorkspace(file, true);
			project.setDefaultCharset("FOO", getMonitor());
			workspace.run((IWorkspaceRunnable) monitor -> {
				assertEquals("0.9", "FOO", file.getCharset());
				file.setCharset("BAR", getMonitor());
				assertEquals("1.0", "BAR", file.getCharset());
				file.move(project.getFullPath().append("file2.txt"), IResource.NONE, monitor);
				IFile file2 = project.getFile("file2.txt");
				assertExistsInWorkspace(file2, false);
				assertEquals("2.0", "BAR", file.getCharset());
			}, null);
		} finally {
			ensureDoesNotExistInWorkspace(project);
		}
	}

	/**
	 * Asserts that the given resources have the given [default] charset.
	 */
	private void assertCharsetIs(String tag, String encoding, IResource[] resources, boolean checkImplicit) throws CoreException {
		for (IResource resource : resources) {
			String resourceCharset = resource instanceof IFile ? ((IFile) resource).getCharset(checkImplicit) : ((IContainer) resource).getDefaultCharset(checkImplicit);
			assertEquals(tag + " " + resource.getFullPath(), encoding, resourceCharset);
		}
	}

	//	private void checkPreferencesContent(String tag, IFile prefs, String[] lines) {
	//		BufferedReader br = null;
	//		try {
	//			br = new BufferedReader(new FileReader(prefs.getLocation().toFile()));
	//			List<String> actualList = new ArrayList<String>();
	//			String line = br.readLine();
	//			while (line != null) {
	//				if (!line.startsWith("#")) {
	//					actualList.add(line);
	//				}
	//				line = br.readLine();
	//			}
	//
	//			assertEquals(tag, lines.length, actualList.size());
	//			List<String> expectedLines = Arrays.asList(lines);
	//			Collections.sort(expectedLines);
	//			Collections.sort(actualList);
	//			for (int i = 0; i < expectedLines.size(); i++) {
	//				assertTrue(tag, expectedLines.get(i).equals(actualList.get(i)));
	//			}
	//		} catch (FileNotFoundException e) {
	//			fail(tag, e);
	//		} catch (IOException e) {
	//			fail(tag, e);
	//		} finally {
	//			if (br != null)
	//				try {
	//					br.close();
	//				} catch (IOException e) {
	//					fail(tag, e);
	//				}
	//		}
	//	}

	private void clearAllEncodings(IResource root) throws CoreException {
		if (root == null || !root.exists()) {
			return;
		}
		IResourceVisitor visitor = resource -> {
			if (!resource.exists()) {
				return false;
			}
			switch (resource.getType()) {
				case IResource.FILE :
					((IFile) resource).setCharset(null, getMonitor());
					break;
				case IResource.ROOT :
					// do nothing
					break;
				default :
					((IContainer) resource).setDefaultCharset(null, getMonitor());
			}
			return true;
		};
		root.accept(visitor);
	}

	private IFile getResourcesPreferenceFile(IProject project, boolean forDerivedResources) {
		if (forDerivedResources) {
			return project.getFolder(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME).getFile(ResourcesPlugin.PI_RESOURCES + ".derived." + EclipsePreferences.PREFS_FILE_EXTENSION);
		}
		return project.getFolder(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME).getFile(ResourcesPlugin.PI_RESOURCES + "." + EclipsePreferences.PREFS_FILE_EXTENSION);
	}

	private Reader getTextContents(String text) {
		return new StringReader(text);
	}

	private boolean isDerivedEncodingStoredSeparately(IProject project) {
		org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE);
		String projectName = project.getName();
		try {
			if (!node.nodeExists(projectName)) {
				return false;
			}
			node = node.node(projectName);
			if (!node.nodeExists(ResourcesPlugin.PI_RESOURCES)) {
				return false;
			}
			node = node.node(ResourcesPlugin.PI_RESOURCES);
			return node.getBoolean(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, false);
		} catch (BackingStoreException e) {
			// default value
			return false;
		}
	}

	private void setDerivedEncodingStoredSeparately(String tag, IProject project, boolean value) {
		org.osgi.service.prefs.Preferences prefs = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES);
		if (!value) {
			prefs.remove(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS);
		} else {
			prefs.putBoolean(ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS, true);
		}
		try {
			prefs.flush();
		} catch (BackingStoreException e) {
			fail(tag, e);
		}
	}

	private static IEclipsePreferences getResourcesPreferences() {
		return InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		// save the workspace charset so it can be restored after the test
		savedWorkspaceCharset = ResourcesPlugin.getPlugin().getPluginPreferences().getString(ResourcesPlugin.PREF_ENCODING);
	}

	@Override
	protected void tearDown() throws Exception {
		// restore the workspace charset
		ResourcesPlugin.getPlugin().getPluginPreferences().setValue(ResourcesPlugin.PREF_ENCODING, savedWorkspaceCharset);
		// Reset the PREF_LIGHTWEIGHT_AUTO_REFRESH preference to its default value.
		getResourcesPreferences().remove(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH);
		super.tearDown();
	}

	public void testBug59899() {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject(getUniqueString());
		try {
			IFile file = project.getFile("file.txt");
			IFolder folder = project.getFolder("folder");
			ensureExistsInWorkspace(new IResource[] {file, folder}, true);
			try {
				file.setCharset("FOO", getMonitor());
			} catch (CoreException e) {
				fail("1.0", e);
			}
			try {
				folder.setDefaultCharset("BAR", getMonitor());
			} catch (CoreException e) {
				fail("2.0", e);
			}
			try {
				project.setDefaultCharset("PROJECT_CHARSET", getMonitor());
			} catch (CoreException e) {
				fail("3.0", e);
			}
			try {
				getWorkspace().getRoot().setDefaultCharset("ROOT_CHARSET", getMonitor());
			} catch (CoreException e) {
				fail("4.0", e);
			}
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	public void testBug62732() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
		IContentType anotherXML = contentTypeManager.getContentType("org.eclipse.core.tests.resources.anotherXML");
		assertNotNull("0.5", anotherXML);
		ensureExistsInWorkspace(project, true);
		IFile file = project.getFile("file.xml");
		ensureExistsInWorkspace(file, new ByteArrayInputStream(SAMPLE_SPECIFIC_XML.getBytes(StandardCharsets.UTF_8)));
		IContentDescription description = file.getContentDescription();
		assertNotNull("1.0", description);
		assertEquals("1.1", anotherXML, description.getContentType());
		description = file.getContentDescription();
		assertNotNull("2.0", description);
		assertEquals("2.1", anotherXML, description.getContentType());
	}

	public void testBug64503() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
		IContentType text = contentTypeManager.getContentType("org.eclipse.core.runtime.text");
		IFile file = project.getFile("file.txt");
		ensureExistsInWorkspace(file, true);
		IContentDescription description = file.getContentDescription();
		assertNotNull("1.0", description);
		assertEquals("1.1", text, description.getContentType());
		ensureDoesNotExistInWorkspace(file);
		try {
			description = file.getContentDescription();
			fail("1.2 - should have failed");
		} catch (CoreException e) {
			// Ok, the resource does not exist.
			assertEquals("1.3", IResourceStatus.RESOURCE_NOT_FOUND, e.getStatus().getCode());
		}
	}

	public void testBug94279() throws CoreException {
		final IWorkspaceRoot root = getWorkspace().getRoot();
		String originalUserCharset = root.getDefaultCharset(false);
		try {
			root.setDefaultCharset(null);
			assertNull("1.0", root.getDefaultCharset(false));
		} finally {
			if (originalUserCharset != null) {
				root.setDefaultCharset(originalUserCharset);
			}
		}
	}

	public void testBug333056() throws CoreException {
		IProject project = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject("MyProject");
			ensureExistsInWorkspace(project, true);
			project.setDefaultCharset("BAR", getMonitor());

			IFolder folder = project.getFolder(getUniqueString());
			IFile file = folder.getFile(getUniqueString());
			assertEquals("1.0", "BAR", file.getCharset(true));

			ensureExistsInWorkspace(folder, true);
			assertEquals("2.0", "BAR", file.getCharset(true));

			folder.setDerived(true, getMonitor());
			assertEquals("3.0", "BAR", file.getCharset(true));

			setDerivedEncodingStoredSeparately("4.0", project, true);
			assertEquals("5.0", "BAR", file.getCharset(true));
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("6.0", e);
			}
		}
	}

	/**
	 * Test for getting charset on an IFile:
	 * #getContentDescription() checks file sync state(), always returning the
	 * correct content description, whereas getCharset() uses the cached charset if available.
	 * @throws Exception
	 */
	public void testBug186984() throws Exception {
		getResourcesPreferences().putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, false);
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject(getUniqueString());
		IFile file = project.getFile("file.xml");

		// Test changing content types externally as per bug 186984 Comment 8
		String ascii = "<?xml version=\"1.0\" encoding=\"ascii\"?>";
		String utf = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";

		// test that we can get the charset, when the file doesn't exist in a file system
		try {
			file.getCharset(true);
		} catch (CoreException ex) {
			fail("1.0");
		}

		// test that we can get the charset, when the file is out-of-sync
		ensureExistsInWorkspace(file, true);
		try {
			if (!file.getLocation().toFile().delete()) {
				fail("2.0");
			}
			file.getCharset(true);
		} catch (CoreException ex) {
			fail("2.1");
		}

		ensureExistsInFileSystem(file);
		ensureOutOfSync(file);
		//getCharset uses a cached value, so it will still pass
		try {
			file.getCharset(true);
		} catch (CoreException ex) {
			fail("3.0");
		}

		// set the content type within the XML file, ensure that #getContentDescription (which respects sync state)
		// returns the correct value.

		// 1) first set the content type to ascii
		file.setContents(new ByteArrayInputStream(ascii.getBytes("ascii")), IResource.FORCE, getMonitor());
		assertTrue("4.0", file.getCharset().equals("ascii"));
		assertTrue("4.1", file.getContentDescription().getCharset().equals("ascii"));

		// 2) Make out of sync - Methods should still work, giving the previous value
		touchInFilesystem(file);
		assertTrue("4.2", file.getCharset().equals("ascii"));
		try {
			file.getContentDescription().getCharset().equals("ascii");
			assertTrue("4.3", false);
		} catch (CoreException e) {
			// Ok, the file is out of sync.
			assertEquals("4.4", IResourceStatus.OUT_OF_SYNC_LOCAL, e.getStatus().getCode());
		}

		// As we now know that #getContentDescription correctly checks sync state, just enable LIGHTWEIGHT refresh
		// for the rest of the test.
		getResourcesPreferences().putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, true);
		assertTrue("4.5", file.getContentDescription().getCharset().equals("ascii"));

		// getContentDescription will have noticed out-of-sync
		Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, getMonitor());
		// Prime the cache...
		assertTrue("4.6", file.getCharset().equals("ascii"));

		// 3) Change the content type of the file under eclipse's feet
		FileWriter writer = new FileWriter(file.getLocation().toFile());
		writer.write(utf);
		writer.close();
		touchInFilesystem(file);
		// #getCharset uses the cached value (bug 209167) - doesn't check sync state
		assertTrue("5.4", file.getCharset().equals("ascii"));
		// #getContentDescription checks sync and discovers the real content type
		assertTrue("5.5", file.getContentDescription().getCharset().equals("UTF-8"));
		// getContentDescription will have noticed out-of-sync
		Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, getMonitor());
		// #getCharset will now have noticed that the file has changed.
		assertTrue("5.6", file.getCharset().equals("UTF-8"));

		// 4) Change the content type of the file under eclipse's feet once more (to non-default).
		writer = new FileWriter(file.getLocation().toFile());
		writer.write(ascii);
		writer.close();
		touchInFilesystem(file);
		// #getCharset uses the cached value (bug 209167) - doesn't check sync state
		assertTrue("6.7", file.getCharset().equals("UTF-8"));
		// #getContentDescription checks sync and discovers the real content type
		assertTrue("6.8", file.getContentDescription().getCharset().equals("ascii"));
		// getContentDescription will have noticed out-of-sync
		Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, getMonitor());
		assertTrue("6.9", file.getCharset().equals("ascii"));
	}

	public void testBug207510() {
		IWorkspace workspace = getWorkspace();
		CharsetVerifier verifier = new CharsetVerifier(CharsetVerifier.IGNORE_BACKGROUND_THREAD);
		CharsetVerifier backgroundVerifier = new CharsetVerifier(CharsetVerifier.IGNORE_CREATION_THREAD);
		IProject project1 = workspace.getRoot().getProject("project1");
		try {
			workspace.addResourceChangeListener(verifier, IResourceChangeEvent.POST_CHANGE);
			workspace.addResourceChangeListener(backgroundVerifier, IResourceChangeEvent.POST_CHANGE);

			IFolder a1 = project1.getFolder("a1");
			IFolder b1 = project1.getFolder("b1");
			IFile a = a1.getFile("a.txt");
			ensureExistsInWorkspace(new IResource[] {project1, a1, b1, a}, true);
			try {
				verifier.reset();
				verifier.addExpectedChange(b1, IResourceDelta.CHANGED, IResourceDelta.DERIVED_CHANGED);
				b1.setDerived(true, getMonitor());
				verifier.waitForEvent(10000);
			} catch (CoreException e) {
				fail("0.1", e);
			}
			IFile regularPrefs = getResourcesPreferenceFile(project1, false);
			IFile derivedPrefs = getResourcesPreferenceFile(project1, true);
			assertDoesNotExistInWorkspace("0.2", regularPrefs);
			assertDoesNotExistInWorkspace("0.3", derivedPrefs);

			//1 - setting preference on project
			verifier.reset();
			verifier.addExpectedChange(regularPrefs.getParent(), IResourceDelta.ADDED, 0);
			verifier.addExpectedChange(regularPrefs, IResourceDelta.ADDED, 0);
			setDerivedEncodingStoredSeparately("1.0", project1, true);
			assertTrue("1.1", verifier.waitForEvent(10000));
			assertTrue("1.2 " + verifier.getMessage(), verifier.isDeltaValid());
			assertExistsInWorkspace("1.3", regularPrefs);
			assertDoesNotExistInWorkspace("1.4", derivedPrefs);
			assertTrue("1.5", isDerivedEncodingStoredSeparately(project1));

			//2 - changing charset for file
			verifier.reset();
			verifier.addExpectedChange(a, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				a.setCharset("UTF-8", getMonitor());
			} catch (CoreException e) {
				fail("2.0", e);
			}
			assertTrue("2.1", verifier.waitForEvent(10000));
			assertTrue("2.2 " + verifier.getMessage(), verifier.isDeltaValid());
			assertExistsInWorkspace("2.3", regularPrefs);
			assertDoesNotExistInWorkspace("2.4", derivedPrefs);

			//3 - setting derived == 'true' for file
			// TODO update the test when bug 345271 is fixed
			try {
				a.setDerived(true, getMonitor());
			} catch (CoreException e) {
				fail("3.0", e);
			}
			//wait for all resource deltas
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				fail("3.0.1", e);
			}
			assertExistsInWorkspace("3.1", regularPrefs);
			assertExistsInWorkspace("3.2", derivedPrefs);
			assertTrue("3.3", derivedPrefs.isDerived());

			//4 - setting derived == 'false' for file
			// TODO update the test when bug 345271 is fixed
			try {
				a.setDerived(false, getMonitor());
			} catch (CoreException e) {
				fail("4.0", e);
			}
			//wait for all resource deltas
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				fail("4.0.1", e);
			}
			assertExistsInWorkspace("4.1", regularPrefs);
			assertDoesNotExistInWorkspace("4.2", derivedPrefs);

			//5 - moving file to derived folder
			IFile source = project1.getFolder("a1").getFile("a.txt");
			IFile destination = project1.getFolder("b1").getFile("a.txt");
			backgroundVerifier.reset();
			backgroundVerifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.ADDED, 0);
			try {
				a.move(destination.getFullPath(), true, getMonitor());
				a = destination;
			} catch (CoreException e) {
				fail("5.0", e);
			}
			assertTrue("5.1", backgroundVerifier.waitForEvent(10000));
			assertTrue("5.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			assertExistsInWorkspace("5.3", regularPrefs);
			assertExistsInWorkspace("5.4", derivedPrefs);
			assertDoesNotExistInWorkspace("5.5", source);
			assertExistsInWorkspace("5.6", destination);
			assertTrue("5.7", derivedPrefs.isDerived());
			try {
				assertCharsetIs("5.8", "UTF-8", new IResource[] {a}, true);
			} catch (CoreException e) {
				fail("5.8.1", e);
			}

			//6 - removing preference on project
			verifier.reset();
			backgroundVerifier.reset();
			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.REMOVED, 0);
			setDerivedEncodingStoredSeparately("6.0", project1, false);
			assertTrue("6.1.1", verifier.waitForEvent(10000));
			assertTrue("6.1.2", backgroundVerifier.waitForEvent(10000));
			assertTrue("6.2.1 " + verifier.getMessage(), verifier.isDeltaValid());
			assertTrue("6.2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			assertExistsInWorkspace("6.3", regularPrefs);
			assertDoesNotExistInWorkspace("6.4", derivedPrefs);

			//7 - setting preference on project with derived files
			verifier.reset();
			backgroundVerifier.reset();
			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.ADDED, 0);
			setDerivedEncodingStoredSeparately("7.0", project1, true);
			assertTrue("7.1.1", verifier.waitForEvent(10000));
			assertTrue("7.1.2", backgroundVerifier.waitForEvent(10000));
			assertTrue("7.2.1 " + verifier.getMessage(), verifier.isDeltaValid());
			assertTrue("7.2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			assertExistsInWorkspace("7.3", regularPrefs);
			assertExistsInWorkspace("7.4", derivedPrefs);
			assertTrue("7.5", isDerivedEncodingStoredSeparately(project1));
			assertTrue("7.6", derivedPrefs.isDerived());

			//			//8 - manually changing preference 'true'->'false'
			//			verifier.reset();
			//			backgroundVerifier.reset();
			//			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			//			backgroundVerifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			//			backgroundVerifier.addExpectedChange(new IResource[] {project1, a1, b1, a, regularPrefs.getParent(), regularPrefs}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			//			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.REMOVED, 0);
			//			assertTrue("7.99", isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				regularPrefs.setContents(new ByteArrayInputStream(SAMPLE_DERIVED_ENCODING_TO_FALSE_REGULAR_PREFS.getBytes()), 0, getMonitor());
			//			} catch (CoreException e) {
			//				fail("8.0", e);
			//			}
			//			assertTrue("8.1.1", verifier.waitForEvent(10000));
			//			assertTrue("8.1.2", backgroundVerifier.waitForEvent(10000));
			//			assertTrue("8.2.1 " + verifier.getMessage(), verifier.isDeltaValid());
			//			assertTrue("8.2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			//			assertExistsInWorkspace("8.3", regularPrefs);
			//			//checkPreferencesContent("8.3.1", regularPrefs, SAMPLE_DERIVED_ENCODING_AFTER_FALSE_REGULAR_PREFS);
			//			assertDoesNotExistInWorkspace("8.4", derivedPrefs);
			//			assertTrue("8.5", !isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				assertCharsetIs("8.6", "UTF-8", new IResource[] {a}, true);
			//			} catch (CoreException e) {
			//				fail("8.6.1", e);
			//			}
			//
			//			//9 - manually changing preference 'false'->'true'
			//			verifier.reset();
			//			backgroundVerifier.reset();
			//			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			//			//backgroundVerifier.addExpectedChange(new IResource[] {project1, a1, b1, a, regularPrefs.getParent(), regularPrefs}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			//			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.ADDED, 0);
			//			assertDoesNotExistInWorkspace("8.98", derivedPrefs);
			//			assertTrue("8.99", !isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				regularPrefs.setContents(new ByteArrayInputStream(SAMPLE_DERIVED_ENCODING_TO_TRUE_REGULAR_PREFS.getBytes()), 0, getMonitor());
			//			} catch (CoreException e) {
			//				fail("9.0", e);
			//			}
			//			assertTrue("9.1.1", verifier.waitForEvent(10000));
			//			assertTrue("9.1.2", backgroundVerifier.waitForEvent(10000));
			//			assertTrue("9.2.1 " + verifier.getMessage(), verifier.isDeltaValid());
			//			assertTrue("9.2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			//			//updating prefs is run in separate job so wait some time for completion
			//			backgroundVerifier.waitForEvent(10000);
			//			assertExistsInWorkspace("9.3", regularPrefs);
			//			//checkPreferencesContent("9.3.1", regularPrefs, SAMPLE_DERIVED_ENCODING_AFTER_TRUE_REGULAR_PREFS);
			//			assertExistsInWorkspace("9.4", derivedPrefs);
			//			checkPreferencesContent("9.4.1", derivedPrefs, SAMPLE_DERIVED_ENCODING_AFTER_TRUE_DERIVED_PREFS);
			//			assertTrue("9.5", isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				assertCharsetIs("9.6", "UTF-8", new IResource[] {a}, true);
			//			} catch (CoreException e) {
			//				fail("9.6.1", e);
			//			}
			//			assertTrue("9.7", derivedPrefs.isDerived());
			//
			//			//10 - manually changing preference 'true'->'false' outside Eclipse
			//			verifier.reset();
			//			backgroundVerifier.reset();
			//			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			//			backgroundVerifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			//			backgroundVerifier.addExpectedChange(new IResource[] {project1, a1, b1, a, regularPrefs.getParent(), regularPrefs}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			//			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.REMOVED, 0);
			//			assertTrue("9.99", isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				File file = regularPrefs.getLocation().toFile();
			//				BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			//				bw.write(SAMPLE_DERIVED_ENCODING_TO_FALSE_REGULAR_PREFS);
			//				bw.close();
			//				regularPrefs.refreshLocal(IResource.DEPTH_ZERO, getMonitor());
			//			} catch (IOException e) {
			//				fail("10.0.1", e);
			//			} catch (CoreException e) {
			//				fail("10.0.2", e);
			//			}
			//			assertTrue("10.1.1", verifier.waitForEvent(10000));
			//			assertTrue("10.1.2", backgroundVerifier.waitForEvent(10000));
			//			assertTrue("10.2.1 " + verifier.getMessage(), verifier.isDeltaValid());
			//			assertTrue("10.2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			//			assertExistsInWorkspace("10.3", regularPrefs);
			//			//checkPreferencesContent("10.3.1", regularPrefs, SAMPLE_DERIVED_ENCODING_AFTER_FALSE_REGULAR_PREFS);
			//			assertDoesNotExistInWorkspace("10.4", derivedPrefs);
			//			assertTrue("10.5", !isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				assertCharsetIs("10.6", "UTF-8", new IResource[] {a}, true);
			//			} catch (CoreException e) {
			//				fail("10.6.1", e);
			//			}
			//
			//			//11 - manually changing preference 'false'->'true' outside Eclipse
			//			verifier.reset();
			//			backgroundVerifier.reset();
			//			verifier.addExpectedChange(regularPrefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			//			//backgroundVerifier.addExpectedChange(new IResource[] {project1, a1, b1, a, regularPrefs.getParent(), regularPrefs}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			//			backgroundVerifier.addExpectedChange(derivedPrefs, IResourceDelta.ADDED, 0);
			//			assertDoesNotExistInWorkspace("10.98", derivedPrefs);
			//			assertTrue("10.99", !isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				File file = regularPrefs.getLocation().toFile();
			//				BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			//				bw.write(SAMPLE_DERIVED_ENCODING_TO_TRUE_REGULAR_PREFS);
			//				bw.close();
			//				regularPrefs.refreshLocal(IResource.DEPTH_ZERO, getMonitor());
			//			} catch (IOException e) {
			//				fail("11.0.1", e);
			//			} catch (CoreException e) {
			//				fail("11.0.2", e);
			//			}
			//			assertTrue("11.1.1", verifier.waitForEvent(10000));
			//			assertTrue("11.1.2", backgroundVerifier.waitForEvent(10000));
			//			assertTrue("11.2.1 " + verifier.getMessage(), verifier.isDeltaValid());
			//			assertTrue("11.2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			//			//updating prefs is run in separate job so wait some time for completion
			//			backgroundVerifier.waitForEvent(10000);
			//			assertExistsInWorkspace("11.3", regularPrefs);
			//			//checkPreferencesContent("11.3.1", regularPrefs, SAMPLE_DERIVED_ENCODING_AFTER_TRUE_REGULAR_PREFS);
			//			assertExistsInWorkspace("11.4", derivedPrefs);
			//			checkPreferencesContent("11.4.1", derivedPrefs, SAMPLE_DERIVED_ENCODING_AFTER_TRUE_DERIVED_PREFS);
			//			assertTrue("11.5", isDerivedEncodingStoredSeparately(project1));
			//			try {
			//				assertCharsetIs("11.6", "UTF-8", new IResource[] {a}, true);
			//			} catch (CoreException e) {
			//				fail("11.6.1", e);
			//			}
			//			assertTrue("11.7", derivedPrefs.isDerived());
		} finally {
			workspace.removeResourceChangeListener(verifier);
			workspace.removeResourceChangeListener(backgroundVerifier);
			try {
				clearAllEncodings(project1);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	/**
	 * In this bug, a file starts with a particular content id and content type. It is then
	 * deleted and recreated, with the same content id but a different content type.
	 * This tricks the content type cache into returning an invalid result.
	 */
	public void testBug261994() throws CoreException {
		//recreate a file with different contents but the same content id
		IWorkspace workspace = getWorkspace();
		IProject project1 = workspace.getRoot().getProject("Project1");
		IFile file = project1.getFile("file1.xml");
		ensureExistsInWorkspace(file, new ByteArrayInputStream(SAMPLE_XML_ISO_8859_1_ENCODING.getBytes(StandardCharsets.ISO_8859_1)));
		ContentDescriptionManagerTest.waitForCacheFlush();
		assertEquals("1.0", "ISO-8859-1", file.getCharset());

		//delete and recreate the file with different contents
		ensureDoesNotExistInWorkspace(file);
		ensureExistsInWorkspace(file, new ByteArrayInputStream(SAMPLE_XML_DEFAULT_ENCODING.getBytes(StandardCharsets.UTF_8)));
		assertEquals("2.0", "UTF-8", file.getCharset());
	}

	public void testChangesDifferentProject() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project1 = workspace.getRoot().getProject("Project1");
		IProject project2 = workspace.getRoot().getProject("Project2");
		try {
			IFolder folder = project1.getFolder("folder1");
			IFile file1 = project1.getFile("file1.txt");
			IFile file2 = folder.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2, project2}, true);
			project1.setDefaultCharset("FOO", getMonitor());
			project2.setDefaultCharset("ZOO", getMonitor());
			folder.setDefaultCharset("BAR", getMonitor());
			// move a folder to another project and ensure its encoding is
			// preserved
			folder.move(project2.getFullPath().append("folder"), false, false, null);
			folder = project2.getFolder("folder");
			assertEquals("1.0", "BAR", folder.getDefaultCharset());
			assertEquals("1.1", "BAR", folder.getFile("file2.txt").getCharset());
			// move a file with no charset set and check if it inherits
			// properly from the new parent
			assertEquals("2.0", project1.getDefaultCharset(), file1.getCharset());
			file1.move(project2.getFullPath().append("file1.txt"), false, false, null);
			file1 = project2.getFile("file1.txt");
			assertEquals("2.1", project2.getDefaultCharset(), file1.getCharset());
		} finally {
			try {
				clearAllEncodings(project1);
				clearAllEncodings(project2);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	public void testChangesSameProject() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		try {
			IFolder folder = project.getFolder("folder1");
			IFile file1 = project.getFile("file1.txt");
			IFile file2 = folder.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);
			project.setDefaultCharset("FOO", getMonitor());
			file1.setCharset("FRED", getMonitor());
			folder.setDefaultCharset("BAR", getMonitor());
			// move a folder inside the project and ensure its encoding is
			// preserved
			folder.move(project.getFullPath().append("folder2"), false, false, null);
			folder = project.getFolder("folder2");
			assertEquals("1.0", "BAR", folder.getDefaultCharset());
			assertEquals("1.1", "BAR", folder.getFile("file2.txt").getCharset());
			// move a file inside the project and ensure its encoding is
			// update accordingly
			file2 = folder.getFile("file2.txt");
			file2.move(project.getFullPath().append("file2.txt"), false, false, null);
			file2 = project.getFile("file2.txt");
			assertEquals("2.0", project.getDefaultCharset(), file2.getCharset());
			// delete a file and recreate it and ensure the encoding is not
			// remembered
			file1.delete(false, false, null);
			ensureExistsInWorkspace(new IResource[] {file1}, true);
			assertEquals("3.0", project.getDefaultCharset(), file1.getCharset());
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	public void testClosingAndReopeningProject() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		try {
			// create a project and set some explicit encodings
			IFolder folder = project.getFolder("folder");
			IFile file1 = project.getFile("file1.txt");
			IFile file2 = folder.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);
			project.setDefaultCharset("FOO", getMonitor());
			file1.setCharset("FRED", getMonitor());
			folder.setDefaultCharset("BAR", getMonitor());
			project.close(null);
			// now reopen the project and ensure the settings were not forgotten
			IProject projectB = workspace.getRoot().getProject(project.getName());
			projectB.open(null);
			assertExistsInWorkspace("0.9", getResourcesPreferenceFile(projectB, false));
			assertEquals("1.0", "FOO", projectB.getDefaultCharset());
			assertEquals("3.0", "FRED", projectB.getFile("file1.txt").getCharset());
			assertEquals("2.0", "BAR", projectB.getFolder("folder").getDefaultCharset());
			assertEquals("2.1", "BAR", projectB.getFolder("folder").getFile("file2.txt").getCharset());
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	/**
	 * Tests Content Manager-based charset setting.
	 */
	public void testContentBasedCharset() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		try {
			ensureExistsInWorkspace(project, true);
			project.setDefaultCharset("FOO", getMonitor());
			IFile file = project.getFile("file.xml");
			assertEquals("0.9", "FOO", project.getDefaultCharset());
			// content-based encoding is BAR
			ensureExistsInWorkspace(file, new ByteArrayInputStream(SAMPLE_XML_US_ASCII_ENCODING.getBytes(StandardCharsets.UTF_8)));
			assertEquals("1.0", "US-ASCII", file.getCharset());
			// content-based encoding is FRED
			file.setContents(new ByteArrayInputStream(SAMPLE_XML_ISO_8859_1_ENCODING.getBytes(StandardCharsets.ISO_8859_1)), false, false, null);
			assertEquals("2.0", "ISO-8859-1", file.getCharset());
			// content-based encoding is UTF-8 (default for XML)
			file.setContents(new ByteArrayInputStream(SAMPLE_XML_DEFAULT_ENCODING.getBytes(StandardCharsets.UTF_8)), false, false, null);
			assertEquals("3.0", "UTF-8", file.getCharset());
			// tests with BOM -BOMs are strings for convenience, encoded itno bytes using ISO-8859-1 (which handles 128-255 bytes better)
			// tests with UTF-8 BOM
			String UTF8_BOM = new String(IContentDescription.BOM_UTF_8, StandardCharsets.ISO_8859_1);
			file.setContents(new ByteArrayInputStream((UTF8_BOM + SAMPLE_XML_DEFAULT_ENCODING).getBytes(StandardCharsets.ISO_8859_1)), false, false, null);
			assertEquals("4.0", "UTF-8", file.getCharset());
			// tests with UTF-16 Little Endian BOM
			String UTF16_LE_BOM = new String(IContentDescription.BOM_UTF_16LE, StandardCharsets.ISO_8859_1);
			file.setContents(new ByteArrayInputStream((UTF16_LE_BOM + SAMPLE_XML_DEFAULT_ENCODING).getBytes(StandardCharsets.ISO_8859_1)), false, false, null);
			assertEquals("5.0", "UTF-16", file.getCharset());
			// tests with UTF-16 Big Endian BOM
			String UTF16_BE_BOM = new String(IContentDescription.BOM_UTF_16BE, StandardCharsets.ISO_8859_1);
			file.setContents(new ByteArrayInputStream((UTF16_BE_BOM + SAMPLE_XML_DEFAULT_ENCODING).getBytes(StandardCharsets.ISO_8859_1)), false, false, null);
			assertEquals("6.0", "UTF-16", file.getCharset());
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	public void testDefaults() throws CoreException {
		IProject project = null;
		String originalCharset = ResourcesPlugin.getPlugin().getPluginPreferences().getString(ResourcesPlugin.PREF_ENCODING);
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject("MyProject");
			IFolder folder1 = project.getFolder("folder1");
			IFolder folder2 = folder1.getFolder("folder2");
			IFile file1 = project.getFile("file1.txt");
			IFile file2 = folder1.getFile("file2.txt");
			IFile file3 = folder2.getFile("file3.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2, file3}, true);
			// project and children should be using the workspace's default now
			assertCharsetIs("1.0", ResourcesPlugin.getEncoding(), new IResource[] {workspace.getRoot(), project, file1, folder1, file2, folder2, file3}, true);
			assertCharsetIs("1.1", null, new IResource[] {project, file1, folder1, file2, folder2, file3}, false);
			// sets workspace default charset
			workspace.getRoot().setDefaultCharset("FOO", getMonitor());
			assertCharsetIs("2.0", "FOO", new IResource[] {workspace.getRoot(), project, file1, folder1, file2, folder2, file3}, true);
			assertCharsetIs("2.1", null, new IResource[] {project, file1, folder1, file2, folder2, file3}, false);
			// sets project default charset
			project.setDefaultCharset("BAR", getMonitor());
			assertCharsetIs("3.0", "BAR", new IResource[] {project, file1, folder1, file2, folder2, file3}, true);
			assertCharsetIs("3.1", null, new IResource[] {file1, folder1, file2, folder2, file3}, false);
			assertCharsetIs("3.2", "FOO", new IResource[] {workspace.getRoot()}, true);
			// sets folder1 default charset
			folder1.setDefaultCharset("FRED", getMonitor());
			assertCharsetIs("4.0", "FRED", new IResource[] {folder1, file2, folder2, file3}, true);
			assertCharsetIs("4.1", null, new IResource[] {file2, folder2, file3}, false);
			assertCharsetIs("4.2", "BAR", new IResource[] {project, file1}, true);
			// sets folder2 default charset
			folder2.setDefaultCharset("ZOO", getMonitor());
			assertCharsetIs("5.0", "ZOO", new IResource[] {folder2, file3}, true);
			assertCharsetIs("5.1", null, new IResource[] {file3}, false);
			assertCharsetIs("5.2", "FRED", new IResource[] {folder1, file2}, true);
			// sets file3 charset
			file3.setCharset("ZIT", getMonitor());
			assertCharsetIs("6.0", "ZIT", new IResource[] {file3}, false);
			folder2.setDefaultCharset(null, getMonitor());
			assertCharsetIs("7.0", folder2.getParent().getDefaultCharset(), new IResource[] {folder2}, true);
			assertCharsetIs("7.1", null, new IResource[] {folder2}, false);
			assertCharsetIs("7.2", "ZIT", new IResource[] {file3}, false);
			folder1.setDefaultCharset(null, getMonitor());
			assertCharsetIs("8.0", folder1.getParent().getDefaultCharset(), new IResource[] {folder1, file2, folder2}, true);
			assertCharsetIs("8.1", null, new IResource[] {folder1, file2, folder2}, false);
			assertCharsetIs("8.2", "ZIT", new IResource[] {file3}, false);
			project.setDefaultCharset(null, getMonitor());
			assertCharsetIs("9.0", project.getParent().getDefaultCharset(), new IResource[] {project, file1, folder1, file2, folder2}, true);
			assertCharsetIs("9.1", null, new IResource[] {project, file1, folder1, file2, folder2}, false);
			assertCharsetIs("9.2", "ZIT", new IResource[] {file3}, false);
			workspace.getRoot().setDefaultCharset(null, getMonitor());
			assertCharsetIs("10.0", project.getParent().getDefaultCharset(), new IResource[] {project, file1, folder1, file2, folder2}, true);
			assertCharsetIs("10.1", "ZIT", new IResource[] {file3}, false);
			file3.setCharset(null, getMonitor());
			assertCharsetIs("11.0", ResourcesPlugin.getEncoding(), new IResource[] {workspace.getRoot(), project, file1, folder1, file2, folder2, file3}, true);
		} finally {
			ResourcesPlugin.getPlugin().getPluginPreferences().setValue(ResourcesPlugin.PREF_ENCODING, originalCharset);
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	// check we react to content type changes
	public void testDeltaOnContentTypeChanges() {
		final String USER_SETTING = "USER_CHARSET";
		final String PROVIDER_SETTING = "PROVIDER_CHARSET";

		// install a verifier
		CharsetVerifier backgroundVerifier = new CharsetVerifier(CharsetVerifier.IGNORE_CREATION_THREAD);
		getWorkspace().addResourceChangeListener(backgroundVerifier, IResourceChangeEvent.POST_CHANGE);
		IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
		IContentType myType = contentTypeManager.getContentType("org.eclipse.core.tests.resources.myContent2");
		assertNotNull("0.1", myType);
		assertEquals("0.2", PROVIDER_SETTING, myType.getDefaultCharset());
		IProject project = getWorkspace().getRoot().getProject("project1");
		try {
			IFolder folder1 = project.getFolder("folder1");
			IFile file1 = folder1.getFile("file1.txt");
			IFile file2 = folder1.getFile("file2.resources-mc");
			IFile file3 = project.getFile("file3.resources-mc");
			IFile file4 = project.getFile("file4.resources-mc");
			ensureExistsInWorkspace(new IResource[] {file1, file2, file3, file4}, true);
			try {
				project.setDefaultCharset("FOO", getMonitor());
			} catch (CoreException e) {
				fail("1.0", e);
			}
			// even files with a user-set charset will appear in the delta
			try {
				file4.setCharset("BAR", getMonitor());
			} catch (CoreException e) {
				fail("1.1", e);
			}
			// configure verifier
			backgroundVerifier.reset();
			backgroundVerifier.addExpectedChange(new IResource[] {file2, file3, file4}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			// change content type's default charset
			try {
				myType.setDefaultCharset(USER_SETTING);
			} catch (CoreException e) {
				fail("2.0", e);
			}
			// ensure the property events were generated
			assertTrue("2.1", backgroundVerifier.waitForEvent(10000));
			assertTrue("2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			try {
				assertEquals("3.0", USER_SETTING, file2.getCharset());
				assertEquals("3.1", USER_SETTING, file3.getCharset());
				assertEquals("3.2", "BAR", file4.getCharset());
			} catch (CoreException e) {
				fail("3.9", e);
			}

			// change back to the provider-provided default
			// configure verifier
			backgroundVerifier.reset();
			backgroundVerifier.addExpectedChange(new IResource[] {file2, file3, file4}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			// reset charset to default
			try {
				myType.setDefaultCharset(null);
			} catch (CoreException e) {
				fail("4.0", e);
			}
			// ensure the property events were generated
			assertTrue("4.1", backgroundVerifier.waitForEvent(10000));
			assertTrue("4.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());
			try {
				assertEquals("5.0", PROVIDER_SETTING, file2.getCharset());
				assertEquals("5.1", PROVIDER_SETTING, file3.getCharset());
				assertEquals("5.2", "BAR", file4.getCharset());
			} catch (CoreException e) {
				fail("5.9", e);
			}
		} finally {
			getWorkspace().removeResourceChangeListener(backgroundVerifier);
			try {
				myType.setDefaultCharset(null);
			} catch (CoreException e) {
				fail("99.0", e);
			}
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	// check preference change events are reflected in the charset settings
	// temporarily disabled
	public void testDeltaOnPreferenceChanges() {

		CharsetVerifier backgroundVerifier = new CharsetVerifier(CharsetVerifier.IGNORE_CREATION_THREAD);
		getWorkspace().addResourceChangeListener(backgroundVerifier, IResourceChangeEvent.POST_CHANGE);
		IProject project = getWorkspace().getRoot().getProject("project1");
		try {
			IFolder folder1 = project.getFolder("folder1");
			IFile file1 = folder1.getFile("file1.txt");
			IFile file2 = project.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);

			IFile resourcesPrefs = getResourcesPreferenceFile(project, false);
			assertTrue("0.9", !resourcesPrefs.exists());

			try {
				file1.setCharset("CHARSET1", getMonitor());
			} catch (CoreException e) {
				fail("1.0", e);
			}
			assertTrue("1.1", resourcesPrefs.exists());

			backgroundVerifier.reset();
			backgroundVerifier.addExpectedChange(new IResource[] {project, folder1, file1, file2, resourcesPrefs, resourcesPrefs.getParent()}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			// cause a resource change event without actually changing contents
			try {
				resourcesPrefs.setContents(resourcesPrefs.getContents(), 0, getMonitor());
			} catch (CoreException e) {
				fail("2.0", e);
			}
			assertTrue("2.1", backgroundVerifier.waitForEvent(10000));
			assertTrue("2.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());

			backgroundVerifier.reset();
			backgroundVerifier.addExpectedChange(new IResource[] {project, folder1, file1, file2, resourcesPrefs.getParent()}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			try {
				// delete the preferences file
				resourcesPrefs.delete(true, getMonitor());
			} catch (CoreException e) {
				fail("3.0", e);
			}
			assertTrue("3.1", backgroundVerifier.waitForEvent(10000));
			assertTrue("3.2 " + backgroundVerifier.getMessage(), backgroundVerifier.isDeltaValid());

		} finally {
			getWorkspace().removeResourceChangeListener(backgroundVerifier);
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	/**
	 * Test the contents of the resource deltas which are generated
	 * when we make encoding changes to containers (folders, projects, root).
	 */
	public void testDeltasContainer() {
		CharsetVerifier verifier = new CharsetVerifier(CharsetVerifier.IGNORE_BACKGROUND_THREAD);
		IProject project = getWorkspace().getRoot().getProject(getUniqueString());
		getWorkspace().addResourceChangeListener(verifier, IResourceChangeEvent.POST_CHANGE);
		try {
			IFile prefs = getResourcesPreferenceFile(project, false);
			// leaf folder
			IFolder folder1 = project.getFolder("folder1");
			ensureExistsInWorkspace(new IResource[] {project, folder1}, true);
			verifier.reset();
			verifier.addExpectedChange(folder1, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(new IResource[] {prefs, prefs.getParent()}, IResourceDelta.ADDED, 0);
			try {
				folder1.setDefaultCharset("new_charset", getMonitor());
			} catch (CoreException e) {
				fail("1.0", e);
			}
			assertTrue("1.1." + verifier.getMessage(), verifier.isDeltaValid());

			// folder with children
			IFolder folder2 = folder1.getFolder("folder2");
			IFile file1 = folder1.getFile("file1.txt");
			IFile file2 = folder2.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {folder2, file1, file2}, true);
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {folder1, folder2, file1, file2}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				folder1.setDefaultCharset("a_charset", getMonitor());
			} catch (CoreException e) {
				fail("2.0", e);
			}
			assertTrue("2.1." + verifier.getMessage(), verifier.isDeltaValid());

			// folder w. children, some with non-inherited values
			try {
				// set the child to have a non-inherited value
				folder2.setDefaultCharset("non-Default", getMonitor());
			} catch (CoreException e) {
				fail("3.0", e);
			}
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {folder1, file1}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				folder1.setDefaultCharset("newOne", getMonitor());
			} catch (CoreException e) {
				fail("3.1", e);
			}
			assertTrue("3.2." + verifier.getMessage(), verifier.isDeltaValid());

			// change from non-default to another non-default
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {folder1, file1}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				folder1.setDefaultCharset("newTwo", getMonitor());
			} catch (CoreException e) {
				fail("4.1", e);
			}
			assertTrue("4.2." + verifier.getMessage(), verifier.isDeltaValid());

			// change to default (clear it)
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {folder1, file1}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				folder1.setDefaultCharset(null, getMonitor());
			} catch (CoreException e) {
				fail("5.0", e);
			}
			assertTrue("5.1." + verifier.getMessage(), verifier.isDeltaValid());

			// change to default (equal to it but it doesn't inherit)
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {folder1, file1}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				folder1.setDefaultCharset(project.getDefaultCharset(), getMonitor());
			} catch (CoreException e) {
				fail("6.0", e);
			}
			assertTrue("6.1." + verifier.getMessage(), verifier.isDeltaValid());

			// clear all the encoding info before we start working with the project
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("7.0", e);
			}
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {project, folder1, folder2, file1, file2, prefs.getParent()}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs, IResourceDelta.ADDED, 0);
			try {
				project.setDefaultCharset("foo", getMonitor());
			} catch (CoreException e) {
				fail("7.1", e);
			}
			assertTrue("7.2." + verifier.getMessage(), verifier.isDeltaValid());

			// clear all the encoding info before we start working with the root
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("8.0", e);
			}
			verifier.reset();
			verifier.addExpectedChange(new IResource[] {project, folder1, folder2, file1, file2, prefs.getParent()}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			try {
				getWorkspace().getRoot().setDefaultCharset("foo", getMonitor());
			} catch (CoreException e) {
				fail("8.1", e);
			}
			assertTrue("8.2." + verifier.getMessage(), verifier.isDeltaValid());
		} finally {
			getWorkspace().removeResourceChangeListener(verifier);
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	/**
	 * Check that we are broadcasting the correct resource deltas when
	 * making encoding changes.
	 *
	 */
	public void testDeltasFile() {
		IWorkspace workspace = getWorkspace();
		CharsetVerifier verifier = new CharsetVerifier(CharsetVerifier.IGNORE_BACKGROUND_THREAD);
		workspace.addResourceChangeListener(verifier, IResourceChangeEvent.POST_CHANGE);
		final IProject project = workspace.getRoot().getProject("MyProject");
		try {
			IFile prefs = getResourcesPreferenceFile(project, false);
			// File:
			// single file
			final IFile file1 = project.getFile("file1.txt");
			ensureExistsInWorkspace(file1, getRandomContents());
			// change from default
			verifier.reset();
			verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(new IResource[] {prefs, prefs.getParent()}, IResourceDelta.ADDED, 0);
			try {
				file1.setCharset("FOO", getMonitor());
			} catch (CoreException e) {
				fail("1.0.0", e);
			}
			assertTrue("1.0.1" + verifier.getMessage(), verifier.isDeltaValid());

			// change to default (clear it)
			verifier.reset();
			verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.REMOVED, 0);
			try {
				file1.setCharset(null, getMonitor());
			} catch (CoreException e) {
				fail("1.1.0", e);
			}
			assertTrue("1.1.1" + verifier.getMessage(), verifier.isDeltaValid());

			// change to default (equal to it but it doesn't inherit)
			verifier.reset();
			verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.ADDED, 0);
			try {
				file1.setCharset(file1.getCharset(), getMonitor());
			} catch (CoreException e) {
				fail("1.2.0", e);
			}
			assertTrue("1.2.1" + verifier.getMessage(), verifier.isDeltaValid());

			// change from non-default to another non-default
			try {
				// sets to a non-default value first
				file1.setCharset("FOO", getMonitor());
			} catch (CoreException e) {
				fail("1.3.0", e);
			}
			verifier.reset();
			verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				// sets to another non-defauilt value
				file1.setCharset("BAR", getMonitor());
			} catch (CoreException e) {
				fail("1.3.1", e);
			}
			assertTrue("1.3.2" + verifier.getMessage(), verifier.isDeltaValid());

			// multiple files (same operation)
			verifier.reset();
			final IFile file2 = project.getFile("file2.txt");
			ensureExistsInWorkspace(file2, getRandomContents());
			verifier.addExpectedChange(new IResource[] {file1, file2}, IResourceDelta.CHANGED, IResourceDelta.ENCODING);
			verifier.addExpectedChange(prefs.getParent(), IResourceDelta.CHANGED, 0);
			verifier.addExpectedChange(prefs, IResourceDelta.CHANGED, IResourceDelta.CONTENT);
			try {
				workspace.run((IWorkspaceRunnable) monitor -> {
					file1.setCharset("FOO", getMonitor());
					file2.setCharset("FOO", getMonitor());
				}, getMonitor());
			} catch (CoreException e) {
				fail("1.4.0", e);
			}
			assertTrue("1.4.1" + verifier.getMessage(), verifier.isDeltaValid());
		} finally {
			getWorkspace().removeResourceChangeListener(verifier);
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	public void testFileCreation() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		try {
			IFolder folder = project.getFolder("folder");
			IFile file1 = project.getFile("file1.txt");
			IFile file2 = folder.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);
			assertDoesNotExistInWorkspace("1.0", getResourcesPreferenceFile(project, false));
			project.setDefaultCharset("FOO", getMonitor());
			assertExistsInWorkspace("2.0", getResourcesPreferenceFile(project, false));
			project.setDefaultCharset(null, getMonitor());
			assertDoesNotExistInWorkspace("3.0", getResourcesPreferenceFile(project, false));
			file1.setCharset("FRED", getMonitor());
			assertExistsInWorkspace("4.0", getResourcesPreferenceFile(project, false));
			folder.setDefaultCharset("BAR", getMonitor());
			assertExistsInWorkspace("5.0", getResourcesPreferenceFile(project, false));
			file1.setCharset(null, getMonitor());
			assertExistsInWorkspace("6.0", getResourcesPreferenceFile(project, false));
			folder.setDefaultCharset(null, getMonitor());
			assertDoesNotExistInWorkspace("7.0", getResourcesPreferenceFile(project, false));
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	/**
	 * See enhancement request 60636.
	 */
	public void testGetCharsetFor() throws CoreException {
		IProject project = null;
		try {
			IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
			//			IContentType text = contentTypeManager.getContentType("org.eclipse.core.runtime.text");
			IContentType xml = contentTypeManager.getContentType("org.eclipse.core.runtime.xml");

			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject("MyProject");
			IFile oldFile = project.getFile("oldfile.xml");
			IFile newXMLFile = project.getFile("newfile.xml");
			IFile newTXTFile = project.getFile("newfile.txt");
			IFile newRandomFile = project.getFile("newFile." + (long) (Math.random() * (Long.MAX_VALUE)));
			ensureExistsInWorkspace(oldFile, SAMPLE_XML_DEFAULT_ENCODING);
			// sets project default charset
			project.setDefaultCharset("BAR", getMonitor());
			oldFile.setCharset("FOO", getMonitor());
			// project and non-existing file share the same encoding
			assertCharsetIs("0.1", "BAR", new IResource[] {project, newXMLFile, newTXTFile, newRandomFile}, true);
			// existing file has encoding determined by user
			assertCharsetIs("0.2", "FOO", new IResource[] {oldFile}, true);

			// for an existing file, user set charset will prevail (if any)
			assertEquals("1.0", "FOO", oldFile.getCharsetFor(getTextContents("")));
			assertEquals("1.1", "FOO", oldFile.getCharsetFor(getTextContents(SAMPLE_XML_DEFAULT_ENCODING)));

			// for a non-existing file, or for a file that exists but does not have a user set charset,  the content type (if any) rules
			assertEquals("2.0", xml.getDefaultCharset(), newXMLFile.getCharsetFor(getTextContents("")));
			assertEquals("2.1", xml.getDefaultCharset(), newXMLFile.getCharsetFor(getTextContents(SAMPLE_XML_DEFAULT_ENCODING)));
			assertEquals("2.2", "US-ASCII", newXMLFile.getCharsetFor(getTextContents(SAMPLE_XML_US_ASCII_ENCODING)));
			oldFile.setCharset(null, getMonitor());
			assertEquals("2.3", xml.getDefaultCharset(), oldFile.getCharsetFor(getTextContents("")));
			assertEquals("2.4", xml.getDefaultCharset(), oldFile.getCharsetFor(getTextContents(SAMPLE_XML_DEFAULT_ENCODING)));
			assertEquals("2.5", "US-ASCII", oldFile.getCharsetFor(getTextContents(SAMPLE_XML_US_ASCII_ENCODING)));

			// if the content type has no default charset, or the file has no known content type, fallback to parent default charset
			assertEquals("3.0", project.getDefaultCharset(), newTXTFile.getCharsetFor(getTextContents("")));
			assertEquals("3.1", project.getDefaultCharset(), newRandomFile.getCharsetFor(getTextContents("")));
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}

	}

	/**
	 * Moves a project and ensures the charsets are preserved.
	 */
	public void testMovingProject() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project1 = workspace.getRoot().getProject("Project1");
		IProject project2 = null;
		try {
			IFolder folder = project1.getFolder("folder1");
			IFile file1 = project1.getFile("file1.txt");
			IFile file2 = folder.getFile("file2.txt");
			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);
			project1.setDefaultCharset("FOO", getMonitor());
			folder.setDefaultCharset("BAR", getMonitor());

			assertEquals("1.0", "BAR", folder.getDefaultCharset());
			assertEquals("1.1", "BAR", file2.getCharset());
			assertEquals("1.2", "FOO", file1.getCharset());
			assertEquals("1.3", "FOO", project1.getDefaultCharset());

			// move project and ensures charsets settings are preserved
			project1.move(new Path("Project2"), false, null);
			project2 = workspace.getRoot().getProject("Project2");
			folder = project2.getFolder("folder1");
			file1 = project2.getFile("file1.txt");
			file2 = folder.getFile("file2.txt");
			assertEquals("2.0", "BAR", folder.getDefaultCharset());
			assertEquals("2.1", "BAR", file2.getCharset());
			assertEquals("2.2", "FOO", project2.getDefaultCharset());
			assertEquals("2.3", "FOO", file1.getCharset());
		} finally {
			try {
				clearAllEncodings(project1);
				clearAllEncodings(project2);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	/**
	 * Two things to test here:
	 * 	- non-existing resources default to the parent's default charset;
	 * 	- cannot set the charset for a non-existing resource (exception is thrown).
	 */
	public void testNonExistingResource() throws CoreException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject("MyProject");
		try {
			try {
				project.setDefaultCharset("FOO", getMonitor());
				fail("1.0");
			} catch (CoreException e) {
				// expected, project does not exist yet
				assertEquals("1.1", IResourceStatus.RESOURCE_NOT_FOUND, e.getStatus().getCode());
			}
			ensureExistsInWorkspace(project, true);
			project.setDefaultCharset("FOO", getMonitor());
			IFile file = project.getFile("file.xml");
			assertDoesNotExistInWorkspace("2.0", file);
			assertEquals("2.2", "FOO", file.getCharset());
			try {
				file.setCharset("BAR", getMonitor());
				fail("2.4");
			} catch (CoreException e) {
				// expected, file does not exist yet
				assertEquals("2.6", IResourceStatus.RESOURCE_NOT_FOUND, e.getStatus().getCode());
			}
			ensureExistsInWorkspace(file, true);
			file.setCharset("BAR", getMonitor());
			assertEquals("2.8", "BAR", file.getCharset());
			file.delete(IResource.NONE, null);
			assertDoesNotExistInWorkspace("2.10", file);
			assertEquals("2.11", "FOO", file.getCharset());
		} finally {
			try {
				clearAllEncodings(project);
			} catch (CoreException e) {
				fail("99.9", e);
			}
		}
	}

	public void testBug464072() throws CoreException {
		getResourcesPreferences().putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, true);
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject(getUniqueString());
		IFile file = project.getFile("file.txt");
		ensureExistsInWorkspace(file, true);
		file.getLocation().toFile().delete();
		try {
			file.getContentDescription();
			fail("1.2 - should have failed");
		} catch (CoreException e) {
			// Ok, the resource does not exist.
			assertEquals("1.3", IResourceStatus.RESOURCE_NOT_FOUND, e.getStatus().getCode());
		}
	}

	public void testBug528827() throws CoreException, OperationCanceledException, InterruptedException {
		IWorkspace workspace = getWorkspace();
		IProject project = workspace.getRoot().getProject(getUniqueString());
		ensureExistsInWorkspace(project, true);
		JobChangeAdapterExtension listener = new JobChangeAdapterExtension();
		Job.getJobManager().addJobChangeListener(listener);
		try {
			String otherCharset = getOtherCharset(workspace.getRoot().getDefaultCharset());
			project.setDefaultCharset(otherCharset, getMonitor());
			assertEquals(otherCharset, project.getDefaultCharset());
			project.delete(false, getMonitor());
			Thread.sleep(100); // leave some time for CharsetDeltaJob.to be scheduled;
			Job.getJobManager().join(CharsetDeltaJob.FAMILY_CHARSET_DELTA, getMonitor());
			assertTrue(listener.getResult().isOK());
		} finally {
			Job.getJobManager().removeJobChangeListener(listener);
		}
	}

	private String getOtherCharset(String referenceCharset) {
		return "MIK".equals(referenceCharset) ? "UTF-8" : "MIK";
	}
}
