class SpellingData {

  private final AhoCorasickDoubleArrayTrie<String> trie = new AhoCorasickDoubleArrayTrie<>();
  private final AhoCorasickDoubleArrayTrie<String> sentenceStartTrie = new AhoCorasickDoubleArrayTrie<>();

  SpellingData(String filePath) {
    trie.build(getCoherencyMap(filePath, false));
    sentenceStartTrie.build(getCoherencyMap(filePath, true));
  }

  @NotNull
  private static Map<String, String> getCoherencyMap(String filePath, boolean sentStartMode) {
    List<String> lines = JLanguageTool.getDataBroker().getFromResourceDirAsLines(filePath);
    Map<String,String> coherencyMap = new HashMap<>();
    for (String line : lines) {
      if (line.startsWith("#")) {
        continue;
      }
      String[] parts = line.split(";");
      if (parts.length < 2) {
        throw new RuntimeException("Unexpected format in file " + filePath + ": " + line);
      }
      String oldSpelling = parts[0];
      String newSpelling = parts[1];
      sanityChecks(filePath, line, oldSpelling, newSpelling, coherencyMap);
      if (sentStartMode && startsWithLowercase(oldSpelling) && startsWithLowercase(newSpelling)) {
        // lowercase words can be uppercase at sentence start:
        coherencyMap.put(uppercaseFirstChar(oldSpelling), uppercaseFirstChar(newSpelling));
      } else {
        coherencyMap.put(oldSpelling, newSpelling);
      }
      if (oldSpelling.contains("ß") && oldSpelling.replaceAll("ß", "ss").equals(newSpelling)) {
        try {
          String[] forms = GermanSynthesizer.INSTANCE.synthesizeForPosTags(oldSpelling, s -> true);
          for (String form : forms) {
            if (!form.contains("ss")) {  // avoid e.g. "Schlüsse" as form of "Schluß", as that's the new spelling
              coherencyMap.put(form, form.replaceAll("ß", "ss"));
            }
          }
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    }
    return coherencyMap;
  }

  private static void sanityChecks(String filePath, String line, String oldSpelling, String newSpelling, Map<String, String> coherencyMap) {<FILL_FUNCTION_BODY>}

  public AhoCorasickDoubleArrayTrie<String> getTrie() {
    return trie;
  }

  public AhoCorasickDoubleArrayTrie<String> getSentenceStartTrie() {
    return sentenceStartTrie;
  }
}

    if (oldSpelling.equals(newSpelling)) {
      throw new RuntimeException("Old and new spelling are the same in " + filePath + ": " + line);
    }
    String lookup = coherencyMap.get(newSpelling);
    if (lookup != null && lookup.equals(oldSpelling)) {
      throw new RuntimeException("Contradictory entry in " + filePath + ": '" + oldSpelling + "' suggests '" + lookup + "' and vice versa");
    }
    if (coherencyMap.containsKey(oldSpelling) && !coherencyMap.get(oldSpelling).equals(newSpelling)) {
      throw new RuntimeException("Duplicate key in " + filePath + ": " + oldSpelling + ", val: " + coherencyMap.get(oldSpelling) + " vs. " + newSpelling);
    }
  
<no_super_class>