restygwt/src/main/java/org/fusesource/restygwt/client/AbstractJsonEncoderDecoder.java
public static <KeyType, ValueType> JSONValue toJSON(Map<KeyType, ValueType> value,
                                                        AbstractJsonEncoderDecoder<? super KeyType> keyEncoder,
                                                        AbstractJsonEncoderDecoder<? super ValueType> valueEncoder,
                                                        Style style) {
        if (value == null) {
            return getNullType();
        }

        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 <KeyType, ValueType> JSONValue toJSON(Map<KeyType, ValueType> value,
                                                        AbstractJsonEncoderDecoder<? super KeyType> keyEncoder,
                                                        AbstractJsonEncoderDecoder<? super ValueType> valueEncoder,
                                                        Style style) {
        if (value == null) {
            return getNullType();
        }

        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());
        }
    }
TODO(sbeutel): new map method to handle other key values than String