// 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;

/*
 * Copyright (c) 2012 - 2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.ferstl.maven.pomenforcers;



/**
 * This enforcer makes sure that your <code>modules</code> section is sorted
 * alphabetically. Modules that should occur at a specific position in the
 * <code>&lt;modules&gt;</code> section can be ignored.
 * <pre>
 * ### Example
 *     &lt;rules&gt;
 *       &lt;moduleOrder implementation=&quot;com.github.ferstl.maven.pomenforcers.PedanticModuleOrderEnforcer&quot;&gt;
 *         &lt;!-- These modules may occur at any place in the modules section --&gt;
 *         &lt;ignoredModules&gt;dist-deb,dist-rpm&lt;/ignoredModules&gt;
 *        &lt;/moduleOrder&gt;
 *     &lt;/rules&gt;
 * </pre>
 *
 * @id {@link PedanticEnforcerRule#MODULE_ORDER}
 * @since 1.0.0
 */
public class PedanticModuleOrderEnforcer extends AbstractPedanticEnforcer {

  /**
   * All modules in this set won't be checked for the correct order.
   */
  private final Set<String> ignoredModules;

  public PedanticModuleOrderEnforcer() {
    this.ignoredModules = Sets.newLinkedHashSet();
  }

  /**
   * Comma-separated list of ignored modules. All modules in this list may occur at any place in the
   * <code>modules</code> section.
   *
   * @param ignoredModules Comma-separated list of ignored modules.
   * @configParam
   * @since 1.0.0
   */
  public void setIgnoredModules(String ignoredModules) {
    CommaSeparatorUtils.splitAndAddToCollection(ignoredModules, this.ignoredModules);
  }

  @Override
  protected PedanticEnforcerRule getDescription() {
    return PedanticEnforcerRule.MODULE_ORDER;
  }

  @Override
  protected void accept(PedanticEnforcerVisitor visitor) {
    visitor.visit(this);
  }

  @Override
  protected void doEnforce(ErrorReport report) {

// 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;

/*
 * Copyright (c) 2012 - 2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.ferstl.maven.pomenforcers;



/**
 * This enforcer makes sure that your <code>modules</code> section is sorted
 * alphabetically. Modules that should occur at a specific position in the
 * <code>&lt;modules&gt;</code> section can be ignored.
 * <pre>
 * ### Example
 *     &lt;rules&gt;
 *       &lt;moduleOrder implementation=&quot;com.github.ferstl.maven.pomenforcers.PedanticModuleOrderEnforcer&quot;&gt;
 *         &lt;!-- These modules may occur at any place in the modules section --&gt;
 *         &lt;ignoredModules&gt;dist-deb,dist-rpm&lt;/ignoredModules&gt;
 *        &lt;/moduleOrder&gt;
 *     &lt;/rules&gt;
 * </pre>
 *
 * @id {@link PedanticEnforcerRule#MODULE_ORDER}
 * @since 1.0.0
 */
public class PedanticModuleOrderEnforcer extends AbstractPedanticEnforcer {

  /**
   * All modules in this set won't be checked for the correct order.
   */
  private final Set<String> ignoredModules;

  public PedanticModuleOrderEnforcer() {
    this.ignoredModules = Sets.newLinkedHashSet();
  }

  /**
   * Comma-separated list of ignored modules. All modules in this list may occur at any place in the
   * <code>modules</code> section.
   *
   * @param ignoredModules Comma-separated list of ignored modules.
   * @configParam
   * @since 1.0.0
   */
  public void setIgnoredModules(String ignoredModules) {
    CommaSeparatorUtils.splitAndAddToCollection(ignoredModules, this.ignoredModules);
  }

  @Override
  protected PedanticEnforcerRule getDescription() {
    return PedanticEnforcerRule.MODULE_ORDER;
  }

  @Override
  protected void accept(PedanticEnforcerVisitor visitor) {
    visitor.visit(this);
  }

  @Override
  protected void doEnforce(ErrorReport report) {

    MavenProject project = EnforcerRuleUtils.getMavenProject(getHelper());
