@Override
    public void set(Object toPojo, Object value, LoadContext context) {
      if (value == null) {
        field.set(toPojo, null);
      } else {
        if (!(value instanceof Collection<?>))
          throw new IllegalStateException(
              "Cannot load non-collection value '" + value + "' into " + field);

        Collection<?> datastoreCollection = (Collection<?>) value;
        Collection<Object> target =
            TypeUtils.prepareCollection(toPojo, field, datastoreCollection.size());

        for (Object datastoreValue : datastoreCollection)
          target.add(importBasic(datastoreValue, componentType));
      }
    }
  @Override
  public Translator<Object> create(
      Path path, Property property, Type type, final CreateContext ctx) {

    final Class<?> clazz = (Class<?>) GenericTypeReflector.erase(type);
    final Serialize serializeAnno = TypeUtils.getAnnotation(Serialize.class, property, clazz);

    // We only work with @Serialize classes
    if (serializeAnno == null) return null;

    // Sanity check so we don't have @Serialize and @Embed
    if (TypeUtils.getAnnotation(Embed.class, property, clazz) != null)
      path.throwIllegalState(
          "You cannot both @Serialize and @Embed; check the field and the target class for annotations");

    return new ValueTranslator<Object, Blob>(path, Blob.class) {
      @Override
      public Object loadValue(Blob value, LoadContext ctx) {
        // Need to be careful here because we don't really know if the data was serialized or not.
        // Start
        // with whatever the annotation says, and if that doesn't work, try the other option.
        try {
          ByteArrayInputStream bais = new ByteArrayInputStream(value.getBytes());

          // Start with the annotation
          boolean unzip = serializeAnno.zip();
          try {
            return readObject(bais, unzip);
          } catch (IOException ex) { // will be one of ZipException or StreamCorruptedException
            if (log.isLoggable(Level.INFO))
              log.log(
                  Level.INFO,
                  "Error trying to deserialize object using unzip="
                      + unzip
                      + ", retrying with "
                      + !unzip,
                  ex);

            unzip = !unzip;
            return readObject(bais, unzip); // this will pass the exception up
          }
        } catch (Exception ex) {
          path.throwIllegalState("Unable to deserialize " + value, ex);
          return null; // never gets here
        }
      }

      /** Try reading an object from the stream */
      private Object readObject(ByteArrayInputStream bais, boolean unzip)
          throws IOException, ClassNotFoundException {
        bais.reset();
        InputStream in = bais;

        if (unzip) in = new InflaterInputStream(in);

        ObjectInputStream ois = new ObjectInputStream(in);
        return ois.readObject();
      }

      @Override
      protected Blob saveValue(Object value, SaveContext ctx) {
        try {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          OutputStream out = baos;

          if (serializeAnno.zip()) {
            Deflater deflater = new Deflater(serializeAnno.compressionLevel());
            out = new DeflaterOutputStream(out, deflater);
          }

          ObjectOutputStream oos = new ObjectOutputStream(out);
          oos.writeObject(value);
          oos.close();

          return new Blob(baos.toByteArray());

        } catch (IOException ex) {
          path.throwIllegalState("Unable to serialize " + value, ex);
          return null; // never gets here
        }
      }
    };
  }