// Java class go.java.Future is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package go.java;

import go.Seq;

public final class Future implements Seq.GoObject, java.util.concurrent.Future {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    Future(Seq.Ref ref) { this.ref = ref; }
    
    public Future() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    public final native java.util.concurrent.Future getFuture();
    public final native void setFuture(java.util.concurrent.Future v);
    
    @Override public native java.lang.Object get();
    @Override public native java.lang.Object get(long p0, java.util.concurrent.TimeUnit p1);
}

// Java class go.java.InputStream is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package go.java;

import go.Seq;

public final class InputStream extends java.io.InputStream implements Seq.GoObject {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    public InputStream() {
        super();
        this.ref = __NewInputStream();
    }
    
    private static native Seq.Ref __NewInputStream();
    
    public final native java.io.InputStream getInputStream();
    public final native void setInputStream(java.io.InputStream v);
    
    @Override public native int read() throws java.io.IOException;
}

// Java class go.java.Object is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package go.java;

import go.Seq;

public final class Object extends java.lang.Object implements Seq.GoObject {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    Object(Seq.Ref ref) { this.ref = ref; }
    
    public Object() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    public final native java.lang.Object getObject();
    public final native void setObject(java.lang.Object v);
    
}

// Java class go.java.Runnable is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package go.java;

import go.Seq;

public final class Runnable implements Seq.GoObject, java.lang.Runnable {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    Runnable(Seq.Ref ref) { this.ref = ref; }
    
    public Runnable() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    public final native java.lang.Runnable getRunnable();
    public final native void setRunnable(java.lang.Runnable v);
    
    @Override public native void run();
}

// Java class go.java.Java is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package go.java;

import go.Seq;

public abstract class Java {
    static {
        Seq.touch(); // for loading the native library
        _init();
    }
    
    private Java() {} // uninstantiable
    
    // touch is called from other bound packages to initialize this package
    public static void touch() {}
    
    private static native void _init();
    
    
    
    public static native InputStream newInputStream();
}
