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

import go.Seq;

public final class S implements Seq.Proxy, I {
    static { Ignore.touch(); }
    
    private final int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    S(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public S() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __New();
    
    // skipped field S.F with unsupported type: interface{}
    
    // skipped method S.Argument with unsupported parameter or return types
    
    // skipped method S.Result with unsupported parameter or return types
    
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof S)) {
            return false;
        }
        S that = (S)o;
        // skipped field S.F with unsupported type: interface{}
        
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("S").append("{");
        return b.append("}").toString();
    }
}

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

import go.Seq;

public interface I {
    // skipped method I.Argument with unsupported parameter or return types
    
    // skipped method I.Result with unsupported parameter or return types
    
    
}

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

import go.Seq;

public abstract class Ignore {
    static {
        Seq.touch(); // for loading the native library
        _init();
    }
    
    private Ignore() {} // uninstantiable
    
    // touch is called from other bound packages to initialize this package
    public static void touch() {}
    
    private static native void _init();
    
    private static final class proxyI implements Seq.Proxy, I {
        private final int refnum;
        
        @Override public final int incRefnum() {
              Seq.incGoRef(refnum, this);
              return refnum;
        }
        
        proxyI(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
        
        // skipped method I.Argument with unsupported parameter or return types
        
        // skipped method I.Result with unsupported parameter or return types
        
    }
    
    // skipped const Cuint with unsupported type: uint
    
    // skipped const Cuint32 with unsupported type: uint32
    
    // skipped const Cuint64 with unsupported type: uint64
    
    // skipped const NamedConst with unsupported type: ignore.NamedString
    
    
    // skipped variable C128 with unsupported type: complex128
    
    // skipped variable C64 with unsupported type: complex64
    
    // skipped variable Uint with unsupported type: uint
    
    // skipped variable Uint32 with unsupported type: uint32
    
    // skipped variable Uint64 with unsupported type: uint64
    
    // skipped variable V with unsupported type: interface{}
    
    // skipped variable Var with unsupported type: interface{}
    
    // skipped function Argument with unsupported parameter or return types
    
    // skipped function Result with unsupported parameter or return types
    
}
