code: ///////////////////////////////////////////////////////////////////////////////////////////////
  // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
  // Copyright (C) 2001-2023 the original author or authors.
  //
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  //
  // This library is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this library; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  ///////////////////////////////////////////////////////////////////////////////////////////////
  
  package com.puppycrawl.tools.checkstyle.bdd;
  
  import java.nio.charset.StandardCharsets;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import com.puppycrawl.tools.checkstyle.Checker;
  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
  import com.puppycrawl.tools.checkstyle.TreeWalker;
  
  public final class TestInputConfiguration {
  
      private static final String ROOT_MODULE_NAME = Checker.class.getSimpleName();
  
      private static final Set<String> CHECKER_CHILDREN = new HashSet<>(Arrays.asList(
              "com.puppycrawl.tools.checkstyle.filefilters.BeforeExecutionExclusionFileFilter",
              "com.puppycrawl.tools.checkstyle.filters.SeverityMatchFilter",
              "com.puppycrawl.tools.checkstyle.filters.SuppressionFilter",
              "com.puppycrawl.tools.checkstyle.filters.SuppressionSingleFilter",
              "com.puppycrawl.tools.checkstyle.filters.SuppressWarningsFilter",
              "com.puppycrawl.tools.checkstyle.filters.SuppressWithNearbyTextFilter",
              "com.puppycrawl.tools.checkstyle.filters.SuppressWithPlainTextCommentFilter",
              "com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck",
              "com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck",
              "com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocPackageCheck",
              "com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck",
              "com.puppycrawl.tools.checkstyle.checks.UniquePropertiesCheck",
              "com.puppycrawl.tools.checkstyle.checks.OrderedPropertiesCheck",
              "com.puppycrawl.tools.checkstyle.checks.regexp.RegexpMultilineCheck",
              "com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck",
              "com.puppycrawl.tools.checkstyle.checks.regexp.RegexpOnFilenameCheck",
              "com.puppycrawl.tools.checkstyle.checks.sizes.FileLengthCheck",
              "com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck",
              "com.puppycrawl.tools.checkstyle.checks.whitespace.FileTabCharacterCheck"
      ));
  
      private final List<ModuleInputConfiguration> childrenModules;
  
      private final List<TestInputViolation> violations;
  
      private final List<TestInputViolation> filteredViolations;
  
      private TestInputConfiguration(List<ModuleInputConfiguration> childrenModules,
                                     List<TestInputViolation> violations,
                                     List<TestInputViolation> filteredViolations) {
          this.childrenModules = childrenModules;
          this.violations = violations;
          this.filteredViolations = filteredViolations;
      }
  
      public List<ModuleInputConfiguration> getChildrenModules() {
          return Collections.unmodifiableList(childrenModules);
      }
  
      public List<TestInputViolation> getViolations() {
          return Collections.unmodifiableList(violations);
      }
  
      public List<TestInputViolation> getFilteredViolations() {
          return Collections.unmodifiableList(filteredViolations);
      }
  
      public DefaultConfiguration createConfiguration() {
          final DefaultConfiguration root = new DefaultConfiguration(ROOT_MODULE_NAME);
          root.addProperty("charset", StandardCharsets.UTF_8.name());
          final DefaultConfiguration treeWalker = createTreeWalker();
          childrenModules
                  .stream()
                  .map(ModuleInputConfiguration::createConfiguration)
                  .forEach(moduleConfig -> {
                      if (CHECKER_CHILDREN.contains(moduleConfig.getName())) {
                          root.addChild(moduleConfig);
                      }
                      else if (!treeWalker.getName().equals(moduleConfig.getName())) {
                          treeWalker.addChild(moduleConfig);
                      }
                  });
          root.addChild(treeWalker);
          return root;
      }
  
      public DefaultConfiguration createConfigurationWithoutFilters() {
          final DefaultConfiguration root = new DefaultConfiguration(ROOT_MODULE_NAME);
          root.addProperty("charset", StandardCharsets.UTF_8.name());
          final DefaultConfiguration treeWalker = createTreeWalker();
          childrenModules
                  .stream()
                  .map(ModuleInputConfiguration::createConfiguration)
                  .filter(moduleConfig -> !moduleConfig.getName().endsWith("Filter"))
                  .forEach(moduleConfig -> {
                      if (CHECKER_CHILDREN.contains(moduleConfig.getName())) {
                          root.addChild(moduleConfig);
                      }
                      else if (!treeWalker.getName().equals(moduleConfig.getName())) {
                          treeWalker.addChild(moduleConfig);
                      }
                  });
          root.addChild(treeWalker);
          return root;
      }
  
      private DefaultConfiguration createTreeWalker() {
          final DefaultConfiguration treeWalker;
          if (childrenModules.get(0).getModuleName().equals(TreeWalker.class.getName())) {
              treeWalker = childrenModules.get(0).createConfiguration();
          }
          else {
              treeWalker = new DefaultConfiguration(TreeWalker.class.getName());
          }
          return treeWalker;
      }
  
      public static final class Builder {
  
          private final List<ModuleInputConfiguration> childrenModules = new ArrayList<>();
  
          private final List<TestInputViolation> violations = new ArrayList<>();
  
          private final List<TestInputViolation> filteredViolations = new ArrayList<>();
  
          public void addChildModule(ModuleInputConfiguration childModule) {
              childrenModules.add(childModule);
          }
  
          public void addViolation(int violationLine, String violationMessage) {
              violations.add(new TestInputViolation(violationLine, violationMessage));
          }
  
          public void addFilteredViolation(int violationLine, String violationMessage) {
              filteredViolations.add(new TestInputViolation(violationLine, violationMessage));
          }
  
          public TestInputConfiguration build() {
              return new TestInputConfiguration(
                      childrenModules,
                      violations,
                      filteredViolations
              );
          }
  
          public List<ModuleInputConfiguration> getChildrenModules() {
              return Collections.unmodifiableList(childrenModules);
          }
      }
  }
  