docs: public int[] add(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) {
          if (valueToAdd == 0) {
              return values;
          }
          // there are more efficient algorithms than this (especially for time only fields)
          // trouble is when dealing with days and months, so we use this technique of
          // adding/removing one from the larger field at a time
          DateTimeField nextField = null;
          
          while (valueToAdd > 0) {
              int max = getMaximumValue(instant, values);
              long proposed = values[fieldIndex] + valueToAdd;
              if (proposed <= max) {
                  values[fieldIndex] = (int) proposed;
                  break;
              }
              if (nextField == null) {
                  if (fieldIndex == 0) {
                      throw new IllegalArgumentException("Maximum value exceeded for add");
                  }
                  nextField = instant.getField(fieldIndex - 1);
                  // test only works if this field is UTC (ie. local)
                  if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
                      throw new IllegalArgumentException("Fields invalid for add");
                  }
              }
              valueToAdd -= (max + 1) - values[fieldIndex];  // reduce the amount to add
              values = nextField.add(instant, fieldIndex - 1, values, 1);  // add 1 to next bigger field
              values[fieldIndex] = getMinimumValue(instant, values);  // reset this field to zero
          }
          while (valueToAdd < 0) {
              int min = getMinimumValue(instant, values);
              long proposed = values[fieldIndex] + valueToAdd;
              if (proposed >= min) {
                  values[fieldIndex] = (int) proposed;
                  break;
              }
              if (nextField == null) {
                  if (fieldIndex == 0) {
                      throw new IllegalArgumentException("Maximum value exceeded for add");
                  }
                  nextField = instant.getField(fieldIndex - 1);
                  if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
                      throw new IllegalArgumentException("Fields invalid for add");
                  }
              }
              valueToAdd -= (min - 1) - values[fieldIndex];  // reduce the amount to add
              values = nextField.add(instant, fieldIndex - 1, values, -1);  // subtract 1 from next bigger field
              values[fieldIndex] = getMaximumValue(instant, values);  // reset this field to max value
          }
          
          return set(instant, fieldIndex, values, values[fieldIndex]);  // adjusts smaller fields
      }