private void constructPatterns() {
    patterns.clear();

    State[][] seqs = new State[sequences.size()][];
    int i = 0;
    int maxLen = 0;
    for (Sequence seq : getSequenceList()) {
      seqs[i] = seq.getStates();
      if (seqs[i].length > maxLen) {
        maxLen = seqs[i].length;
      }
      i++;
    }

    for (int j = 0; j < maxLen; j++) {
      List<State> states = new ArrayList<State>();
      for (i = 0; i < seqs.length; i++) {
        if (j < seqs[i].length) {
          states.add(seqs[i][j]);
        } else {
          states.add(sequenceType.getGapState());
        }
      }
      patterns.add(new BasicPattern(states));
    }
  }
  private void put(Sequence sequence) {
    if (sequenceType == null) {
      sequenceType = sequence.getSequenceType();
    }
    if (sequenceType != sequence.getSequenceType()) {
      throw new IllegalArgumentException(
          "Type of sequence "
              + sequence.getTaxon().getName()
              + " does not match that of other sequences in the alignment"
              + " (data type = "
              + sequence.getSequenceType().getName()
              + ", but expected "
              + sequenceType.getName()
              + ").");
    }

    if (taxonList.indexOf(sequence.getTaxon()) >= 0) {
      throw new IllegalArgumentException("duplicate sequence name " + sequence.getTaxon());
    }

    sequences.put(sequence.getTaxon(), sequence);
    taxonList.add(sequence.getTaxon());
  }