docs: private static List<StateField> enumerateFields(Class<?> clazz, Map<String, Type> fieldTypes)
      {
          ImmutableList.Builder<StateField> builder = ImmutableList.builder();
          final Set<Class<?>> primitiveClasses = ImmutableSet.of(byte.class, boolean.class, long.class, double.class, int.class);
          Set<Class<?>> supportedClasses = getSupportedFieldTypes();
          for (Method method : clazz.getMethods()) {
              if (method.getName().equals("getEstimatedSize")) {
                  continue;
              }
              if (method.getName().startsWith("get")) {
                  Class<?> type = method.getReturnType();
                  checkArgument(supportedClasses.contains(type), type.getName() + " is not supported");
                  String name = method.getName().substring(3);
                  builder.add(new StateField(name, type, getInitialValue(method), method.getName(), Optional.ofNullable(fieldTypes.get(name))));
              }
              if (method.getName().startsWith("is")) {
                  Class<?> type = method.getReturnType();
                  checkArgument(type == boolean.class, "Only boolean is support for 'is' methods");
                  String name = method.getName().substring(2);
                  builder.add(new StateField(name, type, getInitialValue(method), method.getName(), Optional.of(BOOLEAN)));
              }
          }
  
          // We need this ordering because the serializer and deserializer are on different machines, and so the ordering of fields must be stable
          Ordering<StateField> ordering = new Ordering<StateField>()
          {
              @Override
              public int compare(StateField left, StateField right)
              {
                  if (primitiveClasses.contains(left.getType()) && !primitiveClasses.contains(right.getType())) {
                      return -1;
                  }
                  if (primitiveClasses.contains(right.getType()) && !primitiveClasses.contains(left.getType())) {
                      return 1;
                  }
                  // If they're the category, just sort by name
                  return left.getName().compareTo(right.getName());
              }
          };
          List<StateField> fields = ordering.sortedCopy(builder.build());
          checkInterface(clazz, fields);
  
          return fields;
      }