### Question:
AutoMatterTypeAdapterFactory implements TypeAdapterFactory { @SuppressWarnings("unchecked") @Override public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) { final TypeAdapter<T> materialized; final AutoMatter annotation = type.getRawType().getAnnotation(AutoMatter.class); if (annotation != null) { final TypeAdapter<T> cached = (TypeAdapter<T>) adapters.get(type); if (cached != null) { return cached; } final String name = type.getRawType().getName(); final int lastDollar = name.lastIndexOf("$"); final String valueName; if (lastDollar > -1) { final int lastDot = name.lastIndexOf("."); valueName = name.substring(0, lastDot + 1).concat(name.substring(lastDollar + 1)) + VALUE_SUFFIX; } else { valueName = name + VALUE_SUFFIX; } final Class<T> cls; try { cls = (Class<T>) Class.forName(valueName); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("No builder found for @AutoMatter type: " + name, e); } final Map<String, List<String>> serializedNameMethods = getSerializedNameMethods(gson, type.getRawType(), cls); materialized = serializedNameMethods.isEmpty() ? gson.getAdapter(cls) : createForInterface(gson, cls, serializedNameMethods); } else { final Map<String, List<String>> serializedNameMethodsbuilder = new HashMap<>(); final Class<? super T> valueClass = type.getRawType(); for (Class<?> itf : valueClass.getInterfaces()) { if (itf.getAnnotation(AutoMatter.class) != null) { serializedNameMethodsbuilder.putAll(getSerializedNameMethods(gson, itf, valueClass)); } } final Map<String, List<String>> serializedNameMethods = serializedNameMethodsbuilder; if (serializedNameMethods.isEmpty()) { return null; } materialized = createForValue(gson, this, type, serializedNameMethods); } final TypeAdapter<T> existing = (TypeAdapter<T>) adapters.putIfAbsent(type, materialized); return (existing != null) ? existing : materialized; }  @SuppressWarnings("unchecked") @Override TypeAdapter<T> create(final Gson gson, final TypeToken<T> type);  }### Answer:
@Test public void testSerializedNameWithUnderscorePolicy() throws IOException { gson = new GsonBuilder() .registerTypeAdapterFactory(new AutoMatterTypeAdapterFactory()) .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create(); final String json = gson.toJson(BAR); final Bar parsed = gson.fromJson(json, Bar.class); assertThat(parsed, is(BAR)); final String underscoredIsPrivate = "{\"a\":17,\"b\":\"foobar\",\"is_private\":true}"; assertThat(gson.fromJson(underscoredIsPrivate, Bar.class), is(BAR)); }