/** @TODO clean up this code */
    private void addDayRotation(List<Move> moveList) {
      for (ListIterator<Day> firstDayIt = dayList.listIterator(); firstDayIt.hasNext(); ) {
        Day firstDay = firstDayIt.next();
        Map<Team, Match> firstDayTeamMap = dayTeamMap.get(firstDay);
        for (ListIterator<Day> secondDayIt = dayList.listIterator(firstDayIt.nextIndex());
            secondDayIt.hasNext(); ) {
          Day secondDay = secondDayIt.next();
          List<Match> clonedFirstDayMatchList = new ArrayList<Match>(firstDayTeamMap.values());
          while (!clonedFirstDayMatchList.isEmpty()) {
            List<Match> rotateList = new ArrayList<Match>(4);
            Match startMatch = clonedFirstDayMatchList.remove(0);
            boolean otherInFirst = false;
            rotateList.add(startMatch);
            Team startHomeTeam = startMatch.getHomeTeam();
            Team nextTeamToFind = startMatch.getAwayTeam();
            while (!startHomeTeam.equals(nextTeamToFind)) {
              Map<Team, Match> subTeamMap = dayTeamMap.get(otherInFirst ? firstDay : secondDay);
              Match repairMatch = subTeamMap.get(nextTeamToFind);
              if (otherInFirst) {
                clonedFirstDayMatchList.remove(repairMatch);
              }
              rotateList.add(repairMatch);
              nextTeamToFind = getOtherTeam(repairMatch, nextTeamToFind);
              otherInFirst = !otherInFirst;
            }
            // assert(rotateList.size() % 2 == 0);

            // if size is 2 then addCachedHomeAwaySwapMoves will have done it
            if (rotateList.size() > 2) {
              List<Match> emptyList = Collections.emptyList();
              Move rotateMove = new MultipleMatchListRotateMove(rotateList, emptyList);
              moveList.add(rotateMove);
            }
          }
        }
      }
    }
    /** @TODO clean up this code */
    private void addTeamRotation(List<Move> moveList) {
      for (ListIterator<Team> firstTeamIt = teamList.listIterator(); firstTeamIt.hasNext(); ) {
        Team firstTeam = firstTeamIt.next();
        Map<Day, Match> firstTeamDayMap = teamDayMap.get(firstTeam);
        for (ListIterator<Team> secondTeamIt = teamList.listIterator(firstTeamIt.nextIndex());
            secondTeamIt.hasNext(); ) {
          Team secondTeam = secondTeamIt.next();
          List<Match> clonedFirstTeamMatchList = new ArrayList<Match>(firstTeamDayMap.values());
          while (!clonedFirstTeamMatchList.isEmpty()) {
            List<Match> firstRotateList = new ArrayList<Match>();
            List<Match> secondRotateList = new ArrayList<Match>();

            Match firstStartMatch = clonedFirstTeamMatchList.remove(0);
            Team firstStartTeam = getOtherTeam(firstStartMatch, firstTeam);
            Day startDay = firstStartMatch.getDay();
            boolean firstTeamIsHomeTeam = firstStartMatch.getHomeTeam().equals(firstTeam);
            Match secondStartMatch = teamDayMap.get(secondTeam).get(startDay);
            if (firstStartMatch.equals(secondStartMatch)) {
              break;
            }
            firstRotateList.add(0, firstStartMatch);
            secondRotateList.add(secondStartMatch);
            Map<Team, Match> visitedTeamMap = new HashMap<Team, Match>();

            Team teamToFind = getOtherTeam(secondStartMatch, secondTeam);

            while (!teamToFind.equals(firstStartTeam)) {
              //                            boolean shortcut =
              // visitedTeamMap.containsKey(teamToFind);
              //                            if (shortcut) {
              Match firstRepairMatch =
                  homeTeamAwayTeamMap
                      .get(firstTeamIsHomeTeam ? firstTeam : teamToFind)
                      .get(firstTeamIsHomeTeam ? teamToFind : firstTeam);
              if (!clonedFirstTeamMatchList.contains(firstRepairMatch)) {
                if (visitedTeamMap.containsKey(teamToFind)) {
                  // shortcut splitoff is possible
                  Match shortcutMatch = visitedTeamMap.get(teamToFind);
                  int shortcutSize = firstRotateList.indexOf(shortcutMatch) + 1;
                  int reverseShortcutSize = firstRotateList.size() - shortcutSize;
                  List<Match> firstShortcutRotateList =
                      new ArrayList<Match>(firstRotateList.subList(0, shortcutSize));
                  for (Match match : firstShortcutRotateList) {
                    visitedTeamMap.remove(getOtherTeam(match, firstTeam));
                  }
                  List<Match> secondShortcutRotateList =
                      new ArrayList<Match>(
                          secondRotateList.subList(reverseShortcutSize, secondRotateList.size()));
                  firstRotateList =
                      new ArrayList<Match>(
                          firstRotateList.subList(shortcutSize, firstRotateList.size()));
                  secondRotateList =
                      new ArrayList<Match>(secondRotateList.subList(0, reverseShortcutSize));
                  addTeamRotateMove(moveList, firstShortcutRotateList, secondShortcutRotateList);
                }
                firstTeamIsHomeTeam = !firstTeamIsHomeTeam;
                //                            Team firstRepairHomeTeam = (firstTeamIsHomeTeam ^
                // shortcut) ? firstTeam : teamToFind;
                //                            Team firstRepairAwayTeam = (firstTeamIsHomeTeam ^
                // shortcut) ? teamToFind : firstTeam;
                //                            Match firstRepairMatch = homeTeamAwayTeamMap
                //
                // .get(firstRepairHomeTeam).get(firstRepairAwayTeam);
                firstRepairMatch =
                    homeTeamAwayTeamMap
                        .get(firstTeamIsHomeTeam ? firstTeam : teamToFind)
                        .get(firstTeamIsHomeTeam ? teamToFind : firstTeam);
              }

              Day repairDay = firstRepairMatch.getDay();
              Match secondRepairMatch = teamDayMap.get(secondTeam).get(repairDay);
              clonedFirstTeamMatchList.remove(firstRepairMatch);
              visitedTeamMap.put(teamToFind, firstRepairMatch);
              firstRotateList.add(0, firstRepairMatch);
              secondRotateList.add(secondRepairMatch);

              teamToFind = getOtherTeam(secondRepairMatch, secondTeam);
            }

            addTeamRotateMove(moveList, firstRotateList, secondRotateList);
          }
        }
      }
    }