
package de.ivu.elect.dokumente.wahlvorschlag;

import static java.util.Collections.emptyList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import de.ivu.document.generator.template.annotations.Document;
import de.ivu.document.generator.template.annotations.DocumentComplexField;
import de.ivu.document.generator.template.annotations.DocumentRepeat;
import de.ivu.document.generator.template.annotations.DocumentSimpleField;
import de.ivu.document.generator.template.annotations.DocumentSubTemplate;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.control.GruppeByBerechnetePositionComparator;
import de.ivu.elect.business.gruppe.control.GruppeByRelativerPositionComparator;
import de.ivu.elect.business.gruppe.control.GruppeByWahlvorschlagErsterZeitpunktDerEinreichungComparator;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.pruefung.boundary.ZulassungPruefer;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.dokumente.CoreElectContext;
import de.ivu.elect.dokumente.ElectDocument;
import de.ivu.elect.dokumente.gebiet.GebietDokument;
import de.ivu.elect.dokumente.wahlausschuss.WahlausschussDokument;

@Document(DokumentVorlageArt.WAHLVORSCHLAEGE_NACH_GEBIET_DOKUMENT_PREFIX)
public class WahlvorschlaegeNachGebietDocument extends ElectDocument {

  private static final long serialVersionUID = 1L;

  @DocumentComplexField("Wurzelgebiet")
  public final GebietDokument wurzelgebiet; // ELECT-10132

  @DocumentSubTemplate
  @DocumentComplexField("Wahlausschuss")
  public final WahlausschussDokument wahlausschuss;

  /**
   * @deprecated
   * @see WahlvorschlaegeNachGebietDocument#wahlausschuss
   */
  @Deprecated
  @DocumentSubTemplate
  @DocumentComplexField("Wahlauschuss")
  public final WahlausschussDokument wahlauschuss;

  @DocumentSubTemplate
  @DocumentRepeat(value = "WahlvorschlaegeInGebieten", elementClass = WahlvorschlaegeAlsListeDocument.class, itemName = "gebietMitWahlvorschlaegen")
  public final List<WahlvorschlaegeAlsListeDocument> gebieteMitWahlvorschlaegen;

  @DocumentRepeat(value = "WahlvorschlaegeInGruppen", elementClass = CoreGruppeMitAllenWahlvorschlaegenDokument.class, itemName = "gruppeMitWahlvorschlaegen")
  public final List<CoreGruppeMitAllenWahlvorschlaegenDokument> gruppenMitWahlvorschlaegen;

  @DocumentRepeat(value = "WahlvorschlaegeInGruppenNachPositionRelativ", elementClass = CoreGruppeMitAllenWahlvorschlaegenDokument.class, itemName = "gruppeMitWahlvorschlaegen")
  public final List<CoreGruppeMitAllenWahlvorschlaegenDokument> gruppenMitWahlvorschlaegenSortiertNachRelativerPosition; // ELECT-11613

  @DocumentRepeat(value = "WahlvorschlaegeInGruppenNachPositionBerechnet", elementClass = CoreGruppeMitAllenWahlvorschlaegenDokument.class, itemName = "gruppeMitWahlvorschlaegen")
  public final List<CoreGruppeMitAllenWahlvorschlaegenDokument> gruppenMitWahlvorschlaegenSortiertNachBerechneterPosition;

  @DocumentRepeat(value = "WahlvorschlaegeInGruppenNachErsterZeitpunktDerEinreichung", elementClass = CoreGruppeMitAllenWahlvorschlaegenDokument.class, itemName = "gruppeMitWahlvorschlaegen")
  public final List<CoreGruppeMitAllenWahlvorschlaegenDokument> gruppenMitWahlvorschlaegenSortiertNachErsterZeitpunktDerEinreichung; // ELECT-11613

  @DocumentSimpleField("AnzahlWahlvorschlaegeInGebietenInsgesamt")
  public final Long anzahlWahlvorschlaegeInsgesamt;

  @DocumentSimpleField("AnzahlWahlvorschlaegeInGebietenZulassenErlaubt")
  public final Long anzahlWahlvorschlaegeZulassenErlaubt;

  @DocumentSimpleField("AnzahlWahlvorschlaegeInGebietenZugelassen")
  public final Long anzahlWahlvorschlaegeZugelassen;

  @DocumentSimpleField("AnzahlWahlvorschlaegeInGebietenNichtZugelassen")
  public final Long anzahlWahlvorschlaegeNichtZugelassen;

  @DocumentSimpleField("AnzahlListenInGebietenInsgesamt")
  public final Long anzahlListenInsgesamt;

  @DocumentSimpleField("AnzahlListenInGebietenZulassenErlaubt")
  public final Long anzahlListenZulassenErlaubt;

  @DocumentSimpleField("AnzahlListenInGebietenZugelassen")
  public final Long anzahlListenZugelassen;

  @DocumentSimpleField("AnzahlListenInGebietenNichtZugelassen")
  public final Long anzahlListenNichtZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenInsgesamt")
  public final Long anzahlListenkandidaturenInsgesamt;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenInsgesamtAufListenZulassenErlaubt")
  public final Long anzahlListenkandidaturenInsgesamtAufListenZulassenErlaubt;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenInsgesamtAufListenZugelassen")
  public final Long anzahlListenkandidaturenInsgesamtAufListenZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenInsgesamtAufListenNichtZugelassen")
  public final Long anzahlListenkandidaturenInsgesamtAufListenNichtZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZulassenErlaubt")
  public final Long anzahlListenkandidaturenZulassenErlaubt;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZulassenErlaubtAufListenZulassenErlaubt")
  public final Long anzahlListenkandidaturenZulassenErlaubtAufListenZulassenErlaubt;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZulassenErlaubtAufListenZugelassen")
  public final Long anzahlListenkandidaturenZulassenErlaubtAufListenZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZulassenErlaubtAufListenNichtZugelassen")
  public final Long anzahlListenkandidaturenZulassenErlaubtAufListenNichtZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZugelassen")
  public final Long anzahlListenkandidaturenZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZugelassenAufListenZulassenErlaubt")
  public final Long anzahlListenkandidaturenZugelassenAufListenZulassenErlaubt;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZugelassenAufListenZugelassen")
  public final Long anzahlListenkandidaturenZugelassenAufListenZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenZugelassenAufListenNichtZugelassen")
  public final Long anzahlListenkandidaturenZugelassenAufListenNichtZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenNichtZugelassen")
  public final Long anzahlListenkandidaturenNichtZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenNichtZugelassenAufListenZulassenErlaubt")
  public final Long anzahlListenkandidaturenNichtZugelassenAufListenZulassenErlaubt;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenNichtZugelassenAufListenZugelassen")
  public final Long anzahlListenkandidaturenNichtZugelassenAufListenZugelassen;

  @DocumentSimpleField("AnzahlListenkandidaturenInGebietenNichtZugelassenAufListenNichtZugelassen")
  public final Long anzahlListenkandidaturenNichtZugelassenAufListenNichtZugelassen;

  @DocumentSimpleField("AnzahlDirektkandidatenInGebietenInsgesamt")
  public final Long anzahlDirektkandidatenInsgesamt;

  @DocumentSimpleField("AnzahlDirektkandidatenInGebietenZulassenErlaubt")
  public final Long anzahlDirektkandidatenZulassenErlaubt;

  @DocumentSimpleField("AnzahlDirektkandidatenInGebietenZugelassen")
  public final Long anzahlDirektkandidatenZugelassen;

  @DocumentSimpleField("AnzahlDirektkandidatenInGebietenNichtZugelassen")
  public final Long anzahlDirektkandidatenNichtZugelassen;

  @DocumentSimpleField("AnzahlReferendumOptionenInGebietenInsgesamt")
  public final Long anzahlReferendumOptionenInsgesamt;

  @DocumentSimpleField("AnzahlReferendumOptionenInGebietenZulassenErlaubt")
  public final Long anzahlReferendumOptionenZulassenErlaubt;

  @DocumentSimpleField("AnzahlReferendumOptionenInGebietenZugelassen")
  public final Long anzahlReferendumOptionenZugelassen;

  @DocumentSimpleField("AnzahlReferendumOptionenInGebietenNichtZugelassen")
  public final Long anzahlReferendumOptionenNichtZugelassen;

  public WahlvorschlaegeNachGebietDocument(CoreElectContext coreElectContext, Gebiet gebiet, WahlvorschlagCoreDaten wahlvorschlagCoreDaten) {
    super(coreElectContext);

    this.wurzelgebiet = new GebietDokument(coreElectContext, gebiet.getWurzelgebiet());

    this.gebieteMitWahlvorschlaegen = collectGebieteMitWahlvorschlaegen(coreElectContext, gebiet, wahlvorschlagCoreDaten);
    this.gruppenMitWahlvorschlaegen = collectGruppenMitWahlvorschlaegen(coreElectContext, gebiet, wahlvorschlagCoreDaten);

    this.gruppenMitWahlvorschlaegenSortiertNachRelativerPosition = createGruppeDocuments(coreElectContext, gebiet, wahlvorschlagCoreDaten, new GruppeByRelativerPositionComparator());
    this.gruppenMitWahlvorschlaegenSortiertNachBerechneterPosition = createGruppeDocuments(coreElectContext, gebiet, wahlvorschlagCoreDaten,
        new GruppeByBerechnetePositionComparator(wahlvorschlagCoreDaten.getWahlvorschlaegeInWahlPerGruppe().keySet()));
    this.gruppenMitWahlvorschlaegenSortiertNachErsterZeitpunktDerEinreichung = createGruppeDocuments(coreElectContext, gebiet, wahlvorschlagCoreDaten,
        new GruppeByWahlvorschlagErsterZeitpunktDerEinreichungComparator(wahlvorschlagCoreDaten.getWahlvorschlaegeInWahlPerGruppe()));

    this.wahlausschuss = new WahlausschussDokument(coreElectContext, gebiet, wahlvorschlagCoreDaten.getWahlausschussmitgliederInWahlPerGebiet());
    this.wahlauschuss = this.wahlausschuss;

    long anzahlWahlvorschlaegeInsgesamt = 0;
    long anzahlWahlvorschlaegeZulassenErlaubt = 0;
    long anzahlWahlvorschlaegeZugelassen = 0;
    long anzahlWahlvorschlaegeNichtZugelassen = 0;

    long anzahlListenInsgesamt = 0;
    long anzahlListenZulassenErlaubt = 0;
    long anzahlListenZugelassen = 0;
    long anzahlListenNichtZugelassen = 0;

    long anzahlListenkandidaturenInsgesamt = 0;
    long anzahlListenkandidaturenInsgesamtAufListenZulassenErlaubt = 0;
    long anzahlListenkandidaturenInsgesamtAufListenZugelassen = 0;
    long anzahlListenkandidaturenInsgesamtAufListenNichtZugelassen = 0;

    long anzahlListenkandidaturenZulassenErlaubt = 0;
    long anzahlListenkandidaturenZulassenErlaubtAufListenZulassenErlaubt = 0;
    long anzahlListenkandidaturenZulassenErlaubtAufListenZugelassen = 0;
    long anzahlListenkandidaturenZulassenErlaubtAufListenNichtZugelassen = 0;

    long anzahlListenkandidaturenZugelassen = 0;
    long anzahlListenkandidaturenZugelassenAufListenZulassenErlaubt = 0;
    long anzahlListenkandidaturenZugelassenAufListenZugelassen = 0;
    long anzahlListenkandidaturenZugelassenAufListenNichtZugelassen = 0;

    long anzahlListenkandidaturenNichtZugelassen = 0;
    long anzahlListenkandidaturenNichtZugelassenAufListenZulassenErlaubt = 0;
    long anzahlListenkandidaturenNichtZugelassenAufListenZugelassen = 0;
    long anzahlListenkandidaturenNichtZugelassenAufListenNichtZugelassen = 0;

    long anzahlDirektkandidatenInsgesamt = 0;
    long anzahlDirektkandidatenZulassenErlaubt = 0;
    long anzahlDirektkandidatenZugelassen = 0;
    long anzahlDirektkandidatenNichtZugelassen = 0;

    long anzahlReferendumOptionenInsgesamt = 0;
    long anzahlReferendumOptionenZulassenErlaubt = 0;
    long anzahlReferendumOptionenZugelassen = 0;
    long anzahlReferendumOptionenNichtZugelassen = 0;

    for (WahlvorschlaegeAlsListeDocument wahlvorschlaegeAlsListeDocument : this.gebieteMitWahlvorschlaegen) {
      anzahlWahlvorschlaegeInsgesamt += wahlvorschlaegeAlsListeDocument.anzahlWahlvorschlaegeInsgesamt;
      anzahlWahlvorschlaegeZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlWahlvorschlaegeZulassenErlaubt;
      anzahlWahlvorschlaegeZugelassen += wahlvorschlaegeAlsListeDocument.anzahlWahlvorschlaegeZugelassen;
      anzahlWahlvorschlaegeNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlWahlvorschlaegeNichtZugelassen;

      anzahlListenInsgesamt += wahlvorschlaegeAlsListeDocument.anzahlListenInsgesamt;
      anzahlListenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlListenZulassenErlaubt;
      anzahlListenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenZugelassen;
      anzahlListenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenNichtZugelassen;

      anzahlListenkandidaturenInsgesamt += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenInsgesamt;
      anzahlListenkandidaturenInsgesamtAufListenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenInsgesamtAufListenZulassenErlaubt;
      anzahlListenkandidaturenInsgesamtAufListenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenInsgesamtAufListenZugelassen;
      anzahlListenkandidaturenInsgesamtAufListenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenInsgesamtAufListenNichtZugelassen;

      anzahlListenkandidaturenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZulassenErlaubt;
      anzahlListenkandidaturenZulassenErlaubtAufListenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZulassenErlaubtAufListenZulassenErlaubt;
      anzahlListenkandidaturenZulassenErlaubtAufListenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZulassenErlaubtAufListenZugelassen;
      anzahlListenkandidaturenZulassenErlaubtAufListenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZulassenErlaubtAufListenNichtZugelassen;

      anzahlListenkandidaturenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZugelassen;
      anzahlListenkandidaturenZugelassenAufListenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZugelassenAufListenZulassenErlaubt;
      anzahlListenkandidaturenZugelassenAufListenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZugelassenAufListenZugelassen;
      anzahlListenkandidaturenZugelassenAufListenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenZugelassenAufListenNichtZugelassen;

      anzahlListenkandidaturenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenNichtZugelassen;
      anzahlListenkandidaturenNichtZugelassenAufListenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenNichtZugelassenAufListenZulassenErlaubt;
      anzahlListenkandidaturenNichtZugelassenAufListenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenNichtZugelassenAufListenZugelassen;
      anzahlListenkandidaturenNichtZugelassenAufListenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlListenkandidaturenNichtZugelassenAufListenNichtZugelassen;

      anzahlDirektkandidatenInsgesamt += wahlvorschlaegeAlsListeDocument.anzahlDirektkandidatenInsgesamt;
      anzahlDirektkandidatenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlDirektkandidatenZulassenErlaubt;
      anzahlDirektkandidatenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlDirektkandidatenZugelassen;
      anzahlDirektkandidatenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlDirektkandidatenNichtZugelassen;

      anzahlReferendumOptionenInsgesamt += wahlvorschlaegeAlsListeDocument.anzahlReferendumOptionenInsgesamt;
      anzahlReferendumOptionenZulassenErlaubt += wahlvorschlaegeAlsListeDocument.anzahlReferendumOptionenZulassenErlaubt;
      anzahlReferendumOptionenZugelassen += wahlvorschlaegeAlsListeDocument.anzahlReferendumOptionenZugelassen;
      anzahlReferendumOptionenNichtZugelassen += wahlvorschlaegeAlsListeDocument.anzahlReferendumOptionenNichtZugelassen;
    }

    this.anzahlWahlvorschlaegeInsgesamt = anzahlWahlvorschlaegeInsgesamt;
    this.anzahlWahlvorschlaegeZulassenErlaubt = anzahlWahlvorschlaegeZulassenErlaubt;
    this.anzahlWahlvorschlaegeZugelassen = anzahlWahlvorschlaegeZugelassen;
    this.anzahlWahlvorschlaegeNichtZugelassen = anzahlWahlvorschlaegeNichtZugelassen;

    this.anzahlListenInsgesamt = anzahlListenInsgesamt;
    this.anzahlListenZulassenErlaubt = anzahlListenZulassenErlaubt;
    this.anzahlListenZugelassen = anzahlListenZugelassen;
    this.anzahlListenNichtZugelassen = anzahlListenNichtZugelassen;

    this.anzahlListenkandidaturenInsgesamt = anzahlListenkandidaturenInsgesamt;
    this.anzahlListenkandidaturenInsgesamtAufListenZulassenErlaubt = anzahlListenkandidaturenInsgesamtAufListenZulassenErlaubt;
    this.anzahlListenkandidaturenInsgesamtAufListenZugelassen = anzahlListenkandidaturenInsgesamtAufListenZugelassen;
    this.anzahlListenkandidaturenInsgesamtAufListenNichtZugelassen = anzahlListenkandidaturenInsgesamtAufListenNichtZugelassen;

    this.anzahlListenkandidaturenZulassenErlaubt = anzahlListenkandidaturenZulassenErlaubt;
    this.anzahlListenkandidaturenZulassenErlaubtAufListenZulassenErlaubt = anzahlListenkandidaturenZulassenErlaubtAufListenZulassenErlaubt;
    this.anzahlListenkandidaturenZulassenErlaubtAufListenZugelassen = anzahlListenkandidaturenZulassenErlaubtAufListenZugelassen;
    this.anzahlListenkandidaturenZulassenErlaubtAufListenNichtZugelassen = anzahlListenkandidaturenZulassenErlaubtAufListenNichtZugelassen;

    this.anzahlListenkandidaturenZugelassen = anzahlListenkandidaturenZugelassen;
    this.anzahlListenkandidaturenZugelassenAufListenZulassenErlaubt = anzahlListenkandidaturenZugelassenAufListenZulassenErlaubt;
    this.anzahlListenkandidaturenZugelassenAufListenZugelassen = anzahlListenkandidaturenZugelassenAufListenZugelassen;
    this.anzahlListenkandidaturenZugelassenAufListenNichtZugelassen = anzahlListenkandidaturenZugelassenAufListenNichtZugelassen;

    this.anzahlListenkandidaturenNichtZugelassen = anzahlListenkandidaturenNichtZugelassen;
    this.anzahlListenkandidaturenNichtZugelassenAufListenZulassenErlaubt = anzahlListenkandidaturenNichtZugelassenAufListenZulassenErlaubt;
    this.anzahlListenkandidaturenNichtZugelassenAufListenZugelassen = anzahlListenkandidaturenNichtZugelassenAufListenZugelassen;
    this.anzahlListenkandidaturenNichtZugelassenAufListenNichtZugelassen = anzahlListenkandidaturenNichtZugelassenAufListenNichtZugelassen;

    this.anzahlDirektkandidatenInsgesamt = anzahlDirektkandidatenInsgesamt;
    this.anzahlDirektkandidatenZulassenErlaubt = anzahlDirektkandidatenZulassenErlaubt;
    this.anzahlDirektkandidatenZugelassen = anzahlDirektkandidatenZugelassen;
    this.anzahlDirektkandidatenNichtZugelassen = anzahlDirektkandidatenNichtZugelassen;

    this.anzahlReferendumOptionenInsgesamt = anzahlReferendumOptionenInsgesamt;
    this.anzahlReferendumOptionenZulassenErlaubt = anzahlReferendumOptionenZulassenErlaubt;
    this.anzahlReferendumOptionenZugelassen = anzahlReferendumOptionenZugelassen;
    this.anzahlReferendumOptionenNichtZugelassen = anzahlReferendumOptionenNichtZugelassen;
  }

  private List<WahlvorschlaegeAlsListeDocument> collectGebieteMitWahlvorschlaegen(CoreElectContext coreElectContext, Gebiet gebiet, WahlvorschlagCoreDaten wahlvorschlagCoreDaten) {
    List<WahlvorschlaegeAlsListeDocument> result = new ArrayList<>();

    Map<Gebiet, Collection<Wahlvorschlag>> wahlvorschlaegeInWahlPerGebiet = wahlvorschlagCoreDaten.getWahlvorschlaegeInWahlPerGebiet();

    for (Gebiet untergeordnetesWahlvorschlaggebiet : collectUntergeordneteWahlvorschlaggebiete(gebiet)) {
      result.add(new WahlvorschlaegeAlsListeDocument(coreElectContext, untergeordnetesWahlvorschlaggebiet, wahlvorschlagCoreDaten,
          wahlvorschlaegeInWahlPerGebiet.getOrDefault(untergeordnetesWahlvorschlaggebiet, new HashSet<>())));
    }

    return result;
  }

  private List<Gebiet> collectUntergeordneteWahlvorschlaggebiete(Gebiet gebiet) {
    if (gebiet == null) {
      return new ArrayList<>();
    }

    List<Gebiet> result = new ArrayList<>();

    if (gebiet.isWahlvorschlaggebiet()) {
      result.add(gebiet);
    }

    for (Gebiet untergeordnetesGebiet : gebiet.getGebieteSortiertNachPosition()) {
      result.addAll(collectUntergeordneteWahlvorschlaggebiete(untergeordnetesGebiet));
    }

    return result;
  }

  private List<CoreGruppeMitAllenWahlvorschlaegenDokument> collectGruppenMitWahlvorschlaegen(CoreElectContext coreElectContext, Gebiet gebiet, WahlvorschlagCoreDaten wahlvorschlagCoreDaten) {
    return createGruppeDocuments(coreElectContext, gebiet, wahlvorschlagCoreDaten, new GruppeByBerechnetePositionComparator(wahlvorschlagCoreDaten.getWahlvorschlaegeInWahlPerGruppe().keySet())); // ELECT-10835
  }

  private List<CoreGruppeMitAllenWahlvorschlaegenDokument> createGruppeDocuments(CoreElectContext coreElectContext, Gebiet gebiet, WahlvorschlagCoreDaten wahlvorschlagCoreDaten,
      Comparator<Gruppe> comparator) {
    List<CoreGruppeMitAllenWahlvorschlaegenDokument> result = new ArrayList<>();

    ZulassungPruefer zulassungPruefer = wahlvorschlagCoreDaten.getZulassungPruefer();
    Map<Gruppe, Collection<Wahlvorschlag>> wahlvorschlaegeInWahlPerGruppe = wahlvorschlagCoreDaten.getWahlvorschlaegeInWahlPerGruppe();

    List<Gruppe> gruppenSorted = new ArrayList<>(wahlvorschlaegeInWahlPerGruppe.keySet());
    gruppenSorted.sort(new GruppeByRelativerPositionComparator()); // Standardsortierung...
    gruppenSorted.sort(comparator);

    for (Gruppe gruppe : gruppenSorted) {
      result.add(CoreGruppeMitAllenWahlvorschlaegenDokument.lookupOrCreate(coreElectContext, zulassungPruefer, gruppe, wahlvorschlaegeInWahlPerGruppe.getOrDefault(gruppe, emptyList())));
    }

    return result;
  }
}
