/**
   * If this LimitChronology has the same time zone as the one given, then this is returned.
   * Otherwise, a new instance is returned, with the limits adjusted to the new time zone.
   */
  public Chronology withZone(DateTimeZone zone) {
    if (zone == null) {
      zone = DateTimeZone.getDefault();
    }
    if (zone == getZone()) {
      return this;
    }

    if (zone == DateTimeZone.UTC && iWithUTC != null) {
      return iWithUTC;
    }

    DateTime lowerLimit = iLowerLimit;
    if (lowerLimit != null) {
      MutableDateTime mdt = lowerLimit.toMutableDateTime();
      mdt.setZoneRetainFields(zone);
      lowerLimit = mdt.toDateTime();
    }

    DateTime upperLimit = iUpperLimit;
    if (upperLimit != null) {
      MutableDateTime mdt = upperLimit.toMutableDateTime();
      mdt.setZoneRetainFields(zone);
      upperLimit = mdt.toDateTime();
    }

    LimitChronology chrono = getInstance(getBase().withZone(zone), lowerLimit, upperLimit);

    if (zone == DateTimeZone.UTC) {
      iWithUTC = chrono;
    }

    return chrono;
  }
 void checkLimits(long instant, String desc) {
   DateTime limit;
   if ((limit = iLowerLimit) != null && instant < limit.getMillis()) {
     throw new LimitException(desc, true);
   }
   if ((limit = iUpperLimit) != null && instant >= limit.getMillis()) {
     throw new LimitException(desc, false);
   }
 }
  /**
   * Sets the value of the mutable interval from the string.
   *
   * @param writableInterval the interval to set
   * @param object the String to convert, must not be null
   * @param chrono the chronology to use, may be null
   */
  public void setInto(ReadWritableInterval writableInterval, Object object, Chronology chrono) {
    String str = (String) object;

    int separator = str.indexOf('/');
    if (separator < 0) {
      throw new IllegalArgumentException("Format requires a '/' separator: " + str);
    }

    String leftStr = str.substring(0, separator);
    if (leftStr.length() <= 0) {
      throw new IllegalArgumentException("Format invalid: " + str);
    }
    String rightStr = str.substring(separator + 1);
    if (rightStr.length() <= 0) {
      throw new IllegalArgumentException("Format invalid: " + str);
    }

    DateTimeFormatter dateTimeParser = ISODateTimeFormat.dateTimeParser();
    dateTimeParser = dateTimeParser.withChronology(chrono);
    PeriodFormatter periodParser = ISOPeriodFormat.standard();
    long startInstant = 0, endInstant = 0;
    Period period = null;
    Chronology parsedChrono = null;

    // before slash
    char c = leftStr.charAt(0);
    if (c == 'P' || c == 'p') {
      period = periodParser.withParseType(getPeriodType(leftStr)).parsePeriod(leftStr);
    } else {
      DateTime start = dateTimeParser.parseDateTime(leftStr);
      startInstant = start.getMillis();
      parsedChrono = start.getChronology();
    }

    // after slash
    c = rightStr.charAt(0);
    if (c == 'P' || c == 'p') {
      if (period != null) {
        throw new IllegalArgumentException("Interval composed of two durations: " + str);
      }
      period = periodParser.withParseType(getPeriodType(rightStr)).parsePeriod(rightStr);
      chrono = (chrono != null ? chrono : parsedChrono);
      endInstant = chrono.add(period, startInstant, 1);
    } else {
      DateTime end = dateTimeParser.parseDateTime(rightStr);
      endInstant = end.getMillis();
      parsedChrono = (parsedChrono != null ? parsedChrono : end.getChronology());
      chrono = (chrono != null ? chrono : parsedChrono);
      if (period != null) {
        startInstant = chrono.add(period, endInstant, -1);
      }
    }

    writableInterval.setInterval(startInstant, endInstant);
    writableInterval.setChronology(chrono);
  }