Subversion Repositories bacoAlunos

Rev

Blame | Compare with Previous | Last modification | View Log | RSS feed

package genson.convert;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.owlike.genson.reflect.TypeUtil.*;

/**
 * This class contains all default converters and their factories. You can read the source code <a
 * href=
 * "http://code.google.com/p/genson/source/browse/src/main/java/com/owlike/genson/convert/DefaultConverters.java"
 * >here</a> as example on how to implement custom converters and factories.
 *
 * @author eugen
 */

public final class DefaultConverters {
  private DefaultConverters() {
  }

  @genson.annotation.HandleClassMetadata
  public static class SetConverter<E> extends CollectionConverter<E> {

    public SetConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return new HashSet<E>();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class LinkedListConverter<E> extends CollectionConverter<E> {

    public LinkedListConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return new LinkedList<E>();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class TreeSetConverter<E> extends CollectionConverter<E> {

    public TreeSetConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(Collection<E> array, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      TreeSet<E> treeSet = (TreeSet<E>) array;
      if (treeSet.comparator() != null) {
        throw new 1.5.0/docs/api/java/lang/UnsupportedOperationException.html">UnsupportedOperationException("Serialization and deserialization of TreeSet with Comparator is not supported. " +
          "You need to implement a custom Converter to handle it.");
      }
      super.serialize(array, writer, ctx);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return new TreeSet<E>();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class LinkedHashSetConverter<E> extends CollectionConverter<E> {

    public LinkedHashSetConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return new LinkedHashSet<E>();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class ArrayDequeConverter<E> extends CollectionConverter<E> {

    public ArrayDequeConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return new ArrayDeque<E>();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class PriorityQueueConverter<E> extends CollectionConverter<E> {

    public PriorityQueueConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(Collection<E> array, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      PriorityQueue<E> queue = (PriorityQueue<E>) array;
      if (queue.comparator() != null) {
        throw new 1.5.0/docs/api/java/lang/UnsupportedOperationException.html">UnsupportedOperationException("Serialization and deserialization of PriorityQueue with Comparator is not supported. " +
          "You need to implement a custom Converter to handle it.");
      }
      super.serialize(array, writer, ctx);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return new PriorityQueue<E>();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class EnumSetConverter<E> extends CollectionConverter<E> {
    private final Class<E> eClass;

    public EnumSetConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      super(eClass, elementConverter);
      this.eClass = eClass;
    }

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"unchecked", "rawtypes"})
    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Collection<E> create() {
      return 1.5.0/docs/api/java/util/EnumSet.html">EnumSet.noneOf((1.5.0/docs/api/java/lang/Class.html">Class) eClass);
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class CollectionConverter<E> implements genson.Converter<Collection<E>> {

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unused")
    private final Class<E> eClass;
    private final genson.Converter<E> elementConverter;

    public CollectionConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      this.eClass = eClass;
      this.elementConverter = elementConverter;
    }

    public Collection<E> deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      reader.beginArray();
      Collection<E> col = create();
      for (; reader.hasNext(); ) {
        reader.next();
        E e = elementConverter.deserialize(reader, ctx);
        col.add(e);
      }
      reader.endArray();
      return col;
    }

    public void serialize(Collection<E> array, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      writer.beginArray();
      for (E e : array) {
        elementConverter.serialize(e, writer, ctx);
      }
      writer.endArray();
    }

    public genson.Converter<E> getElementConverter() {
      return elementConverter;
    }

    protected Collection<E> create() {
      return new ArrayList<E>();
    }
  }

  public final static class SingleValueAsListFactory implements genson.Factory<genson.Converter<Collection<?>>> {
    public final static SingleValueAsListFactory instance = new SingleValueAsListFactory();

    genson.Factory<genson.Converter<Collection<?>>> defaultFactory = CollectionConverterFactory.instance;

    private SingleValueAsListFactory() {}

    @1.5.0/docs/api/java/lang/Override.html">Override
    public genson.Converter<Collection<?>> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, genson.Genson genson) {
      final CollectionConverter defaultConverter = (CollectionConverter) defaultFactory.create(type, genson);

      return new genson.Converter<Collection<?>>() {
        @1.5.0/docs/api/java/lang/Override.html">Override
        public void serialize(1.5.0/docs/api/java/util/Collection.html">Collection object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
          defaultConverter.serialize(object, writer, ctx);
        }

        @1.5.0/docs/api/java/lang/Override.html">Override
        public 1.5.0/docs/api/java/util/Collection.html">Collection deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
          genson.stream.ValueType vt = reader.getValueType();
          if (vt != genson.stream.ValueType.ARRAY && vt != genson.stream.ValueType.NULL ) {
            5+0%2Fdocs%2Fapi+Object">Object object = defaultConverter.getElementConverter().deserialize(reader, ctx);
            1.5.0/docs/api/java/util/Collection.html">Collection result = defaultConverter.create();
            result.add(object);
            return result;
          } else return defaultConverter.deserialize( reader, ctx );
        }
      };
    }
  }

  public final static class CollectionConverterFactory implements genson.Factory<genson.Converter<Collection<?>>> {
    public final static CollectionConverterFactory instance = new CollectionConverterFactory();

    private CollectionConverterFactory() {
    }

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"rawtypes", "unchecked"})
    public genson.Converter<Collection<?>> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type forType, genson.Genson genson) {
      genson.Converter<?> elementConverter = genson.provideConverter(genson.reflect.TypeUtil.getCollectionType(forType));

      Class<?> parameterRawClass = genson.reflect.TypeUtil.getRawClass(genson.reflect.TypeUtil.getCollectionType(forType));
      Class<?> rawClass = getRawClass(forType);

      if (1.5.0/docs/api/java/util/EnumSet.html">EnumSet.class.isAssignableFrom(rawClass) && parameterRawClass.isEnum())
        return new EnumSetConverter(parameterRawClass, elementConverter);
      if (1.5.0/docs/api/java/util/LinkedHashSet.html">LinkedHashSet.class.isAssignableFrom(rawClass))
        return new LinkedHashSetConverter(parameterRawClass, elementConverter);
      if (1.5.0/docs/api/java/util/TreeSet.html">TreeSet.class.isAssignableFrom(rawClass))
        return new TreeSetConverter(parameterRawClass, elementConverter);
      if (1.5.0/docs/api/java/util/Set.html">Set.class.isAssignableFrom(rawClass))
        return new SetConverter(parameterRawClass, elementConverter);
      if (1.5.0/docs/api/java/util/LinkedList.html">LinkedList.class.isAssignableFrom(rawClass))
        return new LinkedListConverter(parameterRawClass, elementConverter);
      if (ArrayDeque.class.isAssignableFrom(rawClass))
        return new ArrayDequeConverter(parameterRawClass, elementConverter);
      if (1.5.0/docs/api/java/util/PriorityQueue.html">PriorityQueue.class.isAssignableFrom(rawClass))
        return new PriorityQueueConverter(parameterRawClass, elementConverter);

      return new CollectionConverter(parameterRawClass, elementConverter);
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class ArrayConverter<E> implements genson.Converter<Object> {
    private final Class<E> eClass;
    private final genson.Converter<E> elementConverter;

    public ArrayConverter(Class<E> eClass, genson.Converter<E> elementConverter) {
      this.eClass = eClass;
      this.elementConverter = elementConverter;
    }

    public void serialize(5+0%2Fdocs%2Fapi+Object">Object array, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      writer.beginArray();
      int len = 5+0%2Fdocs%2Fapi+Array">Array.getLength(array);
      for (int i = 0; i < len; i++) {
        @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
        E e = (E) 5+0%2Fdocs%2Fapi+Array">Array.get(array, i);
        elementConverter.serialize(e, writer, ctx);
      }
      writer.endArray();
    }

    public 5+0%2Fdocs%2Fapi+Object">Object deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      reader.beginArray();
      int size = 10;
      5+0%2Fdocs%2Fapi+Object">Object array = 5+0%2Fdocs%2Fapi+Array">Array.newInstance(eClass, size);
      int idx = 0;
      for (; reader.hasNext(); ) {
        reader.next();
        if (idx >= size) {
          size = size * 2 + 1;
          array = expandArray(array, idx, size);
        }
        5+0%2Fdocs%2Fapi+Array">Array.set(array, idx++, elementConverter.deserialize(reader, ctx));
      }
      reader.endArray();
      if (idx < size) {
        array = expandArray(array, idx, idx);
      }
      return array;
    }

    private 5+0%2Fdocs%2Fapi+Object">Object expandArray(5+0%2Fdocs%2Fapi+Object">Object array, int len, int size) {
      5+0%2Fdocs%2Fapi+Object">Object tmpArray = 5+0%2Fdocs%2Fapi+Array">Array.newInstance(eClass, size);
      1.5.0/docs/api/java/lang/System.html">System.arraycopy(array, 0, tmpArray, 0, len);
      return tmpArray;
    }
  }

  @genson.annotation.HandleClassMetadata
  public final static class ByteArrayConverter implements genson.Converter<byte[]> {
    public static final ByteArrayConverter instance = new ByteArrayConverter();

    private ByteArrayConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(byte[] object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public byte[] deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsByteArray();
    }
  }

  @genson.annotation.HandleClassMetadata
  public static class ByteArrayAsIntArrayConverter implements genson.Converter<byte[]> {
    public static final ByteArrayAsIntArrayConverter instance = new ByteArrayAsIntArrayConverter();

    private ByteArrayAsIntArrayConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(byte[] object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      writer.beginArray();
      for (int i = 0; i < object.length; i++) writer.writeValue(object[i]);
      writer.endArray();
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public byte[] deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      byte[] array = new byte[256];
      reader.beginArray();
      int i;
      for (i = 0; reader.hasNext(); i++) {
        reader.next();
        genson.Operations.expandArray(array, i, 2);
        array[i] = (byte) reader.valueAsInt();
      }
      reader.endArray();

      return genson.Operations.truncateArray(array, i);
    }
  }

  public final static class ArrayConverterFactory implements genson.Factory<genson.Converter<Object>> {
    public final static ArrayConverterFactory instance = new ArrayConverterFactory();

    private ArrayConverterFactory() {
    }

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"rawtypes", "unchecked"})
    public genson.Converter<Object> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type forType, genson.Genson genson) {
      if (forType instanceof 1.5.0/docs/api/java/lang/reflect/GenericArrayType.html">GenericArrayType
        || (forType instanceof Class<?> && ((Class<?>) forType).isArray())) {
        if (byte.class.equals(getCollectionType(forType))) {
          return (genson.Converter) ByteArrayConverter.instance;
        } else {
          genson.Converter<?> elementConverter = genson.provideConverter(genson.reflect.TypeUtil
            .getCollectionType(forType));
          return new ArrayConverter(genson.reflect.TypeUtil.getRawClass(genson.reflect.TypeUtil
                  .getCollectionType(forType)), elementConverter);
        }
      }
      return null;
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class StringConverter implements genson.Converter<String> {
    public final static StringConverter instance = new StringConverter();

    private StringConverter() {
    }

    public void serialize(1.5.0/docs/api/java/lang/String.html">String value, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(value);
    }

    public 1.5.0/docs/api/java/lang/String.html">String deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsString();
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class BooleanConverter implements genson.Converter<Boolean> {
    public final static BooleanConverter instance = new BooleanConverter();

    private BooleanConverter() {
    }

    public void serialize(1.5.0/docs/api/java/lang/Boolean.html">Boolean obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(obj.booleanValue());
    }

    public 1.5.0/docs/api/java/lang/Boolean.html">Boolean deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsBoolean();
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class IntegerConverter implements genson.Converter<Integer> {
    public final static IntegerConverter instance = new IntegerConverter();

    private IntegerConverter() {
    }

    public void serialize(1.5.0/docs/api/java/lang/Integer.html">Integer obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(obj.intValue());
    }

    public 1.5.0/docs/api/java/lang/Integer.html">Integer deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsInt();
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class LongConverter implements genson.Converter<Long> {
    public final static LongConverter instance = new LongConverter();

    private LongConverter() {
    }

    public 1.5.0/docs/api/java/lang/Long.html">Long deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsLong();
    }

    public void serialize(1.5.0/docs/api/java/lang/Long.html">Long obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(obj.longValue());
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class ShortConverter implements genson.Converter<Short> {
    public final static ShortConverter instance = new ShortConverter();

    private ShortConverter() {
    }

    public 1.5.0/docs/api/java/lang/Short.html">Short deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsShort();
    }

    public void serialize(1.5.0/docs/api/java/lang/Short.html">Short obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(obj.shortValue());
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class DoubleConverter implements genson.Converter<Double> {
    public final static DoubleConverter instance = new DoubleConverter();

    private DoubleConverter() {
    }

    public 1.5.0/docs/api/java/lang/Double.html">Double deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsDouble();
    }

    public void serialize(1.5.0/docs/api/java/lang/Double.html">Double obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      if (obj.isNaN() || obj.isInfinite()) {
        writer.writeUnsafeValue(obj.toString());
      } else {
        writer.writeValue(obj.doubleValue());
      }
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class FloatConverter implements genson.Converter<Float> {
    public final static FloatConverter instance = new FloatConverter();

    private FloatConverter() {
    }

    public 1.5.0/docs/api/java/lang/Float.html">Float deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return reader.valueAsFloat();
    }

    public void serialize(1.5.0/docs/api/java/lang/Float.html">Float obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      if (obj.isNaN() || obj.isInfinite()) {
        writer.writeUnsafeValue(obj.toString());
      } else {
        writer.writeValue(obj.floatValue());
      }
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class NumberConverter implements genson.Converter<Number> {
    public final static NumberConverter instance = new NumberConverter();

    private NumberConverter() {
    }

    public 1.5.0/docs/api/java/lang/Number.html">Number deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      genson.stream.ValueType vt = reader.getValueType();
      if (genson.stream.ValueType.INTEGER.equals(vt))
        return reader.valueAsInt();
      else if (genson.stream.ValueType.DOUBLE.equals(vt))
        return reader.valueAsDouble();
      else {
        1.5.0/docs/api/java/lang/String.html">String value = reader.valueAsString();
        return "".equals(value) ? null : parse(value, vt);
      }
    }

    public void serialize(1.5.0/docs/api/java/lang/Number.html">Number obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      if (isSpecialNumber(obj)) writer.writeUnsafeValue(obj.toString()); else writer.writeValue(obj);
    }

    private boolean isSpecialNumber(1.5.0/docs/api/java/lang/Number.html">Number v) {
      if (v instanceof 1.5.0/docs/api/java/lang/Double.html">Double || v instanceof 1.5.0/docs/api/java/lang/Float.html">Float) {
        1.5.0/docs/api/java/lang/Double.html">Double num = (1.5.0/docs/api/java/lang/Double.html">Double) v;
        return num.isInfinite() || num.isNaN();
      } else {
        return false;
      }
    }

    private 1.5.0/docs/api/java/lang/Number.html">Number parse(1.5.0/docs/api/java/lang/String.html">String value, genson.stream.ValueType valueType) {
      try {
        if (value.indexOf('.') >= 0) {
          return 1.5.0/docs/api/java/lang/Double.html">Double.parseDouble(value);
        }
        long longValue = 1.5.0/docs/api/java/lang/Long.html">Long.parseLong(value);
        if (longValue <= 1.5.0/docs/api/java/lang/Integer.html">Integer.MAX_VALUE && longValue >= 1.5.0/docs/api/java/lang/Integer.html">Integer.MIN_VALUE) {
          return 1.5.0/docs/api/java/lang/Integer.html">Integer.valueOf((int) longValue);
        }
        return 1.5.0/docs/api/java/lang/Long.html">Long.parseLong(value);
      } catch (1.5.0/docs/api/java/lang/NumberFormatException.html">NumberFormatException nfe) {
        throw new genson.JsonBindingException("Could not convert input value " + value
          + " of type " + valueType.toClass() + " to a Number type.", nfe);
      }
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class CharConverter implements genson.Converter<Character> {
    public final static CharConverter instance = new CharConverter();

    private CharConverter() {
    }

    public void serialize(1.5.0/docs/api/java/lang/Character.html">Character obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(obj.toString());
    }

    public 1.5.0/docs/api/java/lang/Character.html">Character deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      1.5.0/docs/api/java/lang/String.html">String str = reader.valueAsString();
      if (str.length() > 1) throw new genson.JsonBindingException(
        "Could not convert a string with length greater than 1 to a single char."
      );

      return str.charAt(0);
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class ByteConverter implements genson.Converter<Byte> {
    public final static ByteConverter instance = new ByteConverter();

    private ByteConverter() {
    }

    public void serialize(1.5.0/docs/api/java/lang/Byte.html">Byte obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(obj.byteValue());
    }

    public 1.5.0/docs/api/java/lang/Byte.html">Byte deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return (byte) reader.valueAsInt();
    }
  }

  public final static class PrimitiveConverterFactory implements genson.Factory<genson.Converter<?>> {
    public final static PrimitiveConverterFactory instance = new PrimitiveConverterFactory();

    private PrimitiveConverterFactory() {
    }

    public genson.Converter<?> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, genson.Genson genson) {
      Class<?> rawClass = genson.reflect.TypeUtil.getRawClass(type);

      if (rawClass == 1.5.0/docs/api/java/lang/Boolean.html">Boolean.class || rawClass == boolean.class) return BooleanConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Integer.html">Integer.class || rawClass == int.class) return IntegerConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Double.html">Double.class || rawClass == double.class) return DoubleConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Long.html">Long.class || rawClass == long.class) return LongConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Short.html">Short.class || rawClass == short.class) return ShortConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Float.html">Float.class || rawClass == float.class) return FloatConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Character.html">Character.class || rawClass == char.class) return CharConverter.instance;
      if (rawClass == 1.5.0/docs/api/java/lang/Byte.html">Byte.class || rawClass == byte.class) return ByteConverter.instance;

      return null;
    }
  }

  @genson.annotation.HandleClassMetadata
  public static abstract class MapConverter<K, V> implements genson.Converter<Map<K, V>> {
    private final genson.Converter<V> valueConverter;
    private final KeyAdapter<K> keyAdapter;

    public MapConverter(KeyAdapter<K> keyAdapter, genson.Converter<V> valueConverter) {
      this.keyAdapter = keyAdapter;
      this.valueConverter = valueConverter;
    }

    public Map<K, V> deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      reader.beginObject();
      Map<K, V> map = create();
      for (; reader.hasNext(); ) {
        reader.next();
        map.put(keyAdapter.adapt(reader.name()), valueConverter.deserialize(reader, ctx));
      }
      reader.endObject();
      return map;
    }

    public void serialize(Map<K, V> obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      writer.beginObject();
      for (1.5.0/docs/api/java/util/Map.html">Map.Entry<K, V> entry : obj.entrySet()) {
        writer.writeName(keyAdapter.adapt(entry.getKey()));
        valueConverter.serialize(entry.getValue(), writer, ctx);
      }
      writer.endObject();
    }

    protected abstract Map<K, V> create();
  }

  public final static class HashMapConverter<K, V> extends MapConverter<K, V> {
    public HashMapConverter(KeyAdapter<K> keyAdapter, genson.Converter<V> valueConverter) {
      super(keyAdapter, valueConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Map<K, V> create() {
      return new HashMap<K, V>();
    }
  }

  public final static class HashTableConverter<K, V> extends MapConverter<K, V> {
    public HashTableConverter(KeyAdapter<K> keyAdapter, genson.Converter<V> valueConverter) {
      super(keyAdapter, valueConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Map<K, V> create() {
      return new Hashtable<K, V>();
    }
  }

  @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("rawtypes")
  public final static class PropertiesConverter extends MapConverter {
    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
    public PropertiesConverter(1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter keyAdapter, genson.Converter valueConverter) {
      super(keyAdapter, valueConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected 1.5.0/docs/api/java/util/Map.html">Map create() {
      return new 1.5.0/docs/api/java/util/Properties.html">Properties();
    }
  }

  public final static class TreeMapConverter<K, V> extends MapConverter<K, V> {
    public TreeMapConverter(KeyAdapter<K> keyAdapter, genson.Converter<V> valueConverter) {
      super(keyAdapter, valueConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(Map<K, V> obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      TreeMap<K, V> treeMap = (TreeMap<K, V>) obj;
      if (((TreeMap<K, V>) obj).comparator() != null)
        throw new 1.5.0/docs/api/java/lang/UnsupportedOperationException.html">UnsupportedOperationException("Serialization and deserialization of TreeMap with Comparator is not supported. " +
          "You need to implement a custom Converter to handle it.");

      super.serialize(obj, writer, ctx);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Map<K, V> create() {
      return new TreeMap<K, V>();
    }
  }

  public final static class LinkedHashMapConverter<K, V> extends MapConverter<K, V> {
    public LinkedHashMapConverter(KeyAdapter<K> keyAdapter, genson.Converter<V> valueConverter) {
      super(keyAdapter, valueConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected Map<K, V> create() {
      return new LinkedHashMap<K, V>();
    }
  }

  public static abstract class KeyAdapter<K> {
    public abstract K adapt(1.5.0/docs/api/java/lang/String.html">String str);

    public abstract 1.5.0/docs/api/java/lang/String.html">String adapt(K key);

    public final static KeyAdapter<Object> runtimeAdapter = new KeyAdapter<Object>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 5+0%2Fdocs%2Fapi+Object">Object adapt(1.5.0/docs/api/java/lang/String.html">String str) {
        return str;
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(5+0%2Fdocs%2Fapi+Object">Object key) {
        return key.toString();
      }
    };

    public final static KeyAdapter<String> strAdapter = new KeyAdapter<String>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(1.5.0/docs/api/java/lang/String.html">String key) {
        return key;
      }
    };

    public final static KeyAdapter<Short> shortAdapter = new KeyAdapter<Short>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/Short.html">Short adapt(1.5.0/docs/api/java/lang/String.html">String str) {
        return 1.5.0/docs/api/java/lang/Short.html">Short.parseShort(str);
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(1.5.0/docs/api/java/lang/Short.html">Short key) {
        return key.toString();
      }
    };

    public final static KeyAdapter<Integer> intAdapter = new KeyAdapter<Integer>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/Integer.html">Integer adapt(1.5.0/docs/api/java/lang/String.html">String str) {
        return 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(str);
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(1.5.0/docs/api/java/lang/Integer.html">Integer key) {
        return key.toString();
      }
    };

    public final static KeyAdapter<Long> longAdapter = new KeyAdapter<Long>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/Long.html">Long adapt(1.5.0/docs/api/java/lang/String.html">String str) {
        return 1.5.0/docs/api/java/lang/Long.html">Long.parseLong(str);
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(1.5.0/docs/api/java/lang/Long.html">Long key) {
        return key.toString();
      }
    };

    public final static KeyAdapter<Float> floatAdapter = new KeyAdapter<Float>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/Float.html">Float adapt(1.5.0/docs/api/java/lang/String.html">String str) {
        return 1.5.0/docs/api/java/lang/Float.html">Float.parseFloat(str);
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(1.5.0/docs/api/java/lang/Float.html">Float key) {
        return key.toString();
      }
    };

    public final static KeyAdapter<Double> doubleAdapter = new KeyAdapter<Double>() {
      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/Double.html">Double adapt(1.5.0/docs/api/java/lang/String.html">String str) {
        return 1.5.0/docs/api/java/lang/Double.html">Double.parseDouble(str);
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public 1.5.0/docs/api/java/lang/String.html">String adapt(1.5.0/docs/api/java/lang/Double.html">Double key) {
        return key.toString();
      }
    };
  }

  @genson.annotation.HandleClassMetadata
  public static class ComplexMapConverter<K, V> implements genson.Converter<Map<K, V>> {
    private final genson.Converter<K> keyConverter;
    private final genson.Converter<V> valueConverter;

    private ComplexMapConverter(genson.Converter<K> keyConverter, genson.Converter<V> valueConverter) {
      super();
      this.keyConverter = keyConverter;
      this.valueConverter = valueConverter;
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(Map<K, V> object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      writer.beginArray();
      for (1.5.0/docs/api/java/util/Map.html">Map.Entry<K, V> entry : object.entrySet()) {
        writer.beginObject().writeName("key");
        keyConverter.serialize(entry.getKey(), writer, ctx);
        writer.writeName("value");
        valueConverter.serialize(entry.getValue(), writer, ctx);
        writer.endObject();
      }
      writer.endArray();
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public Map<K, V> deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      Map<K, V> map = new HashMap<K, V>();
      reader.beginArray();
      while (reader.hasNext()) {
        reader.next();
        reader.beginObject();
        K key = null;
        V value = null;
        while (reader.hasNext()) {
          reader.next();
          if ("key".equals(reader.name())) {
            key = keyConverter.deserialize(reader, ctx);
          } else if ("value".equals(reader.name())) {
            value = valueConverter.deserialize(reader, ctx);
          }
        }
        map.put(key, value);
        reader.endObject();
      }
      reader.endArray();
      return map;
    }
  }

  public final static class MapConverterFactory implements genson.Factory<genson.Converter<? extends Map<?, ?>>> {
    public final static MapConverterFactory instance = new MapConverterFactory();

    private MapConverterFactory() {
    }

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"rawtypes", "unchecked"})
    public genson.Converter<? extends Map<?, ?>> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, genson.Genson genson) {
      // ok this is a fix but not the cleanest one... we make sure it is a parameterized type
      // otherwise we search for map impl in its hierarchy
      1.5.0/docs/api/java/lang/reflect/Type.html">Type expandedType = type;
      if (getRawClass(type).getTypeParameters().length == 0) {
        expandedType = expandType(lookupGenericType(1.5.0/docs/api/java/util/Map.html">Map.class, getRawClass(type)), type);
      }

      1.5.0/docs/api/java/lang/reflect/Type.html">Type keyType = typeOf(0, expandedType);
      1.5.0/docs/api/java/lang/reflect/Type.html">Type valueType = typeOf(1, expandedType);
      Class<?> keyRawClass = getRawClass(keyType);
      KeyAdapter<?> keyAdapter = keyAdapter(keyRawClass);

      if (keyAdapter != null)
        return createConverter(getRawClass(type), keyAdapter, genson.provideConverter(valueType));
      else
        return new ComplexMapConverter(genson.provideConverter(keyType), genson.provideConverter(valueType));
    }

    public static KeyAdapter<?> keyAdapter(Class<?> keyRawClass) {
      if (5+0%2Fdocs%2Fapi+Object">Object.class.equals(keyRawClass)) return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.runtimeAdapter;
      else if (1.5.0/docs/api/java/lang/String.html">String.class.equals(keyRawClass)) return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.strAdapter;
      else if (int.class.equals(keyRawClass) || 1.5.0/docs/api/java/lang/Integer.html">Integer.class.equals(keyRawClass))
        return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.intAdapter;
      else if (double.class.equals(keyRawClass) || 1.5.0/docs/api/java/lang/Double.html">Double.class.equals(keyRawClass))
        return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.doubleAdapter;
      else if (long.class.equals(keyRawClass) || 1.5.0/docs/api/java/lang/Long.html">Long.class.equals(keyRawClass))
        return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.longAdapter;
      else if (float.class.equals(keyRawClass) || 1.5.0/docs/api/java/lang/Float.html">Float.class.equals(keyRawClass))
        return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.floatAdapter;
      else if (short.class.equals(keyRawClass) || 1.5.0/docs/api/java/lang/Short.html">Short.class.equals(keyRawClass))
        return 1.5.0/docs/api/java/awt/event/KeyAdapter.html">KeyAdapter.shortAdapter;
      else return null;
    }

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
    private <K, V> MapConverter<K, V> createConverter(Class<?> typeOfMap,
                                                      KeyAdapter<K> keyAdapter, genson.Converter<V> valueConverter) {
      if (1.5.0/docs/api/java/util/Properties.html">Properties.class.equals(typeOfMap))
        return new PropertiesConverter(keyAdapter, valueConverter);

      if (1.5.0/docs/api/java/util/Hashtable.html">Hashtable.class.equals(typeOfMap))
        return new HashTableConverter<K, V>(keyAdapter, valueConverter);

      if (1.5.0/docs/api/java/util/TreeMap.html">TreeMap.class.equals(typeOfMap))
        return new TreeMapConverter<K, V>(keyAdapter, valueConverter);

      if (1.5.0/docs/api/java/util/LinkedHashMap.html">LinkedHashMap.class.equals(typeOfMap))
        return new LinkedHashMapConverter<K, V>(keyAdapter, valueConverter);

      return new HashMapConverter<K, V>(keyAdapter, valueConverter);
    }
  }

  @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("rawtypes")
  public static class DateContextualFactory implements genson.convert.ContextualFactory {
    @1.5.0/docs/api/java/lang/Override.html">Override
    public genson.Converter create(genson.reflect.BeanProperty property, genson.Genson genson) {
      genson.annotation.JsonDateFormat ann = property.getAnnotation(genson.annotation.JsonDateFormat.class);
      if (ann != null) {
        1.5.0/docs/api/java/util/Locale.html">Locale locale = ann.lang().isEmpty() ? 1.5.0/docs/api/java/util/Locale.html">Locale.getDefault() : new 1.5.0/docs/api/java/util/Locale.html">Locale(
          ann.lang());
        1.5.0/docs/api/java/text/DateFormat.html">DateFormat dateFormat = ann.value() != null && !ann.value().isEmpty() ?
          new 1.5.0/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat(ann.value(), locale) : 1.5.0/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat.getInstance();

        if (5+0%2Fdocs%2Fapi+Date">Date.class.isAssignableFrom(property.getRawClass()))
          return new DateConverter(dateFormat, ann.asTimeInMillis());
        if (1.5.0/docs/api/java/util/Calendar.html">Calendar.class.isAssignableFrom(property.getRawClass()))
          return new CalendarConverter(
            new DateConverter(dateFormat, ann.asTimeInMillis()));
      }
      return null;
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class DateConverter implements genson.Converter<Date> {
    private 1.5.0/docs/api/java/text/DateFormat.html">DateFormat dateFormat;
    private final boolean asTimeInMillis;

    public DateConverter() {
      this(1.5.0/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat.getDateTimeInstance(), true);
    }

    public DateConverter(1.5.0/docs/api/java/text/DateFormat.html">DateFormat dateFormat, boolean asTimeInMillis) {
      if (dateFormat == null) dateFormat = 1.5.0/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat.getDateTimeInstance();
      this.dateFormat = dateFormat;
      this.asTimeInMillis = asTimeInMillis;
    }

    public void serialize(5+0%2Fdocs%2Fapi+Date">Date obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      if (asTimeInMillis)
        writer.writeValue(obj.getTime());
      else
        writer.writeUnsafeValue(format(obj));
    }

    protected synchronized 1.5.0/docs/api/java/lang/String.html">String format(5+0%2Fdocs%2Fapi+Date">Date date) {
      return dateFormat.format(date);
    }

    public 5+0%2Fdocs%2Fapi+Date">Date deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      try {
        genson.stream.ValueType valueType = reader.getValueType();
        if (valueType == genson.stream.ValueType.INTEGER)
          return new 5+0%2Fdocs%2Fapi+Date">Date(reader.valueAsLong());
        else if (valueType == genson.stream.ValueType.STRING)
          return read(reader.valueAsString());
        else throw new genson.JsonBindingException(1.5.0/docs/api/java/lang/String.html">String.format("Can not deserialize type %s to Date, " +
            "only numeric and string accepted.", valueType));
      } catch (1.5.0/docs/api/java/text/ParseException.html">ParseException e) {
        throw new genson.JsonBindingException("Could not parse date " + reader.valueAsString(),
          e);
      }
    }

    protected synchronized 5+0%2Fdocs%2Fapi+Date">Date read(1.5.0/docs/api/java/lang/String.html">String dateString) throws 1.5.0/docs/api/java/text/ParseException.html">ParseException {
      return dateFormat.parse(dateString);
    }
  }

  public final static class UntypedConverterFactory implements genson.Factory<genson.Converter<Object>> {
    public final static UntypedConverterFactory instance = new UntypedConverterFactory();

    private UntypedConverterFactory() {
    }

    public final static class UntypedConverter implements genson.Converter<Object> {
      final static UntypedConverter instance = new UntypedConverter();

      private UntypedConverter() {
      }

      public 5+0%2Fdocs%2Fapi+Object">Object deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
        return ctx.genson.deserialize(genson.GenericType.of(reader.getValueType().toClass()),
          reader, ctx);
      }

      public void serialize(5+0%2Fdocs%2Fapi+Object">Object obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
        if (5+0%2Fdocs%2Fapi+Object">Object.class.equals(obj.getClass()))
          throw new 1.5.0/docs/api/java/lang/UnsupportedOperationException.html">UnsupportedOperationException(
            "Serialization of type Object is not supported by default serializers.");
        ctx.genson.serialize(obj, obj.getClass(), writer, ctx);
      }
    }

    public genson.Converter<Object> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, genson.Genson genson) {
      if (genson.reflect.TypeUtil.match(type, 5+0%2Fdocs%2Fapi+Object">Object.class, true)) {
        return UntypedConverter.instance;
      }
      return null;
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class EnumConverter<T extends Enum<T>> implements genson.Converter<T> {
    private final Class<T> eClass;
    private final Map<String, T> deserializationNames;
    private final boolean caseSensitive;

    public EnumConverter(Class<T> eClass, boolean caseSensitive) {
      this.eClass = eClass;
      this.caseSensitive = caseSensitive;
      deserializationNames = new HashMap<String, T>();
      for (1.5.0/docs/api/java/lang/reflect/Field.html">Field f : eClass.getFields()) {
        try {
          if (!f.isEnumConstant()) {
            continue;
          }
          1.5.0/docs/api/java/lang/String.html">String name = caseSensitive ? f.getName(): f.getName().toUpperCase();
          deserializationNames.put(name, (T) f.get(null));
        } catch (1.5.0/docs/api/java/lang/IllegalAccessException.html">IllegalAccessException e) {
          throw new genson.JsonBindingException("Failed to get enum value " + f.getName(), e);
        }
      }
    }

    public void serialize(T obj, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeUnsafeValue(obj.name());
    }

    public T deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      1.5.0/docs/api/java/lang/String.html">String name = caseSensitive ? reader.valueAsString(): reader.valueAsString().toUpperCase();
      T value = deserializationNames.get(name);
      if (value == null) throw new genson.JsonBindingException("No enum constant " + eClass.getCanonicalName() + "." + name);
      return value;
    }
  }

  public final static class EnumConverterFactory implements genson.Factory<genson.Converter<? extends Enum<?>>> {
    public final static EnumConverterFactory instance = new EnumConverterFactory(true);
    public final boolean caseSensitive;

    public EnumConverterFactory(boolean caseSensitive) {
      this.caseSensitive = caseSensitive;
    }

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"rawtypes", "unchecked"})
    public genson.Converter<Enum<?>> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, genson.Genson genson) {
      Class<?> rawClass = genson.reflect.TypeUtil.getRawClass(type);
      return rawClass.isEnum() || 1.5.0/docs/api/java/lang/Enum.html">Enum.class.isAssignableFrom(rawClass) ? new EnumConverter(
        rawClass, caseSensitive) : null;
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class URLConverter implements genson.Converter<URL> {
    public final static URLConverter instance = new URLConverter();

    private URLConverter() {
    }

    public 1.5.0/docs/api/java/net/URL.html">URL deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      try {
        return new 1.5.0/docs/api/java/net/URL.html">URL(reader.valueAsString());
      } catch (1.5.0/docs/api/java/net/MalformedURLException.html">MalformedURLException e) {
        throw new genson.JsonBindingException("Can not deserializer <" + reader.valueAsString() + "> to URL.");
      }
    }

    public void serialize(1.5.0/docs/api/java/net/URL.html">URL object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object.toExternalForm());
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class URIConverter implements genson.Converter<URI> {
    public final static URIConverter instance = new URIConverter();

    private URIConverter() {
    }

    public void serialize(1.5.0/docs/api/java/net/URI.html">URI object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeUnsafeValue(object.toString());
    }

    public 1.5.0/docs/api/java/net/URI.html">URI deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return 1.5.0/docs/api/java/net/URI.html">URI.create(reader.valueAsString());
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class BigDecimalConverter implements genson.Converter<BigDecimal> {
    public final static BigDecimalConverter instance = new BigDecimalConverter();

    private BigDecimalConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/math/BigDecimal.html">BigDecimal deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return new 1.5.0/docs/api/java/math/BigDecimal.html">BigDecimal(reader.valueAsString());
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(1.5.0/docs/api/java/math/BigDecimal.html">BigDecimal object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object);
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class BigIntegerConverter implements genson.Converter<BigInteger> {
    public final static BigIntegerConverter instance = new BigIntegerConverter();

    private BigIntegerConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/math/BigInteger.html">BigInteger deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return new 1.5.0/docs/api/java/math/BigInteger.html">BigInteger(reader.valueAsString());
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(1.5.0/docs/api/java/math/BigInteger.html">BigInteger object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object);
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class TimestampConverter implements genson.Converter<Timestamp> {
    public final static TimestampConverter instance = new TimestampConverter();

    private TimestampConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 5+0%2Fdocs%2Fapi+Timestamp">Timestamp deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return 5+0%2Fdocs%2Fapi+Timestamp">Timestamp.valueOf(reader.valueAsString());
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(5+0%2Fdocs%2Fapi+Timestamp">Timestamp object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object.toString());
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class UUIDConverter implements genson.Converter<UUID> {
    public final static UUIDConverter instance = new UUIDConverter();

    private UUIDConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(1.5.0/docs/api/java/util/UUID.html">UUID object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object.toString());
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/util/UUID.html">UUID deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return 1.5.0/docs/api/java/util/UUID.html">UUID.fromString(reader.valueAsString());
    }

  }

  public final static class CalendarConverterFactory implements genson.Factory<genson.Converter<Calendar>> {
    private final CalendarConverter calendarConverter;

    public CalendarConverterFactory(DateConverter dateConverter) {
      this.calendarConverter = new CalendarConverter(dateConverter);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public genson.Converter<Calendar> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, genson.Genson genson) {
      if (!1.5.0/docs/api/java/util/Calendar.html">Calendar.class.isAssignableFrom(genson.reflect.TypeUtil.getRawClass(type)))
        throw new 1.5.0/docs/api/java/lang/IllegalStateException.html">IllegalStateException(
          "CalendarConverterFactory create method can be called only for Calendar type and subtypes.");
      return calendarConverter;
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public static class CalendarConverter implements genson.Converter<Calendar> {
    private final DateConverter dateConverter;

    CalendarConverter(final DateConverter dateConverter) {
      this.dateConverter = dateConverter;
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(1.5.0/docs/api/java/util/Calendar.html">Calendar object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      dateConverter.serialize(object.getTime(), writer, ctx);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/util/Calendar.html">Calendar deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      1.5.0/docs/api/java/util/Calendar.html">Calendar cal = null;
      if (genson.stream.ValueType.NULL != reader.getValueType()) {
        cal = new 1.5.0/docs/api/java/util/GregorianCalendar.html">GregorianCalendar();
        cal.setTime(dateConverter.deserialize(reader, ctx));
      }
      return cal;
    }
  }

  @genson.annotation.HandleClassMetadata
  @genson.annotation.HandleBeanView
  public final static class FileConverter implements genson.Converter<File> {
    public final static FileConverter instance = new FileConverter();

    private FileConverter() {
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(1.5.0/docs/api/java/io/File.html">File object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      writer.writeValue(object.getPath());
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public 1.5.0/docs/api/java/io/File.html">File deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) {
      return new 1.5.0/docs/api/java/io/File.html">File(reader.valueAsString());
    }

  }

  public final static class PropertyConverterFactory implements genson.convert.ContextualFactory<Object> {

    @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
    @1.5.0/docs/api/java/lang/Override.html">Override
    public genson.Converter<Object> create(genson.reflect.BeanProperty property, genson.Genson genson) {
      genson.annotation.JsonConverter ann = property.getAnnotation(genson.annotation.JsonConverter.class);
      if (ann != null) {
        1.5.0/docs/api/java/lang/reflect/Type.html">Type converterExpandedType = expandType(
          lookupGenericType(genson.Converter.class, ann.value()), ann.value());
        1.5.0/docs/api/java/lang/reflect/Type.html">Type converterPropertyType = typeOf(0, converterExpandedType);

        Class<?> propertyClass = property.getRawClass();
        if (propertyClass.isPrimitive()) propertyClass = wrap(propertyClass);

        // checking type consistency
        if (!match(propertyClass, converterPropertyType, false))
          throw new 1.5.0/docs/api/java/lang/ClassCastException.html">ClassCastException("The type defined in " + ann.value().getName()
            + " is not assignale from property " + property.getName()
            + " declared in " + property.getDeclaringClass());

        try {
          Constructor<?> ctr = ann.value().getConstructor();
          if (!ctr.isAccessible()) ctr.setAccessible(true);
          return (genson.Converter<Object>) ctr.newInstance();

          // OMG...
        } catch (1.5.0/docs/api/java/lang/InstantiationException.html">InstantiationException e) {
          throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException(e);
        } catch (1.5.0/docs/api/java/lang/IllegalAccessException.html">IllegalAccessException e) {
          throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException(e);
        } catch (1.5.0/docs/api/java/lang/SecurityException.html">SecurityException e) {
          throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException(e);
        } catch (1.5.0/docs/api/java/lang/NoSuchMethodException.html">NoSuchMethodException e) {
          throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException(e);
        } catch (1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException e) {
          throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException(e);
        } catch (1.5.0/docs/api/java/lang/reflect/InvocationTargetException.html">InvocationTargetException e) {
          throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException(e);
        }
      }
      return null;
    }
  }

  public static class WrappedRootValueConverter<T> implements genson.Converter<T> {
    private final 1.5.0/docs/api/java/lang/String.html">String inputName;
    private final 1.5.0/docs/api/java/lang/String.html">String outputName;
    private final genson.Converter<T> delegateConverter;

    public WrappedRootValueConverter(1.5.0/docs/api/java/lang/String.html">String inputName, 1.5.0/docs/api/java/lang/String.html">String outputName, genson.Converter<T> delegateConverter) {
      this.inputName = inputName;
      this.outputName = outputName;
      this.delegateConverter = delegateConverter;
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void serialize(T object, genson.stream.ObjectWriter writer, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      if (writer.enclosingType() == genson.stream.JsonType.EMPTY) {
        writer.beginObject().writeName(outputName);
        delegateConverter.serialize(object, writer, ctx);
        writer.endObject();
      }
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public T deserialize(genson.stream.ObjectReader reader, genson.5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
      T value = null;
      if (reader.enclosingType() == genson.stream.JsonType.EMPTY) {
        reader.beginObject();
        // Lets accept the case where the key is missing
        if (reader.hasNext()) {
          reader.next();

          if (!inputName.equalsIgnoreCase(reader.name())) {
            throw new genson.JsonBindingException(
                1.5.0/docs/api/java/lang/String.html">String.format(
                    "Expected key %s for unwrapping the value, but encountered key %s",
                    inputName,
                    reader.name()
                )
            );
          }

          value = delegateConverter.deserialize(reader, ctx);
        }
        reader.endObject();
      }
      return value;
    }
  }
}