@Override
 public Character decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   return (char) toDouble(value);
 }
 public static int getSize(JSONValue value) {
   if (value == null || value.isNull() != null) {
     return 0;
   }
   JSONArray array = asArray(value);
   return array.size();
 }
        @Override
        public BigInteger decode(JSONValue value) throws DecodingException {
          if (value == null || value.isNull() != null) {
            return null;
          }
          JSONNumber number = value.isNumber();
          if (number == null) {
            JSONString str = value.isString();
            if (str == null) {
              throw new DecodingException(
                  "Expected a json number r string, but was given: " + value);
            }

            // Doing a straight conversion from string to BigInteger will
            // not work for large values
            // So we convert to BigDecimal first and then convert it to
            // BigInteger.
            return new BigDecimal(str.stringValue()).toBigInteger();
          }

          // Doing a straight conversion from string to BigInteger will not
          // work for large values
          // So we convert to BigDecimal first and then convert it to
          // BigInteger.
          return new BigDecimal(value.toString()).toBigInteger();
        }
 @Override
 public BigDecimal decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   return toBigDecimal(value);
 }
 @Override
 public Float decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   return (float) toDouble(value);
 }
  public static <KeyType, ValueType> Map<KeyType, ValueType> toMap(
      JSONValue value,
      AbstractJsonEncoderDecoder<KeyType> keyEncoder,
      AbstractJsonEncoderDecoder<ValueType> valueEncoder,
      Style style) {
    if (value == null || value.isNull() != null) {
      return null;
    }

    switch (style) {
      case DEFAULT:
      case SIMPLE:
        {
          JSONObject object = value.isObject();
          if (object == null) {
            throw new DecodingException("Expected a json object, but was given: " + value);
          }

          HashMap<KeyType, ValueType> rc = new HashMap<KeyType, ValueType>(object.size() * 2);
          for (String key : object.keySet()) {
            rc.put(keyEncoder.decode(key), valueEncoder.decode(object.get(key)));
          }
          return rc;
        }
      case JETTISON_NATURAL:
        {
          JSONObject object = value.isObject();
          if (object == null) {
            throw new DecodingException("Expected a json object, but was given: " + value);
          }
          value = object.get("entry");
          if (value == null) {
            throw new DecodingException("Expected an entry array not found");
          }
          JSONArray entries = value.isArray();
          if (entries == null) {
            throw new DecodingException("Expected an entry array, but was given: " + value);
          }

          HashMap<KeyType, ValueType> rc = new HashMap<KeyType, ValueType>(object.size() * 2);
          for (int i = 0; i < entries.size(); i++) {
            JSONObject entry = entries.get(i).isObject();
            if (entry == null)
              throw new DecodingException("Expected an entry object, but was given: " + value);
            JSONValue key = entry.get("key");
            if (key == null) throw new DecodingException("Expected an entry key field not found");
            JSONString k = key.isString();
            if (k == null)
              throw new DecodingException(
                  "Expected an entry key to be a string, but was given: " + value);
            rc.put(keyEncoder.decode(k.stringValue()), valueEncoder.decode(entry.get("value")));
          }
          return rc;
        }
      default:
        throw new UnsupportedOperationException(
            "The encoding style is not yet supported: " + style.name());
    }
  }
 @Override
 public Boolean decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   JSONBoolean bool = value.isBoolean();
   if (bool == null) {
     throw new DecodingException("Expected a json boolean, but was given: " + value);
   }
   return bool.booleanValue();
 }
 @Override
 public Document decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   JSONString str = value.isString();
   if (str == null) {
     throw new DecodingException("Expected a json string, but was given: " + value);
   }
   return XMLParser.parse(str.stringValue());
 }
 @Override
 public Long decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   final JSONString valueString = value.isString();
   if (valueString != null) {
     return Long.parseLong(valueString.stringValue());
   }
   return (long) toDouble(value);
 }
  public static <Type> Set<Type> toSet(JSONValue value, AbstractJsonEncoderDecoder<Type> encoder) {
    if (value == null || value.isNull() != null) {
      return null;
    }
    JSONArray array = asArray(value);

    HashSet<Type> rc = new HashSet<Type>(array.size() * 2);
    int size = array.size();
    for (int i = 0; i < size; i++) {
      rc.add(encoder.decode(array.get(i)));
    }
    return rc;
  }
  public static boolean[] toArray(
      JSONValue value, AbstractJsonEncoderDecoder<Boolean> encoder, boolean[] template) {
    if (value == null || value.isNull() != null) {
      return null;
    }
    JSONArray array = asArray(value);

    int size = array.size();
    for (int i = 0; i < size; i++) {
      template[i] = encoder.decode(array.get(i));
    }
    return template;
  }
 @Override
 public String decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   JSONString str = value.isString();
   if (str == null) {
     if (value.isBoolean() != null || value.isNumber() != null) {
       return value.toString();
     }
     throw new DecodingException("Expected a json string, but was given: " + value);
   }
   return str.stringValue();
 }
  /**
   * Parse a string from a JSON object
   *
   * @param jsonObj object to parse.
   * @param key key for string to retrieve.
   * @return desired string. Empty string on failure.
   */
  public static String getString(final JSONObject jsonObj, final String key) {
    String ret = ""; // assume failure

    if (jsonObj != null && key != null) {
      JSONValue val = jsonObj.get(key);

      if (val != null && val.isNull() == null) {
        JSONString strVal = val.isString();

        if (strVal != null) {
          ret = strVal.stringValue();
        }
      }
    }

    return ret;
  }
 @Override
 public Date decode(JSONValue value) throws DecodingException {
   if (value == null || value.isNull() != null) {
     return null;
   }
   String format = Defaults.getDateFormat();
   if (format == null) {
     JSONNumber num = value.isNumber();
     if (num == null) {
       throw new DecodingException("Expected a json number, but was given: " + value);
     }
     return new Date((long) num.doubleValue());
   }
   JSONString str = value.isString();
   if (str == null) {
     throw new DecodingException("Expected a json string, but was given: " + value);
   }
   return DateTimeFormat.getFormat(format).parse(str.stringValue());
 }