@SuppressWarnings("unchecked")
  public InductiveMethod getMethod(String methodName)
      throws SecurityException, ClassNotFoundException, IllegalArgumentException,
          InstantiationException, IllegalAccessException, InvocationTargetException {
    Configuration methodConf = confMethods.configurationAt(methodName);
    String methodClass = methodConf.getString("class");

    Constructor[] a = Class.forName(methodClass).getConstructors();
    InductiveMethod ind = (InductiveMethod) a[0].newInstance();
    ind.configClassifier(confMethods, methodName);
    return ind;
  }
  @SuppressWarnings("unchecked")
  public void test() {
    try {
      confRuns.setFileName("confRuns.xml");
      confDbs.setFileName("confDbs.xml");
      confDatasources.setFileName("confDatasources.xml");
      confMethods.setFileName("confMethods.xml");

      confRuns.load();
      confDbs.load();
      confDatasources.load();
      confMethods.load();

      List<String> runs = confRuns.getList("run");
      log.info("Start of testing");
      // runs = new TestRun[confRuns.getInt("threads")];
      int numRuns = confRuns.getInt("threads");
      String resultsFile = "";
      semRuns = new Semaphore(numRuns);
      // Iterate through runs
      for (String run : runs) {
        int dbId = 0;
        run = "runs." + run;
        // Iterate through dbs
        while (confRuns.getProperty(run + ".dbs.db(" + dbId + ").name") != null) {
          String dbName = confRuns.getString(run + ".dbs.db(" + dbId + ").name");
          List<String> datasources = confRuns.getList(run + ".dbs.db(" + dbId + ").datasources");
          int datasourceId = 0;
          // Iterate through datasources
          for (String datasourceName : datasources) {
            int methodId = 0;
            // Iterate through methods
            while (confRuns.getProperty(run + ".methods.method(" + methodId + ").name") != null) {
              String methodName =
                  confRuns.getString(run + ".methods.method(" + methodId + ").name");
              int testId = 0;
              // Iterate through tests
              while (confRuns.getProperty(run + ".tests.test(" + testId + ").class") != null) {
                synchronized (semRuns) {
                  // Waiting for a free slot;
                  semRuns.acquire();

                  String testClass = confRuns.getString(run + ".tests.test(" + testId + ").class");
                  Constructor[] a = Class.forName(testClass).getConstructors();
                  log.info("Datasource " + datasourceName + ", method " + methodName);
                  System.gc();
                  BasicDataSource trainDataSource = getDataSource(datasourceName, dbName);
                  trainDataSource.configDriver(confRuns, run + ".dbs.db(" + dbId + ")");
                  trainDataSource.configDataSource(
                      confRuns, run + ".dbs.db(" + dbId + ").datasources(" + datasourceId + ")");
                  BasicDataSource testDataSource = getDataSource(datasourceName, dbName);
                  testDataSource.configDriver(confRuns, run + ".dbs.db(" + dbId + ")");
                  testDataSource.configDataSource(
                      confRuns, run + ".dbs.db(" + dbId + ").datasources(" + datasourceId + ")");

                  // ExportAsTHSource.exportAsTHSource(trainDataSource, "C:\\data\\",
                  // trainDataSource.getName());
                  // writeRecords(trainDataSource);
                  // writeRecords(testDataSource);
                  // DataSourceStatistics b = new DataSourceStatistics(trainDataSource.getName());
                  // b.getStatistics(trainDataSource);
                  // semRuns.release();
                  InductiveMethod method = getMethod(methodName);
                  method.configClassifier(confRuns, run + ".methods.method(" + methodId + ")");

                  Test test = (Test) a[0].newInstance();
                  test.configTest(confRuns, run + ".tests.test(" + testId + ")");
                  resultsFile = test.getResultsInterpreter().getFilePrefix() + ".csv";

                  log.info("Testing datasource " + trainDataSource.getName());
                  // Making new thread for a new test.
                  new TestRun(this, trainDataSource, testDataSource, method, test).start();
                  // Wait 1 second for avoid of the colision
                  // in writing of results.
                  Thread.sleep(1000);
                }
                testId++;
              }
              methodId++;
            }
            datasourceId++;
          }
          dbId++;
        }
      }
      // Waiting for all other threads to finish.
      for (int i = 0; i < numRuns; i++) semRuns.acquire();

      log.info("End of testing");

      Process p = Runtime.getRuntime().exec("cmd ", null, null);
      p.getOutputStream().write(("loadResults.bat " + resultsFile + "\n").getBytes());
      p.getOutputStream().flush();
      p.getOutputStream().write("exit\n".getBytes());
      p.getOutputStream().flush();
      BufferedReader stdOut = new BufferedReader(new InputStreamReader(p.getInputStream()));
      BufferedReader stdErr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      while (true) {
        try {
          p.exitValue();
          break;
        } catch (Exception e) {
          while (stdOut.ready() || stdErr.ready()) {
            if (stdOut.ready()) stdOut.readLine();
            else stdErr.readLine();
          }
        }
      }
      p.waitFor();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }