// File is generated by gobind. Do not edit.

package Runnable

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Runnable proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Runnable.
	Cast func(v interface{}) Java.Java_lang_Runnable
)

// File is generated by gobind. Do not edit.

package lang

import "Java"

const _ = Java.Dummy

type Runnable Java.Java_lang_Runnable
type Object Java.Java_lang_Object
type System Java.Java_lang_System
// File is generated by gobind. Do not edit.

package InputStream

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.io.InputStream proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.io.InputStream.
	Cast func(v interface{}) Java.Java_io_InputStream
)

// File is generated by gobind. Do not edit.

package io

import "Java"

const _ = Java.Dummy

type InputStream Java.Java_io_InputStream
type Console Java.Java_io_Console
// File is generated by gobind. Do not edit.

package Future

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.concurrent.Future proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.concurrent.Future.
	Cast func(v interface{}) Java.Java_util_concurrent_Future
)

// File is generated by gobind. Do not edit.

package concurrent

import "Java"

const _ = Java.Dummy

type Future Java.Java_util_concurrent_Future
type TimeUnit Java.Java_util_concurrent_TimeUnit
// File is generated by gobind. Do not edit.

package Object

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Object proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Object.
	Cast func(v interface{}) Java.Java_lang_Object
)

// File is generated by gobind. Do not edit.

package TimeUnit

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.concurrent.TimeUnit proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.concurrent.TimeUnit.
	Cast func(v interface{}) Java.Java_util_concurrent_TimeUnit
)

// File is generated by gobind. Do not edit.

package Spliterators

import "Java"

const _ = Java.Dummy

const (
)

var (
	Iterator func(a0 Java.Java_util_Spliterator) Java.Java_util_Iterator
	// Cast takes a proxy for a Java object and converts it to a java.util.Spliterators proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.Spliterators.
	Cast func(v interface{}) Java.Java_util_Spliterators
)

// File is generated by gobind. Do not edit.

package util

import "Java"

const _ = Java.Dummy

type Spliterators Java.Java_util_Spliterators
type Iterator Java.Java_util_Iterator
type Spliterator Java.Java_util_Spliterator
// File is generated by gobind. Do not edit.

package System

import "Java"

const _ = Java.Dummy

const (
)

var (
	Console func() Java.Java_io_Console
	// Cast takes a proxy for a Java object and converts it to a java.lang.System proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.System.
	Cast func(v interface{}) Java.Java_lang_System
)

// File is generated by gobind. Do not edit.

package Future

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.Future proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.Future.
	Cast func(v interface{}) Java.Java_Future
)

// File is generated by gobind. Do not edit.

package java

import "Java"

const _ = Java.Dummy

type Future Java.Java_Future
type InputStream Java.Java_InputStream
type Object Java.Java_Object
type Runnable Java.Java_Runnable
// File is generated by gobind. Do not edit.

package InputStream

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.InputStream proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.InputStream.
	Cast func(v interface{}) Java.Java_InputStream
)

// File is generated by gobind. Do not edit.

package Object

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.Object proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.Object.
	Cast func(v interface{}) Java.Java_Object
)

// File is generated by gobind. Do not edit.

package Runnable

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.Runnable proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.Runnable.
	Cast func(v interface{}) Java.Java_Runnable
)

// File is generated by gobind. Do not edit.

package Iterator

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.Iterator proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.Iterator.
	Cast func(v interface{}) Java.Java_util_Iterator
)

// File is generated by gobind. Do not edit.

package Spliterator

import "Java"

const _ = Java.Dummy

type OfInt Java.Java_util_Spliterator_OfInt
type OfLong Java.Java_util_Spliterator_OfLong
type OfDouble Java.Java_util_Spliterator_OfDouble
const (
	ORDERED = 16
	DISTINCT = 1
	SORTED = 4
	SIZED = 64
	NONNULL = 256
	IMMUTABLE = 1024
	CONCURRENT = 4096
	SUBSIZED = 16384
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.Spliterator proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.Spliterator.
	Cast func(v interface{}) Java.Java_util_Spliterator
)

// File is generated by gobind. Do not edit.

package OfInt

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.PrimitiveIterator.OfInt proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.PrimitiveIterator.OfInt.
	Cast func(v interface{}) Java.Java_util_PrimitiveIterator_OfInt
)

// File is generated by gobind. Do not edit.

package PrimitiveIterator

import "Java"

const _ = Java.Dummy

type OfInt Java.Java_util_PrimitiveIterator_OfInt
type OfLong Java.Java_util_PrimitiveIterator_OfLong
type OfDouble Java.Java_util_PrimitiveIterator_OfDouble
// File is generated by gobind. Do not edit.

package OfInt

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.Spliterator.OfInt proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.Spliterator.OfInt.
	Cast func(v interface{}) Java.Java_util_Spliterator_OfInt
)

// File is generated by gobind. Do not edit.

package OfLong

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.PrimitiveIterator.OfLong proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.PrimitiveIterator.OfLong.
	Cast func(v interface{}) Java.Java_util_PrimitiveIterator_OfLong
)

// File is generated by gobind. Do not edit.

package OfLong

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.Spliterator.OfLong proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.Spliterator.OfLong.
	Cast func(v interface{}) Java.Java_util_Spliterator_OfLong
)

// File is generated by gobind. Do not edit.

package OfDouble

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.PrimitiveIterator.OfDouble proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.PrimitiveIterator.OfDouble.
	Cast func(v interface{}) Java.Java_util_PrimitiveIterator_OfDouble
)

// File is generated by gobind. Do not edit.

package OfDouble

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.util.Spliterator.OfDouble proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.util.Spliterator.OfDouble.
	Cast func(v interface{}) Java.Java_util_Spliterator_OfDouble
)

// File is generated by gobind. Do not edit.

package Console

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.io.Console proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.io.Console.
	Cast func(v interface{}) Java.Java_io_Console
)

// File is generated by gobind. Do not edit.

package Java

// Used to silence this package not used errors
const Dummy = 0

type Java_lang_Runnable interface {
	Run()
}

type Java_io_InputStream interface {
	Read(a0 ...interface{}) (int32, error)
	ToString() string
}

type Java_util_concurrent_Future interface {
	Get(a0 ...interface{}) (Java_lang_Object, error)
}

type Java_lang_Object interface {
	ToString() string
}

type Java_util_concurrent_TimeUnit interface {
	ToString() string
}

type Java_util_Spliterators interface {
	ToString() string
}

type Java_lang_System interface {
	ToString() string
}

type Java_Future interface {
	Get(a0 ...interface{}) (Java_lang_Object, error)
	Super() Java_Future
	// Unwrap returns the Go object this Java instance
	// is wrapping.
	// The return value is a java.Future, but the delclared type is
	// interface{} to avoid import cycles.
	Unwrap() interface{}
}

type Java_InputStream interface {
	Read(a0 ...interface{}) (int32, error)
	ToString() string
	Super() Java_InputStream
	// Unwrap returns the Go object this Java instance
	// is wrapping.
	// The return value is a java.InputStream, but the delclared type is
	// interface{} to avoid import cycles.
	Unwrap() interface{}
}

type Java_Object interface {
	ToString() string
	Super() Java_Object
	// Unwrap returns the Go object this Java instance
	// is wrapping.
	// The return value is a java.Object, but the delclared type is
	// interface{} to avoid import cycles.
	Unwrap() interface{}
}

type Java_Runnable interface {
	Run()
	Super() Java_Runnable
	// Unwrap returns the Go object this Java instance
	// is wrapping.
	// The return value is a java.Runnable, but the delclared type is
	// interface{} to avoid import cycles.
	Unwrap() interface{}
}

type Java_util_Iterator interface {
}

type Java_util_Spliterator interface {
}

type Java_util_PrimitiveIterator_OfInt interface {
}

type Java_util_Spliterator_OfInt interface {
}

type Java_util_PrimitiveIterator_OfLong interface {
}

type Java_util_Spliterator_OfLong interface {
}

type Java_util_PrimitiveIterator_OfDouble interface {
}

type Java_util_Spliterator_OfDouble interface {
}

type Java_io_Console interface {
	Flush() error
	ToString() string
}

// File is generated by gobind. Do not edit.

package gomobile_bind

/*
#include <stdlib.h> // for free()
#include <jni.h>
#include "seq.h"
#include "classes.h"
*/
import "C"

import (
	"Java"
	_seq "golang.org/x/mobile/bind/seq"
)

import "Java/java/lang/Runnable"
import "Java/java/io/InputStream"
import "Java/java/util/concurrent/Future"
import "Java/java/lang/Object"
import "Java/java/util/concurrent/TimeUnit"
import "Java/java/util/Spliterators"
import "Java/java/lang/System"
import "Java/java/Future"
import "Java/java/InputStream"
import "Java/java/Object"
import "Java/java/Runnable"
import "Java/java/util/Iterator"
import "Java/java/util/Spliterator"
import "Java/java/util/PrimitiveIterator/OfInt"
import "Java/java/util/Spliterator/OfInt"
import "Java/java/util/PrimitiveIterator/OfLong"
import "Java/java/util/Spliterator/OfLong"
import "Java/java/util/PrimitiveIterator/OfDouble"
import "Java/java/util/Spliterator/OfDouble"
import "Java/java/io/Console"
import "testdata"
import "unsafe"

import "reflect"

import "fmt"

type proxy interface { Bind_proxy_refnum__() int32 }

// Suppress unused package error

var _ = _seq.FromRefNum
const _ = Java.Dummy

//export initClasses
func initClasses() {
	C.init_proxies()
	init_java_lang_Runnable()
	init_java_io_InputStream()
	init_java_util_concurrent_Future()
	init_java_lang_Object()
	init_java_util_concurrent_TimeUnit()
	init_java_util_Spliterators()
	init_java_lang_System()
	init_java_Future()
	init_java_InputStream()
	init_java_Object()
	init_java_Runnable()
	init_java_util_Iterator()
	init_java_util_Spliterator()
	init_java_util_PrimitiveIterator_OfInt()
	init_java_util_Spliterator_OfInt()
	init_java_util_PrimitiveIterator_OfLong()
	init_java_util_Spliterator_OfLong()
	init_java_util_PrimitiveIterator_OfDouble()
	init_java_util_Spliterator_OfDouble()
	init_java_io_Console()
}

var class_java_lang_Runnable C.jclass

func init_java_lang_Runnable() {
	cls := C.CString("java/lang/Runnable")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Runnable = clazz
	Runnable.Cast = func(v interface{}) Java.Java_lang_Runnable {
		t := reflect.TypeOf((*proxy_class_java_lang_Runnable)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Runnable)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Runnable) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Runnable"))
		}
		return cv
	}
}

type proxy_class_java_lang_Runnable _seq.Ref

func (p *proxy_class_java_lang_Runnable) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_lang_Runnable) Run() {
	res := C.cproxy_java_lang_Runnable_run(C.jint(p.Bind_proxy_refnum__()))
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res))
	if _exc_ref != nil {
		if res < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
}

var class_java_io_InputStream C.jclass

func init_java_io_InputStream() {
	cls := C.CString("java/io/InputStream")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_io_InputStream = clazz
	InputStream.Cast = func(v interface{}) Java.Java_io_InputStream {
		t := reflect.TypeOf((*proxy_class_java_io_InputStream)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_io_InputStream)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_io_InputStream) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.io.InputStream"))
		}
		return cv
	}
}

type proxy_class_java_io_InputStream _seq.Ref

func (p *proxy_class_java_io_InputStream) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_io_InputStream) Read(a0 ...interface{}) (int32, error) {
	switch 0 + len(a0) {
	case 0:
		res := C.cproxy_java_io_InputStream_read__(C.jint(p.Bind_proxy_refnum__()))
		_res := int32(res.res)
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		return _res, _exc
	case 1:
		_a0, ok0 := a0[0].([]byte)
		if ok0 {
			__a0 := fromSlice(_a0, false)
			res := C.cproxy_java_io_InputStream_read___3B(C.jint(p.Bind_proxy_refnum__()), __a0)
			_res := int32(res.res)
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	case 3:
		_a0, ok0 := a0[0].([]byte)
		_a1, ok1 := a0[1].(int32)
		_a2, ok2 := a0[2].(int32)
		if ok0 && ok1 && ok2 {
			__a0 := fromSlice(_a0, false)
			__a1 := C.jint(_a1)
			__a2 := C.jint(_a2)
			res := C.cproxy_java_io_InputStream_read___3BII(C.jint(p.Bind_proxy_refnum__()), __a0, __a1, __a2)
			_res := int32(res.res)
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	}
	panic("no overloaded method found for java.io.InputStream.read that matched the arguments")
}

func (p *proxy_class_java_io_InputStream) ToString() string {
	res := C.cproxy_java_io_InputStream_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_util_concurrent_Future C.jclass

func init_java_util_concurrent_Future() {
	cls := C.CString("java/util/concurrent/Future")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_concurrent_Future = clazz
	Future.Cast = func(v interface{}) Java.Java_util_concurrent_Future {
		t := reflect.TypeOf((*proxy_class_java_util_concurrent_Future)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_concurrent_Future)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_concurrent_Future) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.concurrent.Future"))
		}
		return cv
	}
}

type proxy_class_java_util_concurrent_Future _seq.Ref

func (p *proxy_class_java_util_concurrent_Future) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_util_concurrent_Future) Get(a0 ...interface{}) (Java.Java_lang_Object, error) {
	switch 0 + len(a0) {
	case 0:
		res := C.cproxy_java_util_concurrent_Future_get__(C.jint(p.Bind_proxy_refnum__()))
		var _res Java.Java_lang_Object
		_res_ref := _seq.FromRefNum(int32(res.res))
		if _res_ref != nil {
			if res.res < 0 { // go object
				_res = _res_ref.Get().(Java.Java_lang_Object)
			} else { // foreign object
				_res = (*proxy_class_java_lang_Object)(_res_ref)
			}
		}
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		return _res, _exc
	case 2:
		_a0, ok0 := a0[0].(int64)
		_a1, ok1 := a0[1].(Java.Java_util_concurrent_TimeUnit)
		if ok0 && ok1 {
			__a0 := C.jlong(_a0)
			var __a1 C.jint = _seq.NullRefNum
			if _a1 != nil {
				__a1 = C.jint(_seq.ToRefNum(_a1))
			}
			res := C.cproxy_java_util_concurrent_Future_get__JLjava_util_concurrent_TimeUnit_2(C.jint(p.Bind_proxy_refnum__()), __a0, __a1)
			var _res Java.Java_lang_Object
			_res_ref := _seq.FromRefNum(int32(res.res))
			if _res_ref != nil {
				if res.res < 0 { // go object
					_res = _res_ref.Get().(Java.Java_lang_Object)
				} else { // foreign object
					_res = (*proxy_class_java_lang_Object)(_res_ref)
				}
			}
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	}
	panic("no overloaded method found for java.util.concurrent.Future.get that matched the arguments")
}

var class_java_lang_Object C.jclass

func init_java_lang_Object() {
	cls := C.CString("java/lang/Object")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Object = clazz
	Object.Cast = func(v interface{}) Java.Java_lang_Object {
		t := reflect.TypeOf((*proxy_class_java_lang_Object)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Object)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Object) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Object"))
		}
		return cv
	}
}

type proxy_class_java_lang_Object _seq.Ref

func (p *proxy_class_java_lang_Object) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_lang_Object) ToString() string {
	res := C.cproxy_java_lang_Object_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_util_concurrent_TimeUnit C.jclass

func init_java_util_concurrent_TimeUnit() {
	cls := C.CString("java/util/concurrent/TimeUnit")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_concurrent_TimeUnit = clazz
	TimeUnit.Cast = func(v interface{}) Java.Java_util_concurrent_TimeUnit {
		t := reflect.TypeOf((*proxy_class_java_util_concurrent_TimeUnit)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_concurrent_TimeUnit)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_concurrent_TimeUnit) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.concurrent.TimeUnit"))
		}
		return cv
	}
}

type proxy_class_java_util_concurrent_TimeUnit _seq.Ref

func (p *proxy_class_java_util_concurrent_TimeUnit) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_util_concurrent_TimeUnit) ToString() string {
	res := C.cproxy_java_util_concurrent_TimeUnit_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_util_Spliterators C.jclass

func init_java_util_Spliterators() {
	cls := C.CString("java/util/Spliterators")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_Spliterators = clazz
	Spliterators.Iterator = func(a0 Java.Java_util_Spliterator) Java.Java_util_Iterator {
		{
			var __a0 C.jint = _seq.NullRefNum
			if a0 != nil {
				__a0 = C.jint(_seq.ToRefNum(a0))
			}
			res := C.cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_2(__a0)
			var _res Java.Java_util_Iterator
			_res_ref := _seq.FromRefNum(int32(res.res))
			if _res_ref != nil {
				if res.res < 0 { // go object
					_res = _res_ref.Get().(Java.Java_util_Iterator)
				} else { // foreign object
					_res = (*proxy_class_java_util_Iterator)(_res_ref)
				}
			}
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			if (_exc != nil) { panic(_exc) }
			return _res
		}
		{
			_a0, ok0 := a0.(Java.Java_util_Spliterator_OfInt)
			if ok0 {
				var __a0 C.jint = _seq.NullRefNum
				if _a0 != nil {
					__a0 = C.jint(_seq.ToRefNum(_a0))
				}
				res := C.cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfInt_2(__a0)
				var _res Java.Java_util_PrimitiveIterator_OfInt
				_res_ref := _seq.FromRefNum(int32(res.res))
				if _res_ref != nil {
					if res.res < 0 { // go object
						_res = _res_ref.Get().(Java.Java_util_PrimitiveIterator_OfInt)
					} else { // foreign object
						_res = (*proxy_class_java_util_PrimitiveIterator_OfInt)(_res_ref)
					}
				}
				var _exc error
				_exc_ref := _seq.FromRefNum(int32(res.exc))
				if _exc_ref != nil {
					if res.exc < 0 { // go object
						_exc = _exc_ref.Get().(error)
					} else { // foreign object
						_exc = (*proxy_error)(_exc_ref)
					}
				}
				if (_exc != nil) { panic(_exc) }
				return _res
			}
		}
		{
			_a0, ok0 := a0.(Java.Java_util_Spliterator_OfLong)
			if ok0 {
				var __a0 C.jint = _seq.NullRefNum
				if _a0 != nil {
					__a0 = C.jint(_seq.ToRefNum(_a0))
				}
				res := C.cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfLong_2(__a0)
				var _res Java.Java_util_PrimitiveIterator_OfLong
				_res_ref := _seq.FromRefNum(int32(res.res))
				if _res_ref != nil {
					if res.res < 0 { // go object
						_res = _res_ref.Get().(Java.Java_util_PrimitiveIterator_OfLong)
					} else { // foreign object
						_res = (*proxy_class_java_util_PrimitiveIterator_OfLong)(_res_ref)
					}
				}
				var _exc error
				_exc_ref := _seq.FromRefNum(int32(res.exc))
				if _exc_ref != nil {
					if res.exc < 0 { // go object
						_exc = _exc_ref.Get().(error)
					} else { // foreign object
						_exc = (*proxy_error)(_exc_ref)
					}
				}
				if (_exc != nil) { panic(_exc) }
				return _res
			}
		}
		{
			_a0, ok0 := a0.(Java.Java_util_Spliterator_OfDouble)
			if ok0 {
				var __a0 C.jint = _seq.NullRefNum
				if _a0 != nil {
					__a0 = C.jint(_seq.ToRefNum(_a0))
				}
				res := C.cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfDouble_2(__a0)
				var _res Java.Java_util_PrimitiveIterator_OfDouble
				_res_ref := _seq.FromRefNum(int32(res.res))
				if _res_ref != nil {
					if res.res < 0 { // go object
						_res = _res_ref.Get().(Java.Java_util_PrimitiveIterator_OfDouble)
					} else { // foreign object
						_res = (*proxy_class_java_util_PrimitiveIterator_OfDouble)(_res_ref)
					}
				}
				var _exc error
				_exc_ref := _seq.FromRefNum(int32(res.exc))
				if _exc_ref != nil {
					if res.exc < 0 { // go object
						_exc = _exc_ref.Get().(error)
					} else { // foreign object
						_exc = (*proxy_error)(_exc_ref)
					}
				}
				if (_exc != nil) { panic(_exc) }
				return _res
			}
		}
		panic("no overloaded method found for java.util.Spliterators.iterator that matched the arguments")
	}
	
	Spliterators.Cast = func(v interface{}) Java.Java_util_Spliterators {
		t := reflect.TypeOf((*proxy_class_java_util_Spliterators)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Spliterators)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_Spliterators) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Spliterators"))
		}
		return cv
	}
}

type proxy_class_java_util_Spliterators _seq.Ref

func (p *proxy_class_java_util_Spliterators) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_util_Spliterators) ToString() string {
	res := C.cproxy_java_util_Spliterators_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_lang_System C.jclass

func init_java_lang_System() {
	cls := C.CString("java/lang/System")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_System = clazz
	System.Console = func() Java.Java_io_Console {
		res := C.cproxy_s_java_lang_System_console()
		var _res Java.Java_io_Console
		_res_ref := _seq.FromRefNum(int32(res.res))
		if _res_ref != nil {
			if res.res < 0 { // go object
				_res = _res_ref.Get().(Java.Java_io_Console)
			} else { // foreign object
				_res = (*proxy_class_java_io_Console)(_res_ref)
			}
		}
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		if (_exc != nil) { panic(_exc) }
		return _res
	}
	
	System.Cast = func(v interface{}) Java.Java_lang_System {
		t := reflect.TypeOf((*proxy_class_java_lang_System)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_System)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_System) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.System"))
		}
		return cv
	}
}

type proxy_class_java_lang_System _seq.Ref

func (p *proxy_class_java_lang_System) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_lang_System) ToString() string {
	res := C.cproxy_java_lang_System_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_Future C.jclass

func init_java_Future() {
	cls := C.CString("java/Future")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_Future = clazz
	Future.Cast = func(v interface{}) Java.Java_Future {
		t := reflect.TypeOf((*proxy_class_java_Future)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_Future)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_Future) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.Future"))
		}
		return cv
	}
}

type proxy_class_java_Future _seq.Ref

func (p *proxy_class_java_Future) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_Future) Get(a0 ...interface{}) (Java.Java_lang_Object, error) {
	switch 0 + len(a0) {
	case 0:
		res := C.cproxy_java_Future_get__(C.jint(p.Bind_proxy_refnum__()))
		var _res Java.Java_lang_Object
		_res_ref := _seq.FromRefNum(int32(res.res))
		if _res_ref != nil {
			if res.res < 0 { // go object
				_res = _res_ref.Get().(Java.Java_lang_Object)
			} else { // foreign object
				_res = (*proxy_class_java_lang_Object)(_res_ref)
			}
		}
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		return _res, _exc
	case 2:
		_a0, ok0 := a0[0].(int64)
		_a1, ok1 := a0[1].(Java.Java_util_concurrent_TimeUnit)
		if ok0 && ok1 {
			__a0 := C.jlong(_a0)
			var __a1 C.jint = _seq.NullRefNum
			if _a1 != nil {
				__a1 = C.jint(_seq.ToRefNum(_a1))
			}
			res := C.cproxy_java_Future_get__JLjava_util_concurrent_TimeUnit_2(C.jint(p.Bind_proxy_refnum__()), __a0, __a1)
			var _res Java.Java_lang_Object
			_res_ref := _seq.FromRefNum(int32(res.res))
			if _res_ref != nil {
				if res.res < 0 { // go object
					_res = _res_ref.Get().(Java.Java_lang_Object)
				} else { // foreign object
					_res = (*proxy_class_java_lang_Object)(_res_ref)
				}
			}
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	}
	panic("no overloaded method found for java.Future.get that matched the arguments")
}

func (p *proxy_class_java_Future) Super() Java.Java_Future {
	return &super_java_Future{p}
}

type super_java_Future struct {*proxy_class_java_Future}

func (p *proxy_class_java_Future) Unwrap() interface{} {
	goRefnum := C.go_seq_unwrap(C.jint(p.Bind_proxy_refnum__()))
	return _seq.FromRefNum(int32(goRefnum)).Get().(*java.Future)
}

func (p *super_java_Future) Get(a0 ...interface{}) (Java.Java_lang_Object, error) {
	switch 0 + len(a0) {
	case 0:
		res := C.csuper_java_Future_get__(C.jint(p.Bind_proxy_refnum__()))
		var _res Java.Java_lang_Object
		_res_ref := _seq.FromRefNum(int32(res.res))
		if _res_ref != nil {
			if res.res < 0 { // go object
				_res = _res_ref.Get().(Java.Java_lang_Object)
			} else { // foreign object
				_res = (*proxy_class_java_lang_Object)(_res_ref)
			}
		}
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		return _res, _exc
	case 2:
		_a0, ok0 := a0[0].(int64)
		_a1, ok1 := a0[1].(Java.Java_util_concurrent_TimeUnit)
		if ok0 && ok1 {
			__a0 := C.jlong(_a0)
			var __a1 C.jint = _seq.NullRefNum
			if _a1 != nil {
				__a1 = C.jint(_seq.ToRefNum(_a1))
			}
			res := C.csuper_java_Future_get__JLjava_util_concurrent_TimeUnit_2(C.jint(p.Bind_proxy_refnum__()), __a0, __a1)
			var _res Java.Java_lang_Object
			_res_ref := _seq.FromRefNum(int32(res.res))
			if _res_ref != nil {
				if res.res < 0 { // go object
					_res = _res_ref.Get().(Java.Java_lang_Object)
				} else { // foreign object
					_res = (*proxy_class_java_lang_Object)(_res_ref)
				}
			}
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	}
	panic("no overloaded method found for java.Future.get that matched the arguments")
}

var class_java_InputStream C.jclass

func init_java_InputStream() {
	cls := C.CString("java/InputStream")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_InputStream = clazz
	InputStream.Cast = func(v interface{}) Java.Java_InputStream {
		t := reflect.TypeOf((*proxy_class_java_InputStream)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_InputStream)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_InputStream) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.InputStream"))
		}
		return cv
	}
}

type proxy_class_java_InputStream _seq.Ref

func (p *proxy_class_java_InputStream) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_InputStream) Read(a0 ...interface{}) (int32, error) {
	switch 0 + len(a0) {
	case 0:
		res := C.cproxy_java_InputStream_read__(C.jint(p.Bind_proxy_refnum__()))
		_res := int32(res.res)
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		return _res, _exc
	case 1:
		_a0, ok0 := a0[0].([]byte)
		if ok0 {
			__a0 := fromSlice(_a0, false)
			res := C.cproxy_java_InputStream_read___3B(C.jint(p.Bind_proxy_refnum__()), __a0)
			_res := int32(res.res)
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	case 3:
		_a0, ok0 := a0[0].([]byte)
		_a1, ok1 := a0[1].(int32)
		_a2, ok2 := a0[2].(int32)
		if ok0 && ok1 && ok2 {
			__a0 := fromSlice(_a0, false)
			__a1 := C.jint(_a1)
			__a2 := C.jint(_a2)
			res := C.cproxy_java_InputStream_read___3BII(C.jint(p.Bind_proxy_refnum__()), __a0, __a1, __a2)
			_res := int32(res.res)
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	}
	panic("no overloaded method found for java.InputStream.read that matched the arguments")
}

func (p *proxy_class_java_InputStream) ToString() string {
	res := C.cproxy_java_InputStream_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

func (p *proxy_class_java_InputStream) Super() Java.Java_InputStream {
	return &super_java_InputStream{p}
}

type super_java_InputStream struct {*proxy_class_java_InputStream}

func (p *proxy_class_java_InputStream) Unwrap() interface{} {
	goRefnum := C.go_seq_unwrap(C.jint(p.Bind_proxy_refnum__()))
	return _seq.FromRefNum(int32(goRefnum)).Get().(*java.InputStream)
}

func (p *super_java_InputStream) Read(a0 ...interface{}) (int32, error) {
	switch 0 + len(a0) {
	case 0:
		res := C.csuper_java_InputStream_read__(C.jint(p.Bind_proxy_refnum__()))
		_res := int32(res.res)
		var _exc error
		_exc_ref := _seq.FromRefNum(int32(res.exc))
		if _exc_ref != nil {
			if res.exc < 0 { // go object
				_exc = _exc_ref.Get().(error)
			} else { // foreign object
				_exc = (*proxy_error)(_exc_ref)
			}
		}
		return _res, _exc
	case 1:
		_a0, ok0 := a0[0].([]byte)
		if ok0 {
			__a0 := fromSlice(_a0, false)
			res := C.csuper_java_InputStream_read___3B(C.jint(p.Bind_proxy_refnum__()), __a0)
			_res := int32(res.res)
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	case 3:
		_a0, ok0 := a0[0].([]byte)
		_a1, ok1 := a0[1].(int32)
		_a2, ok2 := a0[2].(int32)
		if ok0 && ok1 && ok2 {
			__a0 := fromSlice(_a0, false)
			__a1 := C.jint(_a1)
			__a2 := C.jint(_a2)
			res := C.csuper_java_InputStream_read___3BII(C.jint(p.Bind_proxy_refnum__()), __a0, __a1, __a2)
			_res := int32(res.res)
			var _exc error
			_exc_ref := _seq.FromRefNum(int32(res.exc))
			if _exc_ref != nil {
				if res.exc < 0 { // go object
					_exc = _exc_ref.Get().(error)
				} else { // foreign object
					_exc = (*proxy_error)(_exc_ref)
				}
			}
			return _res, _exc
		}
	}
	panic("no overloaded method found for java.InputStream.read that matched the arguments")
}

func (p *super_java_InputStream) ToString() string {
	res := C.csuper_java_InputStream_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_Object C.jclass

func init_java_Object() {
	cls := C.CString("java/Object")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_Object = clazz
	Object.Cast = func(v interface{}) Java.Java_Object {
		t := reflect.TypeOf((*proxy_class_java_Object)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_Object)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_Object) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.Object"))
		}
		return cv
	}
}

type proxy_class_java_Object _seq.Ref

func (p *proxy_class_java_Object) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_Object) ToString() string {
	res := C.cproxy_java_Object_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

func (p *proxy_class_java_Object) Super() Java.Java_Object {
	return &super_java_Object{p}
}

type super_java_Object struct {*proxy_class_java_Object}

func (p *proxy_class_java_Object) Unwrap() interface{} {
	goRefnum := C.go_seq_unwrap(C.jint(p.Bind_proxy_refnum__()))
	return _seq.FromRefNum(int32(goRefnum)).Get().(*java.Object)
}

func (p *super_java_Object) ToString() string {
	res := C.csuper_java_Object_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_Runnable C.jclass

func init_java_Runnable() {
	cls := C.CString("java/Runnable")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_Runnable = clazz
	Runnable.Cast = func(v interface{}) Java.Java_Runnable {
		t := reflect.TypeOf((*proxy_class_java_Runnable)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_Runnable)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_Runnable) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.Runnable"))
		}
		return cv
	}
}

type proxy_class_java_Runnable _seq.Ref

func (p *proxy_class_java_Runnable) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_Runnable) Run() {
	res := C.cproxy_java_Runnable_run(C.jint(p.Bind_proxy_refnum__()))
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res))
	if _exc_ref != nil {
		if res < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
}

func (p *proxy_class_java_Runnable) Super() Java.Java_Runnable {
	return &super_java_Runnable{p}
}

type super_java_Runnable struct {*proxy_class_java_Runnable}

func (p *proxy_class_java_Runnable) Unwrap() interface{} {
	goRefnum := C.go_seq_unwrap(C.jint(p.Bind_proxy_refnum__()))
	return _seq.FromRefNum(int32(goRefnum)).Get().(*java.Runnable)
}

func (p *super_java_Runnable) Run() {
	res := C.csuper_java_Runnable_run(C.jint(p.Bind_proxy_refnum__()))
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res))
	if _exc_ref != nil {
		if res < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
}

var class_java_util_Iterator C.jclass

func init_java_util_Iterator() {
	cls := C.CString("java/util/Iterator")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_Iterator = clazz
	Iterator.Cast = func(v interface{}) Java.Java_util_Iterator {
		t := reflect.TypeOf((*proxy_class_java_util_Iterator)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Iterator)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_Iterator) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Iterator"))
		}
		return cv
	}
}

type proxy_class_java_util_Iterator _seq.Ref

func (p *proxy_class_java_util_Iterator) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_Spliterator C.jclass

func init_java_util_Spliterator() {
	cls := C.CString("java/util/Spliterator")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_Spliterator = clazz
	Spliterator.Cast = func(v interface{}) Java.Java_util_Spliterator {
		t := reflect.TypeOf((*proxy_class_java_util_Spliterator)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Spliterator)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_Spliterator) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Spliterator"))
		}
		return cv
	}
}

type proxy_class_java_util_Spliterator _seq.Ref

func (p *proxy_class_java_util_Spliterator) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_PrimitiveIterator_OfInt C.jclass

func init_java_util_PrimitiveIterator_OfInt() {
	cls := C.CString("java/util/PrimitiveIterator$OfInt")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_PrimitiveIterator_OfInt = clazz
	OfInt.Cast = func(v interface{}) Java.Java_util_PrimitiveIterator_OfInt {
		t := reflect.TypeOf((*proxy_class_java_util_PrimitiveIterator_OfInt)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_PrimitiveIterator_OfInt)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_PrimitiveIterator_OfInt) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.PrimitiveIterator.OfInt"))
		}
		return cv
	}
}

type proxy_class_java_util_PrimitiveIterator_OfInt _seq.Ref

func (p *proxy_class_java_util_PrimitiveIterator_OfInt) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_Spliterator_OfInt C.jclass

func init_java_util_Spliterator_OfInt() {
	cls := C.CString("java/util/Spliterator$OfInt")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_Spliterator_OfInt = clazz
	OfInt.Cast = func(v interface{}) Java.Java_util_Spliterator_OfInt {
		t := reflect.TypeOf((*proxy_class_java_util_Spliterator_OfInt)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Spliterator_OfInt)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_Spliterator_OfInt) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Spliterator.OfInt"))
		}
		return cv
	}
}

type proxy_class_java_util_Spliterator_OfInt _seq.Ref

func (p *proxy_class_java_util_Spliterator_OfInt) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_PrimitiveIterator_OfLong C.jclass

func init_java_util_PrimitiveIterator_OfLong() {
	cls := C.CString("java/util/PrimitiveIterator$OfLong")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_PrimitiveIterator_OfLong = clazz
	OfLong.Cast = func(v interface{}) Java.Java_util_PrimitiveIterator_OfLong {
		t := reflect.TypeOf((*proxy_class_java_util_PrimitiveIterator_OfLong)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_PrimitiveIterator_OfLong)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_PrimitiveIterator_OfLong) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.PrimitiveIterator.OfLong"))
		}
		return cv
	}
}

type proxy_class_java_util_PrimitiveIterator_OfLong _seq.Ref

func (p *proxy_class_java_util_PrimitiveIterator_OfLong) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_Spliterator_OfLong C.jclass

func init_java_util_Spliterator_OfLong() {
	cls := C.CString("java/util/Spliterator$OfLong")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_Spliterator_OfLong = clazz
	OfLong.Cast = func(v interface{}) Java.Java_util_Spliterator_OfLong {
		t := reflect.TypeOf((*proxy_class_java_util_Spliterator_OfLong)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Spliterator_OfLong)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_Spliterator_OfLong) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Spliterator.OfLong"))
		}
		return cv
	}
}

type proxy_class_java_util_Spliterator_OfLong _seq.Ref

func (p *proxy_class_java_util_Spliterator_OfLong) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_PrimitiveIterator_OfDouble C.jclass

func init_java_util_PrimitiveIterator_OfDouble() {
	cls := C.CString("java/util/PrimitiveIterator$OfDouble")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_PrimitiveIterator_OfDouble = clazz
	OfDouble.Cast = func(v interface{}) Java.Java_util_PrimitiveIterator_OfDouble {
		t := reflect.TypeOf((*proxy_class_java_util_PrimitiveIterator_OfDouble)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_PrimitiveIterator_OfDouble)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_PrimitiveIterator_OfDouble) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.PrimitiveIterator.OfDouble"))
		}
		return cv
	}
}

type proxy_class_java_util_PrimitiveIterator_OfDouble _seq.Ref

func (p *proxy_class_java_util_PrimitiveIterator_OfDouble) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_util_Spliterator_OfDouble C.jclass

func init_java_util_Spliterator_OfDouble() {
	cls := C.CString("java/util/Spliterator$OfDouble")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_util_Spliterator_OfDouble = clazz
	OfDouble.Cast = func(v interface{}) Java.Java_util_Spliterator_OfDouble {
		t := reflect.TypeOf((*proxy_class_java_util_Spliterator_OfDouble)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_util_Spliterator_OfDouble)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_util_Spliterator_OfDouble) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.util.Spliterator.OfDouble"))
		}
		return cv
	}
}

type proxy_class_java_util_Spliterator_OfDouble _seq.Ref

func (p *proxy_class_java_util_Spliterator_OfDouble) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_io_Console C.jclass

func init_java_io_Console() {
	cls := C.CString("java/io/Console")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_io_Console = clazz
	Console.Cast = func(v interface{}) Java.Java_io_Console {
		t := reflect.TypeOf((*proxy_class_java_io_Console)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_io_Console)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_io_Console) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.io.Console"))
		}
		return cv
	}
}

type proxy_class_java_io_Console _seq.Ref

func (p *proxy_class_java_io_Console) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_io_Console) Flush() error {
	res := C.cproxy_java_io_Console_flush(C.jint(p.Bind_proxy_refnum__()))
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res))
	if _exc_ref != nil {
		if res < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	return _exc
}

func (p *proxy_class_java_io_Console) ToString() string {
	res := C.cproxy_java_io_Console_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

// Package gomobile_bind is an autogenerated binder stub for package java.
//   gobind -lang=go classes
//
// File is generated by gobind. Do not edit.
package gomobile_bind

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "java.h"

*/
import "C"

import (
	java_1 "Java/java"
	"Java/java/io"
	"Java/java/lang"
	"Java/java/util/concurrent"
	"classes"
	_seq "golang.org/x/mobile/bind/seq"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

//export proxyjava_Future_Future_Set
func proxyjava_Future_Future_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v concurrent.Future
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(concurrent.Future)
		} else { // foreign object
			_v = (*proxy_class_java_util_concurrent_Future)(_v_ref)
		}
	}
	ref.Get().(*java.Future).Future = _v
}

//export proxyjava_Future_Future_Get
func proxyjava_Future_Future_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Future).Future
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyjava_Future_Get
func proxyjava_Future_Get(refnum C.int32_t) (C.int32_t, C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Future)
	res_0, res_1 := v.Get()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	var _res_1 C.int32_t = _seq.NullRefNum
	if res_1 != nil {
		_res_1 = C.int32_t(_seq.ToRefNum(res_1))
	}
	return _res_0, _res_1
}

//export proxyjava_Future_Get_
func proxyjava_Future_Get_(refnum C.int32_t, param_p0 C.int64_t, param_p1 C.int32_t) (C.int32_t, C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Future)
	_param_p0 := int64(param_p0)
	var _param_p1 concurrent.TimeUnit
	_param_p1_ref := _seq.FromRefNum(int32(param_p1))
	if _param_p1_ref != nil {
		if param_p1 < 0 { // go object
			_param_p1 = _param_p1_ref.Get().(concurrent.TimeUnit)
		} else { // foreign object
			_param_p1 = (*proxy_class_java_util_concurrent_TimeUnit)(_param_p1_ref)
		}
	}
	res_0, res_1 := v.Get_(_param_p0, _param_p1)
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	var _res_1 C.int32_t = _seq.NullRefNum
	if res_1 != nil {
		_res_1 = C.int32_t(_seq.ToRefNum(res_1))
	}
	return _res_0, _res_1
}

//export new_java_Future
func new_java_Future() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(java.Future)))
}

//export proxyjava_InputStream_InputStream_Set
func proxyjava_InputStream_InputStream_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v io.InputStream
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(io.InputStream)
		} else { // foreign object
			_v = (*proxy_class_java_io_InputStream)(_v_ref)
		}
	}
	ref.Get().(*java.InputStream).InputStream = _v
}

//export proxyjava_InputStream_InputStream_Get
func proxyjava_InputStream_InputStream_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.InputStream).InputStream
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyjava_InputStream_Read
func proxyjava_InputStream_Read(refnum C.int32_t) (C.int32_t, C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.InputStream)
	res_0, res_1 := v.Read()
	_res_0 := C.int32_t(res_0)
	var _res_1 C.int32_t = _seq.NullRefNum
	if res_1 != nil {
		_res_1 = C.int32_t(_seq.ToRefNum(res_1))
	}
	return _res_0, _res_1
}

//export new_java_InputStream
func new_java_InputStream() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(java.InputStream)))
}

//export proxyjava_Object_Object_Set
func proxyjava_Object_Object_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v lang.Object
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(lang.Object)
		} else { // foreign object
			_v = (*proxy_class_java_lang_Object)(_v_ref)
		}
	}
	ref.Get().(*java.Object).Object = _v
}

//export proxyjava_Object_Object_Get
func proxyjava_Object_Object_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Object).Object
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export new_java_Object
func new_java_Object() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(java.Object)))
}

//export proxyjava_Runnable_Runnable_Set
func proxyjava_Runnable_Runnable_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	var _v lang.Runnable
	_v_ref := _seq.FromRefNum(int32(v))
	if _v_ref != nil {
		if v < 0 { // go object
			_v = _v_ref.Get().(lang.Runnable)
		} else { // foreign object
			_v = (*proxy_class_java_lang_Runnable)(_v_ref)
		}
	}
	ref.Get().(*java.Runnable).Runnable = _v
}

//export proxyjava_Runnable_Runnable_Get
func proxyjava_Runnable_Runnable_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Runnable).Runnable
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxyjava_Runnable_Run
func proxyjava_Runnable_Run(refnum C.int32_t, param_this C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Runnable)
	var _param_this java_1.Runnable
	_param_this_ref := _seq.FromRefNum(int32(param_this))
	if _param_this_ref != nil {
		if param_this < 0 { // go object
			_param_this = _param_this_ref.Get().(java_1.Runnable)
		} else { // foreign object
			_param_this = (*proxy_class_java_Runnable)(_param_this_ref)
		}
	}
	v.Run(_param_this)
}

//export new_java_Runnable
func new_java_Runnable() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(java.Runnable)))
}

//export proxyjava__NewInputStream
func proxyjava__NewInputStream() C.int32_t {
	res_0 := java.NewInputStream()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}
