/**
   * Retrieve the weight for this distribution.
   *
   * <p>Performs the standard munge to handle ambiguity symbols. The actual weights for each atomic
   * symbol should be calculated by the getWeightImpl functions.
   *
   * @param sym the Symbol to find the probability of
   * @return the probability that one of the symbols matching amb was emitted
   * @throws IllegalSymbolException if for any reason the symbols within amb are not recognized by
   *     this state
   */
  public final double getWeight(Symbol sym) throws IllegalSymbolException {
    if (sym instanceof AtomicSymbol) {
      return getWeightImpl((AtomicSymbol) sym);
    } else {
      Alphabet ambA = sym.getMatches();
      if (((FiniteAlphabet) ambA).size() == 0) { // a gap
        getAlphabet().validate(sym);

        double totalWeight = 0.0;
        for (Iterator i = ((FiniteAlphabet) getAlphabet()).iterator(); i.hasNext(); ) {

          Symbol s = (Symbol) i.next();
          totalWeight += getWeight(s);
        }
        return 1.0 - totalWeight;
      }
      if (ambA instanceof FiniteAlphabet) {
        FiniteAlphabet fa = (FiniteAlphabet) ambA;
        double sum = 0.0;
        for (Iterator i = fa.iterator(); i.hasNext(); ) {
          Object obj = i.next();
          if (!(obj instanceof AtomicSymbol)) {
            throw new BioError("Assertion Failure: Not an instance of AtomicSymbol: " + obj);
          }
          AtomicSymbol as = (AtomicSymbol) obj;
          sum += getWeightImpl(as);
        }
        return sum;
      } else {
        throw new IllegalSymbolException(
            "Can't find weight for infinite set of symbols matched by " + sym.getName());
      }
    }
  }
 private void doSetWeight(Symbol sym, double weight)
     throws IllegalSymbolException, ChangeVetoException {
   if (sym instanceof AtomicSymbol) {
     setWeightImpl((AtomicSymbol) sym, weight);
   } else {
     // need to divide the weight up amongst the atomic symbols according
     // to the null model
     FiniteAlphabet fa = (FiniteAlphabet) sym.getMatches();
     double totalNullWeight = this.getNullModel().getWeight(sym);
     for (Iterator si = fa.iterator(); si.hasNext(); ) {
       AtomicSymbol as = (AtomicSymbol) si.next();
       double symNullWeight = this.getNullModel().getWeight(as);
       setWeightImpl(as, weight * symNullWeight / totalNullWeight);
     }
   }
 }