public static <Type> JSONValue toJSON(
      Map<String, Type> value, AbstractJsonEncoderDecoder<Type> encoder, Style style) {
    if (value == null) {
      return JSONNull.getInstance();
    }

    switch (style) {
      case DEFAULT:
      case SIMPLE:
        {
          JSONObject rc = new JSONObject();
          for (Entry<String, Type> t : value.entrySet()) {
            rc.put(t.getKey(), encoder.encode(t.getValue()));
          }
          return rc;
        }
      case JETTISON_NATURAL:
        {
          JSONObject rc = new JSONObject();
          JSONArray entries = new JSONArray();
          int i = 0;
          for (Entry<String, Type> t : value.entrySet()) {
            JSONObject entry = new JSONObject();
            entry.put("key", new JSONString(t.getKey()));
            entry.put("value", encoder.encode(t.getValue()));
            entries.set(i++, entry);
          }
          rc.put("entry", entries);
          return rc;
        }
      default:
        throw new UnsupportedOperationException(
            "The encoding style is not yet suppored: " + style.name());
    }
  }
  // TODO(sbeutel): new map method to handle other key values than String
  public static <KeyType, ValueType> JSONValue toJSON(
      Map<KeyType, ValueType> value,
      AbstractJsonEncoderDecoder<KeyType> keyEncoder,
      AbstractJsonEncoderDecoder<ValueType> valueEncoder,
      Style style) {
    if (value == null) {
      return JSONNull.getInstance();
    }

    switch (style) {
      case DEFAULT:
      case SIMPLE:
        {
          JSONObject rc = new JSONObject();

          for (Entry<KeyType, ValueType> t : value.entrySet()) {
            // TODO find a way to check only once
            JSONValue k = keyEncoder.encode(t.getKey());
            if (k.isString() != null) {
              rc.put(k.isString().stringValue(), valueEncoder.encode(t.getValue()));
            } else {
              rc.put(k.toString(), valueEncoder.encode(t.getValue()));
            }
          }
          return rc;
        }
      case JETTISON_NATURAL:
        {
          JSONObject rc = new JSONObject();
          JSONArray entries = new JSONArray();
          int i = 0;
          for (Entry<KeyType, ValueType> t : value.entrySet()) {
            JSONObject entry = new JSONObject();
            // TODO find a way to check only once
            JSONValue k = keyEncoder.encode(t.getKey());
            if (k.isString() != null) {
              entry.put("key", k);
            } else {
              entry.put("key", new JSONString(k.toString()));
            }
            entry.put("value", valueEncoder.encode(t.getValue()));
            entries.set(i++, entry);
          }
          rc.put("entry", entries);
          return rc;
        }
      default:
        throw new UnsupportedOperationException(
            "The encoding style is not yet supported: " + style.name());
    }
  }
 public static <Type> JSONValue toJSON(Type[] value, AbstractJsonEncoderDecoder<Type> encoder) {
   if (value == null) {
     return JSONNull.getInstance();
   }
   JSONArray rc = new JSONArray();
   int i = 0;
   for (Type t : value) {
     rc.set(i++, encoder.encode(t));
   }
   return rc;
 }