/*******************************************************************************
 * Copyright (c) 2000, 2015 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.jdt.core.tests.model;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import junit.framework.Test;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.tests.model.AbstractJavaSearchTests.JavaSearchResultCollector;
import org.eclipse.jdt.internal.core.util.Util;

public class EncodingTests extends ModifyingResourceTests {
	IProject encodingProject;
	IJavaProject encodingJavaProject;
	IFile utf8File;
	ISourceReference utf8Source;
	static String vmEncoding = System.getProperty("file.encoding");
	static String wkspEncoding = vmEncoding;

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

	public static Test suite() {
		return buildModelTestSuite(EncodingTests.class);
	}
	// Use this static initializer to specify subset for tests
	// All specified tests which do not belong to the class are skipped...
	static {
//		TESTS_NAMES = new String[] { "testBug361356" };
//		TESTS_NUMBERS = new int[] { 2, 12 };
//		TESTS_RANGE = new int[] { 16, -1 };
	}

	@Override
	public void setUpSuite() throws Exception {
		super.setUpSuite();
		wkspEncoding = getWorkspaceRoot().getDefaultCharset();
		System.out.println("Encoding tests using Workspace charset: "+wkspEncoding+" and VM charset: "+vmEncoding);
		this.encodingJavaProject = setUpJavaProject("Encoding");
		this.encodingProject = (IProject) this.encodingJavaProject.getResource();
		this.utf8File = (IFile) this.encodingProject.findMember("src/testUTF8/Test.java");
	}

	@Override
	public void tearDownSuite() throws Exception {
		super.tearDownSuite();
		getWorkspaceRoot().setDefaultCharset(null, null);
		deleteProject("Encoding");
	}
	@Override
	protected void setUp() throws Exception {
		super.setUp();
	}

	/*
	 *  (non-Javadoc)
	 * Reset UTF-8 file and project charset to default.
	 * @see junit.framework.TestCase#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		this.encodingProject.setDefaultCharset(null, null);
		if (this.utf8File.exists()) this.utf8File.setCharset(null, null);
		if (this.utf8Source != null) ((IOpenable) this.utf8Source).close();
		this.encodingJavaProject.close();
		super.tearDown();
	}

	void compareContents(ICompilationUnit cu, String encoding) throws JavaModelException {
		compareContents(cu, encoding, false);
	}

	void compareContents(ICompilationUnit cu, String encoding, boolean bom) throws JavaModelException {
		// Compare source strings
		String source = cu.getSource();
		String systemSourceRenamed = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		IFile file = (IFile) cu.getUnderlyingResource();
		String renamedContents = new String (Util.getResourceContentsAsCharArray(file));
		renamedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(renamedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", renamedContents, systemSourceRenamed);
		// Compare bytes array
		byte[] renamedSourceBytes = null;
		try {
			renamedSourceBytes = source.getBytes(encoding);
		}
		catch (UnsupportedEncodingException uue) {
		}
		assertNotNull("Unsupported encoding: "+encoding, renamedSourceBytes);
		byte[] renamedEncodedBytes = Util.getResourceContentsAsByteArray(file);
		int start = bom ? IContentDescription.BOM_UTF_8.length : 0;
		assertEquals("Wrong size of encoded string", renamedEncodedBytes.length-start, renamedSourceBytes.length);
		for (int i = 0, max = renamedSourceBytes.length; i < max; i++) {
			assertTrue("Wrong size of encoded character at " + i, renamedSourceBytes[i] == renamedEncodedBytes[i+start]);
		}
	}

	@Override
	public boolean convertToIndependantLineDelimiter(File file) {
		return false; // don't convert to independant line delimiter as this make tests fail on linux
	}
	/**
	 * Check that the compilation unit is saved with the proper encoding.
	 */
	public void testCreateCompilationUnitAndImportContainer() throws Exception {
		String savedEncoding = null;
		String resourcesPluginId = ResourcesPlugin.getPlugin().getBundle().getSymbolicName();
		IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(resourcesPluginId);
		try {
			savedEncoding = preferences.get(ResourcesPlugin.PREF_ENCODING, "");
			String encoding = "UTF-8";
			preferences.put(ResourcesPlugin.PREF_ENCODING, encoding);
			preferences.flush();

			IJavaProject newProject = createJavaProject("P", new String[] { "" }, "");
			IPackageFragment pkg = getPackageFragment("P", "", "");
			String source = "public class A {\r\n" +
				"	public static main(String[] args) {\r\n" +
				"		System.out.println(\"\u00e9\");\r\n" +
				"	}\r\n" +
				"}";
			ICompilationUnit cu= pkg.createCompilationUnit("A.java", source, false, new NullProgressMonitor());
			assertCreation(cu);
			cu.rename("B.java", true, new NullProgressMonitor());
			cu = pkg.getCompilationUnit("B.java");
			cu.rename("A.java", true, new NullProgressMonitor());
			cu = pkg.getCompilationUnit("A.java");
			byte[] tab = null;
			try {
				tab = cu.getSource().getBytes(encoding);
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}
			byte[] encodedContents = Util.getResourceContentsAsByteArray(newProject.getProject().getWorkspace().getRoot().getFile(cu.getPath()));
			assertEquals("wrong size of encoded string", tab.length, encodedContents.length);
			for (int i = 0, max = tab.length; i < max; i++) {
				assertTrue("wrong size of encoded character at" + i, tab[i] == encodedContents[i]);
			}
		} finally {
			deleteProject("P");
			preferences.put(ResourcesPlugin.PREF_ENCODING, savedEncoding);
			preferences.flush();
		}
	}

	/*
	##################
	#	Test with compilation units
	##################
	/*
	 * Get compilation unit source on a file written in UTF-8 charset using specific UTF-8 encoding for file.
	 * Verify first that source is the same than file contents read using UTF-8 encoding...
	 * Also verify that bytes array converted back to UTF-8 is the same than the file bytes array.
	 */
	public void test001() throws JavaModelException, CoreException, UnsupportedEncodingException {

		// Set file encoding
		String encoding = "UTF-8";
		this.utf8File.setCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = this.utf8Source.getSource();
		String systemSource = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, systemSource);

		// Now compare bytes array
		byte[] sourceBytes = source.getBytes(encoding);
		byte[] encodedBytes = Util.getResourceContentsAsByteArray(this.utf8File);
		assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
		for (int i = 0, max = sourceBytes.length; i < max; i++) {
			assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
		}
	}

	/*
	 * Get compilation unit source on a file written in UTF-8 charset using UTF-8 encoding for project.
	 * Verify first that source is the same than file contents read using UTF-8 encoding...
	 * Also verify that bytes array converted back to UTF-8 is the same than the file bytes array.
	 */
	public void test002() throws JavaModelException, CoreException, UnsupportedEncodingException {

		// Set project encoding
		String encoding = "UTF-8";
		this.encodingProject.setDefaultCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = this.utf8Source.getSource();
		String systemSource = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, systemSource);

		// Now compare bytes array
		byte[] sourceBytes = source.getBytes(encoding);
		byte[] encodedBytes = Util.getResourceContentsAsByteArray(this.utf8File);
		assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
		for (int i = 0, max = sourceBytes.length; i < max; i++) {
			assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
		}
	}

	/*
	 * Get compilation unit source on a file written in UTF-8 charset using workspace default encoding.
	 * Verify that source is the same than file contents read using workspace default encoding...
	 * Also verify that bytes array converted back to wokrspace default encoding is the same than the file bytes array.
	 * Do not compare array contents in case of VM default encoding equals to "ASCII" as meaningful bit 7 is lost
	 * during first conversion...
	 */
	public void test003() throws JavaModelException, CoreException, UnsupportedEncodingException {

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = this.utf8Source.getSource();
		String systemSource = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, systemSource);

		// Now compare bytes array
		byte[] sourceBytes = source.getBytes(wkspEncoding);
		byte[] encodedBytes = Util.getResourceContentsAsByteArray(this.utf8File);
		assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
		// Do not compare arrays contents as system encoding may have lost meaningful bit 7 during convertion...)
//		if (!"ASCII".equals(vmEncoding)) {
//			for (int i = 0, max = sourceBytes.length; i < max; i++) {
//				assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
//			}
//		}
	}

	/*
	 * Get compilation unit source on a file written in UTF-8 charset using an encoding
	 * for file different than VM default one.
	 * Verify that source is different than file contents read using VM default encoding...
	 */
	public void test004() throws JavaModelException, CoreException {

		// Set file encoding
		String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
		this.utf8File.setCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.utf8Source.getSource());
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, vmEncoding));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
	}

	/*
	 * Get compilation unit source on a file written in UTF-8 charset using an encoding
	 * for project different than VM default one.
	 * Verify that source is different than file contents read using VM default encoding...
	 */
	public void test005() throws JavaModelException, CoreException {

		// Set project encoding
		String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
		this.encodingProject.setDefaultCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.utf8Source.getSource());
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, vmEncoding));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
	}

	/*
	 * Get compilation unit source on a file written in UTF-8 charset using workspace default encoding.
	 * Verify that source is different than file contents read using VM default encoding or another one
	 * if VM and Workspace default encodings are identical...
	 */
	public void test006() throws JavaModelException, CoreException {

		// Set encoding different than workspace default one
		String encoding = wkspEncoding.equals(vmEncoding) ? ("UTF-8".equals(wkspEncoding) ? "Cp1252" : "UTF-8") : vmEncoding;

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.utf8Source.getSource());
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, encoding));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
	}

	/*
	##############
	#	Tests with class file
	##############
	/* Same config than test001  */
	public void test011() throws JavaModelException, CoreException, UnsupportedEncodingException {

		// Set file encoding
		String encoding = "UTF-8";
		this.utf8File.setCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getClassFile("Encoding" , "bins", "testUTF8", "Test.class"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		String source = this.utf8Source.getSource();
		String systemSource = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, systemSource);

		// Now compare bytes array
		byte[] sourceBytes = source.getBytes(encoding);
		byte[] encodedBytes = Util.getResourceContentsAsByteArray(this.utf8File);
		assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
		for (int i = 0, max = sourceBytes.length; i < max; i++) {
			assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
		}
	}

	/* Same config than test002  */
	public void test012() throws JavaModelException, CoreException, UnsupportedEncodingException {

		// Set project encoding
		String encoding = "UTF-8";
		this.encodingProject.setDefaultCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getClassFile("Encoding" , "bins", "testUTF8", "Test.class"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		String source = this.utf8Source.getSource();
		String systemSource = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, systemSource);

		// Now compare bytes array
		byte[] sourceBytes = source.getBytes(encoding);
		byte[] encodedBytes = Util.getResourceContentsAsByteArray(this.utf8File);
		assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
		for (int i = 0, max = sourceBytes.length; i < max; i++) {
			assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
		}
	}

	/* Same config than test003  */
	public void test013() throws JavaModelException, CoreException, UnsupportedEncodingException {

		// Get source and compare with file contents
		this.utf8Source = getClassFile("Encoding" , "bins", "testUTF8", "Test.class"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		String source = this.utf8Source.getSource();
		String systemSource = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, systemSource);

		// Now compare bytes array
		byte[] sourceBytes = source.getBytes(wkspEncoding);
		byte[] encodedBytes = Util.getResourceContentsAsByteArray(this.utf8File);
		assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
		// Do not compare arrays contents as system encoding may have lost meaningful bit 7 during convertion...)
//		if (!"ASCII".equals(vmEncoding)) {
//			for (int i = 0, max = sourceBytes.length; i < max; i++) {
//				assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
//			}
//		}
	}

	/* Same config than test004  */
	public void test014() throws JavaModelException, CoreException {

		// Set file encoding
		String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
		this.utf8File.setCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getClassFile("Encoding" , "bins", "testUTF8", "Test.class"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		String source = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.utf8Source.getSource());
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, vmEncoding));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
	}

	/* Same config than test005  */
	public void test015() throws JavaModelException, CoreException {

		// Set project encoding
		String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
		this.encodingProject.setDefaultCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getClassFile("Encoding" , "bins", "testUTF8", "Test.class"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		String source = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.utf8Source.getSource());
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, vmEncoding));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
	}

	/* Same config than test006  */
	public void test016() throws JavaModelException, CoreException {

		// Set encoding different than workspace default one
		String encoding = wkspEncoding.equals(vmEncoding) ? ("UTF-8".equals(wkspEncoding) ? "Cp1252" : "UTF-8") : vmEncoding;

		// Get source and compare with file contents
		this.utf8Source = getClassFile("Encoding" , "bins", "testUTF8", "Test.class"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		String source = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.utf8Source.getSource());
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, encoding));
		encodedContents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(encodedContents);
		assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
	}

	/*
	###############################
	#	Tests with jar file and source attached in zip file
	###############################
	/**
	 * Get class file from jar file with an associated source written in UTF-8 charset using no specific encoding for file.
	 * Verification is done by comparing source with file contents read directly with VM encoding...
	 */
	public void test021() throws JavaModelException, CoreException {

		// Get class file and compare source
		IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testUTF8.jar");
		this.utf8Source = root.getPackageFragment("testUTF8").getClassFile("Test.class");
		assertNotNull(this.utf8Source);
		String source = this.utf8Source.getSource();
		assertNotNull(source);
		String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, vmEncoding));
		assertSourceEquals("Encoded UTF-8 source should have been decoded the same way!", source, encodedContents);

		// Cannot compare bytes array without encoding as we're dependent of linux/windows os for new lines delimiter
	}

	/*
	 * Get class file from jar file with an associated source written in UTF-8 charset using specific UTF-8 encoding for project.
	 * Verification is done by comparing source with file contents read directly with UTF-8 encoding...
	 */
	public void test022() throws JavaModelException, CoreException {
		String oldEncoding = this.encodingProject.getDefaultCharset();
		try{
			// Set project encoding
			String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
			this.encodingProject.setDefaultCharset(vmEncoding, null);

			// Get class file and compare source (should not be the same as modify charset on zip file has no effect...)
			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testUTF8.jar");
			this.utf8Source = root.getPackageFragment("testUTF8").getClassFile("Test.class");
			assertNotNull(this.utf8Source);
			String source = this.utf8Source.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, encoding));
			assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
		}
		finally{
			this.encodingProject.setDefaultCharset(oldEncoding, null);
		}
	}

	/*
	 * Get class file from jar file with an associated source written in UTF-8 charset using specific UTF-8 encoding for file.
	 * Verification is done by comparing source with file contents read directly with UTF-8 encoding...
	 */
	public void test023() throws JavaModelException, CoreException {
		IFile zipFile = (IFile) this.encodingProject.findMember("testUTF8.zip"); //$NON-NLS-1$
		try {
			// Set file encoding
			String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
			assertNotNull("Cannot find class file!", zipFile);
			zipFile.setCharset(vmEncoding, null);

			// Get class file and compare source (should not be the same as modify charset on zip file has no effect...)
			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testUTF8.jar");
			this.utf8Source = root.getPackageFragment("testUTF8").getClassFile("Test.class");
			assertNotNull(this.utf8Source);
			String source = this.utf8Source.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(this.utf8File, encoding));
			assertFalse("Sources should not be the same as they were decoded with different encoding!", encodedContents.equals(source));
		}
		finally {
			// Reset zip file encoding
			zipFile.setCharset(null, null);
		}
	}

	/**
	 * Test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55930.
	 * Verify Buffer.save(IProgressMonitor, boolean) method.
	 */
	public void test030() throws JavaModelException, CoreException {
		ICompilationUnit workingCopy = null;
		try {
			String encoding = "UTF-8";
			this.createJavaProject("P", new String[] {""}, "");
			String initialContent = "/**\n"+
				" */\n"+
				"public class Test {}";
			IFile file = this.createFile("P/Test.java", initialContent);
			file.setCharset(encoding, null);
			ICompilationUnit cu = this.getCompilationUnit("P/Test.java");

			// Modif direct the buffer
			String firstModif = "/**\n"+
				" * Caract?res exotiques:\n"+
				" * ?|#|?|?|?|?|?|?|?|?|??\n"+
				" */\n"+
				"public class Test {}";
			cu.getBuffer().setContents(firstModif);
			cu.getBuffer().save(null, true);
			String source = cu.getBuffer().getContents();

			// Compare strings and bytes arrays
			String encodedContents = new String (Util.getResourceContentsAsCharArray(file, encoding));
			assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, source);
			byte[] sourceBytes = source.getBytes(encoding);
			byte[] encodedBytes = Util.getResourceContentsAsByteArray(file);
			assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
			for (int i = 0, max = sourceBytes.length; i < max; i++) {
				assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
			}
		} catch (UnsupportedEncodingException e) {
		} finally {
			stopDeltas();
			if (workingCopy != null) {
				workingCopy.discardWorkingCopy();
			}
			this.deleteProject("P");
		}

	}

	/**
	 * Test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55930.
	 * Verify CommitWorkingCopyOperation.executeOperation() method.
	 */
	public void test031() throws JavaModelException, CoreException {
		ICompilationUnit workingCopy = null;
		try {
			String encoding = "UTF-8";
			this.createJavaProject("P", new String[] {""}, "");
			String initialContent = "/**\n"+
				" */\n"+
				"public class Test {}";
			IFile file = this.createFile("P/Test.java", initialContent);
			file.setCharset(encoding, null);
			ICompilationUnit cu = this.getCompilationUnit("P/Test.java");

			// Modif using working copy
			workingCopy = cu.getWorkingCopy(null);
			String secondModif = "/**\n"+
				" * Caract?res exotiques:\n"+
				" * ?|#|?|?|?|?|?|?|?|?|??\n"+
				" * Autres caract?res exotiques:\n"+
				" * ?|?|?|?|?|?\n"+
				" */\n"+
				"public class Test {}";
			workingCopy.getBuffer().setContents(secondModif);
			workingCopy.commitWorkingCopy(true, null);
			String source = workingCopy.getBuffer().getContents();

			// Compare strings and bytes arrays
			String encodedContents = new String (Util.getResourceContentsAsCharArray(file));
			assertEquals("Encoded UTF-8 source should have been decoded the same way!", encodedContents, source);
			byte[] sourceBytes = source.getBytes(encoding);
			byte[] encodedBytes = Util.getResourceContentsAsByteArray(file);
			assertEquals("Wrong size of encoded string", encodedBytes.length, sourceBytes.length);
			for (int i = 0, max = sourceBytes.length; i < max; i++) {
				assertTrue("Wrong size of encoded character at " + i, sourceBytes[i] == encodedBytes[i]);
			}
		} catch (UnsupportedEncodingException e) {
		} finally {
			stopDeltas();
			if (workingCopy != null) {
				workingCopy.discardWorkingCopy();
			}
			this.deleteProject("P");
		}
	}

	/*
	 * Get compilation unit source on a file written in UTF-8 BOM charset using default charset.
	 * Verify first that source is the same than UTF-8 file contents read using UTF-8 encoding...
	 */
	public void test032() throws JavaModelException, CoreException {

		// Set file encoding
		String encoding = "UTF-8";
		this.utf8File.setCharset(encoding, null);

		// Get source and compare with file contents
		this.utf8Source = getCompilationUnit(this.utf8File.getFullPath().toString());
		String source = this.utf8Source.getSource();

		// Get source and compare with file contents
		IFile bomFile = (IFile) this.encodingProject.findMember("src/testUTF8BOM/Test.java");
		ISourceReference bomSourceRef = getCompilationUnit(bomFile.getFullPath().toString());
		String bomSource = bomSourceRef.getSource();
		assertEquals("BOM UTF-8 source should be idtentical than UTF-8!", source, bomSource);
	}

	/*
	 * Ensures that a file is reindexed when the encoding changes.
	 * (regression test for bug 68585 index is out of date after encoding change)
	 */
	public void test033() throws CoreException {
		try {
			createFolder("/Encoding/src/test68585");
			final String encoding = "UTF-8".equals(wkspEncoding) ? "Cp1252" : "UTF-8";
			getWorkspace().run(new IWorkspaceRunnable() {
				public void run(IProgressMonitor monitor) throws CoreException {
					// use a different encoding to make the file unreadable
					IFile file = null;
					try {
						file = createFile(
							"/Encoding/src/test68585/X.java",
							"package  test68585;\n" +
							"public class X {\n" +
							"}\n" +
							"class Y\u00F4 {}",
							encoding);
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
						return;
					}
					file.setCharset(wkspEncoding, null);
				}
			},
			null);

			IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
			JavaSearchResultCollector resultCollector = new JavaSearchResultCollector();
			search(
				"Y\u00F4",
				IJavaSearchConstants.TYPE,
				IJavaSearchConstants.DECLARATIONS,
				scope,
				resultCollector);
			assertSearchResults("Should not get any result", "", resultCollector);

			// change encoding so that file is readable
			getFile("/Encoding/src/test68585/X.java").setCharset(encoding, null);
			search(
				"Y\u00F4",
				IJavaSearchConstants.TYPE,
				IJavaSearchConstants.DECLARATIONS,
				scope,
				resultCollector);
			assertSearchResults(
				"Should have been reindexed",
				"src/test68585/X.java test68585.Y\u00F4 [Y\u00F4]",
				resultCollector);
		} finally {
			deleteFolder("/Encoding/src/test68585");
		}
	}

	/*
	 * Ensures that an encoding that a file using an encoding producing more charaters than the file size can
	 * be correctly read.
	 * (regression test for bug 149028 Limiting number of characters to read with the file size is invalid.)
	 */
	public void test034() throws CoreException, IOException {
		try {
			// Create file
			IFile file = createFile("/Encoding/Test34.txt", "acegikm");

			// Read file using a transformation where a character is read and the next alphabetical character is
			// automaticaly added
			final InputStream fileStream = file.getContents();
			try {
				InputStream in = new InputStream() {
					int current = -1;
					@Override
					public int read() throws IOException {
						int result;
						if (this.current != -1) {
							result = this.current;
							this.current = -1;
						} else {
							result = fileStream.read();
							if (result == -1)
								return -1;
							this.current = result + 1;
						}
						return result;
					}
				};
				char[] result = org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsCharArray(in,
						org.eclipse.jdt.internal.compiler.util.Util.UTF_8);
				assertSourceEquals(
					"Unexpected source",
					"abcdefghijklmn",
					new String(result)
				);
			} finally {
				fileStream.close();
			}
		} finally {
			deleteFile("Encoding/Test34.txt");
		}
	}

	/**
	 * Bug 66898: refactor-rename: encoding is not preserved
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=66898"
	 */
	public void testBug66898() throws JavaModelException, CoreException {

		// Set file encoding
		String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
		IFile file = (IFile) this.encodingProject.findMember("src/testBug66898/Test.java");
		file.setCharset(encoding, null);
		String fileName = file.getName();
		ICompilationUnit cu = getCompilationUnit(file.getFullPath().toString());
		createFolder("/Encoding/src/tmp");
		IPackageFragment packFrag = getPackageFragment("Encoding", "src", "tmp");

		try {
			waitUntilIndexesReady();

			// Move file
			cu.move(packFrag, null, null, false, null);
			ICompilationUnit destSource = packFrag.getCompilationUnit(fileName);
			IFile destFile = (IFile) destSource.getUnderlyingResource();
			assertEquals("Moved file should keep encoding", encoding, destFile.getCharset());

			// Get source and compare with file contents
			compareContents(destSource, encoding);

			// Rename file
			destSource.rename("TestUTF8.java", false, null);
			ICompilationUnit renamedSource = packFrag.getCompilationUnit("TestUTF8.java");
			IFile renamedFile = (IFile) renamedSource.getUnderlyingResource();
			assertEquals("Moved file should keep encoding", encoding, renamedFile.getCharset());

			// Compare contents again
			compareContents(renamedSource, encoding);
		}
		finally {
			// Delete temporary folder
			//renamedFile.move(this.utf8File.getFullPath(), false, null);
			//assertEquals("Moved file should keep encoding", encoding, this.utf8File.getCharset());
			deleteFolder("/Encoding/src/tmp");
		}
	}
	public void testBug66898b() throws JavaModelException, CoreException {

		// Set file encoding
		final String encoding = "UTF-8".equals(vmEncoding) ? "Cp1252" : "UTF-8";
		final IFile file = (IFile) this.encodingProject.findMember("src/testBug66898b/Test.java");
		file.setCharset(encoding, null);
		final String fileName = file.getName();
		final IPackageFragment srcFolder = getPackageFragment("Encoding", "src", "testBug66898b");
		createFolder("/Encoding/src/tmp");
		final IPackageFragment tmpFolder = getPackageFragment("Encoding", "src", "tmp");

		try {
			// Copy file
			IWorkspaceRunnable copy = new IWorkspaceRunnable() {
				public void run(IProgressMonitor monitor) throws CoreException {
					ICompilationUnit cu = getCompilationUnit(file.getFullPath().toString());
					cu.copy(tmpFolder, null, null, true, null);
					cu.close(); // purge buffer contents from cache
					ICompilationUnit dest = tmpFolder.getCompilationUnit(fileName);
					IFile destFile = (IFile) dest.getUnderlyingResource();
					assertEquals("Copied file should keep encoding", encoding, destFile.getCharset());

					// Get source and compare with file contents
					compareContents(dest, encoding);
				}
			};
			JavaCore.run(copy, null);

			// Rename file
			IWorkspaceRunnable rename = new IWorkspaceRunnable() {
				public void run(IProgressMonitor monitor) throws CoreException {
					ICompilationUnit cu = tmpFolder.getCompilationUnit(fileName);
					cu.rename("Renamed.java", true, null);
					cu.close(); // purge buffer contents from cache
					ICompilationUnit ren = tmpFolder.getCompilationUnit("Renamed.java");
					IFile renFile = (IFile) ren.getUnderlyingResource();
					assertEquals("Renamed file should keep encoding", encoding, renFile.getCharset());

					// Get source and compare with file contents
					compareContents(ren, encoding);
				}
			};
			JavaCore.run(rename, null);

			// Move file
			IWorkspaceRunnable move = new IWorkspaceRunnable() {
				public void run(IProgressMonitor monitor) throws CoreException {
					ICompilationUnit cu = tmpFolder.getCompilationUnit("Renamed.java");
					cu.move(srcFolder, null, null, true, null);
					cu.close(); // purge buffer contents from cache
					ICompilationUnit moved = srcFolder.getCompilationUnit("Renamed.java");
					IFile movedFile = (IFile) moved.getUnderlyingResource();
					assertEquals("Renamed file should keep encoding", encoding, movedFile.getCharset());

					// Get source and compare with file contents
					compareContents(moved, encoding);
				}
			};
			JavaCore.run(move, null);
		}
		finally {
			// Delete temporary file and folder
			ICompilationUnit cu = srcFolder.getCompilationUnit("Renamed.java");
			if (cu.exists()) cu.delete(true, null);
			deleteFolder("/Encoding/src/tmp");
		}
	}

	/**
	 * Bug 70598: [Encoding] ArrayIndexOutOfBoundsException while testing BOM on *.txt files
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=70598"
	 */
	public void testBug70598() throws JavaModelException, CoreException, IOException {

		// Create empty file
		IFile emptyFile = createFile("/Encoding/src/testUTF8BOM/Empty.java", new byte[0]);

		// Test read empty content using io file
		File file = new File(this.encodingProject.getLocation().toString(), emptyFile.getProjectRelativePath().toString());
		char[] fileContents = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(file, "UTF-8");
		assertEquals("We should not get any character!", "", new String(fileContents));

		// Test read empty content using io file
		char[] ifileContents =Util.getResourceContentsAsCharArray(emptyFile, "UTF-8");
		assertEquals("We should not get any character!", "", new String(ifileContents));

		// Delete empty file
		deleteResource(file);
	}

	/**
	 * Bug 110576: [encoding] Rename CU looses encoding for file which charset is determined by contents
	 * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=110576"
	 */
	public void testBug110576() throws JavaModelException, CoreException {

		String os = System.getProperty("osgi.os");
		if (!"win32".equals(os)) {
			System.out.println("Bug 110576 is not tested under "+os+" os...");
			return;
		}

		// Verify file UTF-8 BOM encoding
		IFile file = (IFile) this.encodingProject.findMember("src/testBug110576/Test.java");
		verifyUtf8BOM(file);

		String fileName = file.getName();
		ICompilationUnit testCU = getCompilationUnit(file.getFullPath().toString());
		createFolder("/Encoding/src/tmp");
		IPackageFragment tmpPackage = getPackageFragment("Encoding", "src", "tmp");

		try {
			// Copy file
			testCU.copy(tmpPackage, null, null, false, null);
			ICompilationUnit copiedCU = tmpPackage.getCompilationUnit(fileName);
			IFile copiedFile = (IFile) copiedCU.getUnderlyingResource();
			verifyUtf8BOM(copiedFile);

			// Get source and compare with file contents
			compareContents(copiedCU, "UTF-8", true/*BOM*/);

			// Rename file
			copiedCU.rename("TestUTF8.java", false, null);
			ICompilationUnit renamedCU = tmpPackage.getCompilationUnit("TestUTF8.java");
			IFile renamedFile = (IFile) renamedCU.getUnderlyingResource();
			verifyUtf8BOM(renamedFile);
			fileName = renamedFile.getName();

			// Compare contents again
			compareContents(renamedCU, "UTF-8", true/*BOM*/);

			// Move file
			createFolder("/Encoding/src/tmp/sub");
			IPackageFragment subPackage = getPackageFragment("Encoding", "src", "tmp.sub");
			renamedCU.move(subPackage, null, null, false, null);
			ICompilationUnit movedCU = subPackage.getCompilationUnit(fileName);
			IFile movedFile = (IFile) movedCU.getUnderlyingResource();
			verifyUtf8BOM(movedFile);

			// Get source and compare with file contents
			compareContents(movedCU, "UTF-8", true/*BOM*/);
		}
		finally {
			// Delete temporary folder
			//renamedFile.move(this.utf8File.getFullPath(), false, null);
			//assertEquals("Moved file should keep encoding", encoding, this.utf8File.getCharset());
			deleteFolder("/Encoding/src/tmp");
		}
	}

	/**
	 * Bug 255501: EncodingTests failing when run by itself
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=255501"
	 */
	public void testBug255501() throws Exception {
		String savedEncoding = null;
		String resourcesPluginId = ResourcesPlugin.getPlugin().getBundle().getSymbolicName();
		IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(resourcesPluginId);
		try {
			savedEncoding = preferences.get(ResourcesPlugin.PREF_ENCODING, "");
			JavaCore.getOptions(); // force options to be cached
			preferences.put(ResourcesPlugin.PREF_ENCODING, "UTF-16");
			preferences.flush();
			String encoding = JavaCore.getOptions().get(JavaCore.CORE_ENCODING);
			assertEquals("Unexpected encoding", "UTF-16", encoding);
		} finally {
			preferences.put(ResourcesPlugin.PREF_ENCODING, savedEncoding);
			preferences.flush();
		}
	}

	/**
	 * Bug 303511: Allow to specify encoding for source attachments
	 * Test whether the source mapper picks the right encoding for the source attachment as a ZIP in workspace.
	 * The encoding could be explicitly set in the absence of which the inherited value from the project
	 * is taken.
	 *
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511"
	 */
	public void testBug303511() throws JavaModelException, CoreException {

		try {
			// Set file encoding
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");

			assertNotNull("Cannot find class file!", zipFile);
			zipFile.setCharset(encoding, null);

			// Get class file and compare source (should not be the same as modify charset on zip file has no effect...)
			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			char[] charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			// Reset zip file encoding
			zipFile.setCharset(null, null);
			String oldEncoding = this.encodingProject.getDefaultCharset();
			this.encodingProject.setDefaultCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			this.encodingProject.setDefaultCharset(null, null);

			root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertFalse("Sources should be decoded the same way", encodedContents.equals(source));

			// Reset zip file encoding
			zipFile.setCharset(null, null);
			this.encodingProject.setDefaultCharset(oldEncoding, null);
		}
		finally {
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}

	/**
	 * Bug 303511: Allow to specify encoding for source attachments
	 * Test whether the source mapper picks the right encoding for an external source attachment
	 * The attachment could be an external folder or external archive and have the encoding
	 * explicitly set. In the absence of encoding for the source attachment resource, the default
	 * encoding from the workspace is applied.
	 *
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511"
	 */
	public void testBug303511a() throws JavaModelException, CoreException {
		try {
			// Set file encoding
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			String externalPath = this.encodingProject.getLocation().toOSString() + File.separator + "testShiftJIS.zip";
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");
			getWorkspaceRoot().setDefaultCharset(encoding, null);

			IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
			IClasspathEntry oldEntry = null;
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					oldEntry = entry;
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(entry.getPath(), new Path(externalPath), null);
					entries[index] = newEntry;
				}
			}
			this.encodingJavaProject.setRawClasspath(entries, null);
			this.encodingJavaProject.getResolvedClasspath(true);

			// Get class file and compare source (should not be the same as modify charset on zip file has no effect...)
			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			char[] charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			entries = this.encodingJavaProject.getRawClasspath();
			String sourcePath = this.encodingProject.getLocation().toOSString() + File.separator + "src";
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(entry.getPath(), new Path(sourcePath), null);
					entries[index] = newEntry;
				}
			}
			this.encodingJavaProject.setRawClasspath(entries, null);
			this.encodingJavaProject.getResolvedClasspath(true);

			entries = this.encodingJavaProject.getRawClasspath();
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					entries[index] = oldEntry;
				}
			}
			this.encodingJavaProject.setRawClasspath(entries, null);
			this.encodingJavaProject.getResolvedClasspath(true);
		}
		finally {
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}

	/**
	 * Bug 303511: Allow to specify encoding for source attachments
	 * Test that, for a source attachment in form of archives from another project (in the same workspace), the
	 * encoding of the archive (IResource), if set, is used. In the absence of explicit encoding, the encoding
	 * of the project that contains this archive is used.
	 *
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511"
	 */
	public void testBug303511b() throws Exception{
		try{
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, "");
			String oldEncoding = this.encodingProject.getDefaultCharset();
			IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");
			assertNotNull("Cannot find class file!", zipFile);

			zipFile.setCharset(encoding, null);

			IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
			IClasspathEntry newEntry = null;
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					newEntry = entries[index];
				}
			}
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null)}, null);

			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			char[] charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			zipFile.setCharset(null, null);
			this.encodingProject.setDefaultCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			this.encodingProject.setDefaultCharset(oldEncoding, null);
		}
		finally {
			deleteProject("Encoding2");
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}
	/**
	 * Bug 303511: Allow to specify encoding for source attachments
	 * Test that, for a source attachment in form of folder from another project (in the same workspace), the
	 * encoding of the folder (IResource), if set, is used. In the absence of explicit encoding, the encoding
	 * of the project which contains this folder is used.
	 *
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511"
	 */
	public void testBug303511c() throws Exception{
		try{
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, "");
			String oldEncoding = this.encodingProject.getDefaultCharset();
			IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");
			assertNotNull("Cannot find class file!", zipFile);

			IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
			IClasspathEntry newEntry = null;
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					newEntry = entries[index];
				}
			}

			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null)}, null);
			this.encodingProject.setDefaultCharset(encoding, null);
			sourceFile.setCharset(null, null);

			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			char[] charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			this.encodingProject.setDefaultCharset(oldEncoding, null);
			sourceFile.setCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			sourceFile.setCharset(null, null);
		}
		finally {
			deleteProject("Encoding2");
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}
	public void testBug361356() throws Exception {
		String oldEncoding = this.encodingProject.getDefaultCharset();
		try{
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			this.encodingProject.setDefaultCharset("UTF-8", null);
			IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, "");
			IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");

			IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
			IClasspathEntry newEntry = null;
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					newEntry = entries[index];
				}
			}

			IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			sourceFile.setCharset(null, null);

			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			char[] charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8");
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			sourceFile.setCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			zipFile.setCharset(null, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8");
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			zipFile.setCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

		}
		finally {
			this.encodingProject.setDefaultCharset(oldEncoding, null);
			deleteProject("Encoding2");
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}
	public void testBug361356a() throws Exception {
		String oldEncoding = this.encodingProject.getDefaultCharset();
		try{
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			this.encodingProject.setDefaultCharset("UTF-8", null);
			IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, "");
			IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");

			IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
			IClasspathEntry newEntry = null;
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					newEntry = entries[index];
				}
			}

			IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			zipFile.setCharset(null, null);

			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			char[] charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8");
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			zipFile.setCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));
		}
		finally {
			this.encodingProject.setDefaultCharset(oldEncoding, null);
			deleteProject("Encoding2");
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}
	public void testBug361356b() throws Exception {
		String oldEncoding = this.encodingProject.getDefaultCharset();
		File externalSourceZip = null;
		File externalSource = null;
		try{
			String encoding = "Shift-JIS";
			if (wkspEncoding.equals(encoding))
				getWorkspaceRoot().setDefaultCharset("UTF-8", null);
			this.encodingProject.setDefaultCharset("UTF-8", null);
			IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, "");
			IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java");

			File internalSourceZip = new File(getWorkspacePath(), "/Encoding/testShiftJIS.zip");
			externalSourceZip = new File(getExternalPath(), "testShiftJIS.zip");
			File internalSource = new File(getWorkspacePath(), "/Encoding/src");
			externalSource = new File(getExternalPath(), "testShiftJIS");

			copyDirectory(internalSource, externalSource);
			copy(internalSourceZip, externalSourceZip);

			IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath();
			IClasspathEntry newEntry = null;
			for (int index = 0; index < entries.length; index++) {
				IClasspathEntry entry = entries[index];
				if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) {
					newEntry = entries[index];
				}
			}

			IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS.zip")), null, null, new IClasspathAttribute[]{attribute}, false)}, null);

			IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			String source = sourceRef.getSource();
			assertNotNull(source);
			String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			char[] charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8");
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS.zip")), null, null, new IClasspathAttribute[]{attribute}, false)}, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertFalse("Sources should not be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding);
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS")), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			sourceFile.setCharset(null, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertTrue("Sources should be decoded the same way", encodedContents.equals(source));

			attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8");
			project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS")), null, null, new IClasspathAttribute[]{attribute}, false)}, null);
			sourceFile.setCharset(encoding, null);

			root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar");
			sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class");
			assertNotNull(sourceRef);
			source = sourceRef.getSource();
			assertNotNull(source);
			encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding));
			charArray = encodedContents.toCharArray();
			encodedContents = new String(CharOperation.remove(charArray, '\r'));
			charArray = source.toCharArray();
			source = new String(CharOperation.remove(charArray, '\r'));
			assertFalse("Sources should not be decoded the same way", encodedContents.equals(source));
		}
		finally {
			if (externalSourceZip != null) externalSourceZip.delete();
			if (externalSource != null) deleteExternalResource("testShiftJIS");
			this.encodingProject.setDefaultCharset(oldEncoding, null);
			deleteProject("Encoding2");
			getWorkspaceRoot().setDefaultCharset(wkspEncoding, null);
		}
	}
	private void verifyUtf8BOM(IFile file) throws CoreException {
		assertNull("File should not have any explicit charset", file.getCharset(false));
		IContentDescription contentDescription = file.getContentDescription();
		assertNotNull("File should have a content description", contentDescription);
		assertEquals("Content description charset should be UTF-8", "UTF-8", contentDescription.getCharset());
		assertNotNull("File should be UTF-8 BOM!", contentDescription.getProperty(IContentDescription.BYTE_ORDER_MARK));
	}
}
