/**
  * Method provides test creator instance. Basically introduced for better mocking capabilities in
  * unit tests but also useful for subclasses to provide customized creator instance. .
  *
  * @return test creator.
  */
 public TestCaseCreator getTestCaseCreator() {
   return TestCaseCreator.build();
 }
  /** @see org.apache.maven.plugin.AbstractMojo#execute() */
  public void execute() throws MojoExecutionException {
    try {
      while (interactiveMode && !StringUtils.hasText(pathToWsdl)) {
        pathToWsdl = prompter.prompt("Enter path to WSDL");
      }

      if (!StringUtils.hasText(pathToWsdl)) {
        throw new MojoExecutionException("Please provide proper path to WSDL file");
      }

      String wsdlNsDelaration = "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/' ";

      // compile wsdl and xsds right now, otherwise later input is useless:
      XmlObject wsdl = compileWsdl();
      SchemaTypeSystem schemaTypeSystem = compileXsd(wsdl);

      getLog().info(separator);
      getLog().info("WSDL compilation successful");
      String serviceName = evaluateAsString(wsdl, wsdlNsDelaration + ".//wsdl:portType/@name");
      getLog().info("Found service: " + serviceName);

      getLog().info(separator);
      getLog().info("Found service operations:");
      XmlObject[] messages = wsdl.selectPath(wsdlNsDelaration + ".//wsdl:message");
      XmlObject[] operations =
          wsdl.selectPath(wsdlNsDelaration + ".//wsdl:portType/wsdl:operation");
      for (XmlObject operation : operations) {
        getLog().info(evaluateAsString(operation, wsdlNsDelaration + "./@name"));
      }
      getLog().info(separator);

      getLog().info("Generating test cases for service operations ...");
      if (interactiveMode) {
        namePrefix = prompter.prompt("Enter test name prefix", namePrefix);
        nameSuffix = prompter.prompt("Enter test name suffix", nameSuffix);
        author = prompter.prompt("Enter test author:", author);
        description = prompter.prompt("Enter test description:", description);
        targetPackage = prompter.prompt("Enter test package:", targetPackage);
        framework = prompter.prompt("Choose unit test framework", framework);

        String confirm =
            prompter.prompt(
                "Confirm test creation:\n"
                    + "framework: "
                    + framework
                    + "\n"
                    + "name e.g.: "
                    + namePrefix
                    + evaluateAsString(operations[0], wsdlNsDelaration + "./@name")
                    + nameSuffix
                    + "\n"
                    + "author: "
                    + author
                    + "\n"
                    + "description: "
                    + description
                    + "\n"
                    + "package: "
                    + targetPackage
                    + "\n",
                CollectionUtils.arrayToList(new String[] {"y", "n"}),
                "y");

        if (confirm.equalsIgnoreCase("n")) {
          return;
        }
      }

      for (XmlObject operation : operations) {
        String operationName = evaluateAsString(operation, wsdlNsDelaration + "./@name");
        String inputMessage =
            removeNsPrefix(evaluateAsString(operation, wsdlNsDelaration + "./wsdl:input/@message"));
        String outputMessage =
            removeNsPrefix(
                evaluateAsString(operation, wsdlNsDelaration + "./wsdl:output/@message"));

        String inputElement = null;
        String outputElement = null;
        for (XmlObject message : messages) {
          String messageName = evaluateAsString(message, wsdlNsDelaration + "./@name");

          if (messageName.equals(inputMessage)) {
            inputElement =
                removeNsPrefix(
                    evaluateAsString(message, wsdlNsDelaration + "./wsdl:part/@element"));
          }

          if (messageName.equals(outputMessage)) {
            outputElement =
                removeNsPrefix(
                    evaluateAsString(message, wsdlNsDelaration + "./wsdl:part/@element"));
          }
        }

        SchemaType requestElem = getSchemaType(schemaTypeSystem, operationName, inputElement);
        SchemaType responseElem = getSchemaType(schemaTypeSystem, operationName, outputElement);

        String testName = namePrefix + operationName + nameSuffix;

        // Now generate it
        TestCaseCreator creator =
            getTestCaseCreator()
                .withFramework(UnitFramework.fromString(framework))
                .withName(testName)
                .withAuthor(author)
                .withDescription(description)
                .usePackage(targetPackage)
                .withXmlRequest(SampleXmlUtil.createSampleForType(requestElem))
                .withXmlResponse(SampleXmlUtil.createSampleForType(responseElem));

        creator.createTestCase();

        getLog().info("Successfully created new test case " + targetPackage + "." + testName);
      }

    } catch (ArrayIndexOutOfBoundsException e) {
      getLog().info(e);
      getLog()
          .info(
              "Wrong parameter usage! See citrus:help for usage details (mvn citrus:help -Ddetail=true -Dgoal=create-suite-from-wsdl).");
    } catch (PrompterException e) {
      getLog().info(e);
      getLog()
          .info(
              "Failed to create suite! See citrus:help for usage details (mvn citrus:help -Ddetail=true -Dgoal=create-suite-from-wsdl).");
    } catch (IOException e) {
      getLog().info(e);
    }
  }