/**
   * @see
   *     org.springframework.test.context.support.AbstractTestExecutionListener#prepareTestInstance(org.springframework.test.context.TestContext)
   */
  @Override
  public void prepareTestInstance(TestContext testContext) throws Exception {
    synchronized (doneMonitor) {
      if (done) {
        return;
      } else {
        TestSuiteAwareExecutionListener.preparationDone();
      }

      ApplicationContext ctx = testContext.getApplicationContext();

      SequenceBeforeSuite beforeSuite = null;
      if (ctx.getBeansOfType(SequenceBeforeSuite.class).size() == 1) {
        beforeSuite = ctx.getBean(SequenceBeforeSuite.class);
      }

      SequenceAfterSuite afterSuite = null;
      if (ctx.getBeansOfType(SequenceAfterSuite.class).size() == 1) {
        afterSuite = ctx.getBean(SequenceAfterSuite.class);
      }

      com.consol.citrus.context.TestContext context =
          ctx.getBean(com.consol.citrus.context.TestContext.class);
      TestSuiteListeners testSuiteListener = ctx.getBean(TestSuiteListeners.class);

      if (beforeSuite != null) {
        try {
          beforeSuite.execute(context);
        } catch (Exception e) {
          throw new CitrusRuntimeException("Before suite failed with errors", e);
        }
      } else {
        testSuiteListener.onStart();
        testSuiteListener.onStartSuccess();
      }

      Runtime.getRuntime()
          .addShutdownHook(
              new Thread(new AfterSuiteShutdownHook(afterSuite, context, testSuiteListener)));
    }
  }