// Path: src/main/java/com/github/ferstl/maven/pomenforcers/util/CommaSeparatorUtils.java
// public final class CommaSeparatorUtils {
// 
//   private static final Splitter COMMA_SPLITTER = Splitter.on(",").trimResults().omitEmptyStrings();
// 
//   public static void splitAndAddToCollection(String commaSeparatedItems, Collection<String> collection) {
//     splitAndAddToCollection(commaSeparatedItems, collection, Function.identity());
//   }
// 
//   public static <T> void splitAndAddToCollection(String commaSeparatedItems, Collection<T> collection, Function<String, T> transformer) {
//     Iterable<String> items = COMMA_SPLITTER.split(commaSeparatedItems);
//     // Don't touch the collection if there is nothing to add.
//     if (items.iterator().hasNext()) {
//       collection.clear();
//     }
//     StreamSupport.stream(items.spliterator(), false)
//         .map(transformer)
//         .collect(toCollection(() -> collection));
//   }
// 
// }
// 
// Path: src/main/java/com/github/ferstl/maven/pomenforcers/util/EnforcerRuleUtils.java
// public final class EnforcerRuleUtils {
// 
//   private static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{.*?}");
// 
//   public static MavenProject getMavenProject(EnforcerRuleHelper helper) {
//     try {
//       return (MavenProject) helper.evaluate("${project}");
//     } catch (ExpressionEvaluationException e) {
//       throw new IllegalStateException("Unable to get maven project", e);
//     }
//   }
// 
//   public static String evaluateProperties(String input, EnforcerRuleHelper helper) {
//     if (!Strings.isNullOrEmpty(input)) {
//       Matcher matcher = PROPERTY_PATTERN.matcher(input);
//       StringBuffer substituted = new StringBuffer();
//       while (matcher.find()) {
//         String property = matcher.group();
//         matcher.appendReplacement(substituted, evaluateStringProperty(property, helper));
//       }
//       matcher.appendTail(substituted);
//       return substituted.toString();
//     }
//     return input;
//   }
// 
//   private static String evaluateStringProperty(String property, EnforcerRuleHelper helper) {
//     try {
//       return (String) helper.evaluate(property);
//     } catch (ExpressionEvaluationException e) {
//       throw new IllegalArgumentException("Unable to resolve property " + property);
//     } catch (ClassCastException e) {
//       throw new IllegalArgumentException("Property " + property + " does not evaluate to a String");
//     }
//   }
// 
//   private EnforcerRuleUtils() {
//   }
// }
// 
// Path: src/main/java/com/github/ferstl/maven/pomenforcers/ErrorReport.java
// public static <T> String toList(Collection<T> collection) {
//   return toList(collection, Function.identity());
// }


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.apache.maven.project.MavenProject;
import com.github.ferstl.maven.pomenforcers.util.CommaSeparatorUtils;
import com.github.ferstl.maven.pomenforcers.util.EnforcerRuleUtils;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import static com.github.ferstl.maven.pomenforcers.ErrorReport.toList;

  @Override
  protected void doEnforce(ErrorReport report) {
    MavenProject project = EnforcerRuleUtils.getMavenProject(getHelper());
    // Do nothing if the project is not a parent project
    if (!isPomProject(project)) {
      return;
    }

    // Remove all modules to be ignored.
    List<String> declaredModules = new ArrayList<>(getProjectModel().getModules());
    declaredModules.removeAll(this.ignoredModules);

    // Enforce the module order
    Ordering<String> moduleOrdering = Ordering.natural();
    if (!moduleOrdering.isOrdered(declaredModules)) {
      reportError(report, declaredModules, moduleOrdering.immutableSortedCopy(declaredModules));
    }
  }

  private boolean isPomProject(MavenProject project) {
    return "pom".equals(project.getPackaging());
  }

  private void reportError(ErrorReport report, Collection<String> declaredModules, Collection<String> orderedModules) {
    report.addLine("You have to sort your modules alphabetically:")
        .emptyLine()
        .addDiff(declaredModules, orderedModules, "Actual Order", "Required Order");
    if (!this.ignoredModules.isEmpty()) {
      report.emptyLine()
          .addLine("You may place these modules anywhere in your <modules> section:")

// Path: src/main/java/com/github/ferstl/maven/pomenforcers/util/CommaSeparatorUtils.java
// public final class CommaSeparatorUtils {
// 
//   private static final Splitter COMMA_SPLITTER = Splitter.on(",").trimResults().omitEmptyStrings();
// 
//   public static void splitAndAddToCollection(String commaSeparatedItems, Collection<String> collection) {
//     splitAndAddToCollection(commaSeparatedItems, collection, Function.identity());
//   }
// 
//   public static <T> void splitAndAddToCollection(String commaSeparatedItems, Collection<T> collection, Function<String, T> transformer) {
//     Iterable<String> items = COMMA_SPLITTER.split(commaSeparatedItems);
//     // Don't touch the collection if there is nothing to add.
//     if (items.iterator().hasNext()) {
//       collection.clear();
//     }
//     StreamSupport.stream(items.spliterator(), false)
//         .map(transformer)
//         .collect(toCollection(() -> collection));
//   }
// 
// }
// 
// Path: src/main/java/com/github/ferstl/maven/pomenforcers/util/EnforcerRuleUtils.java
// public final class EnforcerRuleUtils {
// 
//   private static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{.*?}");
// 
//   public static MavenProject getMavenProject(EnforcerRuleHelper helper) {
//     try {
//       return (MavenProject) helper.evaluate("${project}");
//     } catch (ExpressionEvaluationException e) {
//       throw new IllegalStateException("Unable to get maven project", e);
//     }
//   }
// 
//   public static String evaluateProperties(String input, EnforcerRuleHelper helper) {
//     if (!Strings.isNullOrEmpty(input)) {
//       Matcher matcher = PROPERTY_PATTERN.matcher(input);
//       StringBuffer substituted = new StringBuffer();
//       while (matcher.find()) {
//         String property = matcher.group();
//         matcher.appendReplacement(substituted, evaluateStringProperty(property, helper));
//       }
//       matcher.appendTail(substituted);
//       return substituted.toString();
//     }
//     return input;
//   }
// 
//   private static String evaluateStringProperty(String property, EnforcerRuleHelper helper) {
//     try {
//       return (String) helper.evaluate(property);
//     } catch (ExpressionEvaluationException e) {
//       throw new IllegalArgumentException("Unable to resolve property " + property);
//     } catch (ClassCastException e) {
//       throw new IllegalArgumentException("Property " + property + " does not evaluate to a String");
//     }
//   }
// 
//   private EnforcerRuleUtils() {
//   }
// }
// 
// Path: src/main/java/com/github/ferstl/maven/pomenforcers/ErrorReport.java
// public static <T> String toList(Collection<T> collection) {
//   return toList(collection, Function.identity());
// }


// Path: src/main/java/com/github/ferstl/maven/pomenforcers/PedanticModuleOrderEnforcer.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.apache.maven.project.MavenProject;
import com.github.ferstl.maven.pomenforcers.util.CommaSeparatorUtils;
import com.github.ferstl.maven.pomenforcers.util.EnforcerRuleUtils;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import static com.github.ferstl.maven.pomenforcers.ErrorReport.toList;

  @Override
  protected void doEnforce(ErrorReport report) {
    MavenProject project = EnforcerRuleUtils.getMavenProject(getHelper());
    // Do nothing if the project is not a parent project
    if (!isPomProject(project)) {
      return;
    }

    // Remove all modules to be ignored.
    List<String> declaredModules = new ArrayList<>(getProjectModel().getModules());
    declaredModules.removeAll(this.ignoredModules);

    // Enforce the module order
    Ordering<String> moduleOrdering = Ordering.natural();
    if (!moduleOrdering.isOrdered(declaredModules)) {
      reportError(report, declaredModules, moduleOrdering.immutableSortedCopy(declaredModules));
    }
  }

  private boolean isPomProject(MavenProject project) {
    return "pom".equals(project.getPackaging());
  }

  private void reportError(ErrorReport report, Collection<String> declaredModules, Collection<String> orderedModules) {
    report.addLine("You have to sort your modules alphabetically:")
        .emptyLine()
        .addDiff(declaredModules, orderedModules, "Actual Order", "Required Order");
    if (!this.ignoredModules.isEmpty()) {
      report.emptyLine()
          .addLine("You may place these modules anywhere in your <modules> section:")

          .addLine(toList(this.ignoredModules));
