docs: @Override
      public void execute() throws MojoExecutionException, MojoFailureException {
          validateConfiguration();
  
          try {
              // set git flow configuration
              initGitFlowConfig();
  
              // check uncommitted changes
              checkUncommittedChanges();
  
              // fetch and check remote
              if (fetchRemote) {
                  gitFetchRemoteAndCompare(gitFlowConfig.getDevelopmentBranch());
              }
  
              String featureBranchName = null;
              if (settings.isInteractiveMode()) {
                  try {
                      while (StringUtils.isBlank(featureBranchName)) {
                          featureBranchName = prompter
                                  .prompt("What is a name of feature branch? "
                                          + gitFlowConfig
                                                  .getFeatureBranchPrefix());
  
                          if (!validateBranchName(featureBranchName,
                                  featureNamePattern)) {
                              featureBranchName = null;
                          }
                      }
                  } catch (PrompterException e) {
                      throw new MojoFailureException("feature-start", e);
                  }
              } else if (validateBranchName(featureName, featureNamePattern)) {
                  featureBranchName = featureName;
              }
  
              if (StringUtils.isBlank(featureBranchName)) {
                  throw new MojoFailureException("Feature name is blank.");
              }
  
              featureBranchName = StringUtils.deleteWhitespace(featureBranchName);
  
              // git for-each-ref refs/heads/feature/...
              final boolean featureBranchExists = gitCheckBranchExists(
                      gitFlowConfig.getFeatureBranchPrefix() + featureBranchName);
  
              if (featureBranchExists) {
                  throw new MojoFailureException(
                          "Feature branch with that name already exists. Cannot start feature.");
              }
  
              // git checkout -b ... develop
              gitCreateAndCheckout(
                      gitFlowConfig.getFeatureBranchPrefix() + featureBranchName,
                      gitFlowConfig.getDevelopmentBranch());
  
              if (!skipFeatureVersion && !tychoBuild) {
                  // get current project version from pom
                  final String currentVersion = getCurrentProjectVersion();
  
                  final String version = new GitFlowVersionInfo(currentVersion)
                          .featureVersion(featureBranchName);
  
                  if (StringUtils.isNotBlank(version)) {
                      // mvn versions:set -DnewVersion=...
                      // -DgenerateBackupPoms=false
                      mvnSetVersions(version);
  
                      Map<String, String> properties = new HashMap<String, String>();
                      properties.put("version", version);
                      properties.put("featureName", featureBranchName);
  
                      // git commit -a -m updating versions for feature branch
                      gitCommit(commitMessages.getFeatureStartMessage(),
                              properties);
                  }
              }
  
              if (installProject) {
                  // mvn clean install
                  mvnCleanInstall();
              }
  
              if (pushRemote) {
                  gitPush(gitFlowConfig.getFeatureBranchPrefix()
                          + featureBranchName, false);
              }
          } catch (CommandLineException e) {
              throw new MojoFailureException("feature-start", e);
          } catch (VersionParseException e) {
              throw new MojoFailureException("feature-start", e);
          }
      }