// 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() (int32, error)
}

type Java_util_concurrent_Future interface {
	Get() (Java_lang_Object, error)
	Get2(a0 int64, a1 Java_util_concurrent_TimeUnit) (Java_lang_Object, error)
}

type Java_lang_Object interface {
}

type Java_util_concurrent_TimeUnit interface {
}

type Java_util_Spliterators interface {
}

type Java_lang_System interface {
}

type Java_Future interface {
	Get() (Java_lang_Object, error)
	Get2(a0 int64, a1 Java_util_concurrent_TimeUnit) (Java_lang_Object, error)
	Super() Java_Future
}

type Java_InputStream interface {
	Read() (int32, error)
	Super() Java_InputStream
}

type Java_Object interface {
	Super() Java_Object
}

type Java_Runnable interface {
	Run()
	Super() Java_Runnable
}

type Java_util_PrimitiveIterator_OfInt interface {
}

type Java_util_Spliterator_OfInt interface {
}

type Java_io_Console interface {
	Flush() error
}

// 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/PrimitiveIterator/OfInt"
import "Java/java/util/Spliterator/OfInt"
import "Java/java/io/Console"
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_PrimitiveIterator_OfInt()
	init_java_util_Spliterator_OfInt()
	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() (int32, error) {
	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
}

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() (Java.Java_lang_Object, error) {
	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
}

func (p *proxy_class_java_util_concurrent_Future) Get2(a0 int64, a1 Java.Java_util_concurrent_TimeUnit) (Java.Java_lang_Object, error) {
	_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
}

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() }

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() }

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
	{
		fn := C.CString("iterator")
		fd := C.CString("(Ljava/util/Spliterator$OfInt;)Ljava/util/PrimitiveIterator$OfInt;")
		m := C.go_seq_get_static_method_id(clazz, fn, fd)
		C.free(unsafe.Pointer(fn))
		C.free(unsafe.Pointer(fd))
		if m != nil {
			Spliterators.Iterator_Ljava_util_Spliterator_00024OfInt_2 = func(a0 Java.Java_util_Spliterator_OfInt) Java.Java_util_PrimitiveIterator_OfInt {
				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(clazz, m, _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
			}
		}
	}
	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() }

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
	{
		fn := C.CString("console")
		fd := C.CString("()Ljava/io/Console;")
		m := C.go_seq_get_static_method_id(clazz, fn, fd)
		C.free(unsafe.Pointer(fn))
		C.free(unsafe.Pointer(fd))
		if m != nil {
			System.Console = func() Java.Java_io_Console {
				res := C.cproxy_s_java_lang_System_console(clazz, m)
				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() }

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() (Java.Java_lang_Object, error) {
	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
}

func (p *proxy_class_java_Future) Get2(a0 int64, a1 Java.Java_util_concurrent_TimeUnit) (Java.Java_lang_Object, error) {
	_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
}

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 *super_java_Future) Get() (Java.Java_lang_Object, error) {
	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
}

func (p *super_java_Future) Get2(a0 int64, a1 Java.Java_util_concurrent_TimeUnit) (Java.Java_lang_Object, error) {
	_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
}

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() (int32, error) {
	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
}

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 *super_java_InputStream) Read() (int32, error) {
	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
}

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) Super() Java.Java_Object {
	return &super_java_Object{p}
}

type super_java_Object struct {*proxy_class_java_Object}

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 *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_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_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
}

// 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 {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*java.Future)
	res_0 := v.Get()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}

//export proxyjava_Future_Get2
func proxyjava_Future_Get2(refnum C.int32_t, param_p0 C.int64_t, param_p1 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 := v.Get2(_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))
	}
	return _res_0
}

//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
}
