// Path: core/src/main/java/io/t28/json2java/core/io/JsonParserImpl.java
// public class JsonParserImpl implements JsonParser {
//     private final ObjectMapper mapper;
// 
//     public JsonParserImpl() {
//         this(new ObjectMapper());
//     }
// 
//     @VisibleForTesting
//     JsonParserImpl(@Nonnull ObjectMapper mapper) {
//         this.mapper = mapper;
//     }
// 
//     @Nonnull
//     @Override
//     public JsonValue parse(@Nonnull String json) throws JsonParseException {
//         try {
//             final Object parsed = mapper.readValue(json, Object.class);
//             return JsonValue.wrap(parsed);
//         } catch (IOException e) {
//             throw new JsonParseException("Unable to parse a JSON string(" + json + ")", e);
//         }
//     }
// }
// 
// Path: core/src/main/java/io/t28/json2java/core/io/exception/JsonParseException.java
// public class JsonParseException extends IOException {
//     private static final long serialVersionUID = 1477109671450199015L;
// 
//     public JsonParseException(@Nonnull String message, @Nonnull Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: core/src/main/java/io/t28/json2java/core/json/JsonValue.java
// public abstract class JsonValue {
//     @Nonnull
//     @CheckReturnValue
//     public static JsonValue wrap(@Nullable Object value) {
//         return Stream.of(ValueType.values())
//                 .filter(type -> type.isAcceptable(value))
//                 .findFirst()
//                 .orElseThrow(() -> new IllegalArgumentException("Unsupported type of value(" + value + ")"))
//                 .wrap(value);
//     }
// 
//     @Nonnull
//     public abstract TypeName getType();
// 
//     public abstract Object getValue();
// 
//     @Override
//     public String toString() {
//         return MoreObjects.toStringHelper(this)
//                 .add("type", getType())
//                 .add("value", getValue())
//                 .toString();
//     }
// 
//     @CheckReturnValue
//     public boolean isNull() {
//         return this instanceof JsonNull;
//     }
// 
//     @CheckReturnValue
//     public boolean isBoolean() {
//         return this instanceof JsonBoolean;
//     }
// 
//     @CheckReturnValue
//     public boolean isNumber() {
//         return this instanceof JsonNumber;
//     }
// 
//     @CheckReturnValue
//     public boolean isString() {
//         return this instanceof JsonString;
//     }
// 
//     @CheckReturnValue
//     public boolean isArray() {
//         return this instanceof JsonArray;
//     }
// 
//     @CheckReturnValue
//     public boolean isObject() {
//         return this instanceof JsonObject;
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonNull asNull() {
//         if (isNull()) {
//             return (JsonNull) this;
//         }
//         throw new IllegalStateException("This value is not a null");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonBoolean asBoolean() {
//         if (isBoolean()) {
//             return (JsonBoolean) this;
//         }
//         throw new IllegalStateException("This value is not a boolean");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonNumber asNumber() {
//         if (isNumber()) {
//             return (JsonNumber) this;
//         }
//         throw new IllegalStateException("This value is not a number");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonString asString() {
//         if (isString()) {
//             return (JsonString) this;
//         }
//         throw new IllegalStateException("This value is not a string");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonArray asArray() {
//         if (isArray()) {
//             return (JsonArray) this;
//         }
//         throw new IllegalStateException("This value is not an array");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonObject asObject() {
//         if (isObject()) {
//             return (JsonObject) this;
//         }
//         throw new IllegalStateException("This value is not an object");
//     }
// }
// 
// Path: core/src/test/java/io/t28/json2java/core/Assertions.java
// @Nonnull
// @CheckReturnValue
// public static JsonValueAssert assertThat(@Nullable JsonValue actual) {
//     return new JsonValueAssert(actual);
// }


import static io.t28.json2java.core.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import io.t28.json2java.core.io.JsonParserImpl;
import io.t28.json2java.core.io.exception.JsonParseException;
import io.t28.json2java.core.json.JsonValue;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
        // exercise
        final JsonValue value = underTest.parse("1024");

        // verify
        assertThat(value)
                .isJsonNumber()
                .hasType(TypeName.INT)
                .hasValue(1024);
    }

    @Test
    public void parseShouldReturnJsonNumberWhenLong() throws Exception {
        // exercise
        final JsonValue value = underTest.parse("4294967296");

        // verify
        assertThat(value)
                .isJsonNumber()
                .hasType(TypeName.LONG)
                .hasValue(4294967296L);
    }

    @Test
    public void parseShouldReturnJsonStringWhenString() throws Exception {
        // exercise
        final JsonValue value = underTest.parse("\"JSON string\"");

        // verify
        assertThat(value)
                .isJsonString()
// Path: core/src/main/java/io/t28/json2java/core/io/JsonParserImpl.java
// public class JsonParserImpl implements JsonParser {
//     private final ObjectMapper mapper;
// 
//     public JsonParserImpl() {
//         this(new ObjectMapper());
//     }
// 
//     @VisibleForTesting
//     JsonParserImpl(@Nonnull ObjectMapper mapper) {
//         this.mapper = mapper;
//     }
// 
//     @Nonnull
//     @Override
//     public JsonValue parse(@Nonnull String json) throws JsonParseException {
//         try {
//             final Object parsed = mapper.readValue(json, Object.class);
//             return JsonValue.wrap(parsed);
//         } catch (IOException e) {
//             throw new JsonParseException("Unable to parse a JSON string(" + json + ")", e);
//         }
//     }
// }
// 
// Path: core/src/main/java/io/t28/json2java/core/io/exception/JsonParseException.java
// public class JsonParseException extends IOException {
//     private static final long serialVersionUID = 1477109671450199015L;
// 
//     public JsonParseException(@Nonnull String message, @Nonnull Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: core/src/main/java/io/t28/json2java/core/json/JsonValue.java
// public abstract class JsonValue {
//     @Nonnull
//     @CheckReturnValue
//     public static JsonValue wrap(@Nullable Object value) {
//         return Stream.of(ValueType.values())
//                 .filter(type -> type.isAcceptable(value))
//                 .findFirst()
//                 .orElseThrow(() -> new IllegalArgumentException("Unsupported type of value(" + value + ")"))
//                 .wrap(value);
//     }
// 
//     @Nonnull
//     public abstract TypeName getType();
// 
//     public abstract Object getValue();
// 
//     @Override
//     public String toString() {
//         return MoreObjects.toStringHelper(this)
//                 .add("type", getType())
//                 .add("value", getValue())
//                 .toString();
//     }
// 
//     @CheckReturnValue
//     public boolean isNull() {
//         return this instanceof JsonNull;
//     }
// 
//     @CheckReturnValue
//     public boolean isBoolean() {
//         return this instanceof JsonBoolean;
//     }
// 
//     @CheckReturnValue
//     public boolean isNumber() {
//         return this instanceof JsonNumber;
//     }
// 
//     @CheckReturnValue
//     public boolean isString() {
//         return this instanceof JsonString;
//     }
// 
//     @CheckReturnValue
//     public boolean isArray() {
//         return this instanceof JsonArray;
//     }
// 
//     @CheckReturnValue
//     public boolean isObject() {
//         return this instanceof JsonObject;
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonNull asNull() {
//         if (isNull()) {
//             return (JsonNull) this;
//         }
//         throw new IllegalStateException("This value is not a null");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonBoolean asBoolean() {
//         if (isBoolean()) {
//             return (JsonBoolean) this;
//         }
//         throw new IllegalStateException("This value is not a boolean");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonNumber asNumber() {
//         if (isNumber()) {
//             return (JsonNumber) this;
//         }
//         throw new IllegalStateException("This value is not a number");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonString asString() {
//         if (isString()) {
//             return (JsonString) this;
//         }
//         throw new IllegalStateException("This value is not a string");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonArray asArray() {
//         if (isArray()) {
//             return (JsonArray) this;
//         }
//         throw new IllegalStateException("This value is not an array");
//     }
// 
//     @Nonnull
//     @CheckReturnValue
//     public JsonObject asObject() {
//         if (isObject()) {
//             return (JsonObject) this;
//         }
//         throw new IllegalStateException("This value is not an object");
//     }
// }
// 
// Path: core/src/test/java/io/t28/json2java/core/Assertions.java
// @Nonnull
// @CheckReturnValue
// public static JsonValueAssert assertThat(@Nullable JsonValue actual) {
//     return new JsonValueAssert(actual);
// }


// Path: core/src/test/java/io/t28/json2java/core/io/JsonParserImplTest.java
import static io.t28.json2java.core.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import io.t28.json2java.core.io.JsonParserImpl;
import io.t28.json2java.core.io.exception.JsonParseException;
import io.t28.json2java.core.json.JsonValue;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

        // exercise
        final JsonValue value = underTest.parse("1024");

        // verify
        assertThat(value)
                .isJsonNumber()
                .hasType(TypeName.INT)
                .hasValue(1024);
    }

    @Test
    public void parseShouldReturnJsonNumberWhenLong() throws Exception {
        // exercise
        final JsonValue value = underTest.parse("4294967296");

        // verify
        assertThat(value)
                .isJsonNumber()
                .hasType(TypeName.LONG)
                .hasValue(4294967296L);
    }

    @Test
    public void parseShouldReturnJsonStringWhenString() throws Exception {
        // exercise
        final JsonValue value = underTest.parse("\"JSON string\"");

        // verify
        assertThat(value)
                .isJsonString()
                .hasType(TypeName.get(String.class))