package com.intellij.execution;

import com.intellij.execution.application.ApplicationConfigurable;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.application.ApplicationConfigurationType;
import com.intellij.execution.configurations.*;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.junit.*;
import com.intellij.execution.junit2.configuration.JUnitConfigurable;
import com.intellij.execution.junit2.configuration.JUnitConfigurationModel;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.execution.ui.CommonJavaParametersPanel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.rt.execution.junit.JUnitStarter;
import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
import com.intellij.testFramework.MapDataContext;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.ui.EditorTextFieldWithBrowseButton;
import com.intellij.util.Assertion;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import junit.framework.TestCase;
import org.jdom.Element;

import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class ConfigurationsTest extends BaseConfigurationTestCase {
  private final Assertion CHECK = new Assertion();

  private Sdk myJdk;
  private static final String INNER_TEST_NAME = "test1.InnerTest.Inner";
  private static final String RT_INNER_TEST_NAME = "test1.InnerTest$Inner";

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    addModule("module1");
    addModule("module2");
    addModule("module3");
    assignJdk(getModule1());
  }

  public void testCreateConfiguration() throws IOException, ExecutionException {
    Module module1 = getModule1();
    PsiClass psiClass = findTestA(module1);
    JUnitConfiguration configuration = createConfiguration(psiClass);
    assertEquals(Collections.singleton(module1), ContainerUtilRt.newHashSet(configuration.getModules()));
    checkClassName(psiClass.getQualifiedName(), configuration);
    assertEquals(psiClass.getName(), configuration.getName());
    checkTestObject(JUnitConfiguration.TEST_CLASS, configuration);
    Module module2 = getModule2();
    Assertion.compareUnordered(new Module[]{module1, module2}, configuration.getValidModules());

    PsiClass innerTest = findClass(module1, INNER_TEST_NAME);
    configuration = createJUnitConfiguration(innerTest, TestClassConfigurationProducer.class, new MapDataContext());
    checkClassName(RT_INNER_TEST_NAME, configuration);
    checkCanRun(configuration);

    PsiMethod[] testMethod = innerTest.findMethodsByName("test", false);
    assertEquals(1, testMethod.length);
    configuration = createConfiguration(testMethod[0]);
    checkClassName(RT_INNER_TEST_NAME, configuration);
    checkMethodName("test", configuration);
    checkTestObject(JUnitConfiguration.TEST_METHOD, configuration);
    checkCanRun(configuration);

    PsiMethod mainMethod = innerTest.findMethodsByName("main", false)[0];
    ApplicationConfiguration appConfiguration = createConfiguration(mainMethod);
    assertEquals(RT_INNER_TEST_NAME, appConfiguration.MAIN_CLASS_NAME);
    checkCanRun(configuration);
  }

  public void testModulesSelector() throws ConfigurationException {
    if (PlatformTestUtil.COVERAGE_ENABLED_BUILD) return;

    Module module1 = getModule1();
    Module module2 = getModule2();
    JUnitConfigurable editor = new JUnitConfigurable(myProject);
    try {
      JUnitConfiguration configuration = createConfiguration(findTestA(module2));
      editor.getComponent(); // To get all the watchers installed.
      Configurable configurable = new RunConfigurationConfigurableAdapter(editor, configuration);
      JComboBox comboBox = editor.getModulesComponent();
      configurable.reset();
      assertFalse(configurable.isModified());
      assertEquals(module2.getName(), ((Module)comboBox.getSelectedItem()).getName());
      assertEquals(ModuleManager.getInstance(myProject).getModules().length + 1, comboBox.getModel().getSize()); //no module
      comboBox.setSelectedItem(module1);
      assertTrue(configurable.isModified());
      configurable.apply();
      assertFalse(configurable.isModified());
      assertEquals(Collections.singleton(module1), ContainerUtilRt.newHashSet(configuration.getModules()));
    }
    finally {
      Disposer.dispose(editor);
    }
  }

  public void testCantCreateConfiguration() {
    PsiClass objectClass =
      JavaPsiFacade.getInstance(myProject).findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(myProject));
    assertNull(createConfiguration(objectClass));
    assertNull(createConfiguration(JUnitUtil.getContainingPackage(objectClass)));
  }

  public void testRunningJUnit() throws ExecutionException {
    PsiClass testA = findTestA(getModule1());
    JUnitConfiguration configuration = createConfiguration(testA);
    JavaParameters parameters = checkCanRun(configuration);
    CHECK.empty(parameters.getVMParametersList().getList());
    assertTrue(JUnitStarter.checkVersion(parameters.getProgramParametersList().getArray(),
                                         new SegmentedOutputStream(System.out)));
    assertTrue(parameters.getProgramParametersList().getList().contains(testA.getQualifiedName()));
    assertEquals(JUnitStarter.class.getName(), parameters.getMainClass());
    assertEquals(myJdk.getHomeDirectory().getPresentableUrl(), parameters.getJdkPath());
  }

  public void testRunningAllInPackage() throws IOException, ExecutionException {
    Module module1 = getModule1();
    GlobalSearchScope module1AndLibraries = GlobalSearchScope.moduleWithLibrariesScope(module1);
    PsiClass testCase = findClass(TestCase.class.getName(), module1AndLibraries);
    PsiClass psiClass = findTestA(module1);
    PsiClass psiClass2 = findTestA(getModule2());
    PsiClass derivedTest = findClass(module1, "test1.DerivedTest");
    PsiClass baseTestCase = findClass("junit.framework.ThirdPartyClass", module1AndLibraries);
    PsiClass testB = findClass(getModule3(), "test1.TestB");
    assertNotNull(testCase);
    assertNotNull(derivedTest);
    assertNotNull(psiClass);
    assertTrue(psiClass.isInheritor(testCase, false));
    assertEquals(baseTestCase, derivedTest.getSuperClass());
    assertTrue(baseTestCase.isInheritor(testCase, true));
    assertTrue(derivedTest.isInheritor(testCase, true));
    PsiPackage psiPackage = JUnitUtil.getContainingPackage(psiClass);
    JUnitConfiguration configuration = createConfiguration(psiPackage, module1);
    JavaParameters parameters = checkCanRun(configuration);
    List<String> lines = extractAllInPackageTests(parameters, psiPackage);
    Assertion.compareUnordered(
      new Object[]{"", psiClass.getQualifiedName(), psiClass2.getQualifiedName(), derivedTest.getQualifiedName(), RT_INNER_TEST_NAME,
        testB.getQualifiedName()},
      lines);
  }

  public void testRunAllInPackageWhenPackageIsEmptyInModule() throws ExecutionException {
    assignJdk(getModule2());
    JUnitConfiguration configuration =
      new JUnitConfiguration("", myProject, JUnitConfigurationType.getInstance().getConfigurationFactories()[0]);
    configuration.getPersistentData().TEST_OBJECT = JUnitConfiguration.TEST_PACKAGE;
    configuration.getPersistentData().PACKAGE_NAME = "test2";
    configuration.getPersistentData().setScope(TestSearchScope.WHOLE_PROJECT);
    assertEmpty(configuration.getModules());
    checkCanRun(configuration);
    configuration.getPersistentData().PACKAGE_NAME = "noTests";
//    checkCantRun(configuration, "No tests found in the package '");

    configuration.getPersistentData().PACKAGE_NAME = "com.abcent";
    checkCantRun(configuration, "Package 'com.abcent' not found");
  }

  public void testAllInPackageForCommonAncestorModule() throws IOException, ExecutionException {
    disposeModule(getModule2());
    addModule("module5", true);
    Module ancestor = getModule1();
    Module child1 = getModule2();
    Module child2 = getModule3();
    addDependency(ancestor, child1);
    addDependency(ancestor, child2);
    PsiPackage psiPackage = JavaPsiFacade.getInstance(myProject).findPackage("test1");
    JUnitConfiguration configuration = createJUnitConfiguration(psiPackage, AllInPackageConfigurationProducer.class, new MapDataContext());
    configuration.getPersistentData().setScope(TestSearchScope.WHOLE_PROJECT);
    assertNotNull(configuration);
    checkPackage(psiPackage.getQualifiedName(), configuration);
    assertEmpty(configuration.getModules());
    JavaParameters parameters = checkCanRun(configuration);
    List<String> tests = extractAllInPackageTests(parameters, psiPackage);
    String childTest1 = findClass(child1, "test1.TestB").getQualifiedName();
    String childTest2 = findClass(child2, "test1.Test5").getQualifiedName();
    String ancestorTest = findClass(ancestor, "test1.TestA").getQualifiedName();
    CHECK.containsAll(tests, new Object[]{ancestorTest, childTest1, childTest2});
  }

  public void testClasspathConfiguration() throws CantRunException {
    JavaParameters parameters = new JavaParameters();
    RunConfigurationModule module = new JavaRunConfigurationModule(myProject, false);
    Module module1 = getModule1();
    Module module2 = getModule2();
    addDependency(module1, module2);
    Module module3 = getModule3();
    addDependency(module2, module3);
    addDependency(module1, module3);
    addOutputs(module1, 1);
    addOutputs(module2, 2);
    addOutputs(module3, 3);
    module.setModule(module1);
    parameters.configureByModule(module.getModule(), JavaParameters.JDK_AND_CLASSES_AND_TESTS);
    ArrayList<String> classPath = new ArrayList<String>();
    StringTokenizer tokenizer = new StringTokenizer(parameters.getClassPath().getPathsString(), File.pathSeparator);
    while (tokenizer.hasMoreTokens()) {
      String token = tokenizer.nextToken();
      classPath.add(token);
    }
    CHECK.singleOccurence(classPath, getOutput(module1, false));
    CHECK.singleOccurence(classPath, getOutput(module1, false));
    CHECK.singleOccurence(classPath, getOutput(module1, true));
    CHECK.singleOccurence(classPath, getOutput(module2, false));
    CHECK.singleOccurence(classPath, getOutput(module2, true));
    CHECK.singleOccurence(classPath, getOutput(module3, false));
    CHECK.singleOccurence(classPath, getOutput(module3, true));
    CHECK.singleOccurence(classPath, getFSPath(findFile(MOCK_JUNIT)));
  }

  public void testExternalizeJUnitConfiguration() throws WriteExternalException, InvalidDataException {
    JUnitConfiguration configuration = createConfiguration(findTestA(getModule1()));
    Element element = new Element("cfg");
    configuration.writeExternal(element);
    JUnitConfiguration newCfg =
      new JUnitConfiguration(null, myProject, JUnitConfigurationType.getInstance().getConfigurationFactories()[0]);

    newCfg.readExternal(element);
    checkTestObject(configuration.getPersistentData().TEST_OBJECT, newCfg);
    assertEquals(Collections.singleton(getModule1()), ContainerUtilRt.newHashSet(newCfg.getModules()));
    checkClassName(configuration.getPersistentData().getMainClassName(), newCfg);
  }

  public void testTestClassPathWhenRunningConfigurations() throws IOException, ExecutionException {
    addModule("module4", false);
    Module module4 = getModule4();
    assignJdk(module4);
    addSourcePath(module4, "testSrc", true);
    addSourcePath(module4, "src", false);
    String output = setCompilerOutput(module4, "classes", false);
    String testOuput = setCompilerOutput(module4, "testClasses", true);

    ApplicationConfiguration applicationConfiguration = createConfiguration(findClass(module4, "Application"));
    JavaParameters parameters = checkCanRun(applicationConfiguration);
    String classPath = parameters.getClassPath().getPathsString();
    checkDoesNotContain(classPath, testOuput);
    checkContains(classPath, output);

    JUnitConfiguration junitConfiguration =
      createJUnitConfiguration(findClass(module4, "TestApplication"), TestClassConfigurationProducer.class, new MapDataContext());
    parameters = checkCanRun(junitConfiguration);
    classPath = parameters.getClassPath().getPathsString();
    checkContains(classPath, testOuput);
    checkContains(classPath, output);

    applicationConfiguration.MAIN_CLASS_NAME = junitConfiguration.getPersistentData().getMainClassName();
    classPath = checkCanRun(applicationConfiguration).getClassPath().getPathsString();
    checkContains(classPath, testOuput);
    checkContains(classPath, output);
  }

  public void testSameTestAndCommonOutput() throws IOException, ExecutionException {
    addModule("module4", false);
    Module module = getModule4();
    assignJdk(module);
    addSourcePath(module, "src", false);
    addSourcePath(module, "testSrc", false);
    String output = setCompilerOutput(module, "classes", false);
    assertEquals(output, setCompilerOutput(module, "classes", true));

    RunConfiguration configuration = createConfiguration(findClass(module, "Application"));
    JavaParameters javaParameters = checkCanRun(configuration);
    checkContains(javaParameters.getClassPath().getPathsString(), output);

    configuration = createConfiguration(findClass(module, "TestApplication"));
    javaParameters = checkCanRun(configuration);
    checkContains(javaParameters.getClassPath().getPathsString(), output);
  }

  public void testCreatingApplicationConfiguration() throws ConfigurationException {
    if (PlatformTestUtil.COVERAGE_ENABLED_BUILD) return;

    ApplicationConfiguration configuration = new ApplicationConfiguration(null, myProject, ApplicationConfigurationType.getInstance());
    ApplicationConfigurable editor = new ApplicationConfigurable(myProject);
    try {
      editor.getComponent(); // To get all the watchers installed.
      Configurable configurable = new RunConfigurationConfigurableAdapter(editor, configuration);
      configurable.reset();
      CommonJavaParametersPanel javaParameters = editor.getCommonProgramParameters();
      javaParameters.setProgramParameters("prg");
      javaParameters.setVMParameters("vm");
      javaParameters.setWorkingDirectory("dir");
      assertTrue(configurable.isModified());
      configurable.apply();
      assertEquals("prg", configuration.getProgramParameters());
      assertEquals("vm", configuration.getVMParameters());
      assertEquals("dir", configuration.getWorkingDirectory());
    }
    finally {
      Disposer.dispose(editor);
    }
  }

  public void testCreateInnerPackageLocalApplication() throws ExecutionException {
    PsiClass psiClass = findClass(getModule1(), "test2.NotATest.InnerApplication");
    assertNotNull(psiClass);
    ApplicationConfiguration configuration = createConfiguration(psiClass);
    assertEquals("test2.NotATest$InnerApplication", configuration.MAIN_CLASS_NAME);
    checkCanRun(configuration);
  }

  public void testEditJUnitConfiguration() throws ConfigurationException {
    if (PlatformTestUtil.COVERAGE_ENABLED_BUILD) return;

    PsiClass testA = findTestA(getModule2());
    JUnitConfiguration configuration = createConfiguration(testA);
    JUnitConfigurable editor = new JUnitConfigurable(myProject);
    try {
      Configurable configurable = new RunConfigurationConfigurableAdapter(editor, configuration);
      configurable.reset();
      final EditorTextFieldWithBrowseButton component =
        ((LabeledComponent<EditorTextFieldWithBrowseButton>)editor.getTestLocation(JUnitConfigurationModel.CLASS)).getComponent();
      assertEquals(testA.getQualifiedName(), component.getText());
      PsiClass otherTest = findClass(getModule2(), "test2.Test2");
      component.setText(otherTest.getQualifiedName());
      configurable.apply();
      assertEquals(otherTest.getName(), configuration.getName());
      String specialName = "My name";
      configuration.setName(specialName);
      configuration.setNameChangedByUser(true);
      configurable.reset();
      component.setText(testA.getQualifiedName());
      configurable.apply();
      assertEquals(specialName, configuration.getName());
    }
    finally {
      Disposer.dispose(editor);
    }
  }

  public void testRunThirdPartyApplication() throws ExecutionException {
    ApplicationConfiguration configuration =
      new ApplicationConfiguration("Third party", myProject, ApplicationConfigurationType.getInstance());
    configuration.setModule(getModule1());
    configuration.MAIN_CLASS_NAME = "third.party.Main";
    checkCanRun(configuration);
  }

  public void testAllInPackageForProject() throws IOException, ExecutionException {
    // module1 -> module2 -> module3
    // module5
    addModule("module5");
    addDependency(getModule1(), getModule2());
    addDependency(getModule2(), getModule3());
    String[][] outputs = new String[4][];
    for (int i = 0; i < 4; i++) {
      outputs[i] = addOutputs(getModule(i), i + 1);
    }


    PsiPackage defaultPackage = JavaPsiFacade.getInstance(myProject).findPackage("");
    JUnitConfiguration configuration =
      createJUnitConfiguration(defaultPackage, AllInPackageConfigurationProducer.class, new MapDataContext());
    configuration.getPersistentData().setScope(TestSearchScope.WHOLE_PROJECT);
    JavaParameters javaParameters = checkCanRun(configuration);
    String classPath = javaParameters.getClassPath().getPathsString();
    assertEquals(-1, classPath.indexOf(JarFileSystem.PROTOCOL_PREFIX));
    assertEquals(-1, classPath.indexOf(LocalFileSystem.PROTOCOL_PREFIX));
    for (int i = 0; i < 4; i++) {
      checkContains(classPath, outputs[i][0]);
      checkContains(classPath, outputs[i][1]);
    }
  }

  private void assignJdk(Module module) {
    myJdk = ModuleRootManager.getInstance(myModule).getSdk();
    ModuleRootModificationUtil.setModuleSdk(module, myJdk);
  }

  private static String getOutput(Module module1, boolean test) {
    CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module1);
    assertNotNull(compilerModuleExtension);
    VirtualFile output = test ? compilerModuleExtension.getCompilerOutputPathForTests() : compilerModuleExtension.getCompilerOutputPath();
    return getFSPath(output);
  }

  private static String getFSPath(VirtualFile output) {
    return PathUtil.getLocalPath(output);
  }

  private static String[] addOutputs(Module module, int index) {
    String[] outputs = new String[2];
    String prefix = "outputs" + File.separatorChar;
    VirtualFile generalOutput = findFile(prefix + "general " + index);
    VirtualFile testOutput = findFile(prefix + "tests" + index);
    outputs[0] = generalOutput.getPresentableUrl();
    outputs[1] = testOutput.getPresentableUrl();
    PsiTestUtil.setCompilerOutputPath(module, generalOutput.getUrl(), false);
    PsiTestUtil.setCompilerOutputPath(module, testOutput.getUrl(), true);
    return outputs;
  }

  private static JavaParameters checkCanRun(RunConfiguration configuration) throws ExecutionException {
    final RunProfileState state;
    state = ExecutionEnvironmentBuilder.create(DefaultRunExecutor.getRunExecutorInstance(), configuration).build().getState();
    assertNotNull(state);
    assertTrue(state instanceof JavaCommandLine);
    if (state instanceof TestPackage) {
      @SuppressWarnings("UnusedDeclaration")
      final JavaParameters parameters = ((TestPackage)state).getJavaParameters();
      ((TestPackage)state).findTests();
    }
    try {
      configuration.checkConfiguration();
    }
    catch (RuntimeConfigurationError e) {
      fail("cannot run: " + e.getMessage());
    }
    catch (RuntimeConfigurationException e) {
      //ignore
    }
    return ((JavaCommandLine)state).getJavaParameters();
  }

  private void checkCantRun(RunConfiguration configuration, String reasonBeginning) throws ExecutionException {
    //MockRunRequest request = new MockRunRequest(myProject);
    //CantRunException rejectReason;
    //try {
    //  configuration.runRequested(request);
    //  rejectReason = request.myRejectReason;
    //}
    //catch (CantRunException e) {
    //  rejectReason = e;
    //}
    //if (rejectReason == null) fail("Should not run");
    //rejectReason.getMessage().startsWith(reasonBeginning);

    try {
      configuration.checkConfiguration();
    }
    catch (RuntimeConfigurationError e) {
      assertTrue(e.getLocalizedMessage().startsWith(reasonBeginning));
      return;
    }
    catch (RuntimeConfigurationException ignored) {

    }

    RunProfileState state = configuration.getState(DefaultRunExecutor.getRunExecutorInstance(), new ExecutionEnvironmentBuilder(myProject, DefaultRunExecutor.getRunExecutorInstance()).runProfile(configuration).build());
    assertTrue(state instanceof JavaCommandLine);

    try {
      ((JavaCommandLine)state).getJavaParameters();
    }
    catch (Throwable e) {
      assertTrue(e.getLocalizedMessage().startsWith(reasonBeginning));
      return;
    }

    fail("Should not run");
  }

  private static String setCompilerOutput(Module module, String path, boolean testOutput) {
    VirtualFile output = ModuleRootManager.getInstance(module).getContentEntries()[0].getFile().findChild(path);
    assertNotNull(output);
    PsiTestUtil.setCompilerOutputPath(module, output.getUrl(), testOutput);
    return output.getPath().replace('/', File.separatorChar);
  }

  private static void addSourcePath(Module module, String path, boolean testSource) {
    final ContentEntry entry = ModuleRootManager.getInstance(module).getContentEntries()[0];
    VirtualFile child = entry.getFile().findChild(path);
    assertNotNull(child);
    PsiTestUtil.addSourceRoot(module, child, testSource);
  }

  private JUnitConfiguration createConfiguration(PsiPackage psiPackage, Module module) {
    JUnitConfiguration configuration =
      new JUnitConfiguration("", myProject, JUnitConfigurationType.getInstance().getConfigurationFactories()[0]);
    configuration.getPersistentData().TEST_OBJECT = JUnitConfiguration.TEST_PACKAGE;
    configuration.getPersistentData().PACKAGE_NAME = psiPackage.getQualifiedName();
    configuration.getPersistentData().setScope(TestSearchScope.WHOLE_PROJECT);
    configuration.setModule(module);
    return configuration;
  }

  private PsiClass findTestA(Module module) {
    return findClass(module, "test1.TestA");
  }

  private static List<String> readLinesFrom(File file) throws IOException {
    if (!file.exists()) file.createNewFile();
    ArrayList<String> result = new ArrayList<String>();
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    try {
      String line;
      while ((line = reader.readLine()) != null) result.add(line);
      return result;
    }
    finally {
      reader.close();
    }
  }

  private static List<String> extractAllInPackageTests(JavaParameters parameters, PsiPackage psiPackage)
    throws IOException {
    String filePath = ContainerUtil.find(parameters.getProgramParametersList().getArray(), new Condition<String>() {
      @Override
      public boolean value(String value) {
        return StringUtil.startsWithChar(value, '@');
      }
    }).substring(1);
    List<String> lines = readLinesFrom(new File(filePath));
    assertEquals(psiPackage.getQualifiedName(), lines.get(0));
    //lines.remove(0);
    lines.remove(0);
    return lines;
  }

  private static void checkContains(String string, String fragment) {
    assertTrue(fragment + " in " + string, string.contains(fragment));
  }

  private static void checkDoesNotContain(String string, String fragment) {
    assertFalse(fragment + " in " + string, string.contains(fragment));
  }

  @Override
  protected void tearDown() throws Exception {
    myJdk = null;
    super.tearDown();
  }
}
