/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     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 };
	}

	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");
	}

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

	/*
	 *  (non-Javadoc)
	 * Reset UTF-8 file and project charset to default.
	 * @see junit.framework.TestCase#tearDown()
	 */
	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]);
		}
	}

	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;
					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, (int) file.getLocation().toFile().length(), "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));
	}
}
