public void write(JsonWriter out, Map<K, V> map) throws IOException {
      if (map == null) {
        out.nullValue();
        return;
      }

      if (!complexMapKeySerialization) {
        out.beginObject();
        for (Map.Entry<K, V> entry : map.entrySet()) {
          out.name(String.valueOf(entry.getKey()));
          valueTypeAdapter.write(out, entry.getValue());
        }
        out.endObject();
        return;
      }

      boolean hasComplexKeys = false;
      List<JsonElement> keys = new ArrayList<JsonElement>(map.size());

      List<V> values = new ArrayList<V>(map.size());
      for (Map.Entry<K, V> entry : map.entrySet()) {
        JsonElement keyElement = toJsonTree(keyTypeAdapter, entry.getKey());
        keys.add(keyElement);
        values.add(entry.getValue());
        hasComplexKeys |= keyElement.isJsonArray() || keyElement.isJsonObject();
      }

      if (hasComplexKeys) {
        out.beginArray();
        for (int i = 0; i < keys.size(); i++) {
          out.beginArray(); // entry array
          Streams.write(keys.get(i), out);
          valueTypeAdapter.write(out, values.get(i));
          out.endArray();
        }
        out.endArray();
      } else {
        out.beginObject();
        for (int i = 0; i < keys.size(); i++) {
          JsonElement keyElement = keys.get(i);
          out.name(keyToString(keyElement));
          valueTypeAdapter.write(out, values.get(i));
        }
        out.endObject();
      }
    }
 private String keyToString(JsonElement keyElement) {
   if (keyElement.isJsonPrimitive()) {
     JsonPrimitive primitive = keyElement.getAsJsonPrimitive();
     if (primitive.isNumber()) {
       return String.valueOf(primitive.getAsNumber());
     } else if (primitive.isBoolean()) {
       return Boolean.toString(primitive.getAsBoolean());
     } else if (primitive.isString()) {
       return primitive.getAsString();
     } else {
       throw new AssertionError();
     }
   } else if (keyElement.isJsonNull()) {
     return "null";
   } else {
     throw new AssertionError();
   }
 }