jodd-json/src/main/java/jodd/json/JsonParser.java
protected Object parseValue(final Class targetType, final Class keyType, final Class componentType) {
		final ValueConverter valueConverter;

		final char c = input[ndx];

		switch (c) {
			case '\'':
				if (!looseMode) {
					break;
				}
			case '"':
				ndx++;
				Object string = parseStringContent(c);

				valueConverter = lookupValueConverter();
				if (valueConverter != null) {
					return valueConverter.convert(string);
				}

				if (targetType != null && targetType != String.class) {
					string = convertType(string, targetType);
				}
				return string;

			case '{':
				ndx++;
				if (lazy) {
					if (notFirstObject) {
						final Object value = new ObjectParser(this, targetType, keyType, componentType);

						skipObject();

						return value;
					}
					else {
						notFirstObject = true;
					}
				}

				return parseObjectContent(targetType, keyType, componentType);

			case '[':
				ndx++;
				return parseArrayContent(targetType, componentType);

			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
			case '-':
				Object number = parseNumber();

				valueConverter = lookupValueConverter();
				if (valueConverter != null) {
					return valueConverter.convert(number);
				}

				if (targetType != null) {
					number = convertType(number, targetType);
				}
				return number;

			case 'n':
				ndx++;
				if (match(N_ULL)) {
					valueConverter = lookupValueConverter();
					if (valueConverter != null) {
						return valueConverter.convert(null);
					}
					return null;
				}
				break;

			case 't':
				ndx++;
				if (match(T_RUE)) {
					Object value = Boolean.TRUE;

					valueConverter = lookupValueConverter();
					if (valueConverter != null) {
						return valueConverter.convert(value);
					}

					if (targetType != null) {
						value = convertType(value, targetType);
					}
					return value;
				}
				break;

			case 'f':
				ndx++;
				if (match(F_ALSE)) {
					Object value = Boolean.FALSE;

					valueConverter = lookupValueConverter();
					if (valueConverter != null) {
						return valueConverter.convert(value);
					}

					if (targetType != null) {
						value = convertType(value, targetType);
					}
					return value;
				}
				break;
		}

		if (looseMode) {
			// try to parse unquoted string
			Object string = parseUnquotedStringContent();

			valueConverter = lookupValueConverter();
			if (valueConverter != null) {
				return valueConverter.convert(string);
			}

			if (targetType != null && targetType != String.class) {
				string = convertType(string, targetType);
			}
			return string;
		}

		syntaxError("Invalid char: " + input[ndx]);
		return null;
	}
protected Object parseValue(final Class targetType, final Class keyType, final Class componentType) {
		final ValueConverter valueConverter;

		final char c = input[ndx];

		switch (c) {
			case '\'':
				if (!looseMode) {
					break;
				}
			case '"':
				ndx++;
				Object string = parseStringContent(c);

				valueConverter = lookupValueConverter();
				if (valueConverter != null) {
					return valueConverter.convert(string);
				}

				if (targetType != null && targetType != String.class) {
					string = convertType(string, targetType);
				}
				return string;

			case '{':
				ndx++;
				if (lazy) {
					if (notFirstObject) {
						final Object value = new ObjectParser(this, targetType, keyType, componentType);

						skipObject();

						return value;
					}
					else {
						notFirstObject = true;
					}
				}

				return parseObjectContent(targetType, keyType, componentType);

			case '[':
				ndx++;
				return parseArrayContent(targetType, componentType);

			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
			case '-':
				Object number = parseNumber();

				valueConverter = lookupValueConverter();
				if (valueConverter != null) {
					return valueConverter.convert(number);
				}

				if (targetType != null) {
					number = convertType(number, targetType);
				}
				return number;

			case 'n':
				ndx++;
				if (match(N_ULL)) {
					valueConverter = lookupValueConverter();
					if (valueConverter != null) {
						return valueConverter.convert(null);
					}
					return null;
				}
				break;

			case 't':
				ndx++;
				if (match(T_RUE)) {
					Object value = Boolean.TRUE;

					valueConverter = lookupValueConverter();
					if (valueConverter != null) {
						return valueConverter.convert(value);
					}

					if (targetType != null) {
						value = convertType(value, targetType);
					}
					return value;
				}
				break;

			case 'f':
				ndx++;
				if (match(F_ALSE)) {
					Object value = Boolean.FALSE;

					valueConverter = lookupValueConverter();
					if (valueConverter != null) {
						return valueConverter.convert(value);
					}

					if (targetType != null) {
						value = convertType(value, targetType);
					}
					return value;
				}
				break;
		}

		if (looseMode) {
			// try to parse unquoted string
			Object string = parseUnquotedStringContent();

			valueConverter = lookupValueConverter();
			if (valueConverter != null) {
				return valueConverter.convert(string);
			}

			if (targetType != null && targetType != String.class) {
				string = convertType(string, targetType);
			}
			return string;
		}

		syntaxError("Invalid char: " + input[ndx]);
		return null;
	}
Parses a JSON value.
@param targetType target type to convert, may be <code>null</code>
@param componentType component type for maps and arrays, may be <code>null</code>