class JsonEntityProvider implements EntityProvider<T> {

    @SuppressWarnings({"unchecked"})
    @Override
    public T readFrom(Class<T> type,
                      Type genericType,
                      Annotation[] annotations,
                      MediaType mediaType,
                      MultivaluedMap<String, String> httpHeaders,
                      InputStream entityStream) throws IOException {
        try {
            JsonParser jsonParser = new JsonParser();
            jsonParser.parse(entityStream);
            JsonValue jsonValue = jsonParser.getJsonObject();

            if (JsonValue.class.isAssignableFrom(type)) {
                return (T)jsonValue;
            }

            Types jsonType = JsonUtils.getType(type);
            if (jsonType == Types.ARRAY_BOOLEAN || jsonType == Types.ARRAY_BYTE || jsonType == Types.ARRAY_SHORT
                || jsonType == Types.ARRAY_INT || jsonType == Types.ARRAY_LONG || jsonType == Types.ARRAY_FLOAT
                || jsonType == Types.ARRAY_DOUBLE || jsonType == Types.ARRAY_CHAR || jsonType == Types.ARRAY_STRING
                || jsonType == Types.ARRAY_OBJECT) {
                return (T)ObjectBuilder.createArray(type, jsonValue);
            }
            if (jsonType == Types.COLLECTION) {
                return (T)ObjectBuilder.createCollection((Class)type, genericType, jsonValue);
            }
            if (jsonType == Types.MAP) {
                return (T)ObjectBuilder.createObject((Class)type, genericType, jsonValue);
            }
            return ObjectBuilder.createObject(type, jsonValue);
        } catch (JsonException e) {
            LOG.debug(e.getMessage(), e);
            throw new IOException(String.format("Can't read from input stream %s", e), e);
        }
    }

}