/*******************************************************************************
 * 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
 *     Thirumala Reddy Mutchukota <thirumala@google.com> - Contribution to bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=411423
 *     Terry Parker <tparker@google.com> - [performance] Low hit rates in JavaModel caches - https://bugs.eclipse.org/421165
 *     Vladimir Piskarev <pisv@1c.ru> - Building large Java element deltas is really slow - https://bugs.eclipse.org/443928
 *******************************************************************************/
package org.eclipse.jdt.core.tests.performance;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;

import junit.framework.Test;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IInitializer;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IProblemRequestor;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
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.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests;
import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests.ProblemRequestor;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.IJavaElementRequestor;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.NameLookup;
import org.eclipse.test.performance.Performance;

/**
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class FullSourceWorkspaceModelTests extends FullSourceWorkspaceTests implements IJavaSearchConstants {

	// Tests counters
	static int TESTS_COUNT = 0;
	private final static int WARMUP_COUNT = 50;
	private final static int FOLDERS_COUNT = 200;
	private final static int PACKAGES_COUNT = 200;
	static int TESTS_LENGTH;

	/**
	 * Internal synonym for deprecated constant AST.JSL3
	 * to alleviate deprecation warnings.
	 * @deprecated
	 */
	/*package*/ static final int JLS3_INTERNAL = AST.JLS3;
	
	// Log file streams
	private static PrintStream[] LOG_STREAMS = new PrintStream[DIM_NAMES.length];

	// Type path
	static IPath BIG_PROJECT_TYPE_PATH;
	static ICompilationUnit WORKING_COPY;

/**
 * @param name
 */
public FullSourceWorkspaceModelTests(String name) {
	super(name);
}

static {
//	TESTS_NAMES = new String[] {
//		"testPerfNameLookupFindKnownSecondaryType",
//		"testPerfNameLookupFindUnknownType",
//		"testPerfReconcile",
//		"testPerfSearchAllTypeNamesAndReconcile",
//	};

//	TESTS_PREFIX = "testPerfReconcile";
}
public static Test suite() {
	Test suite = buildSuite(testClass());
	TESTS_LENGTH = TESTS_COUNT = suite.countTestCases();
	createPrintStream(testClass(), LOG_STREAMS, TESTS_COUNT, null);
	return suite;
}

private static Class testClass() {
	return FullSourceWorkspaceModelTests.class;
}

protected void setUp() throws Exception {
	super.setUp();
	setUpBigProject();
	setUpBigJars();
}
private void setUpBigProject() throws CoreException, IOException {
	try {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRoot workspaceRoot = workspace.getRoot();
		String targetWorkspacePath = workspaceRoot.getLocation().toFile().getCanonicalPath();
		long start = System.currentTimeMillis();

		// Print for log in case of project creation troubles...
		File wkspDir = new File(targetWorkspacePath);
		File projectDir = new File(wkspDir, BIG_PROJECT_NAME);
		if (projectDir.exists()) {
			System.out.print("Add existing project "+BIG_PROJECT_NAME+" in "+workspaceRoot.getLocation()+" to workspace...");
			IProject bigProject = workspaceRoot.getProject(BIG_PROJECT_NAME);
			if (bigProject.exists()) {
				ENV.addProject(bigProject);
			} else {
				ENV.addProject(BIG_PROJECT_NAME);
			}
			BIG_PROJECT = (JavaProject) ENV.getJavaProject(BIG_PROJECT_NAME);
			BIG_PROJECT.setRawClasspath(BIG_PROJECT.getRawClasspath(), null);
		} else {
			System.out.println("Create project "+BIG_PROJECT_NAME+" in "+workspaceRoot.getLocation()+":");

			// setup projects with several source folders and several packages per source folder
			System.out.println("	- create "+FOLDERS_COUNT+" folders x "+PACKAGES_COUNT+" packages...");
			final String[] sourceFolders = new String[FOLDERS_COUNT];
			for (int i = 0; i < FOLDERS_COUNT; i++) {
				sourceFolders[i] = "src" + i;
			}
			String path = workspaceRoot.getLocation().toString() + "/BigProject/src";
			for (int i = 0; i < FOLDERS_COUNT; i++) {
				if (PRINT && i>0 && i%10==0) System.out.print("		+ folder src"+i+"...");
				long top = System.currentTimeMillis();
				for (int j = 0; j < PACKAGES_COUNT; j++) {
					new java.io.File(path + i + "/org/eclipse/jdt/core/tests" + i + "/performance" + j).mkdirs();
				}
				if (PRINT && i>0 && i%10==0) System.out.println("("+(System.currentTimeMillis()-top)+"ms)");
			}
			System.out.println("		=> global time = "+(System.currentTimeMillis()-start)/1000.0+" seconds)");

			// Add project to workspace
			start = System.currentTimeMillis();
			System.out.print("	- add project to full source workspace...");
			ENV.addProject(BIG_PROJECT_NAME);
			BIG_PROJECT = (JavaProject) createJavaProject(BIG_PROJECT_NAME, sourceFolders, "bin", "1.4");
			BIG_PROJECT.setRawClasspath(BIG_PROJECT.getRawClasspath(), null);
		}
		System.out.println("("+(System.currentTimeMillis()-start)+"ms)");

		// Add CU with secondary type
		System.out.print("	- Create compilation unit with secondary type...");
		start = System.currentTimeMillis();
		BIG_PROJECT_TYPE_PATH = new Path("/BigProject/src" + (FOLDERS_COUNT-1) + "/org/eclipse/jdt/core/tests" + (FOLDERS_COUNT-1) + "/performance" + (PACKAGES_COUNT-1) + "/TestBigProject.java");
		IFile file = workspaceRoot.getFile(BIG_PROJECT_TYPE_PATH);
		if (!file.exists()) {
			String content = "package org.eclipse.jdt.core.tests" + (FOLDERS_COUNT-1) + ".performance" + (PACKAGES_COUNT-1) + ";\n" +
				"public class TestBigProject {\n" +
				"	class Level1 {\n" +
				"		class Level2 {\n" +
				"			class Level3 {\n" +
				"				class Level4 {\n" +
				"					class Level5 {\n" +
				"						class Level6 {\n" +
				"							class Level7 {\n" +
				"								class Level8 {\n" +
				"									class Level9 {\n" +
				"										class Level10 {}\n" +
				"									}\n" +
				"								}\n" +
				"							}\n" +
				"						}\n" +
				"					}\n" +
				"				}\n" +
				"			}\n" +
				"		}\n" +
				"	}\n" +
				"}\n" +
				"class TestSecondary {}\n";
			file.create(new ByteArrayInputStream(content.getBytes()), true, null);
		}
		WORKING_COPY = (ICompilationUnit)JavaCore.create(file);
		System.out.println("("+(System.currentTimeMillis()-start)+"ms)");
	} finally {
		// do not delete project
	}

}
private void setUpBigJars() throws Exception {
	String bigProjectLocation = BIG_PROJECT.getResource().getLocation().toOSString();
	int size = PACKAGES_COUNT * 10;
	File bigJar1 = new File(bigProjectLocation, BIG_JAR1_NAME);
	if (!bigJar1.exists()) {
		String[] pathAndContents = new String[size * 2];
		for (int i = 0; i < size; i++) {
			pathAndContents[i*2] = "/p" + i + "/X" + i + ".java";
			pathAndContents[i*2 + 1] =
				"package p" + i + ";\n" +
				"public class X" + i + "{\n" +
				"}";
		}
		org.eclipse.jdt.core.tests.util.Util.createJar(pathAndContents, bigJar1.getPath(), "1.3");
		BIG_PROJECT.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
	}
	File bigJar2 = new File(bigProjectLocation, BIG_JAR2_NAME);
	if (!bigJar2.exists()) {
		String[] pathAndContents = new String[size * 2];
		for (int i = 0; i < size; i++) {
			pathAndContents[i*2] = "/q" + i + "/Y" + i + ".java";
			pathAndContents[i*2 + 1] =
				"package q" + i + ";\n" +
				"public class Y" + i + "{\n" +
				"}";
		}
		org.eclipse.jdt.core.tests.util.Util.createJar(pathAndContents, bigJar2.getPath(), "1.3");
		BIG_PROJECT.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
	}
}
/* (non-Javadoc)
 * @see junit.framework.TestCase#tearDown()
 */
protected void tearDown() throws Exception {

	// End of execution => one test less
	TESTS_COUNT--;

	// Log perf result
	if (LOG_DIR != null) {
		logPerfResult(LOG_STREAMS, TESTS_COUNT);
	}

	// Print statistics
	if (TESTS_COUNT == 0) {
		System.out.println("-------------------------------------");
		System.out.println("Model performance test statistics:");
//		NumberFormat intFormat = NumberFormat.getIntegerInstance();
		System.out.println("-------------------------------------\n");
	}
	super.tearDown();
}
/**
 * Simple search result collector: only count matches.
 */
class JavaSearchResultCollector extends SearchRequestor {
	int count = 0;
	public void acceptSearchMatch(SearchMatch match) throws CoreException {
		this.count++;
	}
}

/*
protected void search(String patternString, int searchFor, int limitTo) throws CoreException {
	int matchMode = patternString.indexOf('*') != -1 || patternString.indexOf('?') != -1
		? SearchPattern.R_PATTERN_MATCH
		: SearchPattern.R_EXACT_MATCH;
	SearchPattern pattern = SearchPattern.createPattern(
		patternString,
		searchFor,
		limitTo,
		matchMode | SearchPattern.R_CASE_SENSITIVE);
	this.resultCollector = new JavaSearchResultCollector();
	new SearchEngine().search(
		pattern,
		new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
		this.scope,
		this.resultCollector,
		null);
}
*/

protected void searchAllTypeNames(IJavaSearchScope scope) throws CoreException {
	class TypeNameCounter extends TypeNameRequestor {
		int count = 0;
		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
			this.count++;
		}
	}
	TypeNameCounter requestor = new TypeNameCounter();
	new SearchEngine().searchAllTypeNames(
		null,
		SearchPattern.R_EXACT_MATCH,
		null,
		SearchPattern.R_PREFIX_MATCH, // not case sensitive
		IJavaSearchConstants.TYPE,
		scope,
		requestor,
		WAIT_UNTIL_READY_TO_SEARCH,
		null);
	assertTrue("We should have found at least one type!", requestor.count>0);
}

/**
 * @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#assertElementEquals(String, String, IJavaElement)
 */
protected void assertElementEquals(String message, String expected, IJavaElement element) {
	String actual = element == null ? "<null>" : ((JavaElement) element).toStringWithAncestors(false/*don't show key*/);
	if (!expected.equals(actual)) {
		System.out.println(getName()+" actual result is:");
		System.out.println(actual + ',');
	}
	assertEquals(message, expected, actual);
}
/**
 * @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#assertElementsEqual(String, String, IJavaElement[])
 */
protected void assertElementsEqual(String message, String expected, IJavaElement[] elements) {
	assertElementsEqual(message, expected, elements, false/*don't show key*/);
}
/**
 * @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#assertElementsEqual(String, String, IJavaElement[], boolean)
 */
protected void assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo) {
	StringBuffer buffer = new StringBuffer();
	if (elements != null) {
		for (int i = 0, length = elements.length; i < length; i++){
			JavaElement element = (JavaElement)elements[i];
			if (element == null) {
				buffer.append("<null>");
			} else {
				buffer.append(element.toStringWithAncestors(showResolvedInfo));
			}
			if (i != length-1) buffer.append("\n");
		}
	} else {
		buffer.append("<null>");
	}
	String actual = buffer.toString();
	if (!expected.equals(actual)) {
		System.out.println(getName()+" actual result is:");
		System.out.println(actual + ',');
	}
	assertEquals(message, expected, actual);
}
private void touchFiles(File[] files) {
	for(int index=0; index < files.length; index++) {
		files[index].setLastModified(System.currentTimeMillis());
	}
}
/*
 * Creates a simple Java project with no source folder and only rt.jar on its classpath.
 */
private IJavaProject createJavaProject(String name) throws CoreException {
	IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
	if (project.exists())
		project.delete(true, null);
	project.create(null);
	project.open(null);
	IProjectDescription description = project.getDescription();
	description.setNatureIds(new String[] {JavaCore.NATURE_ID});
	project.setDescription(description, null);
	IJavaProject javaProject = JavaCore.create(project);
	javaProject.setRawClasspath(new IClasspathEntry[] {JavaCore.newVariableEntry(new Path("JRE_LIB"), null, null)}, null);
	return javaProject;
}

private NameLookup getNameLookup(JavaProject project) throws JavaModelException {
	return project.newNameLookup((WorkingCopyOwner)null);
}

/**
 * Performance tests for model: Find known type in name lookup.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testNameLookupFindKnownType() throws CoreException {

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.');
	for (int i=0; i<WARMUP_COUNT; i++) {
		NameLookup nameLookup = BIG_PROJECT.newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
		IType type = nameLookup.findType(fullQualifiedName, false /*full match*/, NameLookup.ACCEPT_ALL);
		if (i==0) assertNotNull("We should find type '"+fullQualifiedName+"' in project "+BIG_PROJECT_NAME, type);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<50000; n++) {
			NameLookup nameLookup = BIG_PROJECT.newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
			nameLookup.findType(fullQualifiedName, false /*full match*/, NameLookup.ACCEPT_ALL);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Performance tests for model: Find known secondary type in name lookup.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testNameLookupFindKnownSecondaryType() throws CoreException {

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).removeLastSegments(1).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.')+".TestSecondary";
	for (int i=0; i<WARMUP_COUNT; i++) {
		NameLookup nameLookup = BIG_PROJECT.newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
		IType type = nameLookup.findType(fullQualifiedName, false /*full match*/, NameLookup.ACCEPT_ALL);
		if (i==0 && LOG_VERSION.compareTo("v_623") > 0) {
			assertNotNull("We should find type '"+fullQualifiedName+"' in project "+BIG_PROJECT_NAME, type);
		}
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<50000; n++) {
			NameLookup nameLookup = BIG_PROJECT.newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
			nameLookup.findType(fullQualifiedName, false /*full match*/, NameLookup.ACCEPT_ALL);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Performance tests for model: Find Unknown type in name lookup.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testNameLookupFindUnknownType() throws CoreException {

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).removeLastSegments(1).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.')+".Unknown";
	for (int i=0; i<WARMUP_COUNT; i++) {
		NameLookup nameLookup = BIG_PROJECT.newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
		IType type = nameLookup.findType(fullQualifiedName, false /*full match*/, NameLookup.ACCEPT_ALL);
		if (i==0) assertNull("We should not find an unknown type in project "+BIG_PROJECT_NAME, type);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<50000; n++) {
			NameLookup nameLookup = BIG_PROJECT.newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
			nameLookup.findType(fullQualifiedName, false /*full match*/, NameLookup.ACCEPT_ALL);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Performance tests for model: Find known type.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testProjectFindKnownType() throws CoreException {
	tagAsSummary("Find known type in project", false); // do NOT put in fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.');
	for (int i=0; i<WARMUP_COUNT; i++) {
		IType type = BIG_PROJECT.findType(fullQualifiedName);
		if (i==0) assertNotNull("We should find type '"+fullQualifiedName+"' in project "+BIG_PROJECT_NAME, type);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<50000; n++) {
			BIG_PROJECT.findType(fullQualifiedName);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Performance tests for model: Find known member type.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testProjectFindKnownMemberType() throws CoreException {
	tagAsSummary("Find known member type in project", false); // do NOT put in fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.');
	for (int i=1; i<=10; i++) {
		fullQualifiedName += ".Level" + i;
	}
	for (int i=0; i<WARMUP_COUNT; i++) {
		IType type = BIG_PROJECT.findType(fullQualifiedName);
		if (i==0) assertNotNull("We should find type '"+fullQualifiedName+"' in project "+BIG_PROJECT_NAME, type);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<4000; n++) {
			BIG_PROJECT.findType(fullQualifiedName);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Performance tests for model: Find known secondary type.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testProjectFindKnownSecondaryType() throws CoreException {
	tagAsSummary("Find known secondary type in project", false); // do NOT put in fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).removeLastSegments(1).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.')+".TestSecondary";
	for (int i=0; i<WARMUP_COUNT; i++) {
		BIG_PROJECT.findType(fullQualifiedName);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<1000; n++) {
			BIG_PROJECT.findType(fullQualifiedName);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Performance tests for model: Find Unknown type.
 *
 * First wait that already started indexing jobs end before perform test.
 * Perform one find before measure performance for warm-up.
 */
public void testProjectFindUnknownType() throws CoreException {
	tagAsSummary("Find unknown type in project", false); // do NOT put in fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).removeLastSegments(1).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.')+".Unknown";
	for (int i=0; i<WARMUP_COUNT; i++) {
		IType type = BIG_PROJECT.findType(fullQualifiedName);
		assertNull("We should not find an unknown type in project "+BIG_PROJECT_NAME, type);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<2000; n++) {
			BIG_PROJECT.findType(fullQualifiedName);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/*
 * Performance tests for model: Find Unknown type after resetting the classpath
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=217059 )
 *
 */
public void testProjectFindUnknownTypeAfterSetClasspath() throws CoreException {
	tagAsSummary("Find unknown type in project after resetting classpath", false); // do NOT put in fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// First findType populates the package fragment roots in the Java model cache
	String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).removeLastSegments(1).toString();
	fullQualifiedName = fullQualifiedName.replace('/', '.')+".Unknown";
	IType type = BIG_PROJECT.findType(fullQualifiedName);
	assertNull("We should not find an unknown type in project "+BIG_PROJECT_NAME, type);

	// Reset classpath
	BIG_PROJECT.setRawClasspath(BIG_PROJECT.getRawClasspath(), null);

	// Warm up
	for (int i=0; i<WARMUP_COUNT; i++) {
		BIG_PROJECT.findType(fullQualifiedName);
	}

	// Measures
	resetCounters();
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int n=0; n<2000; n++) {
			BIG_PROJECT.findType(fullQualifiedName);
		}
		stopMeasuring();
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/**
 * Ensures that the reconciler does nothing when the source
 * to reconcile with is the same as the current contents.
 */
public void testPerfReconcile() throws CoreException {
	tagAsGlobalSummary("Reconcile editor change", true); // put in global fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	ICompilationUnit workingCopy = null;
	try {
		final ProblemRequestor requestor = new ProblemRequestor();
		WorkingCopyOwner owner = new WorkingCopyOwner() {
			public IProblemRequestor getProblemRequestor(ICompilationUnit cu) {
				return requestor;
            }
		};
		workingCopy = PARSER_WORKING_COPY.getWorkingCopy(owner, null);
		int warmup = WARMUP_COUNT / 5;
		for (int i=0; i<warmup; i++) {
			CompilationUnit unit = workingCopy.reconcile(JLS3_INTERNAL, true, null, null);
			assertNotNull("Compilation Unit should not be null!", unit);
			assertNotNull("Bindings were not resolved!", unit.getPackage().resolveBinding());
		}

		// Measures
		resetCounters();
		int iterations = 2;
		for (int i=0; i<MEASURES_COUNT; i++) {
			runGc();
			startMeasuring();
			for (int n=0; n<iterations; n++) {
				workingCopy.reconcile(JLS3_INTERNAL, true, null, null);
			}
			stopMeasuring();
		}
	}
	finally {
		workingCopy.discardWorkingCopy();
	}

	// Commit
	commitMeasurements();
	assertPerformance();

}

/*
 * Ensures that the performance of reconcile on a big CU when there are syntax errors is acceptable.
 * (regression test for bug 135083 RangeUtil#isInInterval(...) takes significant amount of time while editing)
 */
public void testPerfReconcileBigFileWithSyntaxError() throws JavaModelException {
	tagAsSummary("Reconcile editor change on big file with syntax error", false); // do NOT put in fingerprint

	// build big file contents
	String method =
		"() {\n" +
		"  bar(\n" +
		"    \"public class X <E extends Exception> {\\n\" + \r\n" +
		"	 \"    void foo(E e) throws E {\\n\" + \r\n" +
		"	 \"        throw e;\\n\" + \r\n" +
		"	 \"    }\\n\" + \r\n" +
		"	 \"    void bar(E e) {\\n\" + \r\n" +
		"	 \"        try {\\n\" + \r\n" +
		"	 \"            foo(e);\\n\" + \r\n" +
		"	 \"        } catch(Exception ex) {\\n\" + \r\n" +
		"	 \"	        System.out.println(\\\"SUCCESS\\\");\\n\" + \r\n" +
		"	 \"        }\\n\" + \r\n" +
		"	 \"    }\\n\" + \r\n" +
		"	 \"    public static void main(String[] args) {\\n\" + \r\n" +
		"	 \"        new X<Exception>().bar(new Exception());\\n\" + \r\n" +
		"	 \"    }\\n\" + \r\n" +
		"	 \"}\\n\"" +
		"  );\n" +
		"}\n";
	StringBuffer bigContents = new StringBuffer();
	bigContents.append("public class BigCU {\n");
	int fooIndex = 0;
	while (fooIndex < 2000) { // add 2000 methods (so that source is close to 1MB)
		bigContents.append("public void foo");
		bigContents.append(fooIndex++);
		bigContents.append(method);
	}
	// don't add closing } for class def so as to have a syntax error

	ICompilationUnit workingCopy = null;
	try {
		// Setup
		workingCopy = (ICompilationUnit) JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/BigProject/src/org/eclipse/jdt/core/tests/BigCu.java")));
		workingCopy.becomeWorkingCopy(null);

		// Warm up
		int warmup = WARMUP_COUNT / 10;
		for (int i=0; i<warmup; i++) {
			workingCopy.getBuffer().setContents(bigContents.append("a").toString());
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
		}

		// Measures
		resetCounters();
		for (int i=0; i<MEASURES_COUNT; i++) {
			workingCopy.getBuffer().setContents(bigContents.append("a").toString());
			runGc();
			startMeasuring();
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
			stopMeasuring();
		}

		// Commit
		commitMeasurements();
		assertPerformance();

	} finally {
		if (workingCopy != null)
			workingCopy.discardWorkingCopy();
	}
}

/*
 * Ensures that the performance of reconcile on a CU with lots of duplicates is acceptable.
 * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=135906 )
 */
public void testReconcileDuplicates() throws JavaModelException {
	tagAsSummary("Reconcile editor change on file with lots of duplicates", false); // do NOT put in fingerprint

	// build big file contents
	StringBuffer contents = new StringBuffer();
	contents.append("public class CUWithDuplicates {\n");
	int fooIndex = 0;
	while (fooIndex < 2000) { // add 2000 duplicate methods
		contents.append("  void foo() {}\n");
		contents.append(fooIndex++);
	}
	contents.append("} //"); // ensure it ends with a line comment that is edited below

	ICompilationUnit workingCopy = null;
	try {
		// Setup
		workingCopy = (ICompilationUnit) JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/BigProject/src/CUWithDuplicates.java")));
		workingCopy.becomeWorkingCopy(null);

		// Warm up
		int warmup = WARMUP_COUNT / 10;
		for (int i=0; i<warmup; i++) {
			workingCopy.getBuffer().setContents(contents.append('a').toString());
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
		}

		// Measures
		resetCounters();
		for (int i=0; i<MEASURES_COUNT; i++) {
			workingCopy.getBuffer().setContents(contents.append('a').toString());
			runGc();
			startMeasuring();
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
			stopMeasuring();
		}

		// Commit
		commitMeasurements();
		assertPerformance();

	} finally {
		if (workingCopy != null)
			workingCopy.discardWorkingCopy();
	}
}

/*
 * Ensures that the performance of reconcile after deleting lots of members is acceptable
 * (regression test for bug 443928 Building large Java element deltas is really slow)
 */
public void testPerfDeleteLotsOfMembersAndReconcile() throws JavaModelException {
	tagAsSummary("Reconcile editor change after deleting lots of members", false); // do NOT put in fingerprint

	// build big file contents
	StringBuffer contents = new StringBuffer();
	contents.append("public class LotsOfMembers {\n");
	int fooIndex = 0;
	while (fooIndex < 15000) { // add 15000 methods
		contents.append("  void foo");
		contents.append(fooIndex++);
		contents.append("() {}\n");
	}
	contents.append("}");

	String oldContents = contents.toString(); // initially, 15000 members
	String newContents = "public class LotsOfMembers {\n}"; // then, no members

	ICompilationUnit workingCopy = null;
	try {
		// Setup
		workingCopy = (ICompilationUnit) JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/BigProject/src/LotsOfMembers.java")));
		workingCopy.becomeWorkingCopy(null);

		// Warm up
		int warmup = WARMUP_COUNT / 10;
		for (int i=0; i<warmup; i++) {
			workingCopy.getBuffer().setContents(oldContents);
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
			workingCopy.getBuffer().setContents(newContents);
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
		}

		// Measures
		resetCounters();
		for (int i=0; i<MEASURES_COUNT; i++) {
			workingCopy.getBuffer().setContents(oldContents);
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
			workingCopy.getBuffer().setContents(newContents);
			runGc();
			startMeasuring();
			workingCopy.reconcile(JLS3_INTERNAL, false/*no pb detection*/, null/*no owner*/, null/*no progress*/);
			stopMeasuring();
		}

		// Commit
		commitMeasurements();
		assertPerformance();

	} finally {
		if (workingCopy != null)
			workingCopy.discardWorkingCopy();
	}
}

/*
 * Ensures that the performance of reconcile after creating a package fragment in a batch operation is acceptable
 * (regression test for bug 234718 JarPackageFragmentRoot.computeChildren(..) is slow )
 */
public void testPerfBatchCreatePackageAndReconcile() throws CoreException {
	tagAsSummary("Reconcile editor change after creating a package fragment in a batch operation", false); // do NOT put in fingerprint

	IJavaProject project = null;
	try {
		project = createJavaProject("P234718");
		IFile bigJar1 = BIG_PROJECT.getProject().getFile(BIG_JAR1_NAME);
		IFile bigJar2 = BIG_PROJECT.getProject().getFile(BIG_JAR2_NAME);
		project.setRawClasspath(
			new IClasspathEntry[] {
				JavaCore.newSourceEntry(project.getPath()),
				JavaCore.newLibraryEntry(bigJar1.getFullPath(), null, null),
				JavaCore.newLibraryEntry(bigJar2.getFullPath(), null, null),
			}, null);
		final IPackageFragmentRoot root = project.getPackageFragmentRoot(project.getProject());
		ICompilationUnit workingCopy  = root.getPackageFragment("").createCompilationUnit(
			"X.java",
			"public class  {\n" +
			"}"
			, false, null);
		workingCopy.becomeWorkingCopy(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();

		// Warm up
		try {
			final ICompilationUnit copy = workingCopy;
			IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
				public void run(IProgressMonitor monitor) throws CoreException {
					root.createPackageFragment("p2", false/*don't force*/, monitor);
					copy.reconcile(JLS3_INTERNAL, true, null, monitor);
					int warmup = WARMUP_COUNT / 5;
					for (int i=0; i<warmup; i++) {
						copy.reconcile(JLS3_INTERNAL, true, null, monitor);
					}
				}
			};
			try {
				JavaCore.run(runnable, null);
			} finally {
				root.getPackageFragment("p2").delete(false/*don't force*/, null);
			}

			// Measures
			resetCounters();
			runnable = new IWorkspaceRunnable(){
				public void run(IProgressMonitor monitor) throws CoreException {
					root.createPackageFragment("p2", false/*don't force*/, monitor);
					copy.reconcile(JLS3_INTERNAL, true, null, monitor);
					int iterations = 10;
					startMeasuring();
					for (int n=0; n<iterations; n++) {
						copy.reconcile(JLS3_INTERNAL, true, null, monitor);
					}
					stopMeasuring();
				}
			};
			for (int i=0; i<MEASURES_COUNT; i++) {
				runGc();
				try {
					JavaCore.run(runnable, null);
				} finally {
					root.getPackageFragment("p2").delete(false/*don't force*/, null);
				}
			}
		}
		finally {
			workingCopy.discardWorkingCopy();
		}

		// Commit
		commitMeasurements();
		assertPerformance();

	} finally {
		if (project != null)
			project.getProject().delete(true, null);
	}
}

/**
 * Ensures that the reconciler does nothing when the source
 * to reconcile with is the same as the current contents.
 */
public void testPerfSearchAllTypeNamesAndReconcile() throws CoreException {
	tagAsSummary("Reconcile editor change and complete", true); // put in fingerprint

	// Wait for indexing end
	AbstractJavaModelTests.waitUntilIndexesReady();

	// Warm up
	ICompilationUnit workingCopy = null;
	try {
		final ProblemRequestor requestor = new ProblemRequestor();
		WorkingCopyOwner owner = new WorkingCopyOwner() {
			public IProblemRequestor getProblemRequestor(ICompilationUnit cu) {
				return requestor;
            }
		};
		workingCopy = PARSER_WORKING_COPY.getWorkingCopy(owner, null);
		IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { JDT_CORE_PROJECT });
		int warmup = WARMUP_COUNT / 5;
		for (int i=0; i<warmup; i++) {
			searchAllTypeNames(scope);
			CompilationUnit unit = workingCopy.reconcile(JLS3_INTERNAL, true, null, null);
			if (i == 0) {
				assertNotNull("Compilation Unit should not be null!", unit);
				assertNotNull("Bindings were not resolved!", unit.getPackage().resolveBinding());
			}
		}

		// Measures
		int iterations = 2;
		resetCounters();
		for (int i=0; i<MEASURES_COUNT; i++) {
			runGc();
			startMeasuring();
			for (int n=0; n<iterations; n++) {
				searchAllTypeNames(scope);
				workingCopy.reconcile(JLS3_INTERNAL, true, null, null);
			}
			stopMeasuring();
		}
	}
	finally {
		workingCopy.discardWorkingCopy();
	}

	// Commit
	commitMeasurements();
	assertPerformance();

}

/*
 * Performance test for the opening of class files in 2 big jars (that each would fill the Java model cache if all pkgs were opened).
 * (see bug 190094 Java Outline Causes Eclipse Lock-up.)
 */
public void testPopulateTwoBigJars() throws CoreException {

	IJavaProject project = null;
	try {
		project = createJavaProject("HugeJarProject");
		IFile bigJar1 = BIG_PROJECT.getProject().getFile(BIG_JAR1_NAME);
		IFile bigJar2 = BIG_PROJECT.getProject().getFile(BIG_JAR2_NAME);
		project.setRawClasspath(
			new IClasspathEntry[] {
				JavaCore.newLibraryEntry(bigJar1.getFullPath(), null, null),
				JavaCore.newLibraryEntry(bigJar2.getFullPath(), null, null),
			}, null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();
		IPackageFragmentRoot root1 = project.getPackageFragmentRoot(bigJar1);
		IPackageFragmentRoot root2 = project.getPackageFragmentRoot(bigJar2);

		// warm up
		int max = 20;
		int warmup = WARMUP_COUNT / 10;
		for (int i = 0; i < warmup; i++) {
			project.close();
			for (int j = 0; j < max; j++) {
				root1.getPackageFragment("p" + j).open(null);
				root2.getPackageFragment("q" + j).open(null);
			}
		}

		// measure performance
		for (int i = 0; i < MEASURES_COUNT; i++) {
			project.close();
			runGc();
			startMeasuring();
			for (int j = 0; j < max; j++) {
				root1.getPackageFragment("p" + j).open(null);
				root2.getPackageFragment("q" + j).open(null);
			}
			stopMeasuring();
		}

		commitMeasurements();
		assertPerformance();
	} finally {
		if (project != null)
			project.getProject().delete(false, null);
	}
}

/*
 * Performance test for looking up package fragments
 * (see bug 72683 Slow code assist in Display view)
 */
public void testSeekPackageFragments() throws CoreException {
	assertNotNull("We should have the 'BigProject' in workspace!", BIG_PROJECT);
	class PackageRequestor implements IJavaElementRequestor {
		ArrayList pkgs = new ArrayList();
		public void acceptField(IField field) {}
		public void acceptInitializer(IInitializer initializer) {}
		public void acceptMemberType(IType type) {}
		public void acceptMethod(IMethod method) {}
		public void acceptPackageFragment(IPackageFragment packageFragment) {
			if (this.pkgs != null)
				this.pkgs.add(packageFragment);
		}
		public void acceptType(IType type) {}
		public boolean isCanceled() {
			return false;
		}
	}

	// first pass: ensure all class are loaded, and ensure that the test works as expected
	PackageRequestor requestor = new PackageRequestor();
	for (int i=0; i<WARMUP_COUNT; i++) {
		getNameLookup(BIG_PROJECT).seekPackageFragments("org.eclipse.jdt.core.tests78.performance5", false/*not partial match*/, requestor);
		if (i == 0) {
			int size = requestor.pkgs.size();
			IJavaElement[] result = new IJavaElement[size];
			requestor.pkgs.toArray(result);
			assertElementsEqual(
				"Unexpected packages",
				"org.eclipse.jdt.core.tests78.performance5 [in src78 [in "+BIG_PROJECT_NAME+"]]",
				result
			);
		}
	}

	// measure performance
	requestor.pkgs = null;
	resetCounters();
	for (int i = 0; i < MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int j = 0; j < 50000; j++) {
			getNameLookup(BIG_PROJECT).seekPackageFragments("org.eclipse.jdt.core.tests" + i + "0.performance" + i, false/*not partial match*/, requestor);
		}
		stopMeasuring();
	}
	commitMeasurements();
	assertPerformance();
}

public void testCloseProjects() throws JavaModelException {
	tagAsSummary("Close all workspace projects", false); // do NOT put in fingerprint

	// Warm-up
	int length=ALL_PROJECTS.length;
	int wmax = WARMUP_COUNT / 10;
	for (int i=0; i<wmax; i++) {
		for (int j=0; j<length; j++) {
			ENV.closeProject(ALL_PROJECTS[j].getPath());
		}
		for (int j=0; j<length; j++) {
			ENV.openProject(ALL_PROJECTS[j].getPath());
		}
	}

	// Measures
	for (int i=0; i<MEASURES_COUNT; i++) {
		AbstractJavaModelTests.waitUntilIndexesReady();
		runGc();
		startMeasuring();
		for (int j=0; j<length; j++) {
			ENV.closeProject(ALL_PROJECTS[j].getPath());
		}
		stopMeasuring();
		for (int j=0; j<length; j++) {
			ENV.openProject(ALL_PROJECTS[j].getPath());
		}
	}

	// Commit
	commitMeasurements();
	assertPerformance();
}

/*
 * Tests the performance of JavaCore#create(IResource).
 * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=133141)
 */
public void testCreateJavaElement() throws CoreException {
	// setup (force the project cache to be created)
	IFile file = (IFile) WORKING_COPY.getResource();
	getNameLookup(BIG_PROJECT);

	// warm up
	int warmup = WARMUP_COUNT / 10;
	int iterations = 5000;
	for (int i = 0; i < warmup; i++) {
		for (int j = 0; j < iterations; j++) {
			JavaCore.create(file);
		}
	}

	// measure performance
	for (int i = 0; i < MEASURES_COUNT; i++) {
		runGc();
		startMeasuring();
		for (int j = 0; j < iterations; j++) {
			JavaCore.create(file);
		}
		stopMeasuring();
	}

	commitMeasurements();
	assertPerformance();
}

public void testInitJDTPlugin() throws JavaModelException, CoreException {
	tagAsSummary("JDT/Core plugin initialization", true); // put in fingerprint
	setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "Bug 338649:Extra check for source attachment in missing drive causing regression");
	// Warm-up
	int wmax = WARMUP_COUNT / 5;
	for (int i=0; i<wmax; i++) {
		simulateExitRestart();
		JavaCore.initializeAfterLoad(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
	}

	// Measures
	for (int i=0; i<MEASURES_COUNT; i++) {
		// shutdwon
		simulateExit();
		runGc();
		startMeasuring();
		// restart
		simulateRestart();
		JavaCore.initializeAfterLoad(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		stopMeasuring();
	}
	// Commit
	commitMeasurements();
	assertPerformance();
}

/*
 * Performance test for the first use of findType(...)
 * (see bug 161175 JarPackageFragmentRoot slow to initialize)
 */
public void testFindType() throws CoreException {

	IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
	IJavaProject[] existingProjects = model.getJavaProjects();

	try {
		// close existing projects
		for (int i = 0, length = existingProjects.length; i < length; i++) {
			existingProjects[i].getProject().close(null);
		}

		// get 20 projects
		int max = 20;
		IJavaProject[] projects = new IJavaProject[max];
		for (int i = 0; i < max; i++) {
			projects[i] = createJavaProject("FindType" + i);
		}
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();

		try {
			// warm up
			int warmup = WARMUP_COUNT / 10;
			for (int i = 0; i < warmup; i++) {
				model.close();
				for (int j = 0; j < max; j++) {
					projects[j].findType("java.lang.Object");
				}
			}

			// measure performance
			for (int i = 0; i < MEASURES_COUNT; i++) {
				model.close();
				runGc();
				startMeasuring();
				for (int j = 0; j < max; j++) {
					projects[j].findType("java.lang.Object");
				}
				stopMeasuring();
			}

			commitMeasurements();
			assertPerformance();
		} finally {
			for (int i = 0; i < max; i++) {
				projects[i].getProject().delete(false, null);
			}
		}
	} finally {
		// reopen existing projects
		for (int i = 0, length = existingProjects.length; i < length; i++) {
			existingProjects[i].getProject().open(null);
		}
	}
}

/*
 * Performance test for the first time we get the source of a class file in a bug jar with no source attached
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=190840 )
 */
public void testGetSourceBigJarNoAttachment() throws CoreException {

	IJavaProject project = null;
	try {
		project = createJavaProject("HugeJarProject");
		IFile bigJar1 = BIG_PROJECT.getProject().getFile(BIG_JAR1_NAME);
		project.setRawClasspath(
			new IClasspathEntry[] {
				JavaCore.newLibraryEntry(bigJar1.getFullPath(), null, null),
			}, null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();
		IPackageFragmentRoot root = project.getPackageFragmentRoot(bigJar1);
		IClassFile classFile = root.getPackageFragment("p0").getClassFile("X0.class");

		// warm up
		int max = 20;
		int warmup = WARMUP_COUNT / 10;
		for (int i = 0; i < warmup; i++) {
			for (int j = 0; j < max; j++) {
				root.close();
				classFile.getSource();
			}
		}

		// measure performance
		for (int i = 0; i < MEASURES_COUNT; i++) {
			runGc();
			startMeasuring();
			for (int j = 0; j < max; j++) {
				root.close();
				classFile.getSource();
			}
			stopMeasuring();
		}

		commitMeasurements();
		assertPerformance();
	} finally {
		if (project != null)
			project.getProject().delete(false, null);
	}
}

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331632
public void testReopenSingleProject() throws CoreException {
	tagAsSummary("Reopen a single project in a workspace", false); // do NOT put in fingerprint

	// First close all Eclipse projects
	long startTime = 0;
	if (PRINT) {
		System.out.print("Close all Eclipse projects...");
		startTime = System.currentTimeMillis();
	}
	int length=ALL_PROJECTS.length;
	for (int j=0; j<length; j++) {
		ALL_PROJECTS[j].getProject().close(null);
	}		
	AbstractJavaModelTests.waitUntilIndexesReady();
	AbstractJavaModelTests.waitForAutoBuild();
	if (PRINT) {
		System.out.println((System.currentTimeMillis()-startTime)+"ms");
	}
	

	// Warm-up
	if (PRINT) {
		System.out.print("Warmup test...");
		startTime = System.currentTimeMillis();
	}
	final int warmup = WARMUP_COUNT / 10;
	for (int i=0; i<warmup; i++) {
		BIG_PROJECT.getProject().close(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();
		BIG_PROJECT.getProject().open(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();
		AbstractJavaModelTests.waitForManualRefresh();
	}
	if (PRINT) {
		System.out.println((System.currentTimeMillis()-startTime)+"ms");
	}

	// Measures
	if (PRINT) {
		System.out.println();
		System.out.println("Start measures:");
		startTime = System.currentTimeMillis();
	}
	for (int i=0; i<MEASURES_COUNT; i++) {
		runGc();
		BIG_PROJECT.getProject().close(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();
		startMeasuring();
		BIG_PROJECT.getProject().open(null);
		AbstractJavaModelTests.waitUntilIndexesReady();
		AbstractJavaModelTests.waitForAutoBuild();
		AbstractJavaModelTests.waitForManualRefresh();
		stopMeasuring();
	}
	if (PRINT) {
		System.out.println("	total time: "+((System.currentTimeMillis()-startTime)/1000.0)+"s");
	}

	// Commit
	if (PRINT) {
		System.out.println();
		System.out.println("Commit measures:");
		startTime = System.currentTimeMillis();
	}
	commitMeasurements();
	assertPerformance();

	// Finally reopen all Eclipse projects
	if (PRINT) {
		System.out.print("Reopen Eclipse projects...");
		startTime = System.currentTimeMillis();
	}
	for (int i=0; i<length; i++) {
		ALL_PROJECTS[i].getProject().open(null);
	}
	AbstractJavaModelTests.waitUntilIndexesReady();
	AbstractJavaModelTests.waitForAutoBuild();
	AbstractJavaModelTests.waitForManualRefresh();
	runGc();
	if (PRINT) {
		System.out.println((System.currentTimeMillis()-startTime)+"ms");
	}
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=354332
public void testRefreshExternalArchives() throws Exception {
	int jarCount = 100;
	File[] files = new File[jarCount];
	IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
	IClasspathEntry[] oldClasspath = BIG_PROJECT.getRawClasspath();
	try {
		IClasspathEntry[] classpath = new IClasspathEntry[jarCount];
		for (int index = 0; index < jarCount; index++) {
			String filePath = getExternalResourcePath("lib"+ index +".jar");
			org.eclipse.jdt.core.tests.util.Util.createJar(new String[0],
				new String[] {
					"META-INF/MANIFEST.MF",
					"Manifest-Version: 1.0\n",
				},
				filePath,
				JavaCore.VERSION_1_4);
			classpath[index] = JavaCore.newLibraryEntry(new Path(filePath), null, null);
			files[index]  = new File(filePath);
		}
		BIG_PROJECT.setRawClasspath(classpath, null);
		
		// warm up
		int max = 20;
		int warmup = WARMUP_COUNT / 10;
		for (int i = 0; i < warmup; i++) {
			for (int j = 0; j < max; j++) {
				touchFiles(files);
				model.refreshExternalArchives(new IJavaElement[] {BIG_PROJECT}, null);
			}
		}

		// measure performance
		for (int i = 0; i < MEASURES_COUNT; i++) {
			runGc();
			startMeasuring();
			for (int j = 0; j < max; j++) {
				touchFiles(files);
				model.refreshExternalArchives(new IJavaElement[] {BIG_PROJECT}, null);
			}
			stopMeasuring();
		}

		commitMeasurements();
		assertPerformance();		
		
	} finally {
		BIG_PROJECT.setRawClasspath(oldClasspath, null);
		for(int index=0; index < files.length; index++) {
			files[index].delete();
		}
	}
}

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=411423
public void testResolveClasspath() throws Exception {
	int jarCount = 100;
	File[] libraryFiles = new File[jarCount];
	File[] srcAttachmentFiles = new File[jarCount];
	IClasspathEntry[] oldClasspath = BIG_PROJECT.getRawClasspath();
	try {
		IClasspathEntry[] classpath = new IClasspathEntry[jarCount];
		for (int index = 0; index < jarCount; index++) {
			String libraryFilePath = getExternalResourcePath("lib" + index + ".jar");
			org.eclipse.jdt.core.tests.util.Util.createJar(new String[0],
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n",
					},
					libraryFilePath,
					JavaCore.VERSION_1_4);
			libraryFiles[index] = new File(libraryFilePath);

			String srcAttachmentFilePath = getExternalResourcePath("lib" + index + "-src.jar");
			org.eclipse.jdt.core.tests.util.Util.createJar(new String[0],
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n",
					},
					srcAttachmentFilePath,
					JavaCore.VERSION_1_4);
			srcAttachmentFiles[index] = new File(srcAttachmentFilePath);

			classpath[index] = JavaCore.newLibraryEntry(new Path(libraryFilePath), new Path(srcAttachmentFilePath), null);
		}
		BIG_PROJECT.setRawClasspath(classpath, null);

		// warm up
		int max = 20;
		int warmup = WARMUP_COUNT / 10;
		for (int i = 0; i < warmup; i++) {
			for (int j = 0; j < max; j++) {
				BIG_PROJECT.resolveClasspath(classpath);
			}
		}

		// measure performance
		for (int i = 0; i < MEASURES_COUNT; i++) {
			runGc();
			startMeasuring();
			for (int j = 0; j < max; j++) {
				BIG_PROJECT.resolveClasspath(classpath);
			}
			stopMeasuring();
		}

		commitMeasurements();
		assertPerformance();

	} finally {
		BIG_PROJECT.setRawClasspath(oldClasspath, null);
		for (int index = 0; index < libraryFiles.length; index++) {
			libraryFiles[index].delete();
			srcAttachmentFiles[index].delete();
		}
	}
}

/*
 * Overriding getExternalPath() to be on a non-local disk (e.g., NFS) shows the advantages
 * of caching file existence checks in the testJavaModelManagerExternalFilesCache() test.
 */
protected String getExternalPath() {
	// NOTE: Do something similar to this commented-out code to set up the tests to
	// use a non-local file system.
	//	return "/home/" + System.getProperty("user.name") + "/performance_test/";
	return super.getExternalPath();
}

//https://bugs.eclipse.org/bugs/show_bug.cgi?id=421165
public void testGetAllPackageFragmentRoots() throws Exception {
	int jarCount = 100;
	IClasspathEntry[] oldClasspath = BIG_PROJECT.getRawClasspath();
	try {
	    IClasspathEntry[] classpath = new IClasspathEntry[jarCount];
	    for (int index = 0; index < jarCount; index++) {
	        String filePath = getExternalResourcePath("lib"+ index +".jar");
	        org.eclipse.jdt.core.tests.util.Util.createJar(new String[0],
	            new String[] {
	                "META-INF/MANIFEST.MF",
	                "Manifest-Version: 1.0\n",
	            },
	            filePath,
	            JavaCore.VERSION_1_4);
	        classpath[index] = JavaCore.newLibraryEntry(new Path(filePath), null, null);
	    }
	    BIG_PROJECT.setRawClasspath(classpath, null);
	    IFile file = (IFile) WORKING_COPY.getResource();

	    // warm up
	    int max = 20;
	    int warmup = WARMUP_COUNT / 10;
	    for (int i = 0; i < warmup; i++) {
	        for (int j = 0; j < max; j++) {
	            file.touch(null/*no progress*/);
	            BIG_PROJECT.getAllPackageFragmentRoots();
	        }
	    }

	    // measure performance
	    for (int i = 0; i < MEASURES_COUNT; i++) {
	        runGc();
	        startMeasuring();
	        for (int j = 0; j < max; j++) {
	          file.touch(null/*no progress*/);
	          BIG_PROJECT.getAllPackageFragmentRoots();
	        }
	        stopMeasuring();
	    }

	    commitMeasurements();
	    assertPerformance();

	} finally {
	    BIG_PROJECT.setRawClasspath(oldClasspath, null);
	}
}

protected void resetCounters() {
	// do nothing
}
}
