gt:     for (final UnitSupportAttachment rule : get(data)) {
context: package games.strategy.triplea.attachments;
  
  import com.google.common.collect.ImmutableMap;
  import games.strategy.engine.data.Attachable;
  import games.strategy.engine.data.DefaultAttachment;
  import games.strategy.engine.data.GameData;
  import games.strategy.engine.data.GameParseException;
  import games.strategy.engine.data.MutableProperty;
  import games.strategy.engine.data.PlayerId;
  import games.strategy.engine.data.UnitType;
  import games.strategy.triplea.Constants;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.stream.Collectors;
  import java.util.stream.StreamSupport;
  
  /**
   * An attachment for instances of {@link UnitType} that defines properties for unit types that
   * support other units.
   */
  public class UnitSupportAttachment extends DefaultAttachment {
    private static final long serialVersionUID = -3015679930172496082L;
  
    private Set<UnitType> unitType = null;
    private boolean offence = false;
    private boolean defence = false;
    private boolean roll = false;
    private boolean strength = false;
    private boolean aaRoll = false;
    private boolean aaStrength = false;
    private int bonus = 0;
    private int number = 0;
    private boolean allied = false;
    private boolean enemy = false;
    private String bonusType = null;
    private List<PlayerId> players = new ArrayList<>();
    private boolean impArtTech = false;
    // strings
    // roll or strength or AAroll or AAstrength
    private String dice;
    // offence or defence
    private String side;
    private String faction;
  
    public UnitSupportAttachment(
        final String name, final Attachable attachable, final GameData gameData) {
      super(name, attachable, gameData);
    }
  
    public static Set<UnitSupportAttachment> get(final UnitType u) {
      return u.getAttachments().values().stream()
          .filter(attachment -> attachment.getName().startsWith(Constants.SUPPORT_ATTACHMENT_PREFIX))
          .map(UnitSupportAttachment.class::cast)
          .collect(Collectors.toSet());
    }
  
    static UnitSupportAttachment get(final UnitType u, final String nameOfAttachment) {
      return getAttachment(u, nameOfAttachment, UnitSupportAttachment.class);
    }
  
    public static Set<UnitSupportAttachment> get(final GameData data) {
      data.acquireReadLock();
      try {
        return StreamSupport.stream(data.getUnitTypeList().spliterator(), false)
            .map(UnitSupportAttachment::get)
            .flatMap(Collection::stream)
            .collect(Collectors.toSet());
      } finally {
        data.releaseReadLock();
      }
    }
  
    private void setUnitType(final String names) throws GameParseException {
      if (names == null) {
        unitType = null;
        return;
      }
      unitType = new HashSet<>();
      for (final String element : splitOnColon(names)) {
        final UnitType type = getData().getUnitTypeList().getUnitType(element);
        if (type == null) {
          throw new GameParseException("Could not find unitType. name:" + element + thisErrorMsg());
        }
        unitType.add(type);
      }
    }
  
    private void setUnitType(final Set<UnitType> value) {
      unitType = value;
    }
  
    private void resetUnitType() {
      unitType = null;
    }
  
    private void setFaction(final String faction) throws GameParseException {
      this.faction = faction;
      if (faction == null) {
        resetFaction();
        return;
      }
      allied = false;
      enemy = false;
      for (final String element : splitOnColon(faction)) {
        if (element.equalsIgnoreCase("allied")) {
          allied = true;
        } else if (element.equalsIgnoreCase("enemy")) {
          enemy = true;
        } else {
          throw new GameParseException(
              faction + " faction must be allied, or enemy" + thisErrorMsg());
        }
      }
    }
  
    private String getFaction() {
      return faction;
    }
  
    private void resetFaction() {
      allied = false;
      enemy = false;
    }
  
    private void setSide(final String side) throws GameParseException {
      if (side == null) {
        resetSide();
        return;
      }
      defence = false;
      offence = false;
      for (final String element : splitOnColon(side)) {
        if (element.equalsIgnoreCase("defence")) {
          defence = true;
        } else if (element.equalsIgnoreCase("offence")) {
          offence = true;
        } else {
          throw new GameParseException(side + " side must be defence or offence" + thisErrorMsg());
        }
      }
      this.side = side;
    }
  
    private String getSide() {
      return side;
    }
  
    private void resetSide() {
      side = null;
      offence = false;
      defence = false;
    }
  
    private void setDice(final String dice) throws GameParseException {
      resetDice();
      if (dice == null) {
        return;
      }
      this.dice = dice;
      for (final String element : splitOnColon(dice)) {
        if (element.equalsIgnoreCase("roll")) {
          roll = true;
        } else if (element.equalsIgnoreCase("strength")) {
          strength = true;
        } else if (element.equalsIgnoreCase("AAroll")) {
          aaRoll = true;
        } else if (element.equalsIgnoreCase("AAstrength")) {
          aaStrength = true;
        } else {
          throw new GameParseException(
              dice + " dice must be roll, strength, AAroll, or AAstrength: " + thisErrorMsg());
        }
      }
    }
  
    String getDice() {
      return dice;
    }
  
    private void resetDice() {
      dice = null;
      roll = false;
      strength = false;
      aaRoll = false;
      aaStrength = false;
    }
  
    private void setBonus(final String bonus) {
      this.bonus = getInt(bonus);
    }
  
    private void setBonus(final int bonus) {
      this.bonus = bonus;
    }
  
    private void resetBonus() {
      bonus = 0;
    }
  
    private void setNumber(final String number) {
      this.number = getInt(number);
    }
  
    private void setNumber(final int number) {
      this.number = number;
    }
  
    private void resetNumber() {
      number = 0;
    }
  
    private void setBonusType(final String type) {
      bonusType = type;
    }
  
    private void resetBonusType() {
      bonusType = null;
    }
  
    private void setPlayers(final String names) throws GameParseException {
      final String[] s = splitOnColon(names);
      for (final String element : s) {
        final PlayerId player = getData().getPlayerList().getPlayerId(element);
        if (player == null) {
          throw new GameParseException("Could not find player. name:" + element + thisErrorMsg());
        }
        players.add(player);
      }
    }
  
    private void setPlayers(final List<PlayerId> value) {
      players = value;
    }
  
    public List<PlayerId> getPlayers() {
      return players;
    }
  
    private void resetPlayers() {
      players = new ArrayList<>();
    }
  
    private void setImpArtTech(final String tech) {
      impArtTech = getBool(tech);
    }
  
    private void setImpArtTech(final boolean tech) {
      impArtTech = tech;
    }
  
    private void resetImpArtTech() {
      impArtTech = false;
    }
  
    public Set<UnitType> getUnitType() {
      return unitType;
    }
  
    public int getNumber() {
      return number;
    }
  
    public int getBonus() {
      return bonus;
    }
  
    public boolean getAllied() {
      return allied;
    }
  
    public boolean getEnemy() {
      return enemy;
    }
  
    public boolean getRoll() {
      return roll;
    }
  
    public boolean getStrength() {
      return strength;
    }
  
    public boolean getAaRoll() {
      return aaRoll;
    }
  
    public boolean getAaStrength() {
      return aaStrength;
    }
  
    public boolean getDefence() {
      return defence;
    }
  
    public boolean getOffence() {
      return offence;
    }
  
    public String getBonusType() {
      return bonusType;
    }
  
    public boolean getImpArtTech() {
      return impArtTech;
    }
  
    /*
     * following are all to support old artillery flags.
     * boolean first is a cheat, adds a bogus support to a unit
     * in the case that supportable units are declared before any artillery
     */
    static void addRule(final UnitType type, final GameData data, final boolean first)
        throws GameParseException {
      final String attachmentName =
          (first ? Constants.SUPPORT_RULE_NAME_OLD_TEMP_FIRST : Constants.SUPPORT_RULE_NAME_OLD)
              + type.getName();
      final UnitSupportAttachment rule = new UnitSupportAttachment(attachmentName, type, data);
      rule.setBonus(1);
      rule.setBonusType(Constants.OLD_ART_RULE_NAME);
      rule.setDice("strength");
      rule.setFaction("allied");
      rule.setImpArtTech(true);
      rule.setNumber(first ? 0 : 1);
      rule.setSide("offence");
      rule.addUnitTypes(first ? Collections.singleton(type) : getTargets(data));
      if (!first) {
        rule.setPlayers(new ArrayList<>(data.getPlayerList().getPlayers()));
      }
      type.addAttachment(attachmentName, rule);
    }
  
    private static Set<UnitType> getTargets(final GameData data) {
      Set<UnitType> types = null;
  