gt:     int asInt() throws NumberFormatException {
context: // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
  // This source code is licensed under the BSD-style license found in the
  // LICENSE file in the root directory of this source tree. An additional grant
  // of patent rights can be found in the PATENTS file in the same directory.
  
  package org.rocksdb;
  
  import java.util.*;
  
  public class MutableColumnFamilyOptions {
    private final static String KEY_VALUE_PAIR_SEPARATOR = ";";
    private final static char KEY_VALUE_SEPARATOR = '=';
    private final static String INT_ARRAY_INT_SEPARATOR = ",";
  
    private final String[] keys;
    private final String[] values;
  
    // user must use builder pattern, or parser
    private MutableColumnFamilyOptions(final String keys[],
        final String values[]) {
      this.keys = keys;
      this.values = values;
    }
  
    String[] getKeys() {
      return keys;
    }
  
    String[] getValues() {
      return values;
    }
  
    /**
     * Creates a builder which allows you
     * to set MutableColumnFamilyOptions in a fluent
     * manner
     *
     * @return A builder for MutableColumnFamilyOptions
     */
    public static MutableColumnFamilyOptionsBuilder builder() {
      return new MutableColumnFamilyOptionsBuilder();
    }
  
    /**
     * Parses a String representation of MutableColumnFamilyOptions
     *
     * The format is: key1=value1;key2=value2;key3=value3 etc
     *
     * For int[] values, each int should be separated by a comma, e.g.
     *
     * key1=value1;intArrayKey1=1,2,3
     *
     * @param str The string representation of the mutable column family options
     *
     * @return A builder for the mutable column family options
     */
    public static MutableColumnFamilyOptionsBuilder parse(final String str) {
      Objects.requireNonNull(str);
  
      final MutableColumnFamilyOptionsBuilder builder =
          new MutableColumnFamilyOptionsBuilder();
  
      final String options[] = str.trim().split(KEY_VALUE_PAIR_SEPARATOR);
      for(final String option : options) {
        final int equalsOffset = option.indexOf(KEY_VALUE_SEPARATOR);
        if(equalsOffset <= 0) {
          throw new IllegalArgumentException(
              "options string has an invalid key=value pair");
        }
  
        final String key = option.substring(0, equalsOffset);
        if(key == null || key.isEmpty()) {
          throw new IllegalArgumentException("options string is invalid");
        }
  
        final String value = option.substring(equalsOffset + 1);
        if(value == null || value.isEmpty()) {
          throw new IllegalArgumentException("options string is invalid");
        }
  
        builder.fromString(key, value);
      }
  
      return builder;
    }
  
    /**
     * Returns a string representation
     * of MutableColumnFamilyOptions which is
     * suitable for consumption by {@link #parse(String)}
     *
     * @return String representation of MutableColumnFamilyOptions
     */
    @Override
    public String toString() {
      final StringBuilder buffer = new StringBuilder();
      for(int i = 0; i < keys.length; i++) {
        buffer
            .append(keys[i])
            .append(KEY_VALUE_SEPARATOR)
            .append(values[i]);
  
        if(i + 1 < keys.length) {
          buffer.append(KEY_VALUE_PAIR_SEPARATOR);
        }
      }
      return buffer.toString();
    }
  
    public enum ValueType {
      DOUBLE,
      LONG,
      INT,
      BOOLEAN,
      INT_ARRAY
    }
  
    public enum MemtableOption implements MutableColumnFamilyOptionKey {
      write_buffer_size(ValueType.LONG),
      arena_block_size(ValueType.LONG),
      memtable_prefix_bloom_size_ratio(ValueType.DOUBLE),
      @Deprecated memtable_prefix_bloom_bits(ValueType.INT),
      @Deprecated memtable_prefix_bloom_probes(ValueType.INT),
      memtable_huge_page_size(ValueType.LONG),
      max_successive_merges(ValueType.LONG),
      @Deprecated filter_deletes(ValueType.BOOLEAN),
      max_write_buffer_number(ValueType.INT),
      inplace_update_num_locks(ValueType.LONG);
  
      private final ValueType valueType;
      MemtableOption(final ValueType valueType) {
        this.valueType = valueType;
      }
  
      @Override
      public ValueType getValueType() {
        return valueType;
      }
    }
  
    public enum CompactionOption implements MutableColumnFamilyOptionKey {
      disable_auto_compactions(ValueType.BOOLEAN),
      @Deprecated soft_rate_limit(ValueType.DOUBLE),
      soft_pending_compaction_bytes_limit(ValueType.LONG),
      @Deprecated hard_rate_limit(ValueType.DOUBLE),
      hard_pending_compaction_bytes_limit(ValueType.LONG),
      level0_file_num_compaction_trigger(ValueType.INT),
      level0_slowdown_writes_trigger(ValueType.INT),
      level0_stop_writes_trigger(ValueType.INT),
      max_compaction_bytes(ValueType.LONG),
      target_file_size_base(ValueType.LONG),
      target_file_size_multiplier(ValueType.INT),
      max_bytes_for_level_base(ValueType.LONG),
      max_bytes_for_level_multiplier(ValueType.INT),
      max_bytes_for_level_multiplier_additional(ValueType.INT_ARRAY);
  
      private final ValueType valueType;
      CompactionOption(final ValueType valueType) {
        this.valueType = valueType;
      }
  
      @Override
      public ValueType getValueType() {
        return valueType;
      }
    }
  
    public enum MiscOption implements MutableColumnFamilyOptionKey {
      max_sequential_skip_in_iterations(ValueType.LONG),
      paranoid_file_checks(ValueType.BOOLEAN);
  
      private final ValueType valueType;
      MiscOption(final ValueType valueType) {
        this.valueType = valueType;
      }
  
      @Override
      public ValueType getValueType() {
        return valueType;
      }
    }
  
    private interface MutableColumnFamilyOptionKey {
      String name();
      ValueType getValueType();
    }
  
    private static abstract class MutableColumnFamilyOptionValue<T> {
      protected final T value;
  
      MutableColumnFamilyOptionValue(final T value) {
        this.value = value;
      }
  
      abstract double asDouble() throws NumberFormatException;
      abstract long asLong() throws NumberFormatException;
      abstract int asInt() throws NumberFormatException;
      abstract boolean asBoolean() throws IllegalStateException;
      abstract int[] asIntArray() throws IllegalStateException;
      abstract String asString();
    }
  
    private static class MutableColumnFamilyOptionStringValue
        extends MutableColumnFamilyOptionValue<String> {
      MutableColumnFamilyOptionStringValue(final String value) {
        super(value);
      }
  
      @Override
      double asDouble() throws NumberFormatException {
        return Double.parseDouble(value);
      }
  
      @Override
      long asLong() throws NumberFormatException {
        return Long.parseLong(value);
      }
  
      @Override
      int asInt() throws NumberFormatException {
        return Integer.parseInt(value);
      }
  
      @Override
      boolean asBoolean() throws IllegalStateException {
        return Boolean.parseBoolean(value);
      }
  
      @Override
      int[] asIntArray() throws IllegalStateException {
        throw new IllegalStateException("String is not applicable as int[]");
      }
  
      @Override
      String asString() {
        return value;
      }
    }
  
    private static class MutableColumnFamilyOptionDoubleValue
        extends MutableColumnFamilyOptionValue<Double> {
      MutableColumnFamilyOptionDoubleValue(final double value) {
        super(value);
      }
  
      @Override
      double asDouble() {
        return value;
      }
  
      @Override
      long asLong() throws NumberFormatException {
        return value.longValue();
      }
  
      @Override
      int asInt() throws NumberFormatException {
        if(value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
          throw new NumberFormatException(
              "double value lies outside the bounds of int");
        }
        return value.intValue();
      }
  
      @Override
      boolean asBoolean() throws IllegalStateException {
        throw new IllegalStateException(
            "double is not applicable as boolean");
      }
  
      @Override
      int[] asIntArray() throws IllegalStateException {
        if(value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
          throw new NumberFormatException(
              "double value lies outside the bounds of int");
        }
        return new int[] { value.intValue() };
      }
  
      @Override
      String asString() {
        return Double.toString(value);
      }
    }
  
    private static class MutableColumnFamilyOptionLongValue
        extends MutableColumnFamilyOptionValue<Long> {
      MutableColumnFamilyOptionLongValue(final long value) {
        super(value);
      }
  
      @Override
      double asDouble() {
        if(value > Double.MAX_VALUE || value < Double.MIN_VALUE) {
          throw new NumberFormatException(
              "long value lies outside the bounds of int");
        }
        return value.doubleValue();
      }
  
      @Override
      long asLong() throws NumberFormatException {
        return value;
      }
  
      @Override
      int asInt() throws NumberFormatException {
        if(value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
          throw new NumberFormatException(
              "long value lies outside the bounds of int");
        }
        return value.intValue();
      }
  
      @Override
      boolean asBoolean() throws IllegalStateException {
        throw new IllegalStateException(
            "long is not applicable as boolean");
      }
  
      @Override
      int[] asIntArray() throws IllegalStateException {
        if(value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
          throw new NumberFormatException(
              "long value lies outside the bounds of int");
        }
        return new int[] { value.intValue() };
      }
  
      @Override
      String asString() {
        return Long.toString(value);
      }
    }
  
    private static class MutableColumnFamilyOptionIntValue
        extends MutableColumnFamilyOptionValue<Integer> {
      MutableColumnFamilyOptionIntValue(final int value) {
        super(value);
      }
  
      @Override
      double asDouble() {
        if(value > Double.MAX_VALUE || value < Double.MIN_VALUE) {
          throw new NumberFormatException("int value lies outside the bounds of int");
        }
        return value.doubleValue();
      }
  
      @Override
      long asLong() throws NumberFormatException {
        return value;
      }
  
      @Override
      int asInt() throws NumberFormatException {
        return value;
      }
  
      @Override
      boolean asBoolean() throws IllegalStateException {
        throw new IllegalStateException("int is not applicable as boolean");
      }
  
      @Override
      int[] asIntArray() throws IllegalStateException {
        return new int[] { value };
      }
  
      @Override
      String asString() {
        return Integer.toString(value);
      }
    }
  
    private static class MutableColumnFamilyOptionBooleanValue
        extends MutableColumnFamilyOptionValue<Boolean> {
      MutableColumnFamilyOptionBooleanValue(final boolean value) {
        super(value);
      }
  
      @Override
      double asDouble() {
        throw new NumberFormatException("boolean is not applicable as double");
      }
  
      @Override
      long asLong() throws NumberFormatException {
        throw new NumberFormatException("boolean is not applicable as Long");
      }
  
      @Override
      int asInt() throws NumberFormatException {
        throw new NumberFormatException("boolean is not applicable as int");
      }
  
      @Override
      boolean asBoolean() {
        return value;
      }
  
      @Override
      int[] asIntArray() throws IllegalStateException {
        throw new IllegalStateException("boolean is not applicable as int[]");
      }
  
      @Override
      String asString() {
        return Boolean.toString(value);
      }
    }
  
    private static class MutableColumnFamilyOptionIntArrayValue
        extends MutableColumnFamilyOptionValue<int[]> {
      MutableColumnFamilyOptionIntArrayValue(final int[] value) {
        super(value);
      }
  
      @Override
      double asDouble() {
        throw new NumberFormatException("int[] is not applicable as double");
      }
  
      @Override
      long asLong() throws NumberFormatException {
        throw new NumberFormatException("int[] is not applicable as Long");
      }
  
      @Override
  