class AviatorObjectInputStream extends ObjectInputStream {
  private AviatorClassLoader classLoader;
  private AviatorEvaluatorInstance instance;
  private Map<String, byte[]> classBytesCache = new HashMap<String, byte[]>();

  public AviatorObjectInputStream(InputStream in, AviatorEvaluatorInstance instance)
      throws IOException {
    super(in);
    this.classLoader = instance.getAviatorClassLoader(true);
    this.instance = instance;
    this.enableResolveObject(true);
  }

  @Override
  protected Object resolveObject(Object obj) throws IOException {
    Object object = super.resolveObject(obj);
    if (object instanceof BaseExpression) {
      BaseExpression exp = (BaseExpression) object;
      configureExpression(exp);
    }
    if (object instanceof Env) {
      ((Env) object).setInstance(this.instance);
    }

    // Processing some internal constants.
    if (object instanceof AviatorBoolean) {
      AviatorBoolean bool = (AviatorBoolean) object;
      if (bool.getBooleanValue()) {
        object = AviatorBoolean.TRUE;
      } else {
        object = AviatorBoolean.FALSE;
      }
    }
    if (object instanceof AviatorNil) {
      object = AviatorNil.NIL;
    }

    if (object instanceof Range) {
      if (((Range) object).isLoop()) {
        object = Range.LOOP;
      }
    }

    if (object instanceof Variable) {
      object = SymbolTable.tryReserveKeyword((Variable) object);
    }

    return object;
  }

  private void configureExpression(BaseExpression exp) {
    exp.setInstance(this.instance);
    if (exp instanceof ClassExpression) {
      ((ClassExpression) exp).setClassBytes(this.classBytesCache.get(exp.getClass().getName()));
    }
  }

  @Override
  protected Class<?> resolveClass(ObjectStreamClass desc)
      throws IOException, ClassNotFoundException {<FILL_FUNCTION_BODY>}

}

    Class<?> clazz = null;
    try {
      clazz = super.resolveClass(desc);
    } catch (ClassNotFoundException e) {

    }
    if (clazz == null && desc.getName().startsWith("AviatorScript_")) {
      int len = this.readInt();
      byte[] classBytes = new byte[len];

      int readed = 0;
      while (readed < classBytes.length) {
        int n = this.read(classBytes, readed, classBytes.length - readed);
        if (n < 0) {
          break;
        }
        readed += n;
      }

      String name = desc.getName();
      this.classBytesCache.put(name, classBytes);
      try {
        // already in class loader
        clazz = Class.forName(name, false, this.classLoader);
      } catch (ClassNotFoundException ex) {

      }
      if (clazz == null) {
        // still not found, try to define it.
        try {
          clazz = ClassDefiner.defineClass(desc.getName(), Expression.class, classBytes,
              this.classLoader, true);
        } catch (Throwable t) {
          throw Reflector.sneakyThrow(t);
        }
      }

    }
    if (clazz == null) {
      throw new ClassNotFoundException("Class not found:" + desc.getName());
    }
    return clazz;
  
<methods>public void <init>(java.io.InputStream) throws java.io.IOException,public int available() throws java.io.IOException,public void close() throws java.io.IOException,public void defaultReadObject() throws java.io.IOException, java.lang.ClassNotFoundException,public final java.io.ObjectInputFilter getObjectInputFilter() ,public int read() throws java.io.IOException,public int read(byte[], int, int) throws java.io.IOException,public boolean readBoolean() throws java.io.IOException,public byte readByte() throws java.io.IOException,public char readChar() throws java.io.IOException,public double readDouble() throws java.io.IOException,public java.io.ObjectInputStream.GetField readFields() throws java.io.IOException, java.lang.ClassNotFoundException,public float readFloat() throws java.io.IOException,public void readFully(byte[]) throws java.io.IOException,public void readFully(byte[], int, int) throws java.io.IOException,public int readInt() throws java.io.IOException,public java.lang.String readLine() throws java.io.IOException,public long readLong() throws java.io.IOException,public final java.lang.Object readObject() throws java.io.IOException, java.lang.ClassNotFoundException,public short readShort() throws java.io.IOException,public java.lang.String readUTF() throws java.io.IOException,public java.lang.Object readUnshared() throws java.io.IOException, java.lang.ClassNotFoundException,public int readUnsignedByte() throws java.io.IOException,public int readUnsignedShort() throws java.io.IOException,public void registerValidation(java.io.ObjectInputValidation, int) throws java.io.NotActiveException, java.io.InvalidObjectException,public final void setObjectInputFilter(java.io.ObjectInputFilter) ,public int skipBytes(int) throws java.io.IOException<variables>static final boolean $assertionsDisabled,private static final int NULL_HANDLE,private static final jdk.internal.misc.Unsafe UNSAFE,private final java.io.ObjectInputStream.BlockDataInputStream bin,private boolean closed,private java.io.SerialCallbackContext curContext,private boolean defaultDataEnd,private long depth,private final boolean enableOverride,private boolean enableResolve,private final java.io.ObjectInputStream.HandleTable handles,private int passHandle,private static final Map<java.lang.String,Class<?>> primClasses,private java.io.ObjectInputFilter serialFilter,private boolean streamFilterSet,private long totalObjectRefs,private static final java.lang.Object unsharedMarker,private final java.io.ObjectInputStream.ValidationList vlist