// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build java android
// +build cgo

package main

import (
	"fmt"
	"unsafe"

	"v.io/x/ref/services/syncbase/bridge/cgo/ptrmap"
)

/*
#include <stdlib.h>
#include <string.h>
#include "jni_wrapper.h"
#include "lib.h"

static jvalue* allocJValueArray(int elements) {
  return malloc(sizeof(jvalue) * elements);
}

static void setJValueArrayElement(jvalue* arr, int index, jvalue val) {
  arr[index] = val;
}

void v23_syncbase_internal_onChange(v23_syncbase_Handle handle, v23_syncbase_WatchChange);
void v23_syncbase_internal_onError(v23_syncbase_Handle handle, v23_syncbase_VError);

static v23_syncbase_DbWatchPatternsCallbacks newVWatchPatternsCallbacks() {
  v23_syncbase_DbWatchPatternsCallbacks cbs = {
  	0, v23_syncbase_internal_onChange, v23_syncbase_internal_onError};
  return cbs;
}

void v23_syncbase_internal_onKeyValue(v23_syncbase_Handle handle, v23_syncbase_KeyValue);
void v23_syncbase_internal_onDone(v23_syncbase_Handle handle, v23_syncbase_VError);

static v23_syncbase_CollectionScanCallbacks newVScanCallbacks() {
  v23_syncbase_CollectionScanCallbacks cbs = {
  	0, v23_syncbase_internal_onKeyValue, v23_syncbase_internal_onDone};
  return cbs;
}

void v23_syncbase_internal_onInvite(v23_syncbase_Handle handle, v23_syncbase_Invite);

static v23_syncbase_DbSyncgroupInvitesCallbacks newVSyncgroupInvitesCallbacks() {
  v23_syncbase_DbSyncgroupInvitesCallbacks cbs = {
  	0, v23_syncbase_internal_onInvite};
  return cbs;
}

void v23_syncbase_internal_onPeer(v23_syncbase_Handle handle, v23_syncbase_AppPeer);

static v23_syncbase_NeighborhoodScanCallbacks newVNeighborhoodScanCallbacks() {
  v23_syncbase_NeighborhoodScanCallbacks cbs = {
  	0, v23_syncbase_internal_onPeer};
  return cbs;
}
*/
import "C"

var (
	jVM                         *C.JavaVM
	arrayListClass              jArrayListClass
	changeTypeClass             jChangeType
	collectionRowPatternClass   jCollectionRowPattern
	entityTypeClass             jEntityType
	hashMapClass                jHashMap
	idClass                     jIdClass
	keyValueClass               jKeyValue
	neighborhoodPeerClass       jNeighborhoodPeer
	permissionsClass            jPermissions
	syncgroupInviteClass        jSyncgroupInvite
	syncgroupMemberInfoClass    jSyncgroupMemberInfo
	syncgroupSpecClass          jSyncgroupSpec
	verrorClass                 jVErrorClass
	versionedPermissionsClass   jVersionedPermissions
	versionedSyncgroupSpecClass jVersionedSyncgroupSpec
	watchChangeClass            jWatchChange
)

var jniPtrMap = ptrmap.New()

// JNI_OnLoad is called when System.loadLibrary is called. We need to cache the
// *JavaVM because that's the only way to get hold of a JNIEnv that is needed
// for any JNI operation.
//
// Reference: https://developer.android.com/training/articles/perf-jni.html#native_libraries
//
//export JNI_OnLoad
func JNI_OnLoad(vm *C.JavaVM, reserved unsafe.Pointer) C.jint {
	var env *C.JNIEnv
	if C.GetEnv(vm, unsafe.Pointer(&env), C.JNI_VERSION_1_6) != C.JNI_OK {
		return C.JNI_ERR
	}
	jVM = vm

	arrayListClass = newJArrayListClass(env)
	changeTypeClass = newJChangeType(env)
	collectionRowPatternClass = newJCollectionRowPattern(env)
	entityTypeClass = newJEntityType(env)
	hashMapClass = newJHashMap(env)
	idClass = newJIdClass(env)
	keyValueClass = newJKeyValue(env)
	neighborhoodPeerClass = newJNeighborhoodPeer(env)
	permissionsClass = newJPermissions(env)
	syncgroupInviteClass = newJSyncgroupInvite(env)
	syncgroupMemberInfoClass = newJSyncgroupMemberInfo(env)
	syncgroupSpecClass = newJSyncgroupSpec(env)
	verrorClass = newJVErrorClass(env)
	versionedPermissionsClass = newJVersionedPermissions(env)
	versionedSyncgroupSpecClass = newJVersionedSyncgroupSpec(env)
	watchChangeClass = newJWatchChange(env)

	return C.JNI_VERSION_1_6
}

//export Java_io_v_syncbase_internal_Service_Init
func Java_io_v_syncbase_internal_Service_Init(env *C.JNIEnv, cls C.jclass, initRoot C.jstring, testLogin C.jboolean) {
	cInitRoot := newVStringFromJava(env, initRoot)
	var cInitOpts C.v23_syncbase_InitOpts
	(&cInitOpts).init(initOpts{
		clientUnderstandsVOM: true,
		rootDir:              cInitRoot.extract(),
		testLogin:            int(testLogin) != 0,
		verboseLevel:         0,
	})
	v23_syncbase_Init(cInitOpts)
}

//export Java_io_v_syncbase_internal_Service_Serve
func Java_io_v_syncbase_internal_Service_Serve(env *C.JNIEnv, cls C.jclass) {
	var cErr C.v23_syncbase_VError
	v23_syncbase_Serve(&cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Service_Shutdown
func Java_io_v_syncbase_internal_Service_Shutdown(env *C.JNIEnv, cls C.jclass) {
	v23_syncbase_Shutdown()
}

//export Java_io_v_syncbase_internal_Service_Login
func Java_io_v_syncbase_internal_Service_Login(env *C.JNIEnv, cls C.jclass, provider C.jstring, token C.jstring) {
	cProvider := newVStringFromJava(env, provider)
	cToken := newVStringFromJava(env, token)
	var cErr C.v23_syncbase_VError
	v23_syncbase_Login(cProvider, cToken, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Service_IsLoggedIn
func Java_io_v_syncbase_internal_Service_IsLoggedIn(env *C.JNIEnv, cls C.jclass) C.jboolean {
	var r C.bool
	v23_syncbase_IsLoggedIn(&r)
	return r.extractToJava()
}

//export Java_io_v_syncbase_internal_Service_GetPermissions
func Java_io_v_syncbase_internal_Service_GetPermissions(env *C.JNIEnv, cls C.jclass) C.jobject {
	var cPerms C.v23_syncbase_Permissions
	var cVersion C.v23_syncbase_String
	var cErr C.v23_syncbase_VError
	v23_syncbase_ServiceGetPermissions(&cPerms, &cVersion, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return newVersionedPermissions(env, &cPerms, &cVersion)
}

//export Java_io_v_syncbase_internal_Service_SetPermissions
func Java_io_v_syncbase_internal_Service_SetPermissions(env *C.JNIEnv, cls C.jclass, obj C.jobject) {
	cPerms, cVersion := newVPermissionsAndVersionFromJava(env, obj)
	var cErr C.v23_syncbase_VError
	v23_syncbase_ServiceSetPermissions(cPerms, cVersion, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Service_ListDatabases
func Java_io_v_syncbase_internal_Service_ListDatabases(env *C.JNIEnv, cls C.jclass) C.jobject {
	var cIds C.v23_syncbase_Ids
	var cErr C.v23_syncbase_VError
	v23_syncbase_ServiceListDatabases(&cIds, &cErr)
	obj := C.NewObjectA(env, arrayListClass.class, arrayListClass.init, nil)
	// TODO(razvanm): populate the obj based on the data from cIds.
	return obj
}

//export Java_io_v_syncbase_internal_Database_GetPermissions
func Java_io_v_syncbase_internal_Database_GetPermissions(env *C.JNIEnv, cls C.jclass, name C.jstring) C.jobject {
	cName := newVStringFromJava(env, name)
	var cPerms C.v23_syncbase_Permissions
	var cVersion C.v23_syncbase_String
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbGetPermissions(cName, &cPerms, &cVersion, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return newVersionedPermissions(env, &cPerms, &cVersion)
}

//export Java_io_v_syncbase_internal_Database_SetPermissions
func Java_io_v_syncbase_internal_Database_SetPermissions(env *C.JNIEnv, cls C.jclass, name C.jstring, obj C.jobject) {
	cName := newVStringFromJava(env, name)
	cPerms, cVersion := newVPermissionsAndVersionFromJava(env, obj)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbSetPermissions(cName, cPerms, cVersion, &cErr)
	maybeThrowException(env, &cErr)
}

// maybeThrowException takes ownership of cErr and throws a Java exception if
// cErr represents a non-nil error. Returns a boolean indicating whether an
// exception was thrown.
func maybeThrowException(env *C.JNIEnv, cErr *C.v23_syncbase_VError) bool {
	if obj := cErr.extractToJava(env); obj != nil {
		C.Throw(env, obj)
		return true
	}
	return false
}

//export Java_io_v_syncbase_internal_Database_Create
func Java_io_v_syncbase_internal_Database_Create(env *C.JNIEnv, cls C.jclass, name C.jstring, perms C.jobject) {
	cName := newVStringFromJava(env, name)
	cPerms := newVPermissionsFromJava(env, perms)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbCreate(cName, cPerms, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_Destroy
func Java_io_v_syncbase_internal_Database_Destroy(env *C.JNIEnv, cls C.jclass, name C.jstring) {
	cName := newVStringFromJava(env, name)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbDestroy(cName, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_Exists
func Java_io_v_syncbase_internal_Database_Exists(env *C.JNIEnv, cls C.jclass, name C.jstring) C.jboolean {
	cName := newVStringFromJava(env, name)
	var r C.bool
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbExists(cName, &r, &cErr)
	maybeThrowException(env, &cErr)
	return r.extractToJava()
}

//export Java_io_v_syncbase_internal_Database_BeginBatch
func Java_io_v_syncbase_internal_Database_BeginBatch(env *C.JNIEnv, cls C.jclass, name C.jstring, opts C.jobject) C.jstring {
	cName := newVStringFromJava(env, name)
	var cHandle C.v23_syncbase_String
	var cErr C.v23_syncbase_VError
	// TODO(razvanm): construct a C.v23_syncbase_BatchOptions from opts.
	v23_syncbase_DbBeginBatch(cName, C.v23_syncbase_BatchOptions{}, &cHandle, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cHandle.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Database_ListCollections
func Java_io_v_syncbase_internal_Database_ListCollections(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jobject {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cIds C.v23_syncbase_Ids
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbListCollections(cName, cHandle, &cIds, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cIds.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Database_Commit
func Java_io_v_syncbase_internal_Database_Commit(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbCommit(cName, cHandle, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_Abort
func Java_io_v_syncbase_internal_Database_Abort(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbAbort(cName, cHandle, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_GetResumeMarker
func Java_io_v_syncbase_internal_Database_GetResumeMarker(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jbyteArray {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cMarker C.v23_syncbase_Bytes
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbGetResumeMarker(cName, cHandle, &cMarker, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cMarker.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Database_ListSyncgroups
func Java_io_v_syncbase_internal_Database_ListSyncgroups(env *C.JNIEnv, cls C.jclass, name C.jstring) C.jobject {
	cName := newVStringFromJava(env, name)
	var cIds C.v23_syncbase_Ids
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbListSyncgroups(cName, &cIds, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cIds.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Database_CreateSyncgroup
func Java_io_v_syncbase_internal_Database_CreateSyncgroup(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject, spec C.jobject, info C.jobject) {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	cSpec := newVSyngroupSpecFromJava(env, spec)
	cMyInfo := newVSyncgroupMemberInfoFromJava(env, info)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbCreateSyncgroup(cName, cSgId, cSpec, cMyInfo, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_JoinSyncgroup
func Java_io_v_syncbase_internal_Database_JoinSyncgroup(env *C.JNIEnv, cls C.jclass, name C.jstring, remoteSyncbaseName C.jstring, expectedSyncbaseBlessings C.jobject, sgId C.jobject, info C.jobject) C.jobject {
	cName := newVStringFromJava(env, name)
	cRemoteSyncbaseName := newVStringFromJava(env, remoteSyncbaseName)
	cExpectedSyncbaseBlessings := newVStringsFromJava(env, expectedSyncbaseBlessings)
	cSgId := newVIdFromJava(env, sgId)
	cMyInfo := newVSyncgroupMemberInfoFromJava(env, info)
	var cSpec C.v23_syncbase_SyncgroupSpec
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbJoinSyncgroup(cName, cRemoteSyncbaseName, cExpectedSyncbaseBlessings, cSgId, cMyInfo, &cSpec, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cSpec.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Database_LeaveSyncgroup
func Java_io_v_syncbase_internal_Database_LeaveSyncgroup(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject) {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbLeaveSyncgroup(cName, cSgId, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_DestroySyncgroup
func Java_io_v_syncbase_internal_Database_DestroySyncgroup(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject) {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbDestroySyncgroup(cName, cSgId, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_EjectFromSyncgroup
func Java_io_v_syncbase_internal_Database_EjectFromSyncgroup(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject, member C.jstring) {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	cMember := newVStringFromJava(env, member)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbEjectFromSyncgroup(cName, cSgId, cMember, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_GetSyncgroupSpec
func Java_io_v_syncbase_internal_Database_GetSyncgroupSpec(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject) C.jobject {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	var cSpec C.v23_syncbase_SyncgroupSpec
	var cVersion C.v23_syncbase_String
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbGetSyncgroupSpec(cName, cSgId, &cSpec, &cVersion, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	obj := C.NewObjectA(env, versionedSyncgroupSpecClass.class, versionedSyncgroupSpecClass.init, nil)
	C.SetObjectField(env, obj, versionedSyncgroupSpecClass.version, cVersion.extractToJava(env))
	C.SetObjectField(env, obj, versionedSyncgroupSpecClass.syncgroupSpec, cSpec.extractToJava(env))
	return obj
}

//export Java_io_v_syncbase_internal_Database_SetSyncgroupSpec
func Java_io_v_syncbase_internal_Database_SetSyncgroupSpec(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject, versionedSpec C.jobject) {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	cSpec, cVersion := newVSyngroupSpecAndVersionFromJava(env, versionedSpec)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbSetSyncgroupSpec(cName, cSgId, cSpec, cVersion, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Database_GetSyncgroupMembers
func Java_io_v_syncbase_internal_Database_GetSyncgroupMembers(env *C.JNIEnv, cls C.jclass, name C.jstring, sgId C.jobject) C.jobject {
	cName := newVStringFromJava(env, name)
	cSgId := newVIdFromJava(env, sgId)
	var cMembers C.v23_syncbase_SyncgroupMemberInfoMap
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbGetSyncgroupMembers(cName, cSgId, &cMembers, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cMembers.extractToJava(env)
}

//export v23_syncbase_internal_onChange
func v23_syncbase_internal_onChange(handle C.v23_syncbase_Handle, change C.v23_syncbase_WatchChange) {
	id := uint64(uintptr(handle))
	h := jniPtrMap.Get(uintptr(id)).(*watchPatternsCallbacksHandle)
	env, free := getEnv()
	obj := change.extractToJava(env)
	arg := *(*C.jvalue)(unsafe.Pointer(&obj))
	C.CallVoidMethodA(env, C.jobject(unsafe.Pointer(h.obj)), h.callbacks.onChange, &arg)
	if C.ExceptionOccurred(env) != nil {
		C.ExceptionDescribe(env)
		panic("java exception")
	}
	free()
}

//export v23_syncbase_internal_onError
func v23_syncbase_internal_onError(handle C.v23_syncbase_Handle, error C.v23_syncbase_VError) {
	id := uint64(uintptr(handle))
	h := jniPtrMap.Remove(uintptr(id)).(*watchPatternsCallbacksHandle)
	env, free := getEnv()
	obj := error.extractToJava(env)
	arg := *(*C.jvalue)(unsafe.Pointer(&obj))
	C.CallVoidMethodA(env, C.jobject(unsafe.Pointer(h.obj)), h.callbacks.onError, &arg)
	if C.ExceptionOccurred(env) != nil {
		C.ExceptionDescribe(env)
		panic("java exception")
	}
	C.DeleteGlobalRef(env, unsafe.Pointer(h.obj))
	free()
}

type watchPatternsCallbacksHandle struct {
	obj       uintptr
	callbacks jWatchPatternsCallbacks
}

//export Java_io_v_syncbase_internal_Database_WatchPatterns
func Java_io_v_syncbase_internal_Database_WatchPatterns(env *C.JNIEnv, cls C.jclass, name C.jstring, resumeMaker C.jbyteArray, patterns C.jobject, callbacks C.jobject) {
	cName := newVStringFromJava(env, name)
	cResumeMarker := newVBytesFromJava(env, resumeMaker)
	cPatterns := newVCollectionRowPatternsFromJava(env, patterns)
	ptr := uintptr(unsafe.Pointer(C.NewGlobalRef(env, callbacks)))
	cbs := C.newVWatchPatternsCallbacks()
	callbacksHandle := &watchPatternsCallbacksHandle{
		obj:       ptr,
		callbacks: newJWatchPatternsCallbacks(env, callbacks),
	}
	if err := jniPtrMap.Set(ptr, callbacksHandle); err != nil {
		panic(err)
	}
	cbs.handle = C.v23_syncbase_Handle(ptr)
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbWatchPatterns(cName, cResumeMarker, cPatterns, cbs, &cErr)
	maybeThrowException(env, &cErr)
}

//export v23_syncbase_internal_onInvite
func v23_syncbase_internal_onInvite(handle C.v23_syncbase_Handle, invite C.v23_syncbase_Invite) {
	id := uint64(uintptr(handle))
	h := jniPtrMap.Get(uintptr(id)).(*inviteCallbacksHandle)
	env, free := getEnv()
	obj := invite.extractToJava(env)
	arg := *(*C.jvalue)(unsafe.Pointer(&obj))
	C.CallVoidMethodA(env, C.jobject(unsafe.Pointer(h.obj)), h.callbacks.onInvite, &arg)
	if C.ExceptionOccurred(env) != nil {
		C.ExceptionDescribe(env)
		panic("java exception")
	}
	free()
}

type inviteCallbacksHandle struct {
	obj       uintptr
	callbacks jSyncgroupInvitesCallbacks
}

//export Java_io_v_syncbase_internal_Database_SyncgroupInvitesNewScan
func Java_io_v_syncbase_internal_Database_SyncgroupInvitesNewScan(env *C.JNIEnv, cls C.jclass, name C.jstring, callbacks C.jobject) C.jlong {
	cName := newVStringFromJava(env, name)
	cbs := C.newVSyncgroupInvitesCallbacks()
	scanId := uintptr(unsafe.Pointer(C.NewGlobalRef(env, callbacks)))
	callbacksHandle := &inviteCallbacksHandle{
		obj:       scanId,
		callbacks: newJSyncgroupInvitesCallbacks(env, callbacks),
	}
	if err := jniPtrMap.Set(scanId, callbacksHandle); err != nil {
		panic(err)
	}
	cbs.handle = C.v23_syncbase_Handle(uintptr(scanId))
	var cErr C.v23_syncbase_VError
	v23_syncbase_DbSyncgroupInvitesNewScan(cName, cbs, &cErr)
	maybeThrowException(env, &cErr)
	return C.jlong(scanId)
}

//export Java_io_v_syncbase_internal_Database_SyncgroupInvitesStopScan
func Java_io_v_syncbase_internal_Database_SyncgroupInvitesStopScan(env *C.JNIEnv, cls C.jclass, scanId C.jlong) {
	v23_syncbase_DbSyncgroupInvitesStopScan(C.v23_syncbase_Handle(scanId))
	jniPtrMap.Remove(uintptr(scanId))
}

//export Java_io_v_syncbase_internal_Collection_GetPermissions
func Java_io_v_syncbase_internal_Collection_GetPermissions(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jobject {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cPerms C.v23_syncbase_Permissions
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionGetPermissions(cName, cHandle, &cPerms, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cPerms.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Collection_SetPermissions
func Java_io_v_syncbase_internal_Collection_SetPermissions(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring, perms C.jobject) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	cPerms := newVPermissionsFromJava(env, perms)
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionSetPermissions(cName, cHandle, cPerms, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Collection_Create
func Java_io_v_syncbase_internal_Collection_Create(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring, perms C.jobject) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	cPerms := newVPermissionsFromJava(env, perms)
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionCreate(cName, cHandle, cPerms, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Collection_Destroy
func Java_io_v_syncbase_internal_Collection_Destroy(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionDestroy(cName, cHandle, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Collection_Exists
func Java_io_v_syncbase_internal_Collection_Exists(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jboolean {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var r C.bool
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionExists(cName, cHandle, &r, &cErr)
	maybeThrowException(env, &cErr)
	return r.extractToJava()
}

//export Java_io_v_syncbase_internal_Collection_DeleteRange
func Java_io_v_syncbase_internal_Collection_DeleteRange(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring, start C.jbyteArray, limit C.jbyteArray) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	cStart := newVBytesFromJava(env, start)
	cLimit := newVBytesFromJava(env, limit)
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionDeleteRange(cName, cHandle, cStart, cLimit, &cErr)
	maybeThrowException(env, &cErr)
}

//export v23_syncbase_internal_onKeyValue
func v23_syncbase_internal_onKeyValue(handle C.v23_syncbase_Handle, keyValue C.v23_syncbase_KeyValue) {
	id := uint64(uintptr(handle))
	h := jniPtrMap.Get(uintptr(id)).(*scanCallbacksHandle)
	env, free := getEnv()
	obj := keyValue.extractToJava(env)
	arg := *(*C.jvalue)(unsafe.Pointer(&obj))
	C.CallVoidMethodA(env, C.jobject(unsafe.Pointer(h.obj)), h.callbacks.onKeyValue, &arg)
	if C.ExceptionOccurred(env) != nil {
		C.ExceptionDescribe(env)
		panic("java exception")
	}
	free()
}

//export v23_syncbase_internal_onDone
func v23_syncbase_internal_onDone(handle C.v23_syncbase_Handle, error C.v23_syncbase_VError) {
	id := uint64(uintptr(handle))
	h := jniPtrMap.Get(uintptr(id)).(*scanCallbacksHandle)
	env, free := getEnv()
	obj := error.extractToJava(env)
	arg := *(*C.jvalue)(unsafe.Pointer(&obj))
	C.CallVoidMethodA(env, C.jobject(unsafe.Pointer(h.obj)), h.callbacks.onDone, &arg)
	if C.ExceptionOccurred(env) != nil {
		C.ExceptionDescribe(env)
		panic("java exception")
	}
	C.DeleteGlobalRef(env, unsafe.Pointer(h.obj))
	free()
	jniPtrMap.Remove(uintptr(id))
}

type scanCallbacksHandle struct {
	obj       uintptr
	callbacks jScanCallbacks
}

//export Java_io_v_syncbase_internal_Collection_Scan
func Java_io_v_syncbase_internal_Collection_Scan(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring, start C.jbyteArray, limit C.jbyteArray, callbacks C.jobject) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	cStart := newVBytesFromJava(env, start)
	cLimit := newVBytesFromJava(env, limit)
	ptr := uintptr(unsafe.Pointer(C.NewGlobalRef(env, callbacks)))
	callbacksHandle := &scanCallbacksHandle{
		obj:       ptr,
		callbacks: newJScanCallbacks(env, callbacks),
	}
	if err := jniPtrMap.Set(ptr, callbacksHandle); err != nil {
		panic(err)
	}
	cbs := C.newVScanCallbacks()
	cbs.handle = C.v23_syncbase_Handle(ptr)
	var cErr C.v23_syncbase_VError
	v23_syncbase_CollectionScan(cName, cHandle, cStart, cLimit, cbs, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Neighborhood_StartAdvertising
func Java_io_v_syncbase_internal_Neighborhood_StartAdvertising(env *C.JNIEnv, cls C.jclass, visibility C.jobject) {
	cVisibility := newVStringsFromJava(env, visibility)
	var cErr C.v23_syncbase_VError
	v23_syncbase_NeighborhoodStartAdvertising(cVisibility, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Neighborhood_StopAdvertising
func Java_io_v_syncbase_internal_Neighborhood_StopAdvertising(env *C.JNIEnv, cls C.jclass) {
	v23_syncbase_NeighborhoodStopAdvertising()
}

//export Java_io_v_syncbase_internal_Neighborhood_IsAdvertising
func Java_io_v_syncbase_internal_Neighborhood_IsAdvertising(env *C.JNIEnv, cls C.jclass) C.jboolean {
	var x C.bool
	v23_syncbase_NeighborhoodIsAdvertising(&x)
	return x.extractToJava()
}

//export v23_syncbase_internal_onPeer
func v23_syncbase_internal_onPeer(handle C.v23_syncbase_Handle, peer C.v23_syncbase_AppPeer) {
	id := uint64(uintptr(handle))
	h := jniPtrMap.Get(uintptr(id)).(*peerCallbacksHandle)
	env, free := getEnv()
	obj := peer.extractToJava(env)
	arg := *(*C.jvalue)(unsafe.Pointer(&obj))
	C.CallVoidMethodA(env, C.jobject(unsafe.Pointer(h.obj)), h.callbacks.onPeer, &arg)
	if C.ExceptionOccurred(env) != nil {
		C.ExceptionDescribe(env)
		panic("java exception")
	}
	free()
}

type peerCallbacksHandle struct {
	obj       uintptr
	callbacks jNeighborhoodScanCallbacks
}

//export Java_io_v_syncbase_internal_Neighborhood_NewScan
func Java_io_v_syncbase_internal_Neighborhood_NewScan(env *C.JNIEnv, cls C.jclass, callbacks C.jobject) C.jlong {
	cbs := C.newVNeighborhoodScanCallbacks()
	scanId := uintptr(unsafe.Pointer(C.NewGlobalRef(env, callbacks)))
	callbacksHandle := &peerCallbacksHandle{
		obj:       scanId,
		callbacks: newJNeigbhorhoodScanCallbacks(env, callbacks),
	}
	if err := jniPtrMap.Set(scanId, callbacksHandle); err != nil {
		panic(err)
	}
	cbs.handle = C.v23_syncbase_Handle(uintptr(scanId))
	var cErr C.v23_syncbase_VError
	v23_syncbase_NeighborhoodNewScan(cbs, &cErr)
	maybeThrowException(env, &cErr)
	return C.jlong(scanId)
}

//export Java_io_v_syncbase_internal_Neighborhood_StopScan
func Java_io_v_syncbase_internal_Neighborhood_StopScan(env *C.JNIEnv, cls C.jclass, scanId C.jlong) {
	v23_syncbase_NeighborhoodStopScan(C.v23_syncbase_Handle(scanId))
	jniPtrMap.Remove(uintptr(scanId))
}

//export Java_io_v_syncbase_internal_Row_Exists
func Java_io_v_syncbase_internal_Row_Exists(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jboolean {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var r C.bool
	var cErr C.v23_syncbase_VError
	v23_syncbase_RowExists(cName, cHandle, &r, &cErr)
	maybeThrowException(env, &cErr)
	return r.extractToJava()
}

//export Java_io_v_syncbase_internal_Row_Get
func Java_io_v_syncbase_internal_Row_Get(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jbyteArray {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var r C.v23_syncbase_Bytes
	var cErr C.v23_syncbase_VError
	v23_syncbase_RowGet(cName, cHandle, &r, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return r.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Row_Put
func Java_io_v_syncbase_internal_Row_Put(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring, value C.jbyteArray) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cErr C.v23_syncbase_VError
	cValue := newVBytesFromJava(env, value)
	v23_syncbase_RowPut(cName, cHandle, cValue, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Row_Delete
func Java_io_v_syncbase_internal_Row_Delete(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) {
	cName := newVStringFromJava(env, name)
	cHandle := newVStringFromJava(env, handle)
	var cErr C.v23_syncbase_VError
	v23_syncbase_RowDelete(cName, cHandle, &cErr)
	maybeThrowException(env, &cErr)
}

//export Java_io_v_syncbase_internal_Blessings_DebugString
func Java_io_v_syncbase_internal_Blessings_DebugString(env *C.JNIEnv, cls C.jclass) C.jstring {
	var cDebugString C.v23_syncbase_String
	v23_syncbase_BlessingStoreDebugString(&cDebugString)
	return cDebugString.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Blessings_AppBlessingFromContext
func Java_io_v_syncbase_internal_Blessings_AppBlessingFromContext(env *C.JNIEnv, cls C.jclass) C.jstring {
	var cBlessing C.v23_syncbase_String
	var cErr C.v23_syncbase_VError
	v23_syncbase_AppBlessingFromContext(&cBlessing, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cBlessing.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Blessings_UserBlessingFromContext
func Java_io_v_syncbase_internal_Blessings_UserBlessingFromContext(env *C.JNIEnv, cls C.jclass) C.jstring {
	var cBlessing C.v23_syncbase_String
	var cErr C.v23_syncbase_VError
	v23_syncbase_UserBlessingFromContext(&cBlessing, &cErr)
	if maybeThrowException(env, &cErr) {
		return nil
	}
	return cBlessing.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Util_Encode
func Java_io_v_syncbase_internal_Util_Encode(env *C.JNIEnv, cls C.jclass, s C.jstring) C.jstring {
	cPlainStr := newVStringFromJava(env, s)
	var cEncodedStr C.v23_syncbase_String
	v23_syncbase_Encode(cPlainStr, &cEncodedStr)
	return cEncodedStr.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Util_EncodeId
func Java_io_v_syncbase_internal_Util_EncodeId(env *C.JNIEnv, cls C.jclass, obj C.jobject) C.jstring {
	cId := newVIdFromJava(env, obj)
	var cEncodedId C.v23_syncbase_String
	v23_syncbase_EncodeId(cId, &cEncodedId)
	return cEncodedId.extractToJava(env)
}

//export Java_io_v_syncbase_internal_Util_NamingJoin
func Java_io_v_syncbase_internal_Util_NamingJoin(env *C.JNIEnv, cls C.jclass, obj C.jobject) C.jstring {
	cElements := newVStringsFromJava(env, obj)
	var cStr C.v23_syncbase_String
	v23_syncbase_NamingJoin(cElements, &cStr)
	return cStr.extractToJava(env)
}

// The functions below are defined in this file and not in jni_types.go due to
// "inconsistent definitions" errors for various functions (C.NewObjectA and
// C.SetObjectField for example).

// All the extractToJava methods return Java types and deallocate all the
// pointers inside v23_syncbase_* variable.

func (x *C.v23_syncbase_AppPeer) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, neighborhoodPeerClass.class, neighborhoodPeerClass.init, nil)
	C.SetObjectField(env, obj, neighborhoodPeerClass.appName, x.appName.extractToJava(env))
	C.SetObjectField(env, obj, neighborhoodPeerClass.blessings, x.blessings.extractToJava(env))
	C.SetBooleanField(env, obj, neighborhoodPeerClass.isLost, x.isLost.extractToJava())
	return obj
}

func (x *C.v23_syncbase_ChangeType) extractToJava(env *C.JNIEnv) C.jobject {
	var obj C.jobject
	switch *x {
	case C.v23_syncbase_ChangeTypePut:
		obj = C.GetStaticObjectField(env, changeTypeClass.class, changeTypeClass.put)
	case C.v23_syncbase_ChangeTypeDelete:
		obj = C.GetStaticObjectField(env, changeTypeClass.class, changeTypeClass.delete)
	}
	return obj
}

func (x *C.v23_syncbase_EntityType) extractToJava(env *C.JNIEnv) C.jobject {
	var obj C.jobject
	switch *x {
	case C.v23_syncbase_EntityTypeRoot:
		obj = C.GetStaticObjectField(env, entityTypeClass.class, entityTypeClass.root)
	case C.v23_syncbase_EntityTypeCollection:
		obj = C.GetStaticObjectField(env, entityTypeClass.class, entityTypeClass.collection)
	case C.v23_syncbase_EntityTypeRow:
		obj = C.GetStaticObjectField(env, entityTypeClass.class, entityTypeClass.row)
	}
	return obj
}

func (x *C.v23_syncbase_Id) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, idClass.class, idClass.init, nil)
	C.SetObjectField(env, obj, idClass.blessing, x.blessing.extractToJava(env))
	C.SetObjectField(env, obj, idClass.name, x.name.extractToJava(env))
	x.free()
	return obj
}

// newVIds creates a v23_syncbase_Ids from a List<Id>.
func newVIdsFromJava(env *C.JNIEnv, obj C.jobject) C.v23_syncbase_Ids {
	if obj == nil {
		return C.v23_syncbase_Ids{}
	}
	listInterface := newJListInterface(env, obj)
	iterObj := C.CallObjectMethod(env, obj, listInterface.iterator)
	if C.ExceptionOccurred(env) != nil {
		panic("newVIds exception while trying to call List.iterator()")
	}

	iteratorInterface := newJIteratorInterface(env, iterObj)
	tmp := []C.v23_syncbase_Id{}
	for C.CallBooleanMethodA(env, iterObj, iteratorInterface.hasNext, nil) == C.JNI_TRUE {
		idObj := C.CallObjectMethod(env, iterObj, iteratorInterface.next)
		if C.ExceptionOccurred(env) != nil {
			panic("newVIds exception while trying to call Iterator.next()")
		}
		tmp = append(tmp, newVIdFromJava(env, idObj))
	}

	size := C.size_t(len(tmp)) * C.size_t(C.sizeof_v23_syncbase_Id)
	r := C.v23_syncbase_Ids{
		p: (*C.v23_syncbase_Id)(unsafe.Pointer(C.malloc(size))),
		n: C.int(len(tmp)),
	}
	for i := range tmp {
		*r.at(i) = tmp[i]
	}
	return r
}

func (x *C.v23_syncbase_Ids) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, arrayListClass.class, arrayListClass.init, nil)
	for i := 0; i < int(x.n); i++ {
		idObj := x.at(i).extractToJava(env)
		arg := *(*C.jvalue)(unsafe.Pointer(&idObj))
		C.CallBooleanMethodA(env, obj, arrayListClass.add, &arg)
	}
	x.free()
	return obj
}

func (x *C.v23_syncbase_Invite) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, syncgroupInviteClass.class, syncgroupInviteClass.init, nil)
	C.SetObjectField(env, obj, syncgroupInviteClass.syncgroup, x.syncgroup.extractToJava(env))
	C.SetObjectField(env, obj, syncgroupInviteClass.addresses, x.addresses.extractToJava(env))
	C.SetObjectField(env, obj, syncgroupInviteClass.blessingNames, x.blessingNames.extractToJava(env))
	return obj
}

func (x *C.v23_syncbase_KeyValue) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, keyValueClass.class, keyValueClass.init, nil)
	C.SetObjectField(env, obj, keyValueClass.key, x.key.extractToJava(env))
	C.SetObjectField(env, obj, keyValueClass.value, x.value.extractToJava(env))
	return obj
}

func (x *C.v23_syncbase_Permissions) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, permissionsClass.class, permissionsClass.init, nil)
	C.SetObjectField(env, obj, permissionsClass.json, x.json.extractToJava(env))
	return obj
}

// newVersionedPermissions extracts a VersionedPermissions object from a
// v23_syncbase_Permissions and a v23_syncbase_String version.
func newVersionedPermissions(env *C.JNIEnv, cPerms *C.v23_syncbase_Permissions, cVersion *C.v23_syncbase_String) C.jobject {
	obj := C.NewObjectA(env, versionedPermissionsClass.class, versionedPermissionsClass.init, nil)
	C.SetObjectField(env, obj, versionedPermissionsClass.version, cVersion.extractToJava(env))
	C.SetObjectField(env, obj, versionedPermissionsClass.permissions, cPerms.extractToJava(env))
	return obj
}

// newVStringsFromJava creates a v23_syncbase_Strings from a List<String>.
func newVStringsFromJava(env *C.JNIEnv, obj C.jobject) C.v23_syncbase_Strings {
	if obj == nil {
		return C.v23_syncbase_Strings{}
	}
	listInterface := newJListInterface(env, obj)
	iterObj := C.CallObjectMethod(env, obj, listInterface.iterator)
	if C.ExceptionOccurred(env) != nil {
		panic("newVStringsFromJava exception while trying to call List.iterator()")
	}

	iteratorInterface := newJIteratorInterface(env, iterObj)
	tmp := []C.v23_syncbase_String{}
	for C.CallBooleanMethodA(env, iterObj, iteratorInterface.hasNext, nil) == C.JNI_TRUE {
		stringObj := C.CallObjectMethod(env, iterObj, iteratorInterface.next)
		if C.ExceptionOccurred(env) != nil {
			panic("newVStringsFromJava exception while trying to call Iterator.next()")
		}
		tmp = append(tmp, newVStringFromJava(env, C.jstring(stringObj)))
	}

	size := C.size_t(len(tmp)) * C.size_t(C.sizeof_v23_syncbase_String)
	r := C.v23_syncbase_Strings{
		p: (*C.v23_syncbase_String)(unsafe.Pointer(C.malloc(size))),
		n: C.int(len(tmp)),
	}
	for i := range tmp {
		*r.at(i) = tmp[i]
	}
	return r
}

func (x *C.v23_syncbase_Strings) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, arrayListClass.class, arrayListClass.init, nil)
	for i := 0; i < int(x.n); i++ {
		s := x.at(i).extractToJava(env)
		arg := *(*C.jvalue)(unsafe.Pointer(&s))
		C.CallBooleanMethodA(env, obj, arrayListClass.add, &arg)
	}
	x.free()
	return obj
}

func (x *C.v23_syncbase_SyncgroupMemberInfo) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, syncgroupMemberInfoClass.class, syncgroupMemberInfoClass.init, nil)
	C.SetByteField(env, obj, syncgroupMemberInfoClass.syncPriority, C.jbyte(x.syncPriority))
	C.SetByteField(env, obj, syncgroupMemberInfoClass.blobDevType, C.jbyte(x.blobDevType))
	return obj
}

func (x *C.v23_syncbase_SyncgroupMemberInfoMap) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, hashMapClass.class, hashMapClass.init, nil)
	for i := 0; i < int(x.n); i++ {
		k, v := x.at(i)
		key := k.extractToJava(env)
		value := v.extractToJava(env)
		args := C.allocJValueArray(2)
		C.setJValueArrayElement(args, 0, *(*C.jvalue)(unsafe.Pointer(&key)))
		C.setJValueArrayElement(args, 1, *(*C.jvalue)(unsafe.Pointer(&value)))
		C.CallObjectMethodA(env, obj, hashMapClass.put, args)
		C.free(unsafe.Pointer(args))
	}
	x.free()
	return obj
}

func (x *C.v23_syncbase_SyncgroupSpec) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, syncgroupSpecClass.class, syncgroupSpecClass.init, nil)
	C.SetObjectField(env, obj, syncgroupSpecClass.description, x.description.extractToJava(env))
	C.SetObjectField(env, obj, syncgroupSpecClass.publishSyncbaseName, x.publishSyncbaseName.extractToJava(env))
	C.SetObjectField(env, obj, syncgroupSpecClass.permissions, x.perms.extractToJava(env))
	C.SetObjectField(env, obj, syncgroupSpecClass.collections, x.collections.extractToJava(env))
	C.SetObjectField(env, obj, syncgroupSpecClass.mountTables, x.mountTables.extractToJava(env))
	C.SetBooleanField(env, obj, syncgroupSpecClass.isPrivate, x.isPrivate.extractToJava())
	return obj
}

func (x *C.v23_syncbase_VError) extractToJava(env *C.JNIEnv) C.jobject {
	if x.id.p == nil {
		return nil
	}
	obj := C.NewObjectA(env, verrorClass.class, verrorClass.init, nil)
	C.SetObjectField(env, obj, verrorClass.id, x.id.extractToJava(env))
	C.SetLongField(env, obj, verrorClass.actionCode, C.jlong(x.actionCode))
	C.SetObjectField(env, obj, verrorClass.message, x.msg.extractToJava(env))
	C.SetObjectField(env, obj, verrorClass.stack, x.stack.extractToJava(env))
	x.free()
	return obj
}

func (x *C.v23_syncbase_WatchChange) extractToJava(env *C.JNIEnv) C.jobject {
	obj := C.NewObjectA(env, watchChangeClass.class, watchChangeClass.init, nil)
	C.SetObjectField(env, obj, watchChangeClass.entityType, x.entityType.extractToJava(env))
	C.SetObjectField(env, obj, watchChangeClass.collection, x.collection.extractToJava(env))
	C.SetObjectField(env, obj, watchChangeClass.row, x.row.extractToJava(env))
	C.SetObjectField(env, obj, watchChangeClass.changeType, x.changeType.extractToJava(env))
	C.SetObjectField(env, obj, watchChangeClass.value, x.value.extractToJava(env))
	C.SetObjectField(env, obj, watchChangeClass.resumeMarker, x.resumeMarker.extractToJava(env))
	C.SetBooleanField(env, obj, watchChangeClass.fromSync, x.fromSync.extractToJava())
	C.SetBooleanField(env, obj, watchChangeClass.continued, x.continued.extractToJava())
	return obj
}

// newVCollectionRowPatternsFromJava creates a
// v23_syncbase_CollectionRowPatterns from a List<CollectionRowPattern>.
func newVCollectionRowPatternsFromJava(env *C.JNIEnv, obj C.jobject) C.v23_syncbase_CollectionRowPatterns {
	if obj == nil {
		return C.v23_syncbase_CollectionRowPatterns{}
	}
	listInterface := newJListInterface(env, obj)
	iterObj := C.CallObjectMethod(env, obj, listInterface.iterator)
	if C.ExceptionOccurred(env) != nil {
		panic("newVCollectionRowPatternsFromJava exception while trying to call List.iterator()")
	}

	iteratorInterface := newJIteratorInterface(env, iterObj)
	tmp := []C.v23_syncbase_CollectionRowPattern{}
	for C.CallBooleanMethodA(env, iterObj, iteratorInterface.hasNext, nil) == C.JNI_TRUE {
		idObj := C.CallObjectMethod(env, iterObj, iteratorInterface.next)
		if C.ExceptionOccurred(env) != nil {
			panic("newVCollectionRowPatternsFromJava exception while trying to call Iterator.next()")
		}
		tmp = append(tmp, newVCollectionRowPatternFromJava(env, idObj))
	}

	size := C.size_t(len(tmp)) * C.size_t(C.sizeof_v23_syncbase_CollectionRowPattern)
	r := C.v23_syncbase_CollectionRowPatterns{
		p: (*C.v23_syncbase_CollectionRowPattern)(unsafe.Pointer(C.malloc(size))),
		n: C.int(len(tmp)),
	}
	for i := range tmp {
		*r.at(i) = tmp[i]
	}
	return r
}

func jFindClass(env *C.JNIEnv, name string) (C.jclass, error) {
	cName := C.CString(name)
	defer C.free(unsafe.Pointer(cName))

	class := C.FindClass(env, cName)
	if C.ExceptionOccurred(env) != nil {
		return nil, fmt.Errorf("couldn't find class %s", name)
	}

	globalRef := C.jclass(C.NewGlobalRef(env, class))
	if globalRef == nil {
		return nil, fmt.Errorf("couldn't allocate a global reference for class %s", name)
	}
	return globalRef, nil
}
