code: private static <T> T deserializeObject(final Class<T> expectedType, final String json,
              final ClassFieldCache classFieldCache) throws IllegalArgumentException {
          // Parse the JSON
          Object parsedJSON;
          try {
              parsedJSON = JSONParser.parseJSON(json);
          } catch (final ParseException e) {
              throw new IllegalArgumentException("Could not parse JSON", e);
          }
  
          T objectInstance;
          try {
              // Construct an object of the expected type
              final Constructor<?> constructor = classFieldCache.getDefaultConstructorForConcreteTypeOf(expectedType);
              @SuppressWarnings("unchecked")
              final T newInstance = (T) constructor.newInstance();
              objectInstance = newInstance;
          } catch (final ReflectiveOperationException | SecurityException e) {
              throw new IllegalArgumentException("Could not construct object of type " + expectedType.getName(), e);
          }
  
          // Populate the object from the parsed JSON
          final List<Runnable> collectionElementAdders = new ArrayList<>();
          populateObjectFromJsonObject(objectInstance, expectedType, parsedJSON, classFieldCache,
                  getInitialIdToObjectMap(objectInstance, parsedJSON), collectionElementAdders);
          for (final Runnable runnable : collectionElementAdders) {
              runnable.run();
          }
          return objectInstance;
  
      }
docs: Deserialize JSON to a new object graph, with the root object of the specified expected type, using or reusing
  the given type cache. Does not work for generic types, since it is not possible to obtain the generic type of
  a Class reference.
  
  @param <T>
  the expected type
  @param expectedType
  The type that the JSON should conform to.
  @param json
  the JSON string to deserialize.
  @param classFieldCache
  The class field cache. Reusing this cache will increase the speed if many JSON documents of the
  same type need to be parsed.
  @return The object graph after deserialization.
  @throws IllegalArgumentException
  If anything goes wrong during deserialization.