code: public void addTransitionRule(TimeZoneRule rule) {
          if (isFrozen()) {
              throw new UnsupportedOperationException("Attempt to modify a frozen RuleBasedTimeZone instance.");
          }
          if (!rule.isTransitionRule()) {
              throw new IllegalArgumentException("Rule must be a transition rule");
          }
          if (rule instanceof AnnualTimeZoneRule
                  && ((AnnualTimeZoneRule)rule).getEndYear() == AnnualTimeZoneRule.MAX_YEAR) {
              // One of the final rules applicable in future forever
              if (finalRules == null) {
                  finalRules = new AnnualTimeZoneRule[2];
                  finalRules[0] = (AnnualTimeZoneRule)rule;
              } else if (finalRules[1] == null) {
                  finalRules[1] = (AnnualTimeZoneRule)rule;
              } else {
                  // Only a pair of AnnualTimeZoneRule is allowed.
                  throw new IllegalStateException("Too many final rules");
              }
          } else {
              // If this is not a final rule, add it to the historic rule list 
              if (historicRules == null) {
                  historicRules = new ArrayList<TimeZoneRule>();
              }
              historicRules.add(rule);
          }
          // Mark dirty, so transitions are recalculated when offset information is
          // accessed next time.
          upToDate = false;
      }
docs: Adds the <code>TimeZoneRule</code> which represents time transitions.
  The <code>TimeZoneRule</code> must have start times, that is, the result
  of {@link android.icu.util.TimeZoneRule#isTransitionRule()} must be true.
  Otherwise, <code>IllegalArgumentException</code> is thrown.
  
  @param rule The <code>TimeZoneRule</code>.