diff --git a/java/arm-linux/LICENSE b/java/arm-linux/LICENSE
new file mode 100644
index 0000000..b40a0f4
--- /dev/null
+++ b/java/arm-linux/LICENSE
@@ -0,0 +1,347 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it.  By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.  This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it.  (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.  Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights.  These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have.  You must
+make sure that they, too, receive or can get the source code.  And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software.  If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.  We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License.  The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language.  (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope.  The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program).  Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+    a) You must cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in whole or
+    in part contains or is derived from the Program or any part thereof, to be
+    licensed as a whole at no charge to all third parties under the terms of
+    this License.
+
+    c) If the modified program normally reads commands interactively when run,
+    you must cause it, when started running for such interactive use in the
+    most ordinary way, to print or display an announcement including an
+    appropriate copyright notice and a notice that there is no warranty (or
+    else, saying that you provide a warranty) and that users may redistribute
+    the program under these conditions, and telling the user how to view a copy
+    of this License.  (Exception: if the Program itself is interactive but does
+    not normally print such an announcement, your work based on the Program is
+    not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works.  But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable source
+    code, which must be distributed under the terms of Sections 1 and 2 above
+    on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three years, to
+    give any third party, for a charge no more than your cost of physically
+    performing source distribution, a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of Sections 1
+    and 2 above on a medium customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer to
+    distribute corresponding source code.  (This alternative is allowed only
+    for noncommercial distribution and only if you received the program in
+    object code or executable form with such an offer, in accord with
+    Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it.  For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable.  However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License.  Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License.  However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works.  These actions are prohibited by law if you do not
+accept this License.  Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein.  You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License.  If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices.  Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded.  In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time.  Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission.  For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program.  It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+    One line to give the program's name and a brief idea of what it does.
+
+    Copyright (C) <year> <name of author>
+
+    This program is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the Free
+    Software Foundation; either version 2 of the License, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc., 59
+    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free
+    software, and you are welcome to redistribute it under certain conditions;
+    type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.  Here
+is a sample; alter the names:
+
+    Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+    'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+    signature of Ty Coon, 1 April 1989
+
+    Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Oracle America and/or its affiliates are
+subject to the following clarification and special exception to the GPL, but
+only where Oracle has expressly included in the particular source file's header
+the words "Oracle designates this particular file as subject to the "Classpath"
+exception as provided by Oracle in the LICENSE file that accompanied this code."
+
+    Linking this library statically or dynamically with other modules is making
+    a combined work based on this library.  Thus, the terms and conditions of
+    the GNU General Public License cover the whole combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent modules,
+    and to copy and distribute the resulting executable under terms of your
+    choice, provided that you also meet, for each linked independent module,
+    the terms and conditions of the license of that module.  An independent
+    module is a module which is not derived from or based on this library.  If
+    you modify this library, you may extend this exception to your version of
+    the library, but you are not obligated to do so.  If you do not wish to do
+    so, delete this exception statement from your version.
diff --git a/java/arm-linux/jni.h b/java/arm-linux/jni.h
new file mode 100644
index 0000000..2e83cb7
--- /dev/null
+++ b/java/arm-linux/jni.h
@@ -0,0 +1,1960 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * We used part of Netscape's Java Runtime Interface (JRI) as the starting
+ * point of our design and implementation.
+ */
+
+/******************************************************************************
+ * Java Runtime Interface
+ * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved.
+ *****************************************************************************/
+
+#ifndef _JAVASOFT_JNI_H_
+#define _JAVASOFT_JNI_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* jni_md.h contains the machine-dependent typedefs for jbyte, jint
+   and jlong */
+
+#include "jni_md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * JNI Types
+ */
+
+#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H
+
+typedef unsigned char   jboolean;
+typedef unsigned short  jchar;
+typedef short           jshort;
+typedef float           jfloat;
+typedef double          jdouble;
+
+typedef jint            jsize;
+
+#ifdef __cplusplus
+
+class _jobject {};
+class _jclass : public _jobject {};
+class _jthrowable : public _jobject {};
+class _jstring : public _jobject {};
+class _jarray : public _jobject {};
+class _jbooleanArray : public _jarray {};
+class _jbyteArray : public _jarray {};
+class _jcharArray : public _jarray {};
+class _jshortArray : public _jarray {};
+class _jintArray : public _jarray {};
+class _jlongArray : public _jarray {};
+class _jfloatArray : public _jarray {};
+class _jdoubleArray : public _jarray {};
+class _jobjectArray : public _jarray {};
+
+typedef _jobject *jobject;
+typedef _jclass *jclass;
+typedef _jthrowable *jthrowable;
+typedef _jstring *jstring;
+typedef _jarray *jarray;
+typedef _jbooleanArray *jbooleanArray;
+typedef _jbyteArray *jbyteArray;
+typedef _jcharArray *jcharArray;
+typedef _jshortArray *jshortArray;
+typedef _jintArray *jintArray;
+typedef _jlongArray *jlongArray;
+typedef _jfloatArray *jfloatArray;
+typedef _jdoubleArray *jdoubleArray;
+typedef _jobjectArray *jobjectArray;
+
+#else
+
+struct _jobject;
+
+typedef struct _jobject *jobject;
+typedef jobject jclass;
+typedef jobject jthrowable;
+typedef jobject jstring;
+typedef jobject jarray;
+typedef jarray jbooleanArray;
+typedef jarray jbyteArray;
+typedef jarray jcharArray;
+typedef jarray jshortArray;
+typedef jarray jintArray;
+typedef jarray jlongArray;
+typedef jarray jfloatArray;
+typedef jarray jdoubleArray;
+typedef jarray jobjectArray;
+
+#endif
+
+typedef jobject jweak;
+
+typedef union jvalue {
+    jboolean z;
+    jbyte    b;
+    jchar    c;
+    jshort   s;
+    jint     i;
+    jlong    j;
+    jfloat   f;
+    jdouble  d;
+    jobject  l;
+} jvalue;
+
+struct _jfieldID;
+typedef struct _jfieldID *jfieldID;
+
+struct _jmethodID;
+typedef struct _jmethodID *jmethodID;
+
+/* Return values from jobjectRefType */
+typedef enum _jobjectType {
+     JNIInvalidRefType    = 0,
+     JNILocalRefType      = 1,
+     JNIGlobalRefType     = 2,
+     JNIWeakGlobalRefType = 3
+} jobjectRefType;
+
+
+#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */
+
+/*
+ * jboolean constants
+ */
+
+#define JNI_FALSE 0
+#define JNI_TRUE 1
+
+/*
+ * possible return values for JNI functions.
+ */
+
+#define JNI_OK           0                 /* success */
+#define JNI_ERR          (-1)              /* unknown error */
+#define JNI_EDETACHED    (-2)              /* thread detached from the VM */
+#define JNI_EVERSION     (-3)              /* JNI version error */
+#define JNI_ENOMEM       (-4)              /* not enough memory */
+#define JNI_EEXIST       (-5)              /* VM already created */
+#define JNI_EINVAL       (-6)              /* invalid arguments */
+
+/*
+ * used in ReleaseScalarArrayElements
+ */
+
+#define JNI_COMMIT 1
+#define JNI_ABORT 2
+
+/*
+ * used in RegisterNatives to describe native method name, signature,
+ * and function pointer.
+ */
+
+typedef struct {
+    char *name;
+    char *signature;
+    void *fnPtr;
+} JNINativeMethod;
+
+/*
+ * JNI Native Method Interface.
+ */
+
+struct JNINativeInterface_;
+
+struct JNIEnv_;
+
+#ifdef __cplusplus
+typedef JNIEnv_ JNIEnv;
+#else
+typedef const struct JNINativeInterface_ *JNIEnv;
+#endif
+
+/*
+ * JNI Invocation Interface.
+ */
+
+struct JNIInvokeInterface_;
+
+struct JavaVM_;
+
+#ifdef __cplusplus
+typedef JavaVM_ JavaVM;
+#else
+typedef const struct JNIInvokeInterface_ *JavaVM;
+#endif
+
+struct JNINativeInterface_ {
+    void *reserved0;
+    void *reserved1;
+    void *reserved2;
+
+    void *reserved3;
+    jint (JNICALL *GetVersion)(JNIEnv *env);
+
+    jclass (JNICALL *DefineClass)
+      (JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
+       jsize len);
+    jclass (JNICALL *FindClass)
+      (JNIEnv *env, const char *name);
+
+    jmethodID (JNICALL *FromReflectedMethod)
+      (JNIEnv *env, jobject method);
+    jfieldID (JNICALL *FromReflectedField)
+      (JNIEnv *env, jobject field);
+
+    jobject (JNICALL *ToReflectedMethod)
+      (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
+
+    jclass (JNICALL *GetSuperclass)
+      (JNIEnv *env, jclass sub);
+    jboolean (JNICALL *IsAssignableFrom)
+      (JNIEnv *env, jclass sub, jclass sup);
+
+    jobject (JNICALL *ToReflectedField)
+      (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
+
+    jint (JNICALL *Throw)
+      (JNIEnv *env, jthrowable obj);
+    jint (JNICALL *ThrowNew)
+      (JNIEnv *env, jclass clazz, const char *msg);
+    jthrowable (JNICALL *ExceptionOccurred)
+      (JNIEnv *env);
+    void (JNICALL *ExceptionDescribe)
+      (JNIEnv *env);
+    void (JNICALL *ExceptionClear)
+      (JNIEnv *env);
+    void (JNICALL *FatalError)
+      (JNIEnv *env, const char *msg);
+
+    jint (JNICALL *PushLocalFrame)
+      (JNIEnv *env, jint capacity);
+    jobject (JNICALL *PopLocalFrame)
+      (JNIEnv *env, jobject result);
+
+    jobject (JNICALL *NewGlobalRef)
+      (JNIEnv *env, jobject lobj);
+    void (JNICALL *DeleteGlobalRef)
+      (JNIEnv *env, jobject gref);
+    void (JNICALL *DeleteLocalRef)
+      (JNIEnv *env, jobject obj);
+    jboolean (JNICALL *IsSameObject)
+      (JNIEnv *env, jobject obj1, jobject obj2);
+    jobject (JNICALL *NewLocalRef)
+      (JNIEnv *env, jobject ref);
+    jint (JNICALL *EnsureLocalCapacity)
+      (JNIEnv *env, jint capacity);
+
+    jobject (JNICALL *AllocObject)
+      (JNIEnv *env, jclass clazz);
+    jobject (JNICALL *NewObject)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jobject (JNICALL *NewObjectV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jobject (JNICALL *NewObjectA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jclass (JNICALL *GetObjectClass)
+      (JNIEnv *env, jobject obj);
+    jboolean (JNICALL *IsInstanceOf)
+      (JNIEnv *env, jobject obj, jclass clazz);
+
+    jmethodID (JNICALL *GetMethodID)
+      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+    jobject (JNICALL *CallObjectMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jobject (JNICALL *CallObjectMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jobject (JNICALL *CallObjectMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
+
+    jboolean (JNICALL *CallBooleanMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jboolean (JNICALL *CallBooleanMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jboolean (JNICALL *CallBooleanMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
+
+    jbyte (JNICALL *CallByteMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jbyte (JNICALL *CallByteMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jbyte (JNICALL *CallByteMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    jchar (JNICALL *CallCharMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jchar (JNICALL *CallCharMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jchar (JNICALL *CallCharMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    jshort (JNICALL *CallShortMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jshort (JNICALL *CallShortMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jshort (JNICALL *CallShortMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    jint (JNICALL *CallIntMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jint (JNICALL *CallIntMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jint (JNICALL *CallIntMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    jlong (JNICALL *CallLongMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jlong (JNICALL *CallLongMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jlong (JNICALL *CallLongMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    jfloat (JNICALL *CallFloatMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jfloat (JNICALL *CallFloatMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jfloat (JNICALL *CallFloatMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    jdouble (JNICALL *CallDoubleMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    jdouble (JNICALL *CallDoubleMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    jdouble (JNICALL *CallDoubleMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
+
+    void (JNICALL *CallVoidMethod)
+      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+    void (JNICALL *CallVoidMethodV)
+      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+    void (JNICALL *CallVoidMethodA)
+      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
+
+    jobject (JNICALL *CallNonvirtualObjectMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jobject (JNICALL *CallNonvirtualObjectMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jobject (JNICALL *CallNonvirtualObjectMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue * args);
+
+    jboolean (JNICALL *CallNonvirtualBooleanMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jboolean (JNICALL *CallNonvirtualBooleanMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jboolean (JNICALL *CallNonvirtualBooleanMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue * args);
+
+    jbyte (JNICALL *CallNonvirtualByteMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jbyte (JNICALL *CallNonvirtualByteMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jbyte (JNICALL *CallNonvirtualByteMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    jchar (JNICALL *CallNonvirtualCharMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jchar (JNICALL *CallNonvirtualCharMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jchar (JNICALL *CallNonvirtualCharMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    jshort (JNICALL *CallNonvirtualShortMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jshort (JNICALL *CallNonvirtualShortMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jshort (JNICALL *CallNonvirtualShortMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    jint (JNICALL *CallNonvirtualIntMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jint (JNICALL *CallNonvirtualIntMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jint (JNICALL *CallNonvirtualIntMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    jlong (JNICALL *CallNonvirtualLongMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jlong (JNICALL *CallNonvirtualLongMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jlong (JNICALL *CallNonvirtualLongMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    jfloat (JNICALL *CallNonvirtualFloatMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jfloat (JNICALL *CallNonvirtualFloatMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jfloat (JNICALL *CallNonvirtualFloatMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    jdouble (JNICALL *CallNonvirtualDoubleMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    jdouble (JNICALL *CallNonvirtualDoubleMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    jdouble (JNICALL *CallNonvirtualDoubleMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue *args);
+
+    void (JNICALL *CallNonvirtualVoidMethod)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+    void (JNICALL *CallNonvirtualVoidMethodV)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       va_list args);
+    void (JNICALL *CallNonvirtualVoidMethodA)
+      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+       const jvalue * args);
+
+    jfieldID (JNICALL *GetFieldID)
+      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+    jobject (JNICALL *GetObjectField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jboolean (JNICALL *GetBooleanField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jbyte (JNICALL *GetByteField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jchar (JNICALL *GetCharField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jshort (JNICALL *GetShortField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jint (JNICALL *GetIntField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jlong (JNICALL *GetLongField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jfloat (JNICALL *GetFloatField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+    jdouble (JNICALL *GetDoubleField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID);
+
+    void (JNICALL *SetObjectField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val);
+    void (JNICALL *SetBooleanField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val);
+    void (JNICALL *SetByteField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val);
+    void (JNICALL *SetCharField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val);
+    void (JNICALL *SetShortField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val);
+    void (JNICALL *SetIntField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
+    void (JNICALL *SetLongField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val);
+    void (JNICALL *SetFloatField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val);
+    void (JNICALL *SetDoubleField)
+      (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val);
+
+    jmethodID (JNICALL *GetStaticMethodID)
+      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+    jobject (JNICALL *CallStaticObjectMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jobject (JNICALL *CallStaticObjectMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jobject (JNICALL *CallStaticObjectMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jboolean (JNICALL *CallStaticBooleanMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jboolean (JNICALL *CallStaticBooleanMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jboolean (JNICALL *CallStaticBooleanMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jbyte (JNICALL *CallStaticByteMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jbyte (JNICALL *CallStaticByteMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jbyte (JNICALL *CallStaticByteMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jchar (JNICALL *CallStaticCharMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jchar (JNICALL *CallStaticCharMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jchar (JNICALL *CallStaticCharMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jshort (JNICALL *CallStaticShortMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jshort (JNICALL *CallStaticShortMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jshort (JNICALL *CallStaticShortMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jint (JNICALL *CallStaticIntMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jint (JNICALL *CallStaticIntMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jint (JNICALL *CallStaticIntMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jlong (JNICALL *CallStaticLongMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jlong (JNICALL *CallStaticLongMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jlong (JNICALL *CallStaticLongMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jfloat (JNICALL *CallStaticFloatMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jfloat (JNICALL *CallStaticFloatMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jfloat (JNICALL *CallStaticFloatMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    jdouble (JNICALL *CallStaticDoubleMethod)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+    jdouble (JNICALL *CallStaticDoubleMethodV)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+    jdouble (JNICALL *CallStaticDoubleMethodA)
+      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
+
+    void (JNICALL *CallStaticVoidMethod)
+      (JNIEnv *env, jclass cls, jmethodID methodID, ...);
+    void (JNICALL *CallStaticVoidMethodV)
+      (JNIEnv *env, jclass cls, jmethodID methodID, va_list args);
+    void (JNICALL *CallStaticVoidMethodA)
+      (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args);
+
+    jfieldID (JNICALL *GetStaticFieldID)
+      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+    jobject (JNICALL *GetStaticObjectField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jboolean (JNICALL *GetStaticBooleanField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jbyte (JNICALL *GetStaticByteField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jchar (JNICALL *GetStaticCharField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jshort (JNICALL *GetStaticShortField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jint (JNICALL *GetStaticIntField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jlong (JNICALL *GetStaticLongField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jfloat (JNICALL *GetStaticFloatField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+    jdouble (JNICALL *GetStaticDoubleField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID);
+
+    void (JNICALL *SetStaticObjectField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value);
+    void (JNICALL *SetStaticBooleanField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value);
+    void (JNICALL *SetStaticByteField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value);
+    void (JNICALL *SetStaticCharField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value);
+    void (JNICALL *SetStaticShortField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value);
+    void (JNICALL *SetStaticIntField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
+    void (JNICALL *SetStaticLongField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value);
+    void (JNICALL *SetStaticFloatField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value);
+    void (JNICALL *SetStaticDoubleField)
+      (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value);
+
+    jstring (JNICALL *NewString)
+      (JNIEnv *env, const jchar *unicode, jsize len);
+    jsize (JNICALL *GetStringLength)
+      (JNIEnv *env, jstring str);
+    const jchar *(JNICALL *GetStringChars)
+      (JNIEnv *env, jstring str, jboolean *isCopy);
+    void (JNICALL *ReleaseStringChars)
+      (JNIEnv *env, jstring str, const jchar *chars);
+
+    jstring (JNICALL *NewStringUTF)
+      (JNIEnv *env, const char *utf);
+    jsize (JNICALL *GetStringUTFLength)
+      (JNIEnv *env, jstring str);
+    const char* (JNICALL *GetStringUTFChars)
+      (JNIEnv *env, jstring str, jboolean *isCopy);
+    void (JNICALL *ReleaseStringUTFChars)
+      (JNIEnv *env, jstring str, const char* chars);
+
+
+    jsize (JNICALL *GetArrayLength)
+      (JNIEnv *env, jarray array);
+
+    jobjectArray (JNICALL *NewObjectArray)
+      (JNIEnv *env, jsize len, jclass clazz, jobject init);
+    jobject (JNICALL *GetObjectArrayElement)
+      (JNIEnv *env, jobjectArray array, jsize index);
+    void (JNICALL *SetObjectArrayElement)
+      (JNIEnv *env, jobjectArray array, jsize index, jobject val);
+
+    jbooleanArray (JNICALL *NewBooleanArray)
+      (JNIEnv *env, jsize len);
+    jbyteArray (JNICALL *NewByteArray)
+      (JNIEnv *env, jsize len);
+    jcharArray (JNICALL *NewCharArray)
+      (JNIEnv *env, jsize len);
+    jshortArray (JNICALL *NewShortArray)
+      (JNIEnv *env, jsize len);
+    jintArray (JNICALL *NewIntArray)
+      (JNIEnv *env, jsize len);
+    jlongArray (JNICALL *NewLongArray)
+      (JNIEnv *env, jsize len);
+    jfloatArray (JNICALL *NewFloatArray)
+      (JNIEnv *env, jsize len);
+    jdoubleArray (JNICALL *NewDoubleArray)
+      (JNIEnv *env, jsize len);
+
+    jboolean * (JNICALL *GetBooleanArrayElements)
+      (JNIEnv *env, jbooleanArray array, jboolean *isCopy);
+    jbyte * (JNICALL *GetByteArrayElements)
+      (JNIEnv *env, jbyteArray array, jboolean *isCopy);
+    jchar * (JNICALL *GetCharArrayElements)
+      (JNIEnv *env, jcharArray array, jboolean *isCopy);
+    jshort * (JNICALL *GetShortArrayElements)
+      (JNIEnv *env, jshortArray array, jboolean *isCopy);
+    jint * (JNICALL *GetIntArrayElements)
+      (JNIEnv *env, jintArray array, jboolean *isCopy);
+    jlong * (JNICALL *GetLongArrayElements)
+      (JNIEnv *env, jlongArray array, jboolean *isCopy);
+    jfloat * (JNICALL *GetFloatArrayElements)
+      (JNIEnv *env, jfloatArray array, jboolean *isCopy);
+    jdouble * (JNICALL *GetDoubleArrayElements)
+      (JNIEnv *env, jdoubleArray array, jboolean *isCopy);
+
+    void (JNICALL *ReleaseBooleanArrayElements)
+      (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode);
+    void (JNICALL *ReleaseByteArrayElements)
+      (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode);
+    void (JNICALL *ReleaseCharArrayElements)
+      (JNIEnv *env, jcharArray array, jchar *elems, jint mode);
+    void (JNICALL *ReleaseShortArrayElements)
+      (JNIEnv *env, jshortArray array, jshort *elems, jint mode);
+    void (JNICALL *ReleaseIntArrayElements)
+      (JNIEnv *env, jintArray array, jint *elems, jint mode);
+    void (JNICALL *ReleaseLongArrayElements)
+      (JNIEnv *env, jlongArray array, jlong *elems, jint mode);
+    void (JNICALL *ReleaseFloatArrayElements)
+      (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode);
+    void (JNICALL *ReleaseDoubleArrayElements)
+      (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode);
+
+    void (JNICALL *GetBooleanArrayRegion)
+      (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf);
+    void (JNICALL *GetByteArrayRegion)
+      (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);
+    void (JNICALL *GetCharArrayRegion)
+      (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf);
+    void (JNICALL *GetShortArrayRegion)
+      (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf);
+    void (JNICALL *GetIntArrayRegion)
+      (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf);
+    void (JNICALL *GetLongArrayRegion)
+      (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf);
+    void (JNICALL *GetFloatArrayRegion)
+      (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf);
+    void (JNICALL *GetDoubleArrayRegion)
+      (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+    void (JNICALL *SetBooleanArrayRegion)
+      (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf);
+    void (JNICALL *SetByteArrayRegion)
+      (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf);
+    void (JNICALL *SetCharArrayRegion)
+      (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf);
+    void (JNICALL *SetShortArrayRegion)
+      (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf);
+    void (JNICALL *SetIntArrayRegion)
+      (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf);
+    void (JNICALL *SetLongArrayRegion)
+      (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf);
+    void (JNICALL *SetFloatArrayRegion)
+      (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf);
+    void (JNICALL *SetDoubleArrayRegion)
+      (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf);
+
+    jint (JNICALL *RegisterNatives)
+      (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
+       jint nMethods);
+    jint (JNICALL *UnregisterNatives)
+      (JNIEnv *env, jclass clazz);
+
+    jint (JNICALL *MonitorEnter)
+      (JNIEnv *env, jobject obj);
+    jint (JNICALL *MonitorExit)
+      (JNIEnv *env, jobject obj);
+
+    jint (JNICALL *GetJavaVM)
+      (JNIEnv *env, JavaVM **vm);
+
+    void (JNICALL *GetStringRegion)
+      (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
+    void (JNICALL *GetStringUTFRegion)
+      (JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
+
+    void * (JNICALL *GetPrimitiveArrayCritical)
+      (JNIEnv *env, jarray array, jboolean *isCopy);
+    void (JNICALL *ReleasePrimitiveArrayCritical)
+      (JNIEnv *env, jarray array, void *carray, jint mode);
+
+    const jchar * (JNICALL *GetStringCritical)
+      (JNIEnv *env, jstring string, jboolean *isCopy);
+    void (JNICALL *ReleaseStringCritical)
+      (JNIEnv *env, jstring string, const jchar *cstring);
+
+    jweak (JNICALL *NewWeakGlobalRef)
+       (JNIEnv *env, jobject obj);
+    void (JNICALL *DeleteWeakGlobalRef)
+       (JNIEnv *env, jweak ref);
+
+    jboolean (JNICALL *ExceptionCheck)
+       (JNIEnv *env);
+
+    jobject (JNICALL *NewDirectByteBuffer)
+       (JNIEnv* env, void* address, jlong capacity);
+    void* (JNICALL *GetDirectBufferAddress)
+       (JNIEnv* env, jobject buf);
+    jlong (JNICALL *GetDirectBufferCapacity)
+       (JNIEnv* env, jobject buf);
+
+    /* New JNI 1.6 Features */
+
+    jobjectRefType (JNICALL *GetObjectRefType)
+        (JNIEnv* env, jobject obj);
+};
+
+/*
+ * We use inlined functions for C++ so that programmers can write:
+ *
+ *    env->FindClass("java/lang/String")
+ *
+ * in C++ rather than:
+ *
+ *    (*env)->FindClass(env, "java/lang/String")
+ *
+ * in C.
+ */
+
+struct JNIEnv_ {
+    const struct JNINativeInterface_ *functions;
+#ifdef __cplusplus
+
+    jint GetVersion() {
+        return functions->GetVersion(this);
+    }
+    jclass DefineClass(const char *name, jobject loader, const jbyte *buf,
+                       jsize len) {
+        return functions->DefineClass(this, name, loader, buf, len);
+    }
+    jclass FindClass(const char *name) {
+        return functions->FindClass(this, name);
+    }
+    jmethodID FromReflectedMethod(jobject method) {
+        return functions->FromReflectedMethod(this,method);
+    }
+    jfieldID FromReflectedField(jobject field) {
+        return functions->FromReflectedField(this,field);
+    }
+
+    jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) {
+        return functions->ToReflectedMethod(this, cls, methodID, isStatic);
+    }
+
+    jclass GetSuperclass(jclass sub) {
+        return functions->GetSuperclass(this, sub);
+    }
+    jboolean IsAssignableFrom(jclass sub, jclass sup) {
+        return functions->IsAssignableFrom(this, sub, sup);
+    }
+
+    jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) {
+        return functions->ToReflectedField(this,cls,fieldID,isStatic);
+    }
+
+    jint Throw(jthrowable obj) {
+        return functions->Throw(this, obj);
+    }
+    jint ThrowNew(jclass clazz, const char *msg) {
+        return functions->ThrowNew(this, clazz, msg);
+    }
+    jthrowable ExceptionOccurred() {
+        return functions->ExceptionOccurred(this);
+    }
+    void ExceptionDescribe() {
+        functions->ExceptionDescribe(this);
+    }
+    void ExceptionClear() {
+        functions->ExceptionClear(this);
+    }
+    void FatalError(const char *msg) {
+        functions->FatalError(this, msg);
+    }
+
+    jint PushLocalFrame(jint capacity) {
+        return functions->PushLocalFrame(this,capacity);
+    }
+    jobject PopLocalFrame(jobject result) {
+        return functions->PopLocalFrame(this,result);
+    }
+
+    jobject NewGlobalRef(jobject lobj) {
+        return functions->NewGlobalRef(this,lobj);
+    }
+    void DeleteGlobalRef(jobject gref) {
+        functions->DeleteGlobalRef(this,gref);
+    }
+    void DeleteLocalRef(jobject obj) {
+        functions->DeleteLocalRef(this, obj);
+    }
+
+    jboolean IsSameObject(jobject obj1, jobject obj2) {
+        return functions->IsSameObject(this,obj1,obj2);
+    }
+
+    jobject NewLocalRef(jobject ref) {
+        return functions->NewLocalRef(this,ref);
+    }
+    jint EnsureLocalCapacity(jint capacity) {
+        return functions->EnsureLocalCapacity(this,capacity);
+    }
+
+    jobject AllocObject(jclass clazz) {
+        return functions->AllocObject(this,clazz);
+    }
+    jobject NewObject(jclass clazz, jmethodID methodID, ...) {
+        va_list args;
+        jobject result;
+        va_start(args, methodID);
+        result = functions->NewObjectV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jobject NewObjectV(jclass clazz, jmethodID methodID,
+                       va_list args) {
+        return functions->NewObjectV(this,clazz,methodID,args);
+    }
+    jobject NewObjectA(jclass clazz, jmethodID methodID,
+                       const jvalue *args) {
+        return functions->NewObjectA(this,clazz,methodID,args);
+    }
+
+    jclass GetObjectClass(jobject obj) {
+        return functions->GetObjectClass(this,obj);
+    }
+    jboolean IsInstanceOf(jobject obj, jclass clazz) {
+        return functions->IsInstanceOf(this,obj,clazz);
+    }
+
+    jmethodID GetMethodID(jclass clazz, const char *name,
+                          const char *sig) {
+        return functions->GetMethodID(this,clazz,name,sig);
+    }
+
+    jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jobject result;
+        va_start(args,methodID);
+        result = functions->CallObjectMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jobject CallObjectMethodV(jobject obj, jmethodID methodID,
+                        va_list args) {
+        return functions->CallObjectMethodV(this,obj,methodID,args);
+    }
+    jobject CallObjectMethodA(jobject obj, jmethodID methodID,
+                        const jvalue * args) {
+        return functions->CallObjectMethodA(this,obj,methodID,args);
+    }
+
+    jboolean CallBooleanMethod(jobject obj,
+                               jmethodID methodID, ...) {
+        va_list args;
+        jboolean result;
+        va_start(args,methodID);
+        result = functions->CallBooleanMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jboolean CallBooleanMethodV(jobject obj, jmethodID methodID,
+                                va_list args) {
+        return functions->CallBooleanMethodV(this,obj,methodID,args);
+    }
+    jboolean CallBooleanMethodA(jobject obj, jmethodID methodID,
+                                const jvalue * args) {
+        return functions->CallBooleanMethodA(this,obj,methodID, args);
+    }
+
+    jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jbyte result;
+        va_start(args,methodID);
+        result = functions->CallByteMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jbyte CallByteMethodV(jobject obj, jmethodID methodID,
+                          va_list args) {
+        return functions->CallByteMethodV(this,obj,methodID,args);
+    }
+    jbyte CallByteMethodA(jobject obj, jmethodID methodID,
+                          const jvalue * args) {
+        return functions->CallByteMethodA(this,obj,methodID,args);
+    }
+
+    jchar CallCharMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jchar result;
+        va_start(args,methodID);
+        result = functions->CallCharMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jchar CallCharMethodV(jobject obj, jmethodID methodID,
+                          va_list args) {
+        return functions->CallCharMethodV(this,obj,methodID,args);
+    }
+    jchar CallCharMethodA(jobject obj, jmethodID methodID,
+                          const jvalue * args) {
+        return functions->CallCharMethodA(this,obj,methodID,args);
+    }
+
+    jshort CallShortMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jshort result;
+        va_start(args,methodID);
+        result = functions->CallShortMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jshort CallShortMethodV(jobject obj, jmethodID methodID,
+                            va_list args) {
+        return functions->CallShortMethodV(this,obj,methodID,args);
+    }
+    jshort CallShortMethodA(jobject obj, jmethodID methodID,
+                            const jvalue * args) {
+        return functions->CallShortMethodA(this,obj,methodID,args);
+    }
+
+    jint CallIntMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jint result;
+        va_start(args,methodID);
+        result = functions->CallIntMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jint CallIntMethodV(jobject obj, jmethodID methodID,
+                        va_list args) {
+        return functions->CallIntMethodV(this,obj,methodID,args);
+    }
+    jint CallIntMethodA(jobject obj, jmethodID methodID,
+                        const jvalue * args) {
+        return functions->CallIntMethodA(this,obj,methodID,args);
+    }
+
+    jlong CallLongMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jlong result;
+        va_start(args,methodID);
+        result = functions->CallLongMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jlong CallLongMethodV(jobject obj, jmethodID methodID,
+                          va_list args) {
+        return functions->CallLongMethodV(this,obj,methodID,args);
+    }
+    jlong CallLongMethodA(jobject obj, jmethodID methodID,
+                          const jvalue * args) {
+        return functions->CallLongMethodA(this,obj,methodID,args);
+    }
+
+    jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jfloat result;
+        va_start(args,methodID);
+        result = functions->CallFloatMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jfloat CallFloatMethodV(jobject obj, jmethodID methodID,
+                            va_list args) {
+        return functions->CallFloatMethodV(this,obj,methodID,args);
+    }
+    jfloat CallFloatMethodA(jobject obj, jmethodID methodID,
+                            const jvalue * args) {
+        return functions->CallFloatMethodA(this,obj,methodID,args);
+    }
+
+    jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        jdouble result;
+        va_start(args,methodID);
+        result = functions->CallDoubleMethodV(this,obj,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jdouble CallDoubleMethodV(jobject obj, jmethodID methodID,
+                        va_list args) {
+        return functions->CallDoubleMethodV(this,obj,methodID,args);
+    }
+    jdouble CallDoubleMethodA(jobject obj, jmethodID methodID,
+                        const jvalue * args) {
+        return functions->CallDoubleMethodA(this,obj,methodID,args);
+    }
+
+    void CallVoidMethod(jobject obj, jmethodID methodID, ...) {
+        va_list args;
+        va_start(args,methodID);
+        functions->CallVoidMethodV(this,obj,methodID,args);
+        va_end(args);
+    }
+    void CallVoidMethodV(jobject obj, jmethodID methodID,
+                         va_list args) {
+        functions->CallVoidMethodV(this,obj,methodID,args);
+    }
+    void CallVoidMethodA(jobject obj, jmethodID methodID,
+                         const jvalue * args) {
+        functions->CallVoidMethodA(this,obj,methodID,args);
+    }
+
+    jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz,
+                                       jmethodID methodID, ...) {
+        va_list args;
+        jobject result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualObjectMethodV(this,obj,clazz,
+                                                        methodID,args);
+        va_end(args);
+        return result;
+    }
+    jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz,
+                                        jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualObjectMethodV(this,obj,clazz,
+                                                      methodID,args);
+    }
+    jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz,
+                                        jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualObjectMethodA(this,obj,clazz,
+                                                      methodID,args);
+    }
+
+    jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz,
+                                         jmethodID methodID, ...) {
+        va_list args;
+        jboolean result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz,
+                                                         methodID,args);
+        va_end(args);
+        return result;
+    }
+    jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz,
+                                          jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualBooleanMethodV(this,obj,clazz,
+                                                       methodID,args);
+    }
+    jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz,
+                                          jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualBooleanMethodA(this,obj,clazz,
+                                                       methodID, args);
+    }
+
+    jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz,
+                                   jmethodID methodID, ...) {
+        va_list args;
+        jbyte result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualByteMethodV(this,obj,clazz,
+                                                      methodID,args);
+        va_end(args);
+        return result;
+    }
+    jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz,
+                                    jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualByteMethodV(this,obj,clazz,
+                                                    methodID,args);
+    }
+    jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz,
+                                    jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualByteMethodA(this,obj,clazz,
+                                                    methodID,args);
+    }
+
+    jchar CallNonvirtualCharMethod(jobject obj, jclass clazz,
+                                   jmethodID methodID, ...) {
+        va_list args;
+        jchar result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualCharMethodV(this,obj,clazz,
+                                                      methodID,args);
+        va_end(args);
+        return result;
+    }
+    jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz,
+                                    jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualCharMethodV(this,obj,clazz,
+                                                    methodID,args);
+    }
+    jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz,
+                                    jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualCharMethodA(this,obj,clazz,
+                                                    methodID,args);
+    }
+
+    jshort CallNonvirtualShortMethod(jobject obj, jclass clazz,
+                                     jmethodID methodID, ...) {
+        va_list args;
+        jshort result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualShortMethodV(this,obj,clazz,
+                                                       methodID,args);
+        va_end(args);
+        return result;
+    }
+    jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz,
+                                      jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualShortMethodV(this,obj,clazz,
+                                                     methodID,args);
+    }
+    jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz,
+                                      jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualShortMethodA(this,obj,clazz,
+                                                     methodID,args);
+    }
+
+    jint CallNonvirtualIntMethod(jobject obj, jclass clazz,
+                                 jmethodID methodID, ...) {
+        va_list args;
+        jint result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualIntMethodV(this,obj,clazz,
+                                                     methodID,args);
+        va_end(args);
+        return result;
+    }
+    jint CallNonvirtualIntMethodV(jobject obj, jclass clazz,
+                                  jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualIntMethodV(this,obj,clazz,
+                                                   methodID,args);
+    }
+    jint CallNonvirtualIntMethodA(jobject obj, jclass clazz,
+                                  jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualIntMethodA(this,obj,clazz,
+                                                   methodID,args);
+    }
+
+    jlong CallNonvirtualLongMethod(jobject obj, jclass clazz,
+                                   jmethodID methodID, ...) {
+        va_list args;
+        jlong result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualLongMethodV(this,obj,clazz,
+                                                      methodID,args);
+        va_end(args);
+        return result;
+    }
+    jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz,
+                                    jmethodID methodID, va_list args) {
+        return functions->CallNonvirtualLongMethodV(this,obj,clazz,
+                                                    methodID,args);
+    }
+    jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz,
+                                    jmethodID methodID, const jvalue * args) {
+        return functions->CallNonvirtualLongMethodA(this,obj,clazz,
+                                                    methodID,args);
+    }
+
+    jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz,
+                                     jmethodID methodID, ...) {
+        va_list args;
+        jfloat result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualFloatMethodV(this,obj,clazz,
+                                                       methodID,args);
+        va_end(args);
+        return result;
+    }
+    jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz,
+                                      jmethodID methodID,
+                                      va_list args) {
+        return functions->CallNonvirtualFloatMethodV(this,obj,clazz,
+                                                     methodID,args);
+    }
+    jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz,
+                                      jmethodID methodID,
+                                      const jvalue * args) {
+        return functions->CallNonvirtualFloatMethodA(this,obj,clazz,
+                                                     methodID,args);
+    }
+
+    jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz,
+                                       jmethodID methodID, ...) {
+        va_list args;
+        jdouble result;
+        va_start(args,methodID);
+        result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz,
+                                                        methodID,args);
+        va_end(args);
+        return result;
+    }
+    jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz,
+                                        jmethodID methodID,
+                                        va_list args) {
+        return functions->CallNonvirtualDoubleMethodV(this,obj,clazz,
+                                                      methodID,args);
+    }
+    jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz,
+                                        jmethodID methodID,
+                                        const jvalue * args) {
+        return functions->CallNonvirtualDoubleMethodA(this,obj,clazz,
+                                                      methodID,args);
+    }
+
+    void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
+                                  jmethodID methodID, ...) {
+        va_list args;
+        va_start(args,methodID);
+        functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args);
+        va_end(args);
+    }
+    void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
+                                   jmethodID methodID,
+                                   va_list args) {
+        functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args);
+    }
+    void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
+                                   jmethodID methodID,
+                                   const jvalue * args) {
+        functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args);
+    }
+
+    jfieldID GetFieldID(jclass clazz, const char *name,
+                        const char *sig) {
+        return functions->GetFieldID(this,clazz,name,sig);
+    }
+
+    jobject GetObjectField(jobject obj, jfieldID fieldID) {
+        return functions->GetObjectField(this,obj,fieldID);
+    }
+    jboolean GetBooleanField(jobject obj, jfieldID fieldID) {
+        return functions->GetBooleanField(this,obj,fieldID);
+    }
+    jbyte GetByteField(jobject obj, jfieldID fieldID) {
+        return functions->GetByteField(this,obj,fieldID);
+    }
+    jchar GetCharField(jobject obj, jfieldID fieldID) {
+        return functions->GetCharField(this,obj,fieldID);
+    }
+    jshort GetShortField(jobject obj, jfieldID fieldID) {
+        return functions->GetShortField(this,obj,fieldID);
+    }
+    jint GetIntField(jobject obj, jfieldID fieldID) {
+        return functions->GetIntField(this,obj,fieldID);
+    }
+    jlong GetLongField(jobject obj, jfieldID fieldID) {
+        return functions->GetLongField(this,obj,fieldID);
+    }
+    jfloat GetFloatField(jobject obj, jfieldID fieldID) {
+        return functions->GetFloatField(this,obj,fieldID);
+    }
+    jdouble GetDoubleField(jobject obj, jfieldID fieldID) {
+        return functions->GetDoubleField(this,obj,fieldID);
+    }
+
+    void SetObjectField(jobject obj, jfieldID fieldID, jobject val) {
+        functions->SetObjectField(this,obj,fieldID,val);
+    }
+    void SetBooleanField(jobject obj, jfieldID fieldID,
+                         jboolean val) {
+        functions->SetBooleanField(this,obj,fieldID,val);
+    }
+    void SetByteField(jobject obj, jfieldID fieldID,
+                      jbyte val) {
+        functions->SetByteField(this,obj,fieldID,val);
+    }
+    void SetCharField(jobject obj, jfieldID fieldID,
+                      jchar val) {
+        functions->SetCharField(this,obj,fieldID,val);
+    }
+    void SetShortField(jobject obj, jfieldID fieldID,
+                       jshort val) {
+        functions->SetShortField(this,obj,fieldID,val);
+    }
+    void SetIntField(jobject obj, jfieldID fieldID,
+                     jint val) {
+        functions->SetIntField(this,obj,fieldID,val);
+    }
+    void SetLongField(jobject obj, jfieldID fieldID,
+                      jlong val) {
+        functions->SetLongField(this,obj,fieldID,val);
+    }
+    void SetFloatField(jobject obj, jfieldID fieldID,
+                       jfloat val) {
+        functions->SetFloatField(this,obj,fieldID,val);
+    }
+    void SetDoubleField(jobject obj, jfieldID fieldID,
+                        jdouble val) {
+        functions->SetDoubleField(this,obj,fieldID,val);
+    }
+
+    jmethodID GetStaticMethodID(jclass clazz, const char *name,
+                                const char *sig) {
+        return functions->GetStaticMethodID(this,clazz,name,sig);
+    }
+
+    jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID,
+                             ...) {
+        va_list args;
+        jobject result;
+        va_start(args,methodID);
+        result = functions->CallStaticObjectMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID,
+                              va_list args) {
+        return functions->CallStaticObjectMethodV(this,clazz,methodID,args);
+    }
+    jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID,
+                              const jvalue *args) {
+        return functions->CallStaticObjectMethodA(this,clazz,methodID,args);
+    }
+
+    jboolean CallStaticBooleanMethod(jclass clazz,
+                                     jmethodID methodID, ...) {
+        va_list args;
+        jboolean result;
+        va_start(args,methodID);
+        result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jboolean CallStaticBooleanMethodV(jclass clazz,
+                                      jmethodID methodID, va_list args) {
+        return functions->CallStaticBooleanMethodV(this,clazz,methodID,args);
+    }
+    jboolean CallStaticBooleanMethodA(jclass clazz,
+                                      jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticBooleanMethodA(this,clazz,methodID,args);
+    }
+
+    jbyte CallStaticByteMethod(jclass clazz,
+                               jmethodID methodID, ...) {
+        va_list args;
+        jbyte result;
+        va_start(args,methodID);
+        result = functions->CallStaticByteMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jbyte CallStaticByteMethodV(jclass clazz,
+                                jmethodID methodID, va_list args) {
+        return functions->CallStaticByteMethodV(this,clazz,methodID,args);
+    }
+    jbyte CallStaticByteMethodA(jclass clazz,
+                                jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticByteMethodA(this,clazz,methodID,args);
+    }
+
+    jchar CallStaticCharMethod(jclass clazz,
+                               jmethodID methodID, ...) {
+        va_list args;
+        jchar result;
+        va_start(args,methodID);
+        result = functions->CallStaticCharMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jchar CallStaticCharMethodV(jclass clazz,
+                                jmethodID methodID, va_list args) {
+        return functions->CallStaticCharMethodV(this,clazz,methodID,args);
+    }
+    jchar CallStaticCharMethodA(jclass clazz,
+                                jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticCharMethodA(this,clazz,methodID,args);
+    }
+
+    jshort CallStaticShortMethod(jclass clazz,
+                                 jmethodID methodID, ...) {
+        va_list args;
+        jshort result;
+        va_start(args,methodID);
+        result = functions->CallStaticShortMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jshort CallStaticShortMethodV(jclass clazz,
+                                  jmethodID methodID, va_list args) {
+        return functions->CallStaticShortMethodV(this,clazz,methodID,args);
+    }
+    jshort CallStaticShortMethodA(jclass clazz,
+                                  jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticShortMethodA(this,clazz,methodID,args);
+    }
+
+    jint CallStaticIntMethod(jclass clazz,
+                             jmethodID methodID, ...) {
+        va_list args;
+        jint result;
+        va_start(args,methodID);
+        result = functions->CallStaticIntMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jint CallStaticIntMethodV(jclass clazz,
+                              jmethodID methodID, va_list args) {
+        return functions->CallStaticIntMethodV(this,clazz,methodID,args);
+    }
+    jint CallStaticIntMethodA(jclass clazz,
+                              jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticIntMethodA(this,clazz,methodID,args);
+    }
+
+    jlong CallStaticLongMethod(jclass clazz,
+                               jmethodID methodID, ...) {
+        va_list args;
+        jlong result;
+        va_start(args,methodID);
+        result = functions->CallStaticLongMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jlong CallStaticLongMethodV(jclass clazz,
+                                jmethodID methodID, va_list args) {
+        return functions->CallStaticLongMethodV(this,clazz,methodID,args);
+    }
+    jlong CallStaticLongMethodA(jclass clazz,
+                                jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticLongMethodA(this,clazz,methodID,args);
+    }
+
+    jfloat CallStaticFloatMethod(jclass clazz,
+                                 jmethodID methodID, ...) {
+        va_list args;
+        jfloat result;
+        va_start(args,methodID);
+        result = functions->CallStaticFloatMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jfloat CallStaticFloatMethodV(jclass clazz,
+                                  jmethodID methodID, va_list args) {
+        return functions->CallStaticFloatMethodV(this,clazz,methodID,args);
+    }
+    jfloat CallStaticFloatMethodA(jclass clazz,
+                                  jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticFloatMethodA(this,clazz,methodID,args);
+    }
+
+    jdouble CallStaticDoubleMethod(jclass clazz,
+                                   jmethodID methodID, ...) {
+        va_list args;
+        jdouble result;
+        va_start(args,methodID);
+        result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args);
+        va_end(args);
+        return result;
+    }
+    jdouble CallStaticDoubleMethodV(jclass clazz,
+                                    jmethodID methodID, va_list args) {
+        return functions->CallStaticDoubleMethodV(this,clazz,methodID,args);
+    }
+    jdouble CallStaticDoubleMethodA(jclass clazz,
+                                    jmethodID methodID, const jvalue *args) {
+        return functions->CallStaticDoubleMethodA(this,clazz,methodID,args);
+    }
+
+    void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) {
+        va_list args;
+        va_start(args,methodID);
+        functions->CallStaticVoidMethodV(this,cls,methodID,args);
+        va_end(args);
+    }
+    void CallStaticVoidMethodV(jclass cls, jmethodID methodID,
+                               va_list args) {
+        functions->CallStaticVoidMethodV(this,cls,methodID,args);
+    }
+    void CallStaticVoidMethodA(jclass cls, jmethodID methodID,
+                               const jvalue * args) {
+        functions->CallStaticVoidMethodA(this,cls,methodID,args);
+    }
+
+    jfieldID GetStaticFieldID(jclass clazz, const char *name,
+                              const char *sig) {
+        return functions->GetStaticFieldID(this,clazz,name,sig);
+    }
+    jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticObjectField(this,clazz,fieldID);
+    }
+    jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticBooleanField(this,clazz,fieldID);
+    }
+    jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticByteField(this,clazz,fieldID);
+    }
+    jchar GetStaticCharField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticCharField(this,clazz,fieldID);
+    }
+    jshort GetStaticShortField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticShortField(this,clazz,fieldID);
+    }
+    jint GetStaticIntField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticIntField(this,clazz,fieldID);
+    }
+    jlong GetStaticLongField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticLongField(this,clazz,fieldID);
+    }
+    jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticFloatField(this,clazz,fieldID);
+    }
+    jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) {
+        return functions->GetStaticDoubleField(this,clazz,fieldID);
+    }
+
+    void SetStaticObjectField(jclass clazz, jfieldID fieldID,
+                        jobject value) {
+      functions->SetStaticObjectField(this,clazz,fieldID,value);
+    }
+    void SetStaticBooleanField(jclass clazz, jfieldID fieldID,
+                        jboolean value) {
+      functions->SetStaticBooleanField(this,clazz,fieldID,value);
+    }
+    void SetStaticByteField(jclass clazz, jfieldID fieldID,
+                        jbyte value) {
+      functions->SetStaticByteField(this,clazz,fieldID,value);
+    }
+    void SetStaticCharField(jclass clazz, jfieldID fieldID,
+                        jchar value) {
+      functions->SetStaticCharField(this,clazz,fieldID,value);
+    }
+    void SetStaticShortField(jclass clazz, jfieldID fieldID,
+                        jshort value) {
+      functions->SetStaticShortField(this,clazz,fieldID,value);
+    }
+    void SetStaticIntField(jclass clazz, jfieldID fieldID,
+                        jint value) {
+      functions->SetStaticIntField(this,clazz,fieldID,value);
+    }
+    void SetStaticLongField(jclass clazz, jfieldID fieldID,
+                        jlong value) {
+      functions->SetStaticLongField(this,clazz,fieldID,value);
+    }
+    void SetStaticFloatField(jclass clazz, jfieldID fieldID,
+                        jfloat value) {
+      functions->SetStaticFloatField(this,clazz,fieldID,value);
+    }
+    void SetStaticDoubleField(jclass clazz, jfieldID fieldID,
+                        jdouble value) {
+      functions->SetStaticDoubleField(this,clazz,fieldID,value);
+    }
+
+    jstring NewString(const jchar *unicode, jsize len) {
+        return functions->NewString(this,unicode,len);
+    }
+    jsize GetStringLength(jstring str) {
+        return functions->GetStringLength(this,str);
+    }
+    const jchar *GetStringChars(jstring str, jboolean *isCopy) {
+        return functions->GetStringChars(this,str,isCopy);
+    }
+    void ReleaseStringChars(jstring str, const jchar *chars) {
+        functions->ReleaseStringChars(this,str,chars);
+    }
+
+    jstring NewStringUTF(const char *utf) {
+        return functions->NewStringUTF(this,utf);
+    }
+    jsize GetStringUTFLength(jstring str) {
+        return functions->GetStringUTFLength(this,str);
+    }
+    const char* GetStringUTFChars(jstring str, jboolean *isCopy) {
+        return functions->GetStringUTFChars(this,str,isCopy);
+    }
+    void ReleaseStringUTFChars(jstring str, const char* chars) {
+        functions->ReleaseStringUTFChars(this,str,chars);
+    }
+
+    jsize GetArrayLength(jarray array) {
+        return functions->GetArrayLength(this,array);
+    }
+
+    jobjectArray NewObjectArray(jsize len, jclass clazz,
+                                jobject init) {
+        return functions->NewObjectArray(this,len,clazz,init);
+    }
+    jobject GetObjectArrayElement(jobjectArray array, jsize index) {
+        return functions->GetObjectArrayElement(this,array,index);
+    }
+    void SetObjectArrayElement(jobjectArray array, jsize index,
+                               jobject val) {
+        functions->SetObjectArrayElement(this,array,index,val);
+    }
+
+    jbooleanArray NewBooleanArray(jsize len) {
+        return functions->NewBooleanArray(this,len);
+    }
+    jbyteArray NewByteArray(jsize len) {
+        return functions->NewByteArray(this,len);
+    }
+    jcharArray NewCharArray(jsize len) {
+        return functions->NewCharArray(this,len);
+    }
+    jshortArray NewShortArray(jsize len) {
+        return functions->NewShortArray(this,len);
+    }
+    jintArray NewIntArray(jsize len) {
+        return functions->NewIntArray(this,len);
+    }
+    jlongArray NewLongArray(jsize len) {
+        return functions->NewLongArray(this,len);
+    }
+    jfloatArray NewFloatArray(jsize len) {
+        return functions->NewFloatArray(this,len);
+    }
+    jdoubleArray NewDoubleArray(jsize len) {
+        return functions->NewDoubleArray(this,len);
+    }
+
+    jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) {
+        return functions->GetBooleanArrayElements(this,array,isCopy);
+    }
+    jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) {
+        return functions->GetByteArrayElements(this,array,isCopy);
+    }
+    jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) {
+        return functions->GetCharArrayElements(this,array,isCopy);
+    }
+    jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) {
+        return functions->GetShortArrayElements(this,array,isCopy);
+    }
+    jint * GetIntArrayElements(jintArray array, jboolean *isCopy) {
+        return functions->GetIntArrayElements(this,array,isCopy);
+    }
+    jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) {
+        return functions->GetLongArrayElements(this,array,isCopy);
+    }
+    jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) {
+        return functions->GetFloatArrayElements(this,array,isCopy);
+    }
+    jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) {
+        return functions->GetDoubleArrayElements(this,array,isCopy);
+    }
+
+    void ReleaseBooleanArrayElements(jbooleanArray array,
+                                     jboolean *elems,
+                                     jint mode) {
+        functions->ReleaseBooleanArrayElements(this,array,elems,mode);
+    }
+    void ReleaseByteArrayElements(jbyteArray array,
+                                  jbyte *elems,
+                                  jint mode) {
+        functions->ReleaseByteArrayElements(this,array,elems,mode);
+    }
+    void ReleaseCharArrayElements(jcharArray array,
+                                  jchar *elems,
+                                  jint mode) {
+        functions->ReleaseCharArrayElements(this,array,elems,mode);
+    }
+    void ReleaseShortArrayElements(jshortArray array,
+                                   jshort *elems,
+                                   jint mode) {
+        functions->ReleaseShortArrayElements(this,array,elems,mode);
+    }
+    void ReleaseIntArrayElements(jintArray array,
+                                 jint *elems,
+                                 jint mode) {
+        functions->ReleaseIntArrayElements(this,array,elems,mode);
+    }
+    void ReleaseLongArrayElements(jlongArray array,
+                                  jlong *elems,
+                                  jint mode) {
+        functions->ReleaseLongArrayElements(this,array,elems,mode);
+    }
+    void ReleaseFloatArrayElements(jfloatArray array,
+                                   jfloat *elems,
+                                   jint mode) {
+        functions->ReleaseFloatArrayElements(this,array,elems,mode);
+    }
+    void ReleaseDoubleArrayElements(jdoubleArray array,
+                                    jdouble *elems,
+                                    jint mode) {
+        functions->ReleaseDoubleArrayElements(this,array,elems,mode);
+    }
+
+    void GetBooleanArrayRegion(jbooleanArray array,
+                               jsize start, jsize len, jboolean *buf) {
+        functions->GetBooleanArrayRegion(this,array,start,len,buf);
+    }
+    void GetByteArrayRegion(jbyteArray array,
+                            jsize start, jsize len, jbyte *buf) {
+        functions->GetByteArrayRegion(this,array,start,len,buf);
+    }
+    void GetCharArrayRegion(jcharArray array,
+                            jsize start, jsize len, jchar *buf) {
+        functions->GetCharArrayRegion(this,array,start,len,buf);
+    }
+    void GetShortArrayRegion(jshortArray array,
+                             jsize start, jsize len, jshort *buf) {
+        functions->GetShortArrayRegion(this,array,start,len,buf);
+    }
+    void GetIntArrayRegion(jintArray array,
+                           jsize start, jsize len, jint *buf) {
+        functions->GetIntArrayRegion(this,array,start,len,buf);
+    }
+    void GetLongArrayRegion(jlongArray array,
+                            jsize start, jsize len, jlong *buf) {
+        functions->GetLongArrayRegion(this,array,start,len,buf);
+    }
+    void GetFloatArrayRegion(jfloatArray array,
+                             jsize start, jsize len, jfloat *buf) {
+        functions->GetFloatArrayRegion(this,array,start,len,buf);
+    }
+    void GetDoubleArrayRegion(jdoubleArray array,
+                              jsize start, jsize len, jdouble *buf) {
+        functions->GetDoubleArrayRegion(this,array,start,len,buf);
+    }
+
+    void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
+                               const jboolean *buf) {
+        functions->SetBooleanArrayRegion(this,array,start,len,buf);
+    }
+    void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
+                            const jbyte *buf) {
+        functions->SetByteArrayRegion(this,array,start,len,buf);
+    }
+    void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
+                            const jchar *buf) {
+        functions->SetCharArrayRegion(this,array,start,len,buf);
+    }
+    void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
+                             const jshort *buf) {
+        functions->SetShortArrayRegion(this,array,start,len,buf);
+    }
+    void SetIntArrayRegion(jintArray array, jsize start, jsize len,
+                           const jint *buf) {
+        functions->SetIntArrayRegion(this,array,start,len,buf);
+    }
+    void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
+                            const jlong *buf) {
+        functions->SetLongArrayRegion(this,array,start,len,buf);
+    }
+    void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
+                             const jfloat *buf) {
+        functions->SetFloatArrayRegion(this,array,start,len,buf);
+    }
+    void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
+                              const jdouble *buf) {
+        functions->SetDoubleArrayRegion(this,array,start,len,buf);
+    }
+
+    jint RegisterNatives(jclass clazz, const JNINativeMethod *methods,
+                         jint nMethods) {
+        return functions->RegisterNatives(this,clazz,methods,nMethods);
+    }
+    jint UnregisterNatives(jclass clazz) {
+        return functions->UnregisterNatives(this,clazz);
+    }
+
+    jint MonitorEnter(jobject obj) {
+        return functions->MonitorEnter(this,obj);
+    }
+    jint MonitorExit(jobject obj) {
+        return functions->MonitorExit(this,obj);
+    }
+
+    jint GetJavaVM(JavaVM **vm) {
+        return functions->GetJavaVM(this,vm);
+    }
+
+    void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) {
+        functions->GetStringRegion(this,str,start,len,buf);
+    }
+    void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) {
+        functions->GetStringUTFRegion(this,str,start,len,buf);
+    }
+
+    void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) {
+        return functions->GetPrimitiveArrayCritical(this,array,isCopy);
+    }
+    void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) {
+        functions->ReleasePrimitiveArrayCritical(this,array,carray,mode);
+    }
+
+    const jchar * GetStringCritical(jstring string, jboolean *isCopy) {
+        return functions->GetStringCritical(this,string,isCopy);
+    }
+    void ReleaseStringCritical(jstring string, const jchar *cstring) {
+        functions->ReleaseStringCritical(this,string,cstring);
+    }
+
+    jweak NewWeakGlobalRef(jobject obj) {
+        return functions->NewWeakGlobalRef(this,obj);
+    }
+    void DeleteWeakGlobalRef(jweak ref) {
+        functions->DeleteWeakGlobalRef(this,ref);
+    }
+
+    jboolean ExceptionCheck() {
+        return functions->ExceptionCheck(this);
+    }
+
+    jobject NewDirectByteBuffer(void* address, jlong capacity) {
+        return functions->NewDirectByteBuffer(this, address, capacity);
+    }
+    void* GetDirectBufferAddress(jobject buf) {
+        return functions->GetDirectBufferAddress(this, buf);
+    }
+    jlong GetDirectBufferCapacity(jobject buf) {
+        return functions->GetDirectBufferCapacity(this, buf);
+    }
+    jobjectRefType GetObjectRefType(jobject obj) {
+        return functions->GetObjectRefType(this, obj);
+    }
+
+#endif /* __cplusplus */
+};
+
+typedef struct JavaVMOption {
+    char *optionString;
+    void *extraInfo;
+} JavaVMOption;
+
+typedef struct JavaVMInitArgs {
+    jint version;
+
+    jint nOptions;
+    JavaVMOption *options;
+    jboolean ignoreUnrecognized;
+} JavaVMInitArgs;
+
+typedef struct JavaVMAttachArgs {
+    jint version;
+
+    char *name;
+    jobject group;
+} JavaVMAttachArgs;
+
+/* These will be VM-specific. */
+
+#define JDK1_2
+#define JDK1_4
+
+/* End VM-specific. */
+
+struct JNIInvokeInterface_ {
+    void *reserved0;
+    void *reserved1;
+    void *reserved2;
+
+    jint (JNICALL *DestroyJavaVM)(JavaVM *vm);
+
+    jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args);
+
+    jint (JNICALL *DetachCurrentThread)(JavaVM *vm);
+
+    jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version);
+
+    jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args);
+};
+
+struct JavaVM_ {
+    const struct JNIInvokeInterface_ *functions;
+#ifdef __cplusplus
+
+    jint DestroyJavaVM() {
+        return functions->DestroyJavaVM(this);
+    }
+    jint AttachCurrentThread(void **penv, void *args) {
+        return functions->AttachCurrentThread(this, penv, args);
+    }
+    jint DetachCurrentThread() {
+        return functions->DetachCurrentThread(this);
+    }
+
+    jint GetEnv(void **penv, jint version) {
+        return functions->GetEnv(this, penv, version);
+    }
+    jint AttachCurrentThreadAsDaemon(void **penv, void *args) {
+        return functions->AttachCurrentThreadAsDaemon(this, penv, args);
+    }
+#endif
+};
+
+#ifdef _JNI_IMPLEMENTATION_
+#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT
+#else
+#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT
+#endif
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL
+JNI_GetDefaultJavaVMInitArgs(void *args);
+
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL
+JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
+
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL
+JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
+
+/* Defined by native libraries. */
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *vm, void *reserved);
+
+JNIEXPORT void JNICALL
+JNI_OnUnload(JavaVM *vm, void *reserved);
+
+#define JNI_VERSION_1_1 0x00010001
+#define JNI_VERSION_1_2 0x00010002
+#define JNI_VERSION_1_4 0x00010004
+#define JNI_VERSION_1_6 0x00010006
+#define JNI_VERSION_1_8 0x00010008
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* !_JAVASOFT_JNI_H_ */
diff --git a/java/arm-linux/linux/jni_md.h b/java/arm-linux/linux/jni_md.h
new file mode 100644
index 0000000..80eedf3
--- /dev/null
+++ b/java/arm-linux/linux/jni_md.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVASOFT_JNI_MD_H_
+#define _JAVASOFT_JNI_MD_H_
+
+#ifndef __has_attribute
+  #define __has_attribute(x) 0
+#endif
+#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
+  #define JNIEXPORT     __attribute__((visibility("default")))
+  #define JNIIMPORT     __attribute__((visibility("default")))
+#else
+  #define JNIEXPORT
+  #define JNIIMPORT
+#endif
+
+#define JNICALL
+
+typedef int jint;
+#ifdef _LP64 /* 64-bit Solaris */
+typedef long jlong;
+#else
+typedef long long jlong;
+#endif
+
+typedef signed char jbyte;
+
+#endif /* !_JAVASOFT_JNI_MD_H_ */
diff --git a/java/java.gradle b/java/java.gradle
new file mode 100644
index 0000000..8ff6a7b
--- /dev/null
+++ b/java/java.gradle
@@ -0,0 +1,134 @@
+import org.gradle.internal.os.OperatingSystem
+
+apply plugin: 'java'
+
+def generatedJNIHeaderLoc = '../build/include'
+
+sourceSets {
+    main {
+        java {
+            srcDirs = ['../java/src']
+        }
+    }
+}
+
+jar {
+    description = 'Generates NetworkTables jar, with the JNI shared libraries embedded'
+    baseName = 'ntcore'
+    classifier = "$buildPlatform"
+
+    dependsOn { classes }
+    binaries.withType(SharedLibraryBinary) { binary ->
+        from(file(binary.sharedLibraryFile)) {
+            into getPlatformPath(binary)
+        }
+    }
+}
+
+project.tasks.whenTaskAdded { task-> 
+    if (isArm) {
+        if (task.name == 'ntcoreSharedLibrary') jar.dependsOn task
+    } else {
+        if (task.name == 'x64NtcoreSharedLibrary' || task.name == 'x86NtcoreSharedLibrary') 
+            jar.dependsOn task
+    }
+}
+
+task networktablesJavaSource(type: Jar, dependsOn: classes) {
+    description = 'Generates the source jar for NetworkTables java'
+    group = 'WPILib'
+    baseName = 'ntcore'
+    classifier = "sources"
+    from sourceSets.main.allJava
+}
+
+task networktablesJavadoc(type: Jar, dependsOn: javadoc) {
+    description = 'Generates the javadoc jar for NetworkTables java'
+    group = 'WPILib'
+    baseName = 'ntcore'
+    classifier = "javadoc"
+    from javadoc.destinationDir
+}
+
+build.dependsOn networktablesJavaSource
+build.dependsOn networktablesJavadoc
+
+/**
+ * Generates the JNI headers
+ */
+task jniHeadersNetworkTables {
+    description = 'Generates JNI headers from edu.wpi.first.wpilibj.networktables.*'
+    group = 'WPILib'
+    def outputFolder = file(generatedJNIHeaderLoc)
+    inputs.files sourceSets.main.output
+    outputs.file outputFolder
+    doLast {
+        outputFolder.mkdirs()
+        exec {
+            executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah')
+            args '-d', outputFolder
+            args '-classpath', sourceSets.main.output.classesDir
+            args 'edu.wpi.first.wpilibj.networktables.NetworkTablesJNI'
+        }
+    }
+}
+
+clean {
+    delete generatedJNIHeaderLoc
+}
+
+compileJava {
+    options.compilerArgs << '-Xlint:unchecked'
+}
+
+javadoc {
+    options.addStringOption('Xdoclint:none', '-quiet')
+}
+
+// This creates a lambda that the main build.gradle can access, which sets up the JNI includes for the
+// target build platform. This lambda is exposed as a property in the main build.gradle.
+ext.setupJniIncludes = { binaries ->
+    def platformSpecificIncludeFlag = { loc, cppCompiler ->
+        if (OperatingSystem.current().isWindows()) {
+            cppCompiler.args "/I$loc"
+        } else {
+            cppCompiler.args '-I', loc
+        }
+    }
+    binaries.all {
+        tasks.withType(CppCompile) {
+            if (buildPlatform == 'arm') {
+                cppCompiler.args '-I', file('../java/arm-linux').absolutePath
+                cppCompiler.args '-I', file('../java/arm-linux/linux').absolutePath
+            } else {
+                def jdkLocation = org.gradle.internal.jvm.Jvm.current().javaHome
+                platformSpecificIncludeFlag("${jdkLocation}/include", cppCompiler)
+
+                if (targetPlatform.operatingSystem.macOsX) {
+                    platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler)
+                } else if (targetPlatform.operatingSystem.linux) {
+                    platformSpecificIncludeFlag("${jdkLocation}/include/linux", cppCompiler)
+                } else if (targetPlatform.operatingSystem.windows) {
+                    platformSpecificIncludeFlag("${jdkLocation}/include/win32", cppCompiler)
+                } else if (targetPlatform.operatingSystem.freeBSD) {
+                    platformSpecificIncludeFlag("${jdkLocation}/include/freebsd", cppCompiler)
+                } else if (file("$jdkLocation/include/darwin").exists()) {
+                    // TODO: As of Gradle 2.8, targetPlatform.operatingSystem.macOsX returns false
+                    // on El Capitan. We therefore manually test for the darwin folder and include it
+                    // if it exists
+                    platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler)
+                }
+            }
+
+            jniHeadersNetworkTables.outputs.files.each { file ->
+                if (buildPlatform == 'arm') {
+                    cppCompiler.args '-I', file.getPath()
+                } else {
+                    platformSpecificIncludeFlag(file.getPath(), cppCompiler)
+                }
+            }
+
+            dependsOn jniHeadersNetworkTables
+        }
+    }
+}
diff --git a/java/lib/NetworkTablesJNI.cpp b/java/lib/NetworkTablesJNI.cpp
new file mode 100644
index 0000000..d235fd3
--- /dev/null
+++ b/java/lib/NetworkTablesJNI.cpp
@@ -0,0 +1,1454 @@
+#include <jni.h>
+#include <atomic>
+#include <cassert>
+#include <condition_variable>
+#include <mutex>
+#include <sstream>
+#include <queue>
+#include <thread>
+
+#include "edu_wpi_first_wpilibj_networktables_NetworkTablesJNI.h"
+#include "ntcore.h"
+#include "atomic_static.h"
+
+//
+// Globals and load/unload
+//
+
+// Used for callback.
+static JavaVM *jvm = nullptr;
+static jclass booleanCls = nullptr;
+static jclass doubleCls = nullptr;
+static jclass stringCls = nullptr;
+static jclass connectionInfoCls = nullptr;
+static jclass entryInfoCls = nullptr;
+static jclass keyNotDefinedEx = nullptr;
+static jclass persistentEx = nullptr;
+// Thread-attached environment for listener callbacks.
+static JNIEnv *listenerEnv = nullptr;
+
+static void ListenerOnStart() {
+  if (!jvm) return;
+  JNIEnv *env;
+  if (jvm->AttachCurrentThread(reinterpret_cast<void **>(&env),
+                               nullptr) != JNI_OK)
+    return;
+  if (!env || !env->functions) return;
+  listenerEnv = env;
+}
+
+static void ListenerOnExit() {
+  listenerEnv = nullptr;
+  if (!jvm) return;
+  jvm->DetachCurrentThread();
+}
+
+extern "C" {
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+  jvm = vm;
+
+  JNIEnv *env;
+  if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK)
+    return JNI_ERR;
+
+  // Cache references to classes
+  jclass local;
+
+  local = env->FindClass("java/lang/Boolean");
+  if (!local) return JNI_ERR;
+  booleanCls = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!booleanCls) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  local = env->FindClass("java/lang/Double");
+  if (!local) return JNI_ERR;
+  doubleCls = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!doubleCls) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  local = env->FindClass("java/lang/String");
+  if (!local) return JNI_ERR;
+  stringCls = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!stringCls) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  local = env->FindClass("edu/wpi/first/wpilibj/networktables/ConnectionInfo");
+  if (!local) return JNI_ERR;
+  connectionInfoCls = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!connectionInfoCls) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  local = env->FindClass("edu/wpi/first/wpilibj/networktables/EntryInfo");
+  if (!local) return JNI_ERR;
+  entryInfoCls = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!entryInfoCls) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  local =
+      env->FindClass("edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined");
+  keyNotDefinedEx = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!keyNotDefinedEx) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  local =
+      env->FindClass("edu/wpi/first/wpilibj/networktables/PersistentException");
+  persistentEx = static_cast<jclass>(env->NewGlobalRef(local));
+  if (!persistentEx) return JNI_ERR;
+  env->DeleteLocalRef(local);
+
+  // Initial configuration of listener start/exit
+  nt::SetListenerOnStart(ListenerOnStart);
+  nt::SetListenerOnExit(ListenerOnExit);
+
+  return JNI_VERSION_1_6;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
+  JNIEnv *env;
+  if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK)
+    return;
+  // Delete global references
+  if (booleanCls) env->DeleteGlobalRef(booleanCls);
+  if (doubleCls) env->DeleteGlobalRef(doubleCls);
+  if (stringCls) env->DeleteGlobalRef(stringCls);
+  if (connectionInfoCls) env->DeleteGlobalRef(connectionInfoCls);
+  if (entryInfoCls) env->DeleteGlobalRef(entryInfoCls);
+  if (keyNotDefinedEx) env->DeleteGlobalRef(keyNotDefinedEx);
+  if (persistentEx) env->DeleteGlobalRef(persistentEx);
+  jvm = nullptr;
+}
+
+}  // extern "C"
+
+//
+// Helper class to automatically clean up a local reference
+//
+template <typename T>
+class JavaLocal {
+ public:
+  JavaLocal(JNIEnv *env, T obj) : m_env(env), m_obj(obj) {}
+  ~JavaLocal() {
+    if (m_obj) m_env->DeleteLocalRef(m_obj);
+  }
+  operator T() { return m_obj; }
+  T obj() { return m_obj; }
+
+ private:
+  JNIEnv *m_env;
+  T m_obj;
+};
+
+//
+// Helper class to create and clean up a global reference
+//
+template <typename T>
+class JavaGlobal {
+ public:
+  JavaGlobal(JNIEnv *env, T obj)
+      : m_obj(static_cast<T>(env->NewGlobalRef(obj))) {}
+  ~JavaGlobal() {
+    if (!jvm || nt::NotifierDestroyed()) return;
+    JNIEnv *env;
+    if (jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr) !=
+        JNI_OK)
+      return;
+    if (!env || !env->functions) return;
+    env->DeleteGlobalRef(m_obj);
+    jvm->DetachCurrentThread();
+  }
+  operator T() { return m_obj; }
+  T obj() { return m_obj; }
+
+ private:
+  T m_obj;
+};
+
+//
+// Helper class to create and clean up a weak global reference
+//
+template <typename T>
+class JavaWeakGlobal {
+ public:
+  JavaWeakGlobal(JNIEnv *env, T obj)
+      : m_obj(static_cast<T>(env->NewWeakGlobalRef(obj))) {}
+  ~JavaWeakGlobal() {
+    if (!jvm || nt::NotifierDestroyed()) return;
+    JNIEnv *env;
+    if (jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr) !=
+        JNI_OK)
+      return;
+    if (!env || !env->functions) return;
+    env->DeleteWeakGlobalRef(m_obj);
+    jvm->DetachCurrentThread();
+  }
+  JavaLocal<T> obj(JNIEnv *env) {
+    return JavaLocal<T>(env, env->NewLocalRef(m_obj));
+  }
+
+ private:
+  T m_obj;
+};
+
+//
+// Conversions from Java objects to C++
+//
+
+class JavaStringRef {
+ public:
+  JavaStringRef(JNIEnv *env, jstring str)
+      : m_env(env),
+        m_jstr(str),
+        m_str(env->GetStringUTFChars(str, nullptr)) {}
+  ~JavaStringRef() { m_env->ReleaseStringUTFChars(m_jstr, m_str); }
+
+  operator nt::StringRef() const { return nt::StringRef(m_str); }
+  nt::StringRef str() const { return nt::StringRef(m_str); }
+  const char *c_str() const { return m_str; }
+
+ private:
+  JNIEnv *m_env;
+  jstring m_jstr;
+  const char *m_str;
+};
+
+class JavaByteRef {
+ public:
+  JavaByteRef(JNIEnv *env, jbyteArray jarr)
+      : m_env(env),
+        m_jarr(jarr),
+        m_elements(env->GetByteArrayElements(jarr, nullptr)),
+        m_size(env->GetArrayLength(jarr)) {}
+  ~JavaByteRef() {
+    m_env->ReleaseByteArrayElements(m_jarr, m_elements, JNI_ABORT);
+  }
+
+  operator nt::StringRef() const {
+    return nt::StringRef(reinterpret_cast<char *>(m_elements), m_size);
+  }
+
+ private:
+  JNIEnv *m_env;
+  jbyteArray m_jarr;
+  jbyte *m_elements;
+  size_t m_size;
+};
+
+class JavaByteRefBB {
+ public:
+  JavaByteRefBB(JNIEnv *env, jobject bb, int len)
+      : m_elements(env->GetDirectBufferAddress(bb)), m_size(len) {}
+
+  operator nt::StringRef() const {
+    return nt::StringRef(reinterpret_cast<char *>(m_elements), m_size);
+  }
+
+ private:
+  void *m_elements;
+  size_t m_size;
+};
+
+std::shared_ptr<nt::Value> FromJavaRaw(JNIEnv *env, jbyteArray jarr) {
+  size_t len = env->GetArrayLength(jarr);
+  jbyte *elements =
+      static_cast<jbyte *>(env->GetPrimitiveArrayCritical(jarr, nullptr));
+  if (!elements) return nullptr;
+  auto rv = nt::Value::MakeRaw(
+      nt::StringRef(reinterpret_cast<char *>(elements), len));
+  env->ReleasePrimitiveArrayCritical(jarr, elements, JNI_ABORT);
+  return rv;
+}
+
+std::shared_ptr<nt::Value> FromJavaRawBB(JNIEnv *env, jobject jbb, int len) {
+  void* elements = env->GetDirectBufferAddress(jbb);
+  if (!elements) return nullptr;
+  auto rv = nt::Value::MakeRaw(
+      nt::StringRef(reinterpret_cast<char *>(elements), len));
+  return rv;
+}
+
+std::shared_ptr<nt::Value> FromJavaRpc(JNIEnv *env, jbyteArray jarr) {
+  size_t len = env->GetArrayLength(jarr);
+  jbyte *elements =
+      static_cast<jbyte *>(env->GetPrimitiveArrayCritical(jarr, nullptr));
+  if (!elements) return nullptr;
+  auto rv = nt::Value::MakeRpc(
+      nt::StringRef(reinterpret_cast<char *>(elements), len));
+  env->ReleasePrimitiveArrayCritical(jarr, elements, JNI_ABORT);
+  return rv;
+}
+
+std::shared_ptr<nt::Value> FromJavaBooleanArray(JNIEnv *env,
+                                                jbooleanArray jarr) {
+  size_t len = env->GetArrayLength(jarr);
+  std::vector<int> arr;
+  arr.reserve(len);
+  jboolean *elements =
+      static_cast<jboolean*>(env->GetPrimitiveArrayCritical(jarr, nullptr));
+  if (!elements) return nullptr;
+  for (size_t i = 0; i < len; ++i) arr.push_back(elements[i]);
+  env->ReleasePrimitiveArrayCritical(jarr, elements, JNI_ABORT);
+  return nt::Value::MakeBooleanArray(arr);
+}
+
+std::shared_ptr<nt::Value> FromJavaDoubleArray(JNIEnv *env, jdoubleArray jarr) {
+  size_t len = env->GetArrayLength(jarr);
+  jdouble *elements =
+      static_cast<jdouble *>(env->GetPrimitiveArrayCritical(jarr, nullptr));
+  if (!elements) return nullptr;
+  auto rv = nt::Value::MakeDoubleArray(nt::ArrayRef<double>(elements, len));
+  env->ReleasePrimitiveArrayCritical(jarr, elements, JNI_ABORT);
+  return rv;
+}
+
+std::shared_ptr<nt::Value> FromJavaStringArray(JNIEnv *env, jobjectArray jarr) {
+  size_t len = env->GetArrayLength(jarr);
+  std::vector<std::string> arr;
+  arr.reserve(len);
+  for (size_t i = 0; i < len; ++i) {
+    JavaLocal<jstring> elem(
+        env, static_cast<jstring>(env->GetObjectArrayElement(jarr, i)));
+    if (!elem) return nullptr;
+    arr.push_back(JavaStringRef(env, elem).str());
+  }
+  return nt::Value::MakeStringArray(std::move(arr));
+}
+
+//
+// Conversions from C++ to Java objects
+//
+
+static inline jstring ToJavaString(JNIEnv *env, nt::StringRef str) {
+  // fastpath if string already null terminated; if not, need to make a copy
+  if (str.data()[str.size()] == '\0')
+    return env->NewStringUTF(str.data());
+  else
+    return env->NewStringUTF(str.str().c_str());
+}
+
+static jbyteArray ToJavaByteArray(JNIEnv *env, nt::StringRef str) {
+  jbyteArray jarr = env->NewByteArray(str.size());
+  if (!jarr) return nullptr;
+  env->SetByteArrayRegion(jarr, 0, str.size(),
+                          reinterpret_cast<const jbyte *>(str.data()));
+  return jarr;
+}
+
+static jbooleanArray ToJavaBooleanArray(JNIEnv *env, nt::ArrayRef<int> arr)
+{
+  jbooleanArray jarr = env->NewBooleanArray(arr.size());
+  if (!jarr) return nullptr;
+  jboolean *elements =
+      static_cast<jboolean*>(env->GetPrimitiveArrayCritical(jarr, nullptr));
+  if (!elements) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i)
+    elements[i] = arr[i];
+  env->ReleasePrimitiveArrayCritical(jarr, elements, 0);
+  return jarr;
+}
+
+static jdoubleArray ToJavaDoubleArray(JNIEnv *env, nt::ArrayRef<double> arr)
+{
+  jdoubleArray jarr = env->NewDoubleArray(arr.size());
+  if (!jarr) return nullptr;
+  env->SetDoubleArrayRegion(jarr, 0, arr.size(), arr.data());
+  return jarr;
+}
+
+static jobjectArray ToJavaStringArray(JNIEnv *env,
+                                      nt::ArrayRef<std::string> arr) {
+  jobjectArray jarr = env->NewObjectArray(arr.size(), stringCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JavaLocal<jstring> elem(env, env->NewStringUTF(arr[i].c_str()));
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+
+static jobject ToJavaObject(JNIEnv *env, const nt::Value& value) {
+  static jmethodID booleanConstructor = nullptr;
+  static jmethodID doubleConstructor = nullptr;
+  if (!booleanConstructor)
+    booleanConstructor = env->GetMethodID(booleanCls, "<init>", "(Z)V");
+  if (!doubleConstructor)
+    doubleConstructor = env->GetMethodID(doubleCls, "<init>", "(D)V");
+
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      return env->NewObject(booleanCls, booleanConstructor,
+                            (jboolean)(value.GetBoolean() ? 1 : 0));
+    case NT_DOUBLE:
+      return env->NewObject(doubleCls, doubleConstructor,
+                            (jdouble)value.GetDouble());
+    case NT_STRING:
+      return ToJavaString(env, value.GetString());
+    case NT_RAW:
+      return ToJavaByteArray(env, value.GetRaw());
+    case NT_BOOLEAN_ARRAY:
+      return ToJavaBooleanArray(env, value.GetBooleanArray());
+    case NT_DOUBLE_ARRAY:
+      return ToJavaDoubleArray(env, value.GetDoubleArray());
+    case NT_STRING_ARRAY:
+      return ToJavaStringArray(env, value.GetStringArray());
+    case NT_RPC:
+      return ToJavaByteArray(env, value.GetRpc());
+    default:
+      return nullptr;
+  }
+}
+
+static jobject ToJavaObject(JNIEnv *env, const nt::ConnectionInfo &info) {
+  static jmethodID constructor =
+      env->GetMethodID(connectionInfoCls, "<init>",
+                       "(Ljava/lang/String;Ljava/lang/String;IJI)V");
+  JavaLocal<jstring> remote_id(env, ToJavaString(env, info.remote_id));
+  JavaLocal<jstring> remote_name(env, ToJavaString(env, info.remote_name));
+  return env->NewObject(connectionInfoCls, constructor, remote_id.obj(),
+                        remote_name.obj(), (jint)info.remote_port,
+                        (jlong)info.last_update, (jint)info.protocol_version);
+}
+
+static jobject ToJavaObject(JNIEnv *env, const nt::EntryInfo &info) {
+  static jmethodID constructor =
+      env->GetMethodID(entryInfoCls, "<init>", "(Ljava/lang/String;IIJ)V");
+  JavaLocal<jstring> name(env, ToJavaString(env, info.name));
+  return env->NewObject(entryInfoCls, constructor, name.obj(), (jint)info.type,
+                        (jint)info.flags, (jlong)info.last_change);
+}
+
+//
+// Exception throwers
+//
+
+static void ThrowTableKeyNotDefined(JNIEnv *env, jstring key) {
+  static jmethodID constructor = nullptr;
+  if (!constructor)
+    constructor =
+        env->GetMethodID(keyNotDefinedEx, "<init>", "(Ljava/lang/String;)V");
+  jobject exception = env->NewObject(keyNotDefinedEx, constructor, key);
+  env->Throw(static_cast<jthrowable>(exception));
+}
+
+extern "C" {
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    containsKey
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_containsKey
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val) return false;
+  return true;
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getType
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getType
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val) return NT_UNASSIGNED;
+  return val->type();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putBoolean
+ * Signature: (Ljava/lang/String;Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putBoolean
+  (JNIEnv *env, jclass, jstring key, jboolean value)
+{
+  return nt::SetEntryValue(JavaStringRef(env, key),
+                           nt::Value::MakeBoolean(value != JNI_FALSE));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putDouble
+ * Signature: (Ljava/lang/String;D)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putDouble
+  (JNIEnv *env, jclass, jstring key, jdouble value)
+{
+  return nt::SetEntryValue(JavaStringRef(env, key),
+                           nt::Value::MakeDouble(value));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putString
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putString
+  (JNIEnv *env, jclass, jstring key, jstring value)
+{
+  return nt::SetEntryValue(JavaStringRef(env, key),
+                           nt::Value::MakeString(JavaStringRef(env, value)));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putRaw
+ * Signature: (Ljava/lang/String;[B)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putRaw__Ljava_lang_String_2_3B
+  (JNIEnv *env, jclass, jstring key, jbyteArray value)
+{
+  auto v = FromJavaRaw(env, value);
+  if (!v) return false;
+  return nt::SetEntryValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putRaw
+ * Signature: (Ljava/lang/String;Ljava/nio/ByteBuffer;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putRaw__Ljava_lang_String_2Ljava_nio_ByteBuffer_2I
+  (JNIEnv *env, jclass, jstring key, jobject value, jint len)
+{
+  auto v = FromJavaRawBB(env, value, len);
+  if (!v) return false;
+  return nt::SetEntryValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putBooleanArray
+ * Signature: (Ljava/lang/String;[Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putBooleanArray
+  (JNIEnv *env, jclass, jstring key, jbooleanArray value)
+{
+  auto v = FromJavaBooleanArray(env, value);
+  if (!v) return false;
+  return nt::SetEntryValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putDoubleArray
+ * Signature: (Ljava/lang/String;[D)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putDoubleArray
+  (JNIEnv *env, jclass, jstring key, jdoubleArray value)
+{
+  auto v = FromJavaDoubleArray(env, value);
+  if (!v) return false;
+  return nt::SetEntryValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    putStringArray
+ * Signature: (Ljava/lang/String;[Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putStringArray
+  (JNIEnv *env, jclass, jstring key, jobjectArray value)
+{
+  auto v = FromJavaStringArray(env, value);
+  if (!v) return false;
+  return nt::SetEntryValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutBoolean
+ * Signature: (Ljava/lang/String;Z)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutBoolean
+  (JNIEnv *env, jclass, jstring key, jboolean value)
+{
+  nt::SetEntryTypeValue(JavaStringRef(env, key), nt::Value::MakeBoolean(value != JNI_FALSE));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutDouble
+ * Signature: (Ljava/lang/String;D)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutDouble
+  (JNIEnv *env, jclass, jstring key, jdouble value)
+{
+  nt::SetEntryTypeValue(JavaStringRef(env, key), nt::Value::MakeDouble(value));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutString
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutString
+  (JNIEnv *env, jclass, jstring key, jstring value)
+{
+  nt::SetEntryTypeValue(JavaStringRef(env, key),
+                        nt::Value::MakeString(JavaStringRef(env, value)));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutRaw
+ * Signature: (Ljava/lang/String;[B)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutRaw__Ljava_lang_String_2_3B
+  (JNIEnv *env, jclass, jstring key, jbyteArray value)
+{
+  auto v = FromJavaRaw(env, value);
+  if (!v) return;
+  nt::SetEntryTypeValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutRaw
+ * Signature: (Ljava/lang/String;Ljava/nio/ByteBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutRaw__Ljava_lang_String_2Ljava_nio_ByteBuffer_2I
+  (JNIEnv *env, jclass, jstring key, jobject value, jint len)
+{
+  auto v = FromJavaRawBB(env, value, len);
+  if (!v) return;
+  nt::SetEntryTypeValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutBooleanArray
+ * Signature: (Ljava/lang/String;[Z)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutBooleanArray
+  (JNIEnv *env, jclass, jstring key, jbooleanArray value)
+{
+  auto v = FromJavaBooleanArray(env, value);
+  if (!v) return;
+  nt::SetEntryTypeValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutDoubleArray
+ * Signature: (Ljava/lang/String;[D)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutDoubleArray
+  (JNIEnv *env, jclass, jstring key, jdoubleArray value)
+{
+  auto v = FromJavaDoubleArray(env, value);
+  if (!v) return;
+  nt::SetEntryTypeValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    forcePutStringArray
+ * Signature: (Ljava/lang/String;[Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutStringArray
+  (JNIEnv *env, jclass, jstring key, jobjectArray value)
+{
+  auto v = FromJavaStringArray(env, value);
+  if (!v) return;
+  nt::SetEntryTypeValue(JavaStringRef(env, key), v);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getValue
+ * Signature: (Ljava/lang/String;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getValue__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaObject(env, *val);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getBoolean
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBoolean__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsBoolean()) {
+    ThrowTableKeyNotDefined(env, key);
+    return false;
+  }
+  return val->GetBoolean();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getDouble
+ * Signature: (Ljava/lang/String;)D
+ */
+JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDouble__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsDouble()) {
+    ThrowTableKeyNotDefined(env, key);
+    return 0;
+  }
+  return val->GetDouble();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getString
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getString__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsString()) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaString(env, val->GetString());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getRaw
+ * Signature: (Ljava/lang/String;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRaw__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsRaw()) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaByteArray(env, val->GetRaw());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getBooleanArray
+ * Signature: (Ljava/lang/String;)[Z
+ */
+JNIEXPORT jbooleanArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBooleanArray__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsBooleanArray()) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaBooleanArray(env, val->GetBooleanArray());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getDoubleArray
+ * Signature: (Ljava/lang/String;)[D
+ */
+JNIEXPORT jdoubleArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDoubleArray__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsDoubleArray()) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaDoubleArray(env, val->GetDoubleArray());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getStringArray
+ * Signature: (Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getStringArray__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsStringArray()) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaStringArray(env, val->GetStringArray());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getValue
+ * Signature: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getValue__Ljava_lang_String_2Ljava_lang_Object_2
+  (JNIEnv *env, jclass, jstring key, jobject defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val) return defaultValue;
+  return ToJavaObject(env, *val);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getBoolean
+ * Signature: (Ljava/lang/String;Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBoolean__Ljava_lang_String_2Z
+  (JNIEnv *env, jclass, jstring key, jboolean defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsBoolean()) return defaultValue;
+  return val->GetBoolean();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getDouble
+ * Signature: (Ljava/lang/String;D)D
+ */
+JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDouble__Ljava_lang_String_2D
+  (JNIEnv *env, jclass, jstring key, jdouble defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsDouble()) return defaultValue;
+  return val->GetDouble();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getString
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getString__Ljava_lang_String_2Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key, jstring defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsString()) return defaultValue;
+  return ToJavaString(env, val->GetString());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getRaw
+ * Signature: (Ljava/lang/String;[B)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRaw__Ljava_lang_String_2_3B
+  (JNIEnv *env, jclass, jstring key, jbyteArray defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsRaw()) return defaultValue;
+  return ToJavaByteArray(env, val->GetRaw());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getBooleanArray
+ * Signature: (Ljava/lang/String;[Z)[Z
+ */
+JNIEXPORT jbooleanArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBooleanArray__Ljava_lang_String_2_3Z
+  (JNIEnv *env, jclass, jstring key, jbooleanArray defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsBooleanArray()) return defaultValue;
+  return ToJavaBooleanArray(env, val->GetBooleanArray());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getDoubleArray
+ * Signature: (Ljava/lang/String;[D)[D
+ */
+JNIEXPORT jdoubleArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDoubleArray__Ljava_lang_String_2_3D
+  (JNIEnv *env, jclass, jstring key, jdoubleArray defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsDoubleArray()) return defaultValue;
+  return ToJavaDoubleArray(env, val->GetDoubleArray());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getStringArray
+ * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getStringArray__Ljava_lang_String_2_3Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key, jobjectArray defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsStringArray()) return defaultValue;
+  return ToJavaStringArray(env, val->GetStringArray());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    setEntryFlags
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setEntryFlags
+  (JNIEnv *env, jclass, jstring key, jint flags)
+{
+  nt::SetEntryFlags(JavaStringRef(env, key), flags);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getEntryFlags
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getEntryFlags
+  (JNIEnv *env, jclass, jstring key)
+{
+  return nt::GetEntryFlags(JavaStringRef(env, key));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    deleteEntry
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_deleteEntry
+  (JNIEnv *env, jclass, jstring key)
+{
+  nt::DeleteEntry(JavaStringRef(env, key));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    deleteAllEntries
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_deleteAllEntries
+  (JNIEnv *, jclass)
+{
+  nt::DeleteAllEntries();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getEntries
+ * Signature: (Ljava/lang/String;I)[Ledu/wpi/first/wpilibj/networktables/EntryInfo;
+ */
+JNIEXPORT jobjectArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getEntries
+  (JNIEnv *env, jclass, jstring prefix, jint types)
+{
+  auto arr = nt::GetEntryInfo(JavaStringRef(env, prefix), types);
+  jobjectArray jarr = env->NewObjectArray(arr.size(), entryInfoCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JavaLocal<jobject> jelem(env, ToJavaObject(env, arr[i]));
+    env->SetObjectArrayElement(jarr, i, jelem);
+  }
+  return jarr;
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    flush
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_flush
+  (JNIEnv *, jclass)
+{
+  nt::Flush();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    addEntryListener
+ * Signature: (Ljava/lang/String;Ledu/wpi/first/wpilibj/networktables/NetworkTablesJNI/EntryListenerFunction;Z)I
+ */
+JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_addEntryListener
+  (JNIEnv *envouter, jclass, jstring prefix, jobject listener, jint flags)
+{
+  // the shared pointer to the weak global will keep it around until the
+  // entry listener is destroyed
+  auto listener_global =
+      std::make_shared<JavaGlobal<jobject>>(envouter, listener);
+
+  // cls is a temporary here; cannot be used within callback functor
+	jclass cls = envouter->GetObjectClass(listener);
+  if (!cls) return 0;
+
+  // method ids, on the other hand, are safe to retain
+  jmethodID mid = envouter->GetMethodID(
+      cls, "apply", "(ILjava/lang/String;Ljava/lang/Object;I)V");
+  if (!mid) return 0;
+
+  return nt::AddEntryListener(
+      JavaStringRef(envouter, prefix),
+      [=](unsigned int uid, nt::StringRef name,
+          std::shared_ptr<nt::Value> value, unsigned int flags_) {
+        JNIEnv *env = listenerEnv;
+        if (!env || !env->functions) return;
+
+        // get the handler
+        auto handler = listener_global->obj();
+
+        // convert the value into the appropriate Java type
+        jobject jobj = ToJavaObject(env, *value);
+        if (!jobj) return;
+
+        if (env->ExceptionCheck()) {
+          env->ExceptionDescribe();
+          env->ExceptionClear();
+          return;
+        }
+        env->CallVoidMethod(handler, mid, (jint)uid, ToJavaString(env, name),
+                            jobj, (jint)(flags_));
+        if (env->ExceptionCheck()) {
+          env->ExceptionDescribe();
+          env->ExceptionClear();
+        }
+      },
+      flags);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    removeEntryListener
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_removeEntryListener
+  (JNIEnv *, jclass, jint entryListenerUid)
+{
+  nt::RemoveEntryListener(entryListenerUid);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    addConnectionListener
+ * Signature: (Ledu/wpi/first/wpilibj/networktables/NetworkTablesJNI/ConnectionListenerFunction;Z)I
+ */
+JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_addConnectionListener
+  (JNIEnv *envouter, jclass, jobject listener, jboolean immediateNotify)
+{
+  // the shared pointer to the weak global will keep it around until the
+  // entry listener is destroyed
+  auto listener_global =
+      std::make_shared<JavaGlobal<jobject>>(envouter, listener);
+
+  // cls is a temporary here; cannot be used within callback functor
+	jclass cls = envouter->GetObjectClass(listener);
+  if (!cls) return 0;
+
+  // method ids, on the other hand, are safe to retain
+  jmethodID mid = envouter->GetMethodID(
+      cls, "apply", "(IZLedu/wpi/first/wpilibj/networktables/ConnectionInfo;)V");
+  if (!mid) return 0;
+
+  return nt::AddConnectionListener(
+      [=](unsigned int uid, bool connected, const nt::ConnectionInfo& conn) {
+        JNIEnv *env = listenerEnv;
+        if (!env || !env->functions) return;
+
+        // get the handler
+        auto handler = listener_global->obj();
+        //if (!handler) goto done; // can happen due to weak reference
+
+        // convert into the appropriate Java type
+        jobject jobj = ToJavaObject(env, conn);
+        if (!jobj) return;
+
+        if (env->ExceptionCheck()) {
+          env->ExceptionDescribe();
+          env->ExceptionClear();
+          return;
+        }
+        env->CallVoidMethod(handler, mid, (jint)uid,
+                            (jboolean)(connected ? 1 : 0), jobj);
+        if (env->ExceptionCheck()) {
+          env->ExceptionDescribe();
+          env->ExceptionClear();
+        }
+      },
+      immediateNotify != JNI_FALSE);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    removeConnectionListener
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_removeConnectionListener
+  (JNIEnv *, jclass, jint connListenerUid)
+{
+  nt::RemoveConnectionListener(connListenerUid);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getRpc
+ * Signature: (Ljava/lang/String;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRpc__Ljava_lang_String_2
+  (JNIEnv *env, jclass, jstring key)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsRpc()) {
+    ThrowTableKeyNotDefined(env, key);
+    return nullptr;
+  }
+  return ToJavaByteArray(env, val->GetRpc());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getRpc
+ * Signature: (Ljava/lang/String;[B)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRpc__Ljava_lang_String_2_3B
+  (JNIEnv *env, jclass, jstring key, jbyteArray defaultValue)
+{
+  auto val = nt::GetEntryValue(JavaStringRef(env, key));
+  if (!val || !val->IsRpc()) return defaultValue;
+  return ToJavaByteArray(env, val->GetRpc());
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    callRpc
+ * Signature: (Ljava/lang/String;[B)I
+ */
+JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_callRpc__Ljava_lang_String_2_3B
+  (JNIEnv *env, jclass, jstring key, jbyteArray params)
+{
+  return nt::CallRpc(JavaStringRef(env, key), JavaByteRef(env, params));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    callRpc
+ * Signature: (Ljava/lang/String;Ljava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_callRpc__Ljava_lang_String_2Ljava_nio_ByteBuffer_2I
+  (JNIEnv *env, jclass, jstring key, jobject params, jint params_len)
+{
+  return nt::CallRpc(JavaStringRef(env, key),
+                     JavaByteRefBB(env, params, params_len));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    setNetworkIdentity
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setNetworkIdentity
+  (JNIEnv *env, jclass, jstring name)
+{
+  nt::SetNetworkIdentity(JavaStringRef(env, name));
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    startServer
+ * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startServer
+  (JNIEnv *env, jclass, jstring persistFilename, jstring listenAddress,
+   jint port)
+{
+  nt::StartServer(JavaStringRef(env, persistFilename),
+                  JavaStringRef(env, listenAddress).c_str(), port);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    stopServer
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_stopServer
+  (JNIEnv *, jclass)
+{
+  nt::StopServer();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    startClient
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient
+  (JNIEnv *env, jclass, jstring serverName, jint port)
+{
+  nt::StartClient(JavaStringRef(env, serverName).c_str(), port);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    stopClient
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_stopClient
+  (JNIEnv *, jclass)
+{
+  nt::StopClient();
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    setUpdateRate
+ * Signature: (D)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setUpdateRate
+  (JNIEnv *, jclass, jdouble interval)
+{
+  nt::SetUpdateRate(interval);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    getConnections
+ * Signature: ()[Ledu/wpi/first/wpilibj/networktables/ConnectionInfo;
+ */
+JNIEXPORT jobjectArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getConnections
+  (JNIEnv *env, jclass)
+{
+  auto arr = nt::GetConnections();
+  jobjectArray jarr =
+      env->NewObjectArray(arr.size(), connectionInfoCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JavaLocal<jobject> jelem(env, ToJavaObject(env, arr[i]));
+    env->SetObjectArrayElement(jarr, i, jelem);
+  }
+  return jarr;
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    savePersistent
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_savePersistent
+  (JNIEnv *env, jclass, jstring filename)
+{
+  const char *err = nt::SavePersistent(JavaStringRef(env, filename));
+  if (err) env->ThrowNew(persistentEx, err);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    loadPersistent
+ * Signature: (Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_loadPersistent
+  (JNIEnv *env, jclass, jstring filename)
+{
+  std::vector<std::string> warns;
+  const char *err = nt::LoadPersistent(JavaStringRef(env, filename),
+                                       [&](size_t line, const char *msg) {
+                                         std::ostringstream oss;
+                                         oss << line << ": " << msg;
+                                         warns.push_back(oss.str());
+                                       });
+  if (err) {
+    env->ThrowNew(persistentEx, err);
+    return nullptr;
+  }
+  return ToJavaStringArray(env, warns);
+}
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    now
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_now
+  (JNIEnv *, jclass)
+{
+  return nt::Now();
+}
+
+}  // extern "C"
+
+// Thread where log callbacks are actually performed.
+//
+// JNI's AttachCurrentThread() creates a Java Thread object on every
+// invocation, which is both time inefficient and causes issues with Eclipse
+// (which tries to keep a thread list up-to-date and thus gets swamped).
+//
+// Instead, this class attaches just once.  When a hardware notification
+// occurs, a condition variable wakes up this thread and this thread actually
+// makes the call into Java.
+class LoggerThreadJNI {
+ public:
+  static LoggerThreadJNI& GetInstance() {
+    ATOMIC_STATIC(LoggerThreadJNI, instance);
+    return instance;
+  }
+  LoggerThreadJNI();
+  ~LoggerThreadJNI();
+  void SetFunc(JNIEnv* env, jobject func, jmethodID mid);
+  void Start();
+  void Stop();
+
+  void Log(unsigned int level, const char* file, unsigned int line,
+           const char* msg);
+
+ private:
+  void ThreadMain();
+
+  std::thread m_thread;
+  std::mutex m_mutex;
+  std::condition_variable m_cond;
+  std::atomic_bool m_active;
+  struct LogMessage {
+    LogMessage(unsigned int level_, const char* file_, unsigned int line_,
+               const char* msg_)
+        : level(level_), file(file_), line(line_), msg(msg_) {}
+    unsigned int level;
+    const char* file;
+    unsigned int line;
+    std::string msg;
+  };
+  std::queue<LogMessage> m_queue;
+  std::mutex m_shutdown_mutex;
+  std::condition_variable m_shutdown_cv;
+  bool m_shutdown = false;
+  jobject m_func = nullptr;
+  jmethodID m_mid;
+
+  ATOMIC_STATIC_DECL(LoggerThreadJNI)
+};
+
+ATOMIC_STATIC_INIT(LoggerThreadJNI)
+
+LoggerThreadJNI::LoggerThreadJNI() {
+  m_active = false;
+}
+
+LoggerThreadJNI::~LoggerThreadJNI() {
+  Stop();
+}
+
+void LoggerThreadJNI::SetFunc(JNIEnv* env, jobject func, jmethodID mid) {
+  std::lock_guard<std::mutex> lock(m_mutex);
+  // free global reference
+  if (m_func) env->DeleteGlobalRef(m_func);
+  // create global reference
+  m_func = env->NewGlobalRef(func);
+  m_mid = mid;
+}
+
+void LoggerThreadJNI::Start() {
+  {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    if (m_active) return;
+    m_active = true;
+  }
+  {
+    std::lock_guard<std::mutex> lock(m_shutdown_mutex);
+    m_shutdown = false;
+  }
+  m_thread = std::thread(&LoggerThreadJNI::ThreadMain, this);
+}
+
+void LoggerThreadJNI::Stop() {
+  {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    if (!m_active) return;
+    m_active = false;
+  }
+  m_cond.notify_one();  // wake up thread
+
+  // join threads, with timeout
+  if (m_thread.joinable()) {
+    std::unique_lock<std::mutex> lock(m_shutdown_mutex);
+    auto timeout_time =
+        std::chrono::steady_clock::now() + std::chrono::seconds(1);
+    if (m_shutdown_cv.wait_until(lock, timeout_time,
+                                 [&] { return m_shutdown; }))
+      m_thread.join();
+    else
+      m_thread.detach();  // timed out, detach it
+  }
+}
+
+void LoggerThreadJNI::Log(unsigned int level, const char *file,
+                          unsigned int line, const char *msg) {
+  std::lock_guard<std::mutex> lock(m_mutex);
+  if (!m_active) return;
+  m_queue.emplace(level, file, line, msg);
+  m_cond.notify_one();
+}
+
+void LoggerThreadJNI::ThreadMain() {
+  JNIEnv *env;
+  jint rs = jvm->AttachCurrentThread((void**)&env, NULL);
+  if (rs != JNI_OK) return;
+
+  std::unique_lock<std::mutex> lock(m_mutex);
+  while (m_active) {
+    m_cond.wait(lock, [&] { return !m_active || !m_queue.empty(); });
+    if (!m_active) break;
+    while (!m_queue.empty()) {
+      if (!m_active) break;
+      auto item = std::move(m_queue.front());
+      m_queue.pop();
+      auto func = m_func;
+      auto mid = m_mid;
+      lock.unlock();  // don't hold mutex during callback execution
+      env->CallVoidMethod(func, mid, (jint)item.level,
+                          ToJavaString(env, item.file), (jint)item.line,
+                          ToJavaString(env, item.msg));
+      if (env->ExceptionCheck()) {
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+      }
+      lock.lock();
+    }
+  }
+
+  if (jvm) jvm->DetachCurrentThread();
+
+  // use condition variable to signal thread shutdown
+  {
+    std::lock_guard<std::mutex> lock(m_shutdown_mutex);
+    m_shutdown = true;
+    m_shutdown_cv.notify_one();
+  }
+}
+
+extern "C" {
+
+/*
+ * Class:     edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
+ * Method:    setLogger
+ * Signature: (Ledu/wpi/first/wpilibj/networktables/NetworkTablesJNI/LoggerFunction;I)V
+ */
+JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setLogger
+  (JNIEnv *env, jclass, jobject func, jint minLevel)
+{
+  // cls is a temporary here; cannot be used within callback functor
+	jclass cls = env->GetObjectClass(func);
+  if (!cls) return;
+
+  // method ids, on the other hand, are safe to retain
+  jmethodID mid = env->GetMethodID(
+      cls, "apply", "(ILjava/lang/String;ILjava/lang/String;)V");
+  if (!mid) return;
+
+  auto& thread = LoggerThreadJNI::GetInstance();
+  thread.SetFunc(env, func, mid);
+  thread.Start();
+
+  nt::SetLogger(
+      [](unsigned int level, const char *file, unsigned int line,
+         const char *msg) {
+        LoggerThreadJNI::GetInstance().Log(level, file, line, msg);
+      },
+      minLevel);
+}
+
+}  // extern "C"
diff --git a/java/src/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java b/java/src/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java
new file mode 100644
index 0000000..d9f0e1d
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java
@@ -0,0 +1,17 @@
+package edu.wpi.first.wpilibj.networktables;
+
+public class ConnectionInfo {
+  final String remote_id;
+  final String remote_name;
+  final int remote_port;
+  final long last_update;
+  final int protocol_version;
+
+  ConnectionInfo(String remote_id, String remote_name, int remote_port, long last_update, int protocol_version) {
+    this.remote_id = remote_id;
+    this.remote_name = remote_name;
+    this.remote_port = remote_port;
+    this.last_update = last_update;
+    this.protocol_version = protocol_version;
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables/EntryInfo.java b/java/src/edu/wpi/first/wpilibj/networktables/EntryInfo.java
new file mode 100644
index 0000000..164d789
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables/EntryInfo.java
@@ -0,0 +1,15 @@
+package edu.wpi.first.wpilibj.networktables;
+
+public class EntryInfo {
+  final String name;
+  final int type;
+  final int flags;
+  final long last_change;
+
+  EntryInfo(String name, int type, int flags, long last_change) {
+    this.name = name;
+    this.type = type;
+    this.flags = flags;
+    this.last_change = last_change;
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java
new file mode 100644
index 0000000..a2d1eb6
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java
@@ -0,0 +1,958 @@
+package edu.wpi.first.wpilibj.networktables;
+
+import edu.wpi.first.wpilibj.tables.*;
+import edu.wpi.first.wpilibj.networktables2.type.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+/**
+ * A network table that knows its subtable path.
+ */
+public class NetworkTable implements ITable, IRemote {
+  /**
+   * The path separator for sub-tables and keys
+   *
+   */
+  public static final char PATH_SEPARATOR = '/';
+  /**
+   * The default port that network tables operates on
+   */
+  public static final int DEFAULT_PORT = 1735;
+
+  private static boolean client = false;
+  private static boolean running = false;
+  private static int port = DEFAULT_PORT;
+  private static String ipAddress = "";
+  private static String persistentFilename = "networktables.ini";
+
+  private synchronized static void checkInit() {
+    if (running)
+      throw new IllegalStateException(
+          "Network tables has already been initialized");
+  }
+
+  /**
+   * initializes network tables
+   */
+  public synchronized static void initialize() {
+    if (running)
+      shutdown();
+    if (client)
+      NetworkTablesJNI.startClient(ipAddress, port);
+    else
+      NetworkTablesJNI.startServer(persistentFilename, "", port);
+    running = true;
+  }
+
+  /**
+   * shuts down network tables
+   */
+  public synchronized static void shutdown() {
+    if (!running)
+      return;
+    if (client)
+      NetworkTablesJNI.stopClient();
+    else
+      NetworkTablesJNI.stopServer();
+    running = false;
+  }
+
+  /**
+   * set that network tables should be a server
+   * This must be called before initialize or getTable
+   */
+  public synchronized static void setServerMode() {
+    if (!client)
+      return;
+    checkInit();
+    client = false;
+  }
+
+  /**
+   * set that network tables should be a client
+   * This must be called before initialize or getTable
+   */
+  public synchronized static void setClientMode() {
+    if (client)
+      return;
+    checkInit();
+    client = true;
+  }
+
+  /**
+   * set the team the robot is configured for (this will set the mdns address that
+   * network tables will connect to in client mode)
+   * This must be called before initialize or getTable
+   * @param team the team number
+   */
+  public synchronized static void setTeam(int team) {
+    setIPAddress("roboRIO-" + team + "-FRC.local");
+  }
+
+  /**
+   * @param address the adress that network tables will connect to in client
+   * mode
+   */
+  public synchronized static void setIPAddress(final String address) {
+    if (ipAddress.equals(address))
+      return;
+    checkInit();
+    ipAddress = address;
+  }
+
+  /**
+   * @param aport the port number that network tables will connect to in client
+   * mode or listen to in server mode
+   */
+  public synchronized static void setPort(int aport) {
+    if (port == aport)
+      return;
+    checkInit();
+    port = aport;
+  }
+
+  /**
+   * Sets the persistent filename.
+   * @param filename the filename that the network tables server uses for
+   * automatic loading and saving of persistent values
+   */
+  public synchronized static void setPersistentFilename(final String filename) {
+    if (persistentFilename.equals(filename))
+      return;
+    checkInit();
+    persistentFilename = filename;
+  }
+
+  /**
+   * Sets the network identity.
+   * This is provided in the connection info on the remote end.
+   * @param name identity
+   */
+  public static void setNetworkIdentity(String name) {
+    NetworkTablesJNI.setNetworkIdentity(name);
+  }
+
+  public static boolean[] toNative(Boolean[] arr) {
+    boolean[] out = new boolean[arr.length];
+    for (int i = 0; i < arr.length; i++)
+      out[i] = arr[i];
+    return out;
+  }
+
+  public static double[] toNative(Double[] arr) {
+    double[] out = new double[arr.length];
+    for (int i = 0; i < arr.length; i++)
+      out[i] = arr[i];
+    return out;
+  }
+
+  public static Boolean[] fromNative(boolean[] arr) {
+    Boolean[] out = new Boolean[arr.length];
+    for (int i = 0; i < arr.length; i++)
+      out[i] = arr[i];
+    return out;
+  }
+
+  public static Double[] fromNative(double[] arr) {
+    Double[] out = new Double[arr.length];
+    for (int i = 0; i < arr.length; i++)
+      out[i] = arr[i];
+    return out;
+  }
+
+  /**
+   * Gets the table with the specified key. If the table does not exist, a new
+   *table will be created.<br>
+   * This will automatically initialize network tables if it has not been
+   *already
+   *
+   * @param key
+   *            the key name
+   * @return the network table requested
+   */
+  public synchronized static NetworkTable getTable(String key) {
+    if (!running)
+      initialize();
+    if (key.isEmpty())
+      return new NetworkTable(key);
+    return new NetworkTable(PATH_SEPARATOR + key);
+  }
+
+  private final String path;
+
+  NetworkTable(String path) {
+    this.path = path;
+  }
+  public String toString() { return "NetworkTable: " + path; }
+
+  public static ConnectionInfo[] connections() {
+    return NetworkTablesJNI.getConnections();
+  }
+
+  public boolean isConnected() {
+    ConnectionInfo[] conns = NetworkTablesJNI.getConnections();
+    return conns.length > 0;
+  }
+
+  public boolean isServer() {
+    return !client;
+  }
+
+  private class ListenerBase {
+    public int uid;
+  }
+
+  private class ConnectionListenerAdapter extends ListenerBase implements NetworkTablesJNI.ConnectionListenerFunction {
+    private final IRemote targetSource;
+    private final IRemoteConnectionListener targetListener;
+
+    public ConnectionListenerAdapter(IRemote targetSource, IRemoteConnectionListener targetListener) {
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    public void apply(int uid, boolean connected, ConnectionInfo conn) {
+      if (connected)
+        targetListener.connected(targetSource);
+      else
+        targetListener.disconnected(targetSource);
+    }
+  }
+
+  private final Hashtable<IRemoteConnectionListener,ConnectionListenerAdapter> connectionListenerMap = new Hashtable<IRemoteConnectionListener,ConnectionListenerAdapter>();
+  public synchronized void addConnectionListener(IRemoteConnectionListener listener,
+                                                 boolean immediateNotify) {
+    ConnectionListenerAdapter adapter = connectionListenerMap.get(listener);
+    if (adapter != null)
+      throw new IllegalStateException("Cannot add the same listener twice");
+    adapter = new ConnectionListenerAdapter(this, listener);
+    adapter.uid = NetworkTablesJNI.addConnectionListener(adapter, immediateNotify);
+    connectionListenerMap.put(listener, adapter);
+  }
+
+  public synchronized void removeConnectionListener(IRemoteConnectionListener listener) {
+    ConnectionListenerAdapter adapter = connectionListenerMap.get(listener);
+    if (adapter != null) {
+      NetworkTablesJNI.removeConnectionListener(adapter.uid);
+      connectionListenerMap.remove(listener);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void addTableListener(ITableListener listener) {
+    addTableListenerEx(listener, NOTIFY_NEW | NOTIFY_UPDATE);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void addTableListener(ITableListener listener,
+                               boolean immediateNotify) {
+    int flags = NOTIFY_NEW | NOTIFY_UPDATE;
+    if (immediateNotify)
+      flags |= NOTIFY_IMMEDIATE;
+    addTableListenerEx(listener, flags);
+  }
+
+  private class TableListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
+    private final int prefixLen;
+    private final ITable targetSource;
+    private final ITableListener targetListener;
+
+    public TableListenerAdapter(int prefixLen, ITable targetSource, ITableListener targetListener) {
+      this.prefixLen = prefixLen;
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    public void apply(int uid, String key, Object value, int flags) {
+      String relativeKey = key.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1)
+        return;
+      targetListener.valueChangedEx(targetSource, relativeKey, value, flags);
+    }
+  }
+
+  private final Hashtable<ITableListener,List<ListenerBase>> listenerMap = new Hashtable<ITableListener,List<ListenerBase>>();
+  public synchronized void addTableListenerEx(ITableListener listener,
+                                              int flags) {
+    List<ListenerBase> adapters = listenerMap.get(listener);
+    if (adapters == null) {
+      adapters = new ArrayList<ListenerBase>();
+      listenerMap.put(listener, adapters);
+    }
+    TableListenerAdapter adapter =
+        new TableListenerAdapter(path.length() + 1, this, listener);
+    adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, flags);
+    adapters.add(adapter);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void addTableListener(String key, ITableListener listener,
+                               boolean immediateNotify) {
+    int flags = NOTIFY_NEW | NOTIFY_UPDATE;
+    if (immediateNotify)
+      flags |= NOTIFY_IMMEDIATE;
+    addTableListenerEx(key, listener, flags);
+  }
+
+  private class KeyListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
+    private final String relativeKey;
+    private final String fullKey;
+    private final ITable targetSource;
+    private final ITableListener targetListener;
+
+    public KeyListenerAdapter(String relativeKey, String fullKey, ITable targetSource, ITableListener targetListener) {
+      this.relativeKey = relativeKey;
+      this.fullKey = fullKey;
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    public void apply(int uid, String key, Object value, int flags) {
+      if (!key.equals(fullKey))
+        return;
+      targetListener.valueChangedEx(targetSource, relativeKey, value, flags);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public synchronized void addTableListenerEx(String key,
+                                              ITableListener listener,
+                                              int flags) {
+    List<ListenerBase> adapters = listenerMap.get(listener);
+    if (adapters == null) {
+      adapters = new ArrayList<ListenerBase>();
+      listenerMap.put(listener, adapters);
+    }
+    String fullKey = path + PATH_SEPARATOR + key;
+    KeyListenerAdapter adapter =
+        new KeyListenerAdapter(key, fullKey, this, listener);
+    adapter.uid = NetworkTablesJNI.addEntryListener(fullKey, adapter, flags);
+    adapters.add(adapter);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void addSubTableListener(final ITableListener listener) {
+    addSubTableListener(listener, false);
+  }
+
+  private class SubListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
+    private final int prefixLen;
+    private final ITable targetSource;
+    private final ITableListener targetListener;
+    private final Set<String> notifiedTables = new HashSet<String>();
+
+    public SubListenerAdapter(int prefixLen, ITable targetSource, ITableListener targetListener) {
+      this.prefixLen = prefixLen;
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    public void apply(int uid, String key, Object value, int flags) {
+      String relativeKey = key.substring(prefixLen);
+      int endSubTable = relativeKey.indexOf(PATH_SEPARATOR);
+      if (endSubTable == -1)
+        return;
+      String subTableKey = relativeKey.substring(0, endSubTable);
+      if (notifiedTables.contains(subTableKey))
+        return;
+      notifiedTables.add(subTableKey);
+      targetListener.valueChangedEx(targetSource, subTableKey, targetSource.getSubTable(subTableKey), flags);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public synchronized void addSubTableListener(final ITableListener listener,
+                                               boolean localNotify) {
+    List<ListenerBase> adapters = listenerMap.get(listener);
+    if (adapters == null) {
+      adapters = new ArrayList<ListenerBase>();
+      listenerMap.put(listener, adapters);
+    }
+    SubListenerAdapter adapter =
+        new SubListenerAdapter(path.length() + 1, this, listener);
+    int flags = NOTIFY_NEW | NOTIFY_IMMEDIATE;
+    if (localNotify)
+      flags |= NOTIFY_LOCAL;
+    adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, flags);
+    adapters.add(adapter);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public synchronized void removeTableListener(ITableListener listener) {
+    List<ListenerBase> adapters = listenerMap.get(listener);
+    if (adapters != null) {
+      for (int i = 0; i < adapters.size(); ++i)
+        NetworkTablesJNI.removeEntryListener(adapters.get(i).uid);
+      adapters.clear();
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ITable getSubTable(String key) {
+    return new NetworkTable(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean containsKey(String key) {
+    return NetworkTablesJNI.containsKey(path + PATH_SEPARATOR + key);
+  }
+
+  public boolean containsSubTable(String key) {
+    EntryInfo[] entries = NetworkTablesJNI.getEntries(path + PATH_SEPARATOR + key + PATH_SEPARATOR, 0);
+    return entries.length != 0;
+  }
+
+  /**
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return keys currently in the table
+   */
+  public Set<String> getKeys(int types) {
+    Set<String> keys = new HashSet<String>();
+    int prefixLen = path.length() + 1;
+    for (EntryInfo entry : NetworkTablesJNI.getEntries(path + PATH_SEPARATOR, types)) {
+      String relativeKey = entry.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1)
+        continue;
+      keys.add(relativeKey);
+    }
+    return keys;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<String> getKeys() {
+    return getKeys(0);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<String> getSubTables() {
+    Set<String> keys = new HashSet<String>();
+    int prefixLen = path.length() + 1;
+    for (EntryInfo entry : NetworkTablesJNI.getEntries(path + PATH_SEPARATOR, 0)) {
+      String relativeKey = entry.name.substring(prefixLen);
+      int endSubTable = relativeKey.indexOf(PATH_SEPARATOR);
+      if (endSubTable == -1)
+        continue;
+      keys.add(relativeKey.substring(0, endSubTable));
+    }
+    return keys;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putNumber(String key, double value) {
+    return NetworkTablesJNI.putDouble(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getNumber(String, double)}.
+   */
+  @Override
+  @Deprecated
+  public double getNumber(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getDouble(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public double getNumber(String key, double defaultValue) {
+    return NetworkTablesJNI.getDouble(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putString(String key, String value) {
+    return NetworkTablesJNI.putString(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getString(String, String)}.
+   */
+  @Override
+  @Deprecated
+  public String getString(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getString(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getString(String key, String defaultValue) {
+    return NetworkTablesJNI.getString(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putBoolean(String key, boolean value) {
+    return NetworkTablesJNI.putBoolean(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getBoolean(String, boolean)}.
+   */
+  @Override
+  @Deprecated
+  public boolean getBoolean(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getBoolean(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean getBoolean(String key, boolean defaultValue) {
+    return NetworkTablesJNI.getBoolean(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putBooleanArray(String key, boolean[] value) {
+    return NetworkTablesJNI.putBooleanArray(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putBooleanArray(String key, Boolean[] value) {
+    return putBooleanArray(key, toNative(value));
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getBooleanArray(String, boolean[])}.
+   */
+  @Override
+  @Deprecated
+  public boolean[] getBooleanArray(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getBooleanArray(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean[] getBooleanArray(String key, boolean[] defaultValue) {
+    return NetworkTablesJNI.getBooleanArray(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Boolean[] getBooleanArray(String key, Boolean[] defaultValue) {
+    try {
+      return fromNative(getBooleanArray(key));
+    } catch (TableKeyNotDefinedException e) {
+      return defaultValue;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putNumberArray(String key, double[] value) {
+    return NetworkTablesJNI.putDoubleArray(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putNumberArray(String key, Double[] value) {
+    return putNumberArray(key, toNative(value));
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getNumberArray(String, double[])}.
+   */
+  @Override
+  @Deprecated
+  public double[] getNumberArray(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getDoubleArray(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public double[] getNumberArray(String key, double[] defaultValue) {
+    return NetworkTablesJNI.getDoubleArray(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Double[] getNumberArray(String key, Double[] defaultValue) {
+    try {
+      return fromNative(getNumberArray(key));
+    } catch (TableKeyNotDefinedException e) {
+      return defaultValue;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putStringArray(String key, String[] value) {
+    return NetworkTablesJNI.putStringArray(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getStringArray(String, String[])}.
+   */
+  @Override
+  @Deprecated
+  public String[] getStringArray(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getStringArray(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String[] getStringArray(String key, String[] defaultValue) {
+    return NetworkTablesJNI.getStringArray(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putRaw(String key, byte[] value) {
+    return NetworkTablesJNI.putRaw(path + PATH_SEPARATOR + key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putRaw(String key, ByteBuffer value, int len) {
+    if (!value.isDirect())
+      throw new IllegalArgumentException("must be a direct buffer");
+    if (value.capacity() < len)
+      throw new IllegalArgumentException("buffer is too small, must be at least " + len);
+    return NetworkTablesJNI.putRaw(path + PATH_SEPARATOR + key, value, len);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getRaw(String, byte[])}.
+   */
+  @Override
+  @Deprecated
+  public byte[] getRaw(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getRaw(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public byte[] getRaw(String key, byte[] defaultValue) {
+    return NetworkTablesJNI.getRaw(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putValue(String key, Object value) throws IllegalArgumentException {
+    if (value instanceof Boolean)
+      return NetworkTablesJNI.putBoolean(path + PATH_SEPARATOR + key, ((Boolean)value).booleanValue());
+    else if (value instanceof Double)
+      return NetworkTablesJNI.putDouble(path + PATH_SEPARATOR + key, ((Double)value).doubleValue());
+    else if (value instanceof String)
+      return NetworkTablesJNI.putString(path + PATH_SEPARATOR + key, (String)value);
+    else if (value instanceof byte[])
+      return NetworkTablesJNI.putRaw(path + PATH_SEPARATOR + key, (byte[])value);
+    else if (value instanceof boolean[])
+      return NetworkTablesJNI.putBooleanArray(path + PATH_SEPARATOR + key, (boolean[])value);
+    else if (value instanceof double[])
+      return NetworkTablesJNI.putDoubleArray(path + PATH_SEPARATOR + key, (double[])value);
+    else if (value instanceof Boolean[])
+      return NetworkTablesJNI.putBooleanArray(path + PATH_SEPARATOR + key, toNative((Boolean[])value));
+    else if (value instanceof Double[])
+      return NetworkTablesJNI.putDoubleArray(path + PATH_SEPARATOR + key, toNative((Double[])value));
+    else if (value instanceof String[])
+      return NetworkTablesJNI.putStringArray(path + PATH_SEPARATOR + key, (String[])value);
+    else if (value instanceof BooleanArray)
+      return NetworkTablesJNI.putBooleanArray(path + PATH_SEPARATOR + key, toNative((Boolean[])((ArrayData)value).getDataArray()));
+    else if (value instanceof NumberArray)
+      return NetworkTablesJNI.putDoubleArray(path + PATH_SEPARATOR + key, toNative((Double[])((ArrayData)value).getDataArray()));
+    else if (value instanceof StringArray)
+      return NetworkTablesJNI.putStringArray(path + PATH_SEPARATOR + key, (String[])((ArrayData)value).getDataArray());
+    else
+      throw new IllegalArgumentException(key);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use get*Array functions instead.
+   */
+  @Override
+  @Deprecated
+  public void retrieveValue(String key, Object externalData) throws TableKeyNotDefinedException {
+    Object value = getValue(key);
+    if (value instanceof boolean[] && externalData instanceof BooleanArray)
+      ((ArrayData)externalData).setDataArray(fromNative((boolean[])value));
+    else if (value instanceof double[] && externalData instanceof NumberArray)
+      ((ArrayData)externalData).setDataArray(fromNative((double[])value));
+    else if (value instanceof String[] && externalData instanceof StringArray)
+      ((ArrayData)externalData).setDataArray((String[])value);
+    else
+      throw new TableKeyNotDefinedException(key);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getValue(String, Object)}.
+   */
+  @Override
+  @Deprecated
+  public Object getValue(String key) throws TableKeyNotDefinedException {
+    return NetworkTablesJNI.getValue(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Object getValue(String key, Object defaultValue) {
+    return NetworkTablesJNI.getValue(path + PATH_SEPARATOR + key, defaultValue);
+  }
+
+  /** The persistent flag value. */
+  public static final int PERSISTENT = 1;
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setPersistent(String key) {
+    setFlags(key, PERSISTENT);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void clearPersistent(String key) {
+    clearFlags(key, PERSISTENT);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean isPersistent(String key) {
+    return (getFlags(key) & PERSISTENT) != 0;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setFlags(String key, int flags) {
+    NetworkTablesJNI.setEntryFlags(path + PATH_SEPARATOR + key, getFlags(key) | flags);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void clearFlags(String key, int flags) {
+    NetworkTablesJNI.setEntryFlags(path + PATH_SEPARATOR + key, getFlags(key) & ~flags);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int getFlags(String key) {
+    return NetworkTablesJNI.getEntryFlags(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void delete(String key) {
+    NetworkTablesJNI.deleteEntry(path + PATH_SEPARATOR + key);
+  }
+
+  /**
+   * Deletes ALL keys in ALL subtables.  Use with caution!
+   */
+  public static void globalDeleteAll() {
+    NetworkTablesJNI.deleteAllEntries();
+  }
+
+  /**
+   * Flushes all updated values immediately to the network.
+   * Note: This is rate-limited to protect the network from flooding.
+   * This is primarily useful for synchronizing network updates with
+   * user code.
+   */
+  public static void flush() {
+    NetworkTablesJNI.flush();
+  }
+
+  /**
+   * Set the periodic update rate.
+   *
+   * @param interval update interval in seconds (range 0.1 to 1.0)
+   */
+  public static void setUpdateRate(double interval) {
+    NetworkTablesJNI.setUpdateRate(interval);
+  }
+
+  /**
+   * Saves persistent keys to a file.  The server does this automatically.
+   *
+   * @param filename file name
+   * @throws PersistentException if error saving file
+   */
+  public static void savePersistent(String filename) throws PersistentException {
+    NetworkTablesJNI.savePersistent(filename);
+  }
+
+  /**
+   * Loads persistent keys from a file.  The server does this automatically.
+   *
+   * @param filename file name
+   * @return List of warnings (errors result in an exception instead)
+   * @throws PersistentException if error reading file
+   */
+  public static String[] loadPersistent(String filename) throws PersistentException {
+    return NetworkTablesJNI.loadPersistent(filename);
+  }
+
+  /*
+   * Deprecated Methods
+   */
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link #putNumber(String, double)} instead.
+   */
+  @Override
+  @Deprecated
+  public boolean putInt(String key, int value) {
+    return putNumber(key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Override
+  @Deprecated
+  public int getInt(String key) throws TableKeyNotDefinedException {
+    return (int)getNumber(key);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Override
+  @Deprecated
+  public int getInt(String key, int defaultValue) throws TableKeyNotDefinedException {
+    try {
+      return (int)getNumber(key);
+    } catch (NoSuchElementException ex) {
+      return defaultValue;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link #putNumber(String, double)} instead.
+   */
+  @Override
+  @Deprecated
+  public boolean putDouble(String key, double value) {
+    return putNumber(key, value);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Override
+  @Deprecated
+  public double getDouble(String key) throws TableKeyNotDefinedException {
+    return getNumber(key);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Override
+  @Deprecated
+  public double getDouble(String key, double defaultValue) {
+    return getNumber(key, defaultValue);
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java
new file mode 100644
index 0000000..d654cfc
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java
@@ -0,0 +1,22 @@
+package edu.wpi.first.wpilibj.networktables;
+
+import edu.wpi.first.wpilibj.tables.TableKeyNotDefinedException;
+
+/**
+ * An exception throw when the lookup a a key-value fails in a {@link NetworkTable}
+ * 
+ * @deprecated to provide backwards compatability for new api
+ * 
+ * @author Mitchell
+ *
+ */
+public class NetworkTableKeyNotDefined extends TableKeyNotDefinedException {
+
+	/**
+	 * @param key the key that was not defined in the table
+	 */
+	public NetworkTableKeyNotDefined(String key) {
+		super(key);
+	}
+
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java
new file mode 100644
index 0000000..810d7f8
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java
@@ -0,0 +1,155 @@
+package edu.wpi.first.wpilibj.networktables;
+
+import edu.wpi.first.wpilibj.tables.*;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class NetworkTablesJNI {
+  static boolean libraryLoaded = false;
+  static File jniLibrary = null;
+  static {
+    if (!libraryLoaded) {
+      try {
+        String osname = System.getProperty("os.name");
+        String resname;
+        if (osname.startsWith("Windows"))
+          resname = "/Windows/" + System.getProperty("os.arch") + "/";
+        else
+          resname = "/" + osname + "/" + System.getProperty("os.arch") + "/";
+        System.out.println("platform: " + resname);
+        if (osname.startsWith("Windows"))
+          resname += "ntcore.dll";
+        else if (osname.startsWith("Mac"))
+          resname += "libntcore.dylib";
+        else
+          resname += "libntcore.so";
+        InputStream is = NetworkTablesJNI.class.getResourceAsStream(resname);
+        if (is != null) {
+          // create temporary file
+          if (System.getProperty("os.name").startsWith("Windows"))
+            jniLibrary = File.createTempFile("NetworkTablesJNI", ".dll");
+          else if (System.getProperty("os.name").startsWith("Mac"))
+            jniLibrary = File.createTempFile("libNetworkTablesJNI", ".dylib");
+          else
+            jniLibrary = File.createTempFile("libNetworkTablesJNI", ".so");
+          // flag for delete on exit
+          jniLibrary.deleteOnExit();
+          OutputStream os = new FileOutputStream(jniLibrary);
+
+          byte[] buffer = new byte[1024];
+          int readBytes;
+          try {
+            while ((readBytes = is.read(buffer)) != -1) {
+              os.write(buffer, 0, readBytes);
+            }
+          } finally {
+            os.close();
+            is.close();
+          }
+
+          System.load(jniLibrary.getAbsolutePath());
+        } else {
+          System.loadLibrary("ntcore");
+        }
+      } catch (IOException ex) {
+        ex.printStackTrace();
+        System.exit(1);
+      }
+      libraryLoaded = true;
+    }
+  }
+
+  public static native boolean containsKey(String key);
+  public static native int getType(String key);
+
+  public static native boolean putBoolean(String key, boolean value);
+  public static native boolean putDouble(String key, double value);
+  public static native boolean putString(String key, String value);
+  public static native boolean putRaw(String key, byte[] value);
+  public static native boolean putRaw(String key, ByteBuffer value, int len);
+  public static native boolean putBooleanArray(String key, boolean[] value);
+  public static native boolean putDoubleArray(String key, double[] value);
+  public static native boolean putStringArray(String key, String[] value);
+
+  public static native void forcePutBoolean(String key, boolean value);
+  public static native void forcePutDouble(String key, double value);
+  public static native void forcePutString(String key, String value);
+  public static native void forcePutRaw(String key, byte[] value);
+  public static native void forcePutRaw(String key, ByteBuffer value, int len);
+  public static native void forcePutBooleanArray(String key, boolean[] value);
+  public static native void forcePutDoubleArray(String key, double[] value);
+  public static native void forcePutStringArray(String key, String[] value);
+
+  public static native Object getValue(String key) throws TableKeyNotDefinedException;
+  public static native boolean getBoolean(String key) throws TableKeyNotDefinedException;
+  public static native double getDouble(String key) throws TableKeyNotDefinedException;
+  public static native String getString(String key) throws TableKeyNotDefinedException;
+  public static native byte[] getRaw(String key) throws TableKeyNotDefinedException;
+  public static native boolean[] getBooleanArray(String key) throws TableKeyNotDefinedException;
+  public static native double[] getDoubleArray(String key) throws TableKeyNotDefinedException;
+  public static native String[] getStringArray(String key) throws TableKeyNotDefinedException;
+
+  public static native Object getValue(String key, Object defaultValue);
+  public static native boolean getBoolean(String key, boolean defaultValue);
+  public static native double getDouble(String key, double defaultValue);
+  public static native String getString(String key, String defaultValue);
+  public static native byte[] getRaw(String key, byte[] defaultValue);
+  public static native boolean[] getBooleanArray(String key, boolean[] defaultValue);
+  public static native double[] getDoubleArray(String key, double[] defaultValue);
+  public static native String[] getStringArray(String key, String[] defaultValue);
+
+  public static native void setEntryFlags(String key, int flags);
+  public static native int getEntryFlags(String key);
+
+  public static native void deleteEntry(String key);
+  public static native void deleteAllEntries();
+
+  public static native EntryInfo[] getEntries(String prefix, int types);
+
+  public static native void flush();
+
+  public interface EntryListenerFunction {
+    void apply(int uid, String key, Object value, int flags);
+  }
+  public static native int addEntryListener(String prefix, EntryListenerFunction listener, int flags);
+  public static native void removeEntryListener(int entryListenerUid);
+
+  public interface ConnectionListenerFunction {
+    void apply(int uid, boolean connected, ConnectionInfo conn);
+  }
+  public static native int addConnectionListener(ConnectionListenerFunction listener, boolean immediateNotify);
+  public static native void removeConnectionListener(int connListenerUid);
+
+  // public static native void createRpc(String key, byte[] def, IRpc rpc);
+  // public static native void createRpc(String key, ByteBuffer def, int def_len, IRpc rpc);
+  public static native byte[] getRpc(String key) throws TableKeyNotDefinedException;
+  public static native byte[] getRpc(String key, byte[] defaultValue);
+  public static native int callRpc(String key, byte[] params);
+  public static native int callRpc(String key, ByteBuffer params, int params_len);
+  // public static native byte[] getRpcResultBlocking(int callUid);
+  // public static native byte[] getRpcResultNonblocking(int callUid) throws RpcNoResponseException;
+
+  public static native void setNetworkIdentity(String name);
+  public static native void startServer(String persistFilename, String listenAddress, int port);
+  public static native void stopServer();
+  public static native void startClient(String serverName, int port);
+  public static native void stopClient();
+  public static native void setUpdateRate(double interval);
+
+  public static native ConnectionInfo[] getConnections();
+
+  public static native void savePersistent(String filename) throws PersistentException;
+  public static native String[] loadPersistent(String filename) throws PersistentException;  // returns warnings
+
+  public static native long now();
+
+  public interface LoggerFunction {
+    void apply(int level, String file, int line, String msg);
+  }
+  public static native void setLogger(LoggerFunction func, int minLevel);
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables/PersistentException.java b/java/src/edu/wpi/first/wpilibj/networktables/PersistentException.java
new file mode 100644
index 0000000..8d521fb
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables/PersistentException.java
@@ -0,0 +1,18 @@
+package edu.wpi.first.wpilibj.networktables;
+
+import java.io.IOException;
+
+/**
+ * An exception thrown when persistent load/save fails in a {@link NetworkTable}
+ * 
+ */
+public class PersistentException extends IOException {
+
+	/**
+	 * @param message The error message
+	 */
+	public PersistentException(String message) {
+		super(message);
+	}
+
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java b/java/src/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java
new file mode 100644
index 0000000..e05f3a0
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java
@@ -0,0 +1,49 @@
+package edu.wpi.first.wpilibj.networktables2.type;
+
+/**
+ * @deprecated Use ArrayList instead.
+ */
+public class ArrayData {
+  private Object[] data = new Object[0];
+
+  protected Object getAsObject(int index) {
+    return data[index];
+  }
+  protected void _set(int index, Object value) {
+    data[index] = value;
+  }
+  protected void _add(Object value) {
+    setSize(size() + 1);
+    data[size() - 1] = value;
+  }
+  public void remove(int index) {
+    if (index < 0 || index >= size())
+      throw new IndexOutOfBoundsException();
+    if (index < size() - 1)
+      System.arraycopy(data, index + 1, data, index, size() - index - 1);
+    setSize(size() - 1);
+  }
+  public void setSize(int size) {
+    if (size == data.length)
+      return;
+    Object[] newArray = new Object[size];
+    if (size < data.length)
+      System.arraycopy(data, 0, newArray, 0, size);
+    else {
+      System.arraycopy(data, 0, newArray, 0, data.length);
+      for (int i = data.length; i < newArray.length; ++i)
+        newArray[i] = null;
+    }
+    data = newArray;
+  }
+  public int size() {
+    return data.length;
+  }
+
+  public Object[] getDataArray() {
+    return data;
+  }
+  public void setDataArray(Object[] value) {
+    data = value;
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java b/java/src/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java
new file mode 100644
index 0000000..f2c78e6
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java
@@ -0,0 +1,16 @@
+package edu.wpi.first.wpilibj.networktables2.type;
+
+/**
+ * @deprecated Use {@literal ArrayList<Boolean>} instead.
+ */
+public class BooleanArray extends ArrayData {
+  public boolean get(int index) {
+    return ((Boolean)getAsObject(index)).booleanValue();
+  }
+  public void set(int index, boolean value) {
+    _set(index, value?Boolean.TRUE:Boolean.FALSE);
+  }
+  public void add(boolean value) {
+    _add(value?Boolean.TRUE:Boolean.FALSE);
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java b/java/src/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java
new file mode 100644
index 0000000..1066159
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java
@@ -0,0 +1,16 @@
+package edu.wpi.first.wpilibj.networktables2.type;
+
+/**
+ * @deprecated Use {@literal ArrayList<Double>} instead.
+ */
+public class NumberArray extends ArrayData {
+  public double get(int index) {
+    return ((Double)getAsObject(index)).doubleValue();
+  }
+  public void set(int index, double value) {
+    _set(index, new Double(value));
+  }
+  public void add(double value) {
+    _add(new Double(value));
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/StringArray.java b/java/src/edu/wpi/first/wpilibj/networktables2/type/StringArray.java
new file mode 100644
index 0000000..5eea0d3
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/networktables2/type/StringArray.java
@@ -0,0 +1,16 @@
+package edu.wpi.first.wpilibj.networktables2.type;
+
+/**
+ * @deprecated Use {@literal ArrayList<String>} instead.
+ */
+public class StringArray extends ArrayData {
+  public String get(int index) {
+    return ((String)getAsObject(index));
+  }
+  public void set(int index, String value) {
+    _set(index, value);
+  }
+  public void add(String value) {
+    _add(value);
+  }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/tables/IRemote.java b/java/src/edu/wpi/first/wpilibj/tables/IRemote.java
new file mode 100644
index 0000000..a79f740
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/tables/IRemote.java
@@ -0,0 +1,37 @@
+package edu.wpi.first.wpilibj.tables;
+
+
+/**
+ * Represents an object that has a remote connection
+ * 
+ * @author Mitchell
+ *
+ */
+public interface IRemote {
+	/**
+	 * Register an object to listen for connection and disconnection events
+	 * 
+	 * @param listener the listener to be register
+	 * @param immediateNotify if the listener object should be notified of the current connection state
+	 */
+	public void addConnectionListener(IRemoteConnectionListener listener, boolean immediateNotify);
+
+	/**
+	 * Unregister a listener from connection events
+	 * 
+	 * @param listener the listener to be unregistered
+	 */
+	public void removeConnectionListener(IRemoteConnectionListener listener);
+	
+	/**
+	 * Get the current state of the objects connection
+	 * @return the current connection state
+	 */
+    public boolean isConnected();
+	
+	/**
+	 * If the object is acting as a server
+	 * @return if the object is a server
+	 */
+    public boolean isServer();
+}
diff --git a/java/src/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java b/java/src/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java
new file mode 100644
index 0000000..cab9b1c
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java
@@ -0,0 +1,20 @@
+package edu.wpi.first.wpilibj.tables;
+
+/**
+ * A listener that listens for connection changes in a {@link IRemote} object
+ * 
+ * @author Mitchell
+ *
+ */
+public interface IRemoteConnectionListener {
+	/**
+	 * Called when an IRemote is connected
+	 * @param remote the object that connected
+	 */
+	public void connected(IRemote remote);
+	/**
+	 * Called when an IRemote is disconnected
+	 * @param remote the object that disconnected
+	 */
+	public void disconnected(IRemote remote);
+}
diff --git a/java/src/edu/wpi/first/wpilibj/tables/ITable.java b/java/src/edu/wpi/first/wpilibj/tables/ITable.java
new file mode 100644
index 0000000..81d12be
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/tables/ITable.java
@@ -0,0 +1,547 @@
+package edu.wpi.first.wpilibj.tables;
+
+import java.nio.ByteBuffer;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+
+/**
+ * A table whose values can be read and written to
+ */
+public interface ITable {
+
+  /**
+   * Checks the table and tells if it contains the specified key
+   *
+   * @param key the key to search for
+   * @return true if the table as a value assigned to the given key
+   */
+  public boolean containsKey(String key);
+
+  /**
+   * @param key the key to search for
+   * @return true if there is a subtable with the key which contains at least
+   * one key/subtable of its own
+   */
+  public boolean containsSubTable(String key);
+
+  /**
+   * Returns the table at the specified key. If there is no table at the
+   * specified key, it will create a new table
+   *
+   * @param key the name of the table relative to this one
+   * @return a sub table relative to this one
+   */
+  public ITable getSubTable(String key);
+
+  /**
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return keys currently in the table
+   */
+  public Set<String> getKeys(int types);
+
+  /**
+   * @return keys currently in the table
+   */
+  public Set<String> getKeys();
+
+  /**
+   * @return subtables currently in the table
+   */
+  public Set<String> getSubTables();
+
+  /**
+   * Makes a key's value persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   */
+  public void setPersistent(String key);
+
+  /**
+   * Stop making a key's value persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   */
+  public void clearPersistent(String key);
+
+  /**
+   * Returns whether the value is persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   * @return True if the value is persistent.
+   */
+  public boolean isPersistent(String key);
+
+  /**
+   * Sets flags on the specified key in this table. The key can
+   * not be null.
+   *
+   * @param key the key name
+   * @param flags the flags to set (bitmask)
+   */
+  public void setFlags(String key, int flags);
+
+  /**
+   * Clears flags on the specified key in this table. The key can
+   * not be null.
+   *
+   * @param key the key name
+   * @param flags the flags to clear (bitmask)
+   */
+  public void clearFlags(String key, int flags);
+
+  /**
+   * Returns the flags for the specified key.
+   *
+   * @param key the key name
+   * @return the flags, or 0 if the key is not defined
+   */
+  public int getFlags(String key);
+
+  /**
+   * Deletes the specified key in this table. The key can
+   * not be null.
+   *
+   * @param key the key name
+   */
+  public void delete(String key);
+
+  /**
+   * Gets the value associated with a key as an object. If the key does not
+   * exist, it will return the default value
+   * NOTE: If the value is a double, it will return a Double object,
+   * not a primitive.  To get the primitive, use
+   * {@link #getDouble(String, double)}.
+   * @param key the key of the value to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getValue(String, Object)}.
+   */
+  @Deprecated
+  public Object getValue(String key) throws TableKeyNotDefinedException;
+
+  /**
+   * Gets the value associated with a key as an object.
+   * NOTE: If the value is a double, it will return a Double object,
+   * not a primitive.  To get the primitive, use
+   * {@link #getDouble(String, double)}.
+   * @param key the key of the value to look up
+   * @param defaultValue the default value if the key is null
+   * @return the value associated with the given key
+   */
+  public Object getValue(String key, Object defaultValue);
+
+  /**
+   * Put a value in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   * @throws IllegalArgumentException when the value is not supported by the
+   * table
+   */
+  public boolean putValue(String key, Object value)
+      throws IllegalArgumentException;
+
+  /**
+   * Retrieve an array data type from the table.
+   * @param key the key to be assigned to
+   * @param externalValue the array data type to retreive into
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated Use get*Array functions instead.
+   */
+  @Deprecated
+  public void retrieveValue(String key, Object externalValue) throws TableKeyNotDefinedException;
+
+  /**
+   * Put a number in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putNumber(String key, double value);
+  /**
+   * Returns the number the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getNumber(String, double)}.
+   */
+  @Deprecated
+  public double getNumber(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the number the key maps to. If the key does not exist or is of
+   * different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public double getNumber(String key, double defaultValue);
+
+  /**
+   * Put a string in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putString(String key, String value);
+  /**
+   * Returns the string the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getString(String, String)}.
+   */
+  @Deprecated
+  public String getString(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the string the key maps to. If the key does not exist or is of
+   * different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public String getString(String key, String defaultValue);
+
+  /**
+   * Put a boolean in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putBoolean(String key, boolean value);
+  /**
+   * Returns the boolean the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getBoolean(String, boolean)}.
+   */
+  @Deprecated
+  public boolean getBoolean(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the boolean the key maps to. If the key does not exist or is of
+   * different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public boolean getBoolean(String key, boolean defaultValue);
+
+  /**
+   * Put a boolean array in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putBooleanArray(String key, boolean[] value);
+  /**
+   * Put a boolean array in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putBooleanArray(String key, Boolean[] value);
+  /**
+   * Returns the boolean array the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getBooleanArray(String, boolean[])}.
+   */
+  @Deprecated
+  public boolean[] getBooleanArray(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the boolean array the key maps to. If the key does not exist or is
+   * of different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public boolean[] getBooleanArray(String key, boolean[] defaultValue);
+  /**
+   * Returns the boolean array the key maps to. If the key does not exist or is
+   * of different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public Boolean[] getBooleanArray(String key, Boolean[] defaultValue);
+
+  /**
+   * Put a number array in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putNumberArray(String key, double[] value);
+  /**
+   * Put a number array in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putNumberArray(String key, Double[] value);
+  /**
+   * Returns the number array the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getNumberArray(String, double[])}.
+   */
+  @Deprecated
+  public double[] getNumberArray(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the number array the key maps to. If the key does not exist or is
+   * of different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public double[] getNumberArray(String key, double[] defaultValue);
+  /**
+   * Returns the number array the key maps to. If the key does not exist or is
+   * of different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public Double[] getNumberArray(String key, Double[] defaultValue);
+
+  /**
+   * Put a string array in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putStringArray(String key, String[] value);
+  /**
+   * Returns the string array the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getStringArray(String, String[])}.
+   */
+  @Deprecated
+  public String[] getStringArray(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the string array the key maps to. If the key does not exist or is
+   * of different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public String[] getStringArray(String key, String[] defaultValue);
+
+  /**
+   * Put a raw value (byte array) in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putRaw(String key, byte[] value);
+  /**
+   * Put a raw value (bytes from a byte buffer) in the table
+   * @param key the key to be assigned to
+   * @param value the value that will be assigned
+   * @param len the length of the value
+   * @return False if the table key already exists with a different type
+   */
+  public boolean putRaw(String key, ByteBuffer value, int len);
+  /**
+   * Returns the raw value (byte array) the key maps to.
+   * @param key the key to look up
+   * @return the value associated with the given key
+   * @throws TableKeyNotDefinedException if there is no value associated with
+   * the given key
+   * @deprecated This exception-raising method has been replaced by the
+   * default-taking method {@link #getRaw(String, byte[])}.
+   */
+  @Deprecated
+  public byte[] getRaw(String key) throws TableKeyNotDefinedException;
+  /**
+   * Returns the raw value (byte array) the key maps to. If the key does not
+   * exist or is of different type, it will return the default value.
+   * @param key the key to look up
+   * @param defaultValue the value to be returned if no value is found
+   * @return the value associated with the given key or the given default value
+   * if there is no value associated with the key
+   */
+  public byte[] getRaw(String key, byte[] defaultValue);
+
+  /** Notifier flag values. */
+  public static final int NOTIFY_IMMEDIATE = 0x01;
+  public static final int NOTIFY_LOCAL = 0x02;
+  public static final int NOTIFY_NEW = 0x04;
+  public static final int NOTIFY_DELETE = 0x08;
+  public static final int NOTIFY_UPDATE = 0x10;
+  public static final int NOTIFY_FLAGS = 0x20;
+
+  /**
+   * Add a listener for changes to the table
+   * @param listener the listener to add
+   */
+  public void addTableListener(ITableListener listener);
+  /**
+   * Add a listener for changes to the table
+   * @param listener the listener to add
+   * @param immediateNotify if true then this listener will be notified of all
+   * current entries (marked as new)
+   */
+  public void addTableListener(ITableListener listener,
+                               boolean immediateNotify);
+  /**
+   * Add a listener for changes to the table
+   * @param listener the listener to add
+   * @param flags bitmask specifying desired notifications
+   */
+  public void addTableListenerEx(ITableListener listener, int flags);
+
+  /**
+   * Add a listener for changes to a specific key the table
+   * @param key the key to listen for
+   * @param listener the listener to add
+   * @param immediateNotify if true then this listener will be notified of all
+   * current entries (marked as new)
+   */
+  public void addTableListener(String key, ITableListener listener,
+                               boolean immediateNotify);
+  /**
+   * Add a listener for changes to a specific key the table
+   * @param key the key to listen for
+   * @param listener the listener to add
+   * @param flags bitmask specifying desired notifications
+   */
+  public void addTableListenerEx(String key, ITableListener listener,
+                                 int flags);
+  /**
+   * This will immediately notify the listener of all current sub tables
+   * @param listener the listener to notify
+   */
+  public void addSubTableListener(final ITableListener listener);
+  /**
+   * This will immediately notify the listener of all current sub tables
+   * @param listener the listener to notify
+   * @param localNotify if true then this listener will be notified of all
+   * local changes in addition to all remote changes
+   */
+  public void addSubTableListener(final ITableListener listener,
+                                  boolean localNotify);
+  /**
+   * Remove a listener from receiving table events
+   * @param listener the listener to be removed
+   */
+  public void removeTableListener(ITableListener listener);
+
+  /*
+   * Deprecated Methods
+   */
+
+  /**
+   * Maps the specified key to the specified value in this table.
+   * The key can not be null.
+   * The value can be retrieved by calling the get method with a key that is
+   * equal to the original key.
+   * @param key the key
+   * @param value the value
+   * @return False if the table key already exists with a different type
+   * @throws IllegalArgumentException if key is null
+   * @deprecated Use {@link #putNumber(String, double)} instead.
+   */
+  @Deprecated
+  public boolean putInt(String key, int value);
+
+  /**
+   * Returns the value at the specified key.
+   * @param key the key
+   * @return the value
+   * @throws TableKeyNotDefinedException if there is no value mapped to by the
+   * key
+   * @throws IllegalArgumentException if the value mapped to by the key is not
+   * an int
+   * @throws IllegalArgumentException if the key is null
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Deprecated
+  public int getInt(String key) throws TableKeyNotDefinedException;
+
+  /**
+   * Returns the value at the specified key.
+   * @param key the key
+   * @param defaultValue the value returned if the key is undefined
+   * @return the value
+   * @throws IllegalArgumentException if the value mapped to by the key is not
+   * an int
+   * @throws IllegalArgumentException if the key is null
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Deprecated
+  public int getInt(String key, int defaultValue)
+      throws TableKeyNotDefinedException;
+
+  /**
+   * Maps the specified key to the specified value in this table.
+   * The key can not be null.
+   * The value can be retrieved by calling the get method with a key that is
+   * equal to the original key.
+   * @param key the key
+   * @param value the value
+   * @return False if the table key already exists with a different type
+   * @throws IllegalArgumentException if key is null
+   * @deprecated Use {@link #putNumber(String, double)} instead.
+   */
+  @Deprecated
+  public boolean putDouble(String key, double value);
+
+  /**
+   * Returns the value at the specified key.
+   * @param key the key
+   * @return the value
+   * @throws TableKeyNotDefinedException if there is no
+   * value mapped to by the key
+   * @throws IllegalArgumentException if the value mapped to by the key is not a
+   * double
+   * @throws IllegalArgumentException if the key is null
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Deprecated
+  public double getDouble(String key) throws TableKeyNotDefinedException;
+
+  /**
+   * Returns the value at the specified key.
+   * @param key the key
+   * @param defaultValue the value returned if the key is undefined
+   * @return the value
+   * @throws IllegalArgumentException if the value mapped to by the key is not a
+   * double
+   * @throws IllegalArgumentException if the key is null
+   * @deprecated Use {@link #getNumber(String, double)} instead.
+   */
+  @Deprecated
+  public double getDouble(String key, double defaultValue);
+}
diff --git a/java/src/edu/wpi/first/wpilibj/tables/ITableListener.java b/java/src/edu/wpi/first/wpilibj/tables/ITableListener.java
new file mode 100644
index 0000000..e1d9259
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/tables/ITableListener.java
@@ -0,0 +1,35 @@
+package edu.wpi.first.wpilibj.tables;
+
+/**
+ * A listener that listens to changes in values in a {@link ITable}
+ * 
+ * @author Mitchell
+ *
+ */
+@FunctionalInterface
+public interface ITableListener {
+    /**
+     * Called when a key-value pair is changed in a {@link ITable}
+     * @param source the table the key-value pair exists in
+     * @param key the key associated with the value that changed
+     * @param value the new value
+     * @param isNew true if the key did not previously exist in the table, otherwise it is false
+     */
+    public void valueChanged(ITable source, String key, Object value, boolean isNew);
+
+    /**
+     * Extended version of valueChanged.  Called when a key-value pair is
+     * changed in a {@link ITable}.  The default implementation simply calls
+     * valueChanged().  If this is overridden, valueChanged() will not be
+     * called.
+     * @param source the table the key-value pair exists in
+     * @param key the key associated with the value that changed
+     * @param value the new value
+     * @param flags update flags; for example, NOTIFY_NEW if the key did not
+     * previously exist in the table
+     */
+    default public void valueChangedEx(ITable source, String key, Object value, int flags) {
+        // NOTIFY_NEW = 0x04
+        valueChanged(source, key, value, (flags & 0x04) != 0);
+    }
+}
diff --git a/java/src/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java b/java/src/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java
new file mode 100644
index 0000000..4ca3a54
--- /dev/null
+++ b/java/src/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java
@@ -0,0 +1,20 @@
+package edu.wpi.first.wpilibj.tables;
+
+import java.util.NoSuchElementException;
+
+/**
+ * An exception throw when the lookup a a key-value fails in a {@link ITable}
+ * 
+ * @author Mitchell
+ *
+ */
+public class TableKeyNotDefinedException extends NoSuchElementException {
+
+	/**
+	 * @param key the key that was not defined in the table
+	 */
+	public TableKeyNotDefinedException(String key) {
+		super("Unknown Table Key: "+key);
+	}
+
+}
diff --git a/java/test/Client.java b/java/test/Client.java
new file mode 100644
index 0000000..7f18690
--- /dev/null
+++ b/java/test/Client.java
@@ -0,0 +1,39 @@
+import edu.wpi.first.wpilibj.networktables.*;
+import edu.wpi.first.wpilibj.tables.*;
+
+public class Client {
+  private static class MyLogger implements NetworkTablesJNI.LoggerFunction {
+    public void apply(int level, String file, int line, String msg) {
+      System.err.println(msg);
+    }
+  }
+
+  public static void main(String[] args) {
+    NetworkTablesJNI.setLogger(new MyLogger(), 0);
+    NetworkTable.setIPAddress("127.0.0.1");
+    NetworkTable.setPort(10000);
+    NetworkTable.setClientMode();
+    NetworkTable nt = NetworkTable.getTable("");
+    try { Thread.sleep(2000); } catch (InterruptedException e) {}
+    try {
+      System.out.println("Got foo: " + nt.getNumber("foo"));
+    } catch(TableKeyNotDefinedException ex) {
+    }
+    nt.putBoolean("bar", false);
+    nt.setFlags("bar", NetworkTable.PERSISTENT);
+    nt.putBoolean("bar2", true);
+    nt.putBoolean("bar2", false);
+    nt.putBoolean("bar2", true);
+    nt.putString("str", "hello world");
+    double[] nums = new double[3];
+    nums[0] = 0.5;
+    nums[1] = 1.2;
+    nums[2] = 3.0;
+    nt.putNumberArray("numarray", nums);
+    String[] strs = new String[2];
+    strs[0] = "Hello";
+    strs[1] = "World";
+    nt.putStringArray("strarray", strs);
+    try { Thread.sleep(10000); } catch (InterruptedException e) {}
+  }
+}
diff --git a/java/test/Server.java b/java/test/Server.java
new file mode 100644
index 0000000..33844fb
--- /dev/null
+++ b/java/test/Server.java
@@ -0,0 +1,26 @@
+import edu.wpi.first.wpilibj.networktables.*;
+import edu.wpi.first.wpilibj.tables.*;
+
+public class Server {
+  private static class MyLogger implements NetworkTablesJNI.LoggerFunction {
+    public void apply(int level, String file, int line, String msg) {
+      System.err.println(msg);
+    }
+  }
+
+  public static void main(String[] args) {
+    NetworkTablesJNI.setLogger(new MyLogger(), 0);
+    NetworkTable.setIPAddress("127.0.0.1");
+    NetworkTable.setPort(10000);
+    NetworkTable.setServerMode();
+    NetworkTable nt = NetworkTable.getTable("");
+    try { Thread.sleep(1000); } catch (InterruptedException e) {}
+    nt.putNumber("foo", 0.5);
+    nt.setFlags("foo", NetworkTable.PERSISTENT);
+    nt.putNumber("foo2", 0.5);
+    nt.putNumber("foo2", 0.7);
+    nt.putNumber("foo2", 0.6);
+    nt.putNumber("foo2", 0.5);
+    try { Thread.sleep(10000); } catch (InterruptedException e) {}
+  }
+}
