diff --git a/ntcore/.styleguide b/ntcore/.styleguide
new file mode 100644
index 0000000..4c00fa9
--- /dev/null
+++ b/ntcore/.styleguide
@@ -0,0 +1,31 @@
+cHeaderFileInclude {
+  _c\.h$
+}
+
+cppHeaderFileInclude {
+  (?<!_c)\.h$
+  \.inc$
+}
+
+cppSrcFileInclude {
+  \.cpp$
+}
+
+generatedFileExclude {
+  ntcore/doc/
+}
+
+repoRootNameOverride {
+  ntcore
+}
+
+includeGuardRoots {
+  ntcore/src/main/native/cpp/
+  ntcore/src/main/native/include/
+  ntcore/src/test/native/cpp/
+}
+
+includeOtherLibs {
+  ^support/
+  ^wpi/
+}
diff --git a/ntcore/CMakeLists.txt b/ntcore/CMakeLists.txt
new file mode 100644
index 0000000..1852702
--- /dev/null
+++ b/ntcore/CMakeLists.txt
@@ -0,0 +1,84 @@
+project(ntcore)
+
+include(CompileWarnings)
+include(AddTest)
+
+file(GLOB
+    ntcore_native_src src/main/native/cpp/*.cpp
+    ntcore_native_src src/main/native/cpp/networktables/*.cpp
+    ntcore_native_src src/main/native/cpp/tables/*.cpp)
+add_library(ntcore ${ntcore_native_src})
+set_target_properties(ntcore PROPERTIES DEBUG_POSTFIX "d")
+target_include_directories(ntcore PUBLIC
+                $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/include>
+                            $<INSTALL_INTERFACE:${include_dest}/ntcore>)
+wpilib_target_warnings(ntcore)
+target_link_libraries(ntcore PUBLIC wpiutil)
+
+set_property(TARGET ntcore PROPERTY FOLDER "libraries")
+
+install(TARGETS ntcore EXPORT ntcore DESTINATION "${main_lib_dest}")
+install(DIRECTORY src/main/native/include/ DESTINATION "${include_dest}/ntcore")
+
+if (MSVC OR FLAT_INSTALL_WPILIB)
+    set (ntcore_config_dir ${wpilib_dest})
+else()
+    set (ntcore_config_dir share/ntcore)
+endif()
+
+configure_file(ntcore-config.cmake.in ${CMAKE_BINARY_DIR}/ntcore-config.cmake )
+install(FILES ${CMAKE_BINARY_DIR}/ntcore-config.cmake DESTINATION ${ntcore_config_dir})
+install(EXPORT ntcore DESTINATION ${ntcore_config_dir})
+
+# Java bindings
+if (NOT WITHOUT_JAVA)
+    find_package(Java REQUIRED)
+    find_package(JNI REQUIRED)
+    include(UseJava)
+    set(CMAKE_JAVA_COMPILE_FLAGS "-Xlint:unchecked")
+
+    file(GLOB
+        ntcore_jni_src src/main/native/cpp/jni/NetworkTablesJNI.cpp)
+
+    file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
+    set(CMAKE_JNI_TARGET true)
+
+    if(${CMAKE_VERSION} VERSION_LESS "3.11.0")
+        set(CMAKE_JAVA_COMPILE_FLAGS "-h" "${CMAKE_CURRENT_BINARY_DIR}/jniheaders")
+        add_jar(ntcore_jar ${JAVA_SOURCES} INCLUDE_JARS wpiutil_jar OUTPUT_NAME ntcore)
+    else()
+        add_jar(ntcore_jar ${JAVA_SOURCES} INCLUDE_JARS wpiutil_jar OUTPUT_NAME ntcore GENERATE_NATIVE_HEADERS ntcore_jni_headers)
+    endif()
+
+    get_property(NTCORE_JAR_FILE TARGET ntcore_jar PROPERTY JAR_FILE)
+    install(FILES ${NTCORE_JAR_FILE} DESTINATION "${java_lib_dest}")
+
+    set_property(TARGET ntcore_jar PROPERTY FOLDER "java")
+
+    add_library(ntcorejni ${ntcore_jni_src})
+    wpilib_target_warnings(ntcorejni)
+    target_link_libraries(ntcorejni PUBLIC ntcore wpiutil)
+
+    set_property(TARGET ntcorejni PROPERTY FOLDER "libraries")
+
+    if (MSVC)
+        install(TARGETS ntcorejni RUNTIME DESTINATION "${jni_lib_dest}" COMPONENT Runtime)
+    endif()
+
+    if(${CMAKE_VERSION} VERSION_LESS "3.11.0")
+        target_include_directories(ntcorejni PRIVATE ${JNI_INCLUDE_DIRS})
+        target_include_directories(ntcorejni PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/jniheaders")
+    else()
+        target_link_libraries(ntcorejni PRIVATE ntcore_jni_headers)
+    endif()
+    add_dependencies(ntcorejni ntcore_jar)
+
+    install(TARGETS ntcorejni EXPORT ntcorejni DESTINATION "${main_lib_dest}")
+
+endif()
+
+if (WITH_TESTS)
+    wpilib_add_test(ntcore src/test/native/cpp)
+    target_include_directories(ntcore_test PRIVATE src/main/native/cpp)
+    target_link_libraries(ntcore_test ntcore gmock_main)
+endif()
diff --git a/ntcore/build.gradle b/ntcore/build.gradle
new file mode 100644
index 0000000..5739b71
--- /dev/null
+++ b/ntcore/build.gradle
@@ -0,0 +1,33 @@
+ext {
+    nativeName = 'ntcore'
+    devMain = 'edu.wpi.first.ntcore.DevMain'
+}
+
+apply from: "${rootDir}/shared/jni/setupBuild.gradle"
+
+nativeUtils.exportsConfigs {
+    ntcore {
+        x86ExcludeSymbols = ['_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
+                            '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
+                            '_TI5?AVfailure', '_CT??_R0?AVout_of_range', '_CTA3?AVout_of_range',
+                            '_TI3?AVout_of_range', '_CT??_R0?AVbad_cast']
+        x64ExcludeSymbols = ['_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
+                            '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
+                            '_TI5?AVfailure', '_CT??_R0?AVout_of_range', '_CTA3?AVout_of_range',
+                            '_TI3?AVout_of_range', '_CT??_R0?AVbad_cast']
+    }
+    ntcoreJNI {
+        x86SymbolFilter = { symbols ->
+            symbols.removeIf({ !it.startsWith('NT_') })
+        }
+        x64SymbolFilter = { symbols ->
+            symbols.removeIf({ !it.startsWith('NT_') })
+        }
+    }
+}
+
+if (!project.hasProperty('skipPMD')) {
+    pmdMain {
+        pmdMain.enabled = false
+    }
+}
diff --git a/ntcore/doc/alloy-model.adoc b/ntcore/doc/alloy-model.adoc
new file mode 100644
index 0000000..35ca7d8
--- /dev/null
+++ b/ntcore/doc/alloy-model.adoc
@@ -0,0 +1,198 @@
+= Network Tables Alloy Model
+
+Alloy (http://alloy.mit.edu/alloy/) is a formal logic tool that can analyze
+first-order logic expressions. Under the proposed sequence number -based
+protocol, assuming that all nodes start from the same state, Alloy is unable to
+find a way where two nodes with the same sequence number have different state
+when activity ceases.
+
+The model used is included below. Although Alloy cannot test all cases, since
+such an exhaustive search is intractable, it provides a high level of
+confidence in the proposed protocol.
+
+----
+--- Models a distributed, centralized hash table system called NetworkTables
+--- System state is protected by sequence numbers; the server's value for a certain sequence number always wins
+--- Paul Malmsten, 2012 pmalmsten@gmail.com
+
+open util/ordering[Time] as TO
+open util/natural as natural
+
+sig Time {}
+sig State {}
+
+--- Define nodes and server
+sig Node {
+    state: State -> Time,
+    sequenceNumber: Natural -> Time
+}
+
+--- Only one server
+one sig Server extends Node {
+}
+
+--- Define possible events
+abstract sig Event {
+    pre,post: Time,
+    receiver: one Node
+}
+
+// For all events, event.post is the time directly following event.pre
+fact {
+    all e:Event {
+        e.post = e.pre.next
+    }
+}
+
+// Represents that state has changed on a node
+sig StateChangeEvent extends Event {
+}
+
+// Represents that state has been transferred from one node to another
+sig StateTransferEvent extends Event {
+    sender: one Node
+}
+
+fact {
+    --- Every node must assume at most one state
+    all t:Time, n:Node | #n.state.t = 1
+
+    --- Every node must assume one sequence number
+    all t:Time, n:Node | #n.sequenceNumber.t = 1
+
+    --- Sequence numbers may only increment
+    all t:Time - last, n:Node | let t' = t.next | natural/gte[n.sequenceNumber.t', n.sequenceNumber.t]
+}
+
+
+fact stateChangedImpliesAStateTransfer {
+    all sce:StateChangeEvent {
+        // A StateChange on a client causes a transfer to the Server if its sequence number is greater than the server's
+        sce.receiver in Node - Server and natural/gt[sce.receiver.sequenceNumber.(sce.post), Server.sequenceNumber.(sce.post)]
+         implies
+            some ste:StateTransferEvent {
+                ste.pre = sce.post and ste.sender = sce.receiver and ste.receiver = Server
+            }
+    }
+
+    all sce:StateChangeEvent {
+        // A StateChange on the server causes a transfer to all clients
+        sce.receiver = Server implies
+            all n:Node - Server {
+                some ste:StateTransferEvent {
+                     ste.pre = sce.post and ste.sender = Server and ste.receiver = n
+                }
+            }
+    }
+
+    all sce:StateTransferEvent {
+        // A StateTransfer to the server causes a transfer to all clients
+        sce.receiver = Server implies
+            all n:Node - Server {
+                some ste:StateTransferEvent {
+                     ste.pre = sce.post and ste.sender = Server and ste.receiver = n
+                }
+            }
+    }
+}
+
+fact stateTransferEventsMoveState {
+    all ste:StateTransferEvent {
+        ste.sender = Server and not ste.receiver = Server or ste.receiver = Server and not ste.sender = Server
+
+        // Nodes can only post to the server if their sequence number is greater than the servers
+        ste.receiver = Server implies natural/gt[ste.sender.sequenceNumber.(ste.pre), ste.receiver.sequenceNumber.(ste.pre)]
+
+        // Server can only post to clients if its sequence number is greater than or equal to the client
+        ste.sender = Server implies natural/gte[ste.sender.sequenceNumber.(ste.pre), ste.receiver.sequenceNumber.(ste.pre)]
+
+        // Actual transfer
+        (ste.receiver.state.(ste.post) = ste.sender.state.(ste.pre) and
+          ste.receiver.sequenceNumber.(ste.post) = ste.sender.sequenceNumber.(ste.pre))
+    }
+}
+
+
+fact noEventsPendingAtEnd {
+    no e:Event {
+        e.pre = last
+    }
+}
+
+fact noDuplicateEvents {
+    all e,e2:Event {
+        // Two different events with the same receiver imply they occurred at different times
+        e.receiver = e2.receiver and e != e2 implies e.pre != e2.pre
+    }
+}
+
+fact noStateTransfersToSelf {
+    all ste:StateTransferEvent {
+        ste.sender != ste.receiver
+    }
+}
+
+fact noDuplicateStateTransferEvents {
+    all ste,ste2:StateTransferEvent {
+        // Two state transfer events with the same nodes imply that they occurred at different times
+        ste.sender = ste2.sender and ste.receiver = ste2.receiver and ste != ste2 implies ste.pre != ste2.pre
+    }
+}
+
+--- Trace (time invariant)
+fact trace {
+    all t:Time - last | let t' = t.next {
+        all n:Node {
+                // A node in (pre.t).receiver means it is being pointed to by some event that will happen over the next time step
+                n in (pre.t).receiver implies n.state.t' != n.state.t and n.sequenceNumber.t' != n.sequenceNumber.t    // A node which receives some sort of event at time t causes it to change state
+                                                       else n.state.t' = n.state.t and n.sequenceNumber.t' = n.sequenceNumber.t     // Otherwise, it does not change state
+        }
+    }
+}
+
+--- Things we might like to be true, but are not always true
+
+pred atLeastOneEvent {
+    #Event >= 1
+}
+
+pred allNodesStartAtSameStateAndSequenceNumber {
+    all n,n2:Node {
+        n.state.first = n2.state.first and n.sequenceNumber.first = n2.sequenceNumber.first
+    }
+}
+
+pred noStateChangeEventsAtEnd {
+    no e:StateChangeEvent {
+        e.post = last
+    }
+}
+
+--- Demonstration (Alloy will try to satisfy this)
+
+pred show {
+    atLeastOneEvent
+}
+run show
+
+--- Assertions (Alloy will try to break these)
+
+assert allNodesConsistentAtEnd {
+    allNodesStartAtSameStateAndSequenceNumber implies
+        all n,n2:Node {
+            // At the end of a sequence (last) all nodes with the same sequence number have the same state
+            n.sequenceNumber.last = n2.sequenceNumber.last implies n.state.last = n2.state.last
+        }
+}
+check allNodesConsistentAtEnd for 3 Event, 10 Node, 3 State, 5 Time, 5 Natural
+check allNodesConsistentAtEnd for 8 Event, 2 Node, 5 State, 9 Time, 9 Natural
+
+assert serverHasHighestSeqNumAtEnd {
+    allNodesStartAtSameStateAndSequenceNumber implies
+        all n:Node - Server{
+            // At the end of a sequence (last) all nodes with the same sequence number have the same state
+            natural/gte[Server.sequenceNumber.last, n.sequenceNumber.last]
+        }
+}
+check serverHasHighestSeqNumAtEnd for 3 Event, 10 Node, 3 State, 5 Time, 5 Natural
+----
diff --git a/ntcore/doc/networktables2.adoc b/ntcore/doc/networktables2.adoc
new file mode 100644
index 0000000..8471f86
--- /dev/null
+++ b/ntcore/doc/networktables2.adoc
@@ -0,0 +1,456 @@
+= Network Tables Protocol Specification, Version 2.0
+WPILib Developers <wpilib@wpi.edu>
+Protocol Revision 2.0 (0x0200), 1/8/2013
+:toc:
+:toc-placement: preamble
+:sectanchors:
+
+This document defines a network protocol for a key-value store that may be read
+from and written to by multiple remote clients. A central server, most often
+running on a FIRST FRC robot controller, is responsible for providing
+information consistency and for facilitating communication between clients.
+This document describes protocol revision 2.0 (0x0200).
+
+Information consistency is guaranteed through the use of a sequence number
+associated with each key-value pair. An update of a key-value pair increments
+the associated sequence number, and this update information is shared with all
+participating clients. The central server only applies and redistributes
+updates which have a larger sequence number than its own, which guarantees that
+a client must have received a server's most recent state before it can replace
+it with a new value.
+
+This is a backwards-incompatible rework of the Network Tables network protocol
+originally introduced for the 2012 FIRST Robotics Competition. Note that this
+revision of the Network Tables protocol no longer includes the concept of
+sub-tables. We suggest that instead of representing sub-tables as first-class
+data types in the network protocol, it would be easy for an implementation to
+provide a similar API abstraction by adding prefixes to keys. For example, we
+suggest using Unix-style path strings to define sub-table hierarchies. The
+prefix ensures that sub-table namespaces do not collide in a global hashtable
+without requiring an explicit sub-table representation.
+
+In addition, the explicit concept of grouping multiple updates such that they
+are all visible at the same time to user code on a remote device was discarded.
+Instead, array types for all common elements are provided. By using an array
+data type, users may achieve the same level of atomicity for common operations
+(e.g. sending a cartesian coordinate pair) without requiring the complexity of
+arbitrarily grouped updates.
+
+This document conforms to <<rfc2119>> - Key words for use in RFCs to Indicate
+Requirement Levels.
+
+[[references]]
+== References
+
+[[rfc1982,RFC 1982]]
+* RFC 1982, Serial Number Arithmetic, http://tools.ietf.org/html/rfc1982
+
+[[rfc2119,RFC 2119]]
+* RFC 2119, Key words for use in RFCs to Indicate Requirement Levels,
+http://tools.ietf.org/html/rfc2119
+
+[[definitions]]
+== Definitions
+
+[[def-client]]
+Client:: An implementation of this protocol running in client configuration.
+Any number of Clients may exist for a given Network.
+
+[[def-entry]]
+Entry:: A data value identified by a string name.
+
+[[def-entry-id]]
+Entry ID:: An unsigned 2-byte ID by which the Server and Clients refer to an
+Entry across the network instead of using the full string key for the Entry.
+Entry IDs range from 0x0000 to 0xFFFE (0xFFFF is reserved for an Entry
+Assignment issued by a Client).
+
+[[def-server]]
+Server:: An implementation of this protocol running in server configuration.
+One and only one Server must exist for a given Network.
+
+[[def-network]]
+Network:: One or more Client nodes connected to a Server.
+
+[[def-user-code]]
+User Code:: User-supplied code which may interact with a Client or Server. User
+Code should be executed on the same computer as the Client or Server instance
+it interacts with.
+
+[[def-sequence-number]]
+Sequence Number:: An unsigned number which allows the Server to resolve update
+conflicts between Clients and/or the Server. Sequence numbers may overflow.
+Sequential arithmetic comparisons, which must be used with Sequence Numbers,
+are defined by RFC 1982.
+
+[[def-protocol-revision]]
+Protocol Revision:: A 16-bit unsigned integer which indicates the version of
+the network tables protocol that a client wishes to use. The protocol revision
+assigned to this version of the network tables specification is listed at the
+top of this document. This number is listed in dot-decimal notation as well as
+its equivalent hexadecimal value.
+
+== Transport Layer
+
+Conventional implementations of this protocol should use TCP for reliable
+communication; the Server should listen on TCP port 1735 for incoming
+connections.
+
+== Example Exchanges
+
+[[exchange-connect]]
+=== Client Connects to the Server
+
+Directly after client establishes a connection with the Server, the following
+procedure must be followed:
+
+. The Client sends a <<msg-client-hello>> message to the Server
+
+. The Server sends one <<msg-assign>> for every field it currently recognizes.
+
+. The Server sends a <<msg-server-hello-complete>> message.
+
+. For all Entries the Client recognizes that the Server did not identify with a
+Entry Assignment, the client follows the <<exchange-client-creates-entry>>
+protocol.
+
+In the event that the Server does not support the protocol revision that the
+Client has requested in a Client Hello message, the Server must instead issue a
+<<msg-protocol-unsupported>> message to the joining client and close the
+connection.
+
+[[exchange-client-creates-entry]]
+=== Client Creates an Entry
+
+When User Code on a Client assigns a value to an Entry that the Server has not
+yet issued a Entry Assignment for, the following procedure must be followed:
+
+. The Client sends an <<msg-assign>> with an Entry ID of 0xFFFF.
+
+. The Server issues an <<msg-assign>> to all Clients (including the sender) for
+the new field containing a real Entry ID and Sequence Number for the new field.
+
+In the event that User Code on the Client updates the value of the
+to-be-announced field again before the expected Entry Assignment is received,
+then the Client must save the new value and take no other action (the most
+recent value of the field should be issued when the Entry Assignment arrives,
+if it differs from the value contained in the received Entry Assignment).
+
+In the event that the Client receives a Entry Assignment from the Server for
+the Entry that it intended to issue an Entry Assignment for, before it issued
+its own Entry Assignment, the procedure may end early.
+
+In the event that the Server receives a duplicate Entry Assignment from a
+Client (likely due to the client having not yet received the Server's Entry
+Assignment), the Server should ignore the duplicate Entry Assignment.
+
+[[exchange-client-updates-entry]]
+=== Client Updates an Entry
+
+When User Code on a Client updates the value of an Entry, the Client must send
+an <<msg-update>> message to the Server. The Sequence Number included in the
+Entry Update message must be the most recently received Sequence Number for the
+Entry to be updated incremented by one.
+
+.Example:
+
+. Client receives Entry Assignment message for Entry "a" with integer value 1,
+Entry ID of 0, and Sequence Number 1.
+
+. User Code on Client updates value of Entry "a" to 16 (arbitrary).
+
+. Client sends Entry Update message to Server for Entry 0 with a Sequence
+Number of 2 and a value of 16.
+
+When the Server receives an Entry Update message, it first checks the Sequence
+Number in the message against the Server's value for the Sequence Number
+associated with the Entry to be updated. If the received Sequence Number is
+strictly greater than (aside: see definition of "greater than" under the
+definition of Sequence Number) the Server's Sequence Number for the Entry to be
+updated, the Server must apply the new value for the indicated Entry and repeat
+the Entry Update message to all other connected Clients.
+
+If the received Sequence Number is less than or equal (see definition of "less
+than or equal" in RFC 1982) to the Server's Sequence Number for the Entry to be
+updated, this implies that the Client which issued the Entry Update message has
+not yet received one or more Entry Update message(s) that the Server recently
+sent to it; therefore, the Server must ignore the received Entry Update
+message. In the event that comparison between two Sequence Numbers is undefined
+(see RFC 1982), then the Server must always win (it ignores the Entry Update
+message under consideration).
+
+[[update-rate]]
+NOTE: If User Code modifies the value of an Entry too quickly, 1) users may not
+see every value appear on remote machines, and 2) the consistency protection
+offered by the Entry's Sequence Number may be lost (by overflowing before
+remote devices hear recent values). It is recommended that implementations
+detect when user code updates an Entry more frequently than once every 5
+milliseconds and print a warning message to the user (and/or offer some other
+means of informing User Code of this condition).
+
+[[exchange-server-creates-entry]]
+=== Server Creates an Entry
+
+When User Code on the Server assigns a value to a Entry which does not exist,
+the Server must issue an <<msg-assign>> message to all connected clients.
+
+[[exchange-server-updates-entry]]
+=== Server Updates an Entry
+
+When User Code on the Server updates the value of an Entry, the Server must
+apply the new value to the Entry immediately, increment the associated Entry's
+Sequence Number, and issue a <<msg-update>> message containing the new value
+and Sequence Number of the associated Entry to all connected Clients.
+
+NOTE: See <<update-rate,Note>> under <<exchange-client-updates-entry>>.
+
+[[exchange-keep-alive]]
+=== Keep Alive
+
+To maintain a connection and prove a socket is still open, a Client or Server
+may issue <<msg-keep-alive>> messages. Clients and the Server should ignore
+incoming Keep Alive messages.
+
+The intent is that by writing a Keep Alive to a socket, a Client forces its
+network layer (TCP) to reevaluate the state of the network connection as it
+attempts to deliver the Keep Alive message. In the event that a connection is
+no longer usable, a Client's network layer should inform the Client that it is
+no longer usable within a few attempts to send a Keep Alive message.
+
+To provide timely connection status information, Clients should send a Keep
+Alive message to the Server after every 1 second period of connection
+inactivity (i.e. no information is being sent to the Server). Clients should
+not send Keep Alive messages more frequently than once every 100 milliseconds.
+
+Since the Server does not require as timely information about the status of a
+connection, it is not required to send Keep Alive messages during a period of
+inactivity.
+
+[[bandwidth]]
+== Bandwidth and Latency Considerations
+
+To reduce unnecessary bandwidth usage, implementations of this protocol should:
+
+* Send an Entry Update if and only if the value of an Entry is changed to a
+value that is different from its prior value.
+
+* Buffer messages and transmit them in groups, when possible, to reduce
+transport protocol overhead.
+
+* Only send the most recent value of an Entry. When User Code updates the value
+of an Entry more than once before the new value is transmitted, only the latest
+value of the Entry should be sent.
+
+It is important to note that these behaviors will increase the latency between
+when a Client or Server updates the value of an Entry and when all Clients
+reflect the new value. The exact behavior of this buffering is left to
+implementations to determine, although the chosen scheme should reflect the
+needs of User Code. Implementations may include a method by which User Code can
+specify the maximum tolerable send latency.
+
+[[entry-types]]
+== Entry Types
+
+Entry Type must assume one the following values:
+
+[cols="1,3"]
+|===
+|Numeric Value |Type
+
+|0x00
+|Boolean
+
+|0x01
+|Double
+
+|0x02
+|String
+
+|0x10
+|Boolean Array
+
+|0x11
+|Double Array
+
+|0x12
+|String Array
+|===
+
+[[entry-values]]
+== Entry Values
+
+Entry Value must assume the following structure as indicated by Entry Type:
+
+[cols="1,3"]
+|===
+|Entry Type |Entry Value Format
+
+|[[entry-value-boolean]]Boolean
+|1 byte, unsigned; True = 0x01, False = 0x00
+
+|[[entry-value-double]]Double
+|8 bytes, IEEE 754 floating-point "double format" bit layout; (big endian)
+
+|[[entry-value-string]]String
+|2 byte, unsigned length prefix (big endian) of the number of raw bytes to
+follow, followed by the string encoded in UTF-8
+
+|[[entry-value-boolean-array]]Boolean Array
+|1 byte, unsigned, number of elements within the array to follow
+
+N bytes - The raw bytes representing each Boolean element contained within the
+array, beginning with the item at index 0 within the array.
+
+|[[entry-value-double-array]]Double Array
+|1 byte, unsigned, number of elements within the array to follow
+
+N bytes - The raw bytes representing each Double element contained within the
+array, beginning with the item at index 0 within the array.
+
+|[[entry-value-string-array]]String Array
+|1 byte, unsigned, number of elements within the array to follow
+
+N bytes - The raw bytes representing each String element contained within the
+array, beginning with the item at index 0 within the array.
+|===
+
+== Message Structures
+
+All messages are of the following format:
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|Message Type
+|1 byte, unsigned
+
+|Message Data
+|N bytes (length determined by Message Type)
+|===
+
+[[msg-keep-alive]]
+=== Keep Alive
+
+Indicates that the remote party is checking the status of a network connection.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x00 - Keep Alive
+|1 byte, unsigned; Message Type
+|===
+
+[[msg-client-hello]]
+=== Client Hello
+
+A Client issues a Client Hello message when first establishing a connection.
+The Client Protocol Revision field specifies the Network Table protocol
+revision that the Client would like to use.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x01 - Client Hello
+|1 byte, unsigned; Message Type
+
+|Client Protocol Revision
+|2 bytes, Unsigned 16-bit integer (big-endian).
+
+See <<def-protocol-revision,Protocol Revision>>
+|===
+
+[[msg-protocol-unsupported]]
+=== Protocol Version Unsupported
+
+A Server issues a Protocol Version Unsupported message to a Client to inform it
+that the requested protocol revision is not supported. It also includes the
+most recent protocol revision which it supports, such that a Client may
+reconnect under a prior protocol revision if able.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x02 - Protocol Version Unsupported
+|1 byte, unsigned; Message Type
+
+|Server Supported Protocol Revision
+|2 bytes, Unsigned 16-bit integer (big-endian).
+
+See <<def-protocol-revision,Protocol Revision>>
+|===
+
+[[msg-server-hello-complete]]
+=== Server Hello Complete
+
+A Server issues a Server Hello Complete message when it has finished informing
+a newly-connected client of all of the fields it currently recognizes.
+Following the receipt of this message, a Client should inform the Server of
+any/all additional fields that it recognizes that the Server did not announce.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x03 - Server Hello Complete
+|1 byte, unsigned; Message Type
+|===
+
+[[msg-assign]]
+=== Entry Assignment
+
+A Entry Assignment message informs the remote party of a new Entry. An Entry
+Assignment's value field must be the most recent value of the field being
+assigned at the time that the Entry Assignment is sent.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x10 - Entry Assignment
+|1 byte, unsigned; Message Type
+
+|Entry Name
+|<<entry-value-string,String>>
+
+|Entry Type
+|1 byte, unsigned; see <<entry-types,Entry Types>>
+
+|Entry ID
+|2 bytes, unsigned
+
+|Entry Sequence Number
+|2 bytes, unsigned
+
+|Entry Value
+|N bytes, length depends on Entry Type
+|===
+
+If the Entry ID is 0xFFFF, then this assignment represents a request from a
+Client to the Server. In this event, the Entry ID field and the Entry Sequence
+Number field must not be stored or relied upon as they otherwise would be.
+
+[[msg-update]]
+=== Entry Update
+
+An Entry Update message informs a remote party of a new value for an Entry.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x11 - Entry Update
+|1 byte, unsigned; Message Type
+
+|Entry ID
+|2 bytes, unsigned
+
+|Entry Sequence Number
+|2 bytes, unsigned
+
+|Entry Value
+|N bytes, length dependent on value type
+|===
diff --git a/ntcore/doc/networktables3.adoc b/ntcore/doc/networktables3.adoc
new file mode 100644
index 0000000..af8b953
--- /dev/null
+++ b/ntcore/doc/networktables3.adoc
@@ -0,0 +1,885 @@
+= Network Tables Protocol Specification, Version 3.0
+WPILib Developers <wpilib@wpi.edu>
+Protocol Revision 3.0 (0x0300), 6/12/2015
+:toc:
+:toc-placement: preamble
+:sectanchors:
+
+This document defines a network protocol for a key-value store that may be read
+from and written to by multiple remote clients. A central server, most often
+running on a FIRST FRC robot controller, is responsible for providing
+information consistency and for facilitating communication between clients.
+This document describes protocol revision 3.0 (0x0300).
+
+Information consistency is guaranteed through the use of a sequence number
+associated with each key-value pair. An update of a key-value pair increments
+the associated sequence number, and this update information is shared with all
+participating clients. The central server only applies and redistributes
+updates which have a larger sequence number than its own, which guarantees that
+a client must have received a server's most recent state before it can replace
+it with a new value.
+
+This is a backwards-compatible update of <<networktables2,version 2.0>> of the
+Network Tables network protocol. The protocol is designed such that 3.0 clients
+and servers can interoperate with 2.0 clients and servers with the only loss of
+functionality being the extended features introduced in 3.0.
+
+This document conforms to <<rfc2119>> - Key words for use in RFCs to Indicate
+Requirement Levels.
+
+== Summary of Changes from 2.0 to 3.0
+
+3 way connection handshake:: When a Client establishes a connection, after
+receiving the <<msg-server-hello-complete>> message and sending its local
+entries, it finishes with a <<msg-client-hello-complete>> message to the
+server. This enables the Server to be aware of when the Client is fully
+synchronized.
+
+String length encoding:: String length is now encoded as unsigned <<leb128>>
+rather than as a 2-byte unsigned integer. This both allows string lengths
+longer than 64K and is more space efficient for the common case of short
+strings (<128 byte strings only require a single byte for length).
+
+Entry deletion:: Entries may now be deleted by any member of the Network using
+the <<msg-delete>> and <<msg-clear-all>> messages. Note that in a Network
+consisting of mixed 2.0 and 3.0 Clients, deletion may be ineffective because
+the deletion message will not be propagated to the 2.0 Clients.
+
+// TODO: needs more description in the text of how these messages are
+// propagated
+
+Remote procedure call:: The Server may create specially-typed entries that
+inform Clients of remotely callable functions on the Server. Clients can then
+execute these functions via the Network Tables protocol. See <<rpc-operation>>.
+
+Raw data type:: An arbitrary data type has been added. While string could be
+used to encode raw data, the reason for a different data type is so that
+dashboards can choose not to display the raw data (or display it in a different
+format).
+
+Client and server self-identification:: Clients self-identify with a
+user-defined string name when connecting to the Server (this is part of the new
+<<msg-client-hello-complete>> message). This provides a more reliable method
+than simply the remote IP address for determining on the Server side whether or
+not a particular Client is connected.  While Clients are less likely to care
+what Server they are connected to, for completeness a similar Server
+self-identification string has been added to the Server Hello Complete message.
+Note that Server connection information is not provided from the Server to
+Clients (at least in a way built into the protocol), so it is not possible for
+a Client to determine what other Clients are connected to the Server.
+
+Server reboot detection:: The Server keeps an internal list of all Client
+identity strings that have ever connected to it (this list is always empty at
+Server start). During the initial connection process, the Server sends the
+Client a flag (as part of the new <<msg-server-hello>> message) that indicates
+whether or not the Client was already on this list. Clients use this flag to
+determine whether the Server has rebooted since the previous connection.
+
+Entry flags:: Each Entry now has an 8-bit flags value associated with it (see
+<<entry-flags>>). The initial value of the flags are provided as part of the
+<<msg-assign>> message. The value of the flags may be updated by any member of
+the Network via use of the <<msg-flags-update>> message.
+
+Entry persistence:: The Server is required to provide a feature to
+automatically save entries (including their last known values) across Server
+restarts. By default, no values are automatically saved in this manner, but
+any member of the Network may set the “Persistent” Entry Flag on an Entry to
+indicate to the server that the Entry must be persisted by the Server. The
+Server must periodically save such flagged Entries to a file; on Server start,
+the Server reads the file to create the initial set of Server Entries.
+
+More robust Entry Update message encoding:: The entry type has been added to
+the <<msg-update>> message. This is used only to specify the length of value
+encoded in the Entry Update message, and has no effect on the Client or Server
+handling of Entry Updates. Clients and Servers must ignore Entry Update
+messages with mismatching type to their currently stored value. This increases
+robustness of Entry Updates in the presence of Entry Assignments with varying
+type (which should be uncommon, but this fixes a weakness in the 2.0 protocol).
+
+////
+TODO
+
+Synchronization on reconnect:: The approach to how Clients should handle
+conflicting values when reconnecting to a Server has been clarified.
+
+////
+
+[[references]]
+== References
+
+[[networktables2]]
+* <<networktables2.adoc#,Network Tables Protocol Specification, Protocol
+Revision 2.0 (0x0200)>>, dated 1/8/2013.
+
+[[leb128,LEB128]]
+* LEB128 definition in DWARF Specification 3.0
+(http://dwarfstd.org/doc/Dwarf3.pdf, section 7.6 and Appendix C, also explained
+in http://en.wikipedia.org/wiki/LEB128)
+
+[[rfc1982,RFC1982]]
+* RFC 1982, Serial Number Arithmetic, http://tools.ietf.org/html/rfc1982
+
+[[rfc2119,RFC2119]]
+* RFC 2119, Key words for use in RFCs to Indicate Requirement Levels,
+http://tools.ietf.org/html/rfc2119
+
+[[definitions]]
+== Definitions
+
+[[def-client]]
+Client:: An implementation of this protocol running in client configuration.
+Any number of Clients may exist for a given Network.
+
+[[def-entry]]
+Entry:: A data value identified by a string name.
+
+[[def-entry-id]]
+Entry ID:: An unsigned 2-byte ID by which the Server and Clients refer to an
+Entry across the network instead of using the full string key for the Entry.
+Entry IDs range from 0x0000 to 0xFFFE (0xFFFF is reserved for an Entry
+Assignment issued by a Client).
+
+[[def-server]]
+Server:: An implementation of this protocol running in server configuration.
+One and only one Server must exist for a given Network.
+
+[[def-network]]
+Network:: One or more Client nodes connected to a Server.
+
+[[def-user-code]]
+User Code:: User-supplied code which may interact with a Client or Server. User
+Code should be executed on the same computer as the Client or Server instance
+it interacts with.
+
+[[def-sequence-number]]
+Sequence Number:: An unsigned number which allows the Server to resolve update
+conflicts between Clients and/or the Server. Sequence numbers may overflow.
+Sequential arithmetic comparisons, which must be used with Sequence Numbers,
+are defined by <<rfc1982>>.
+
+[[def-protocol-revision]]
+Protocol Revision:: A 16-bit unsigned integer which indicates the version of
+the network tables protocol that a client wishes to use. The protocol revision
+assigned to this version of the network tables specification is listed at the
+top of this document. This number is listed in dot-decimal notation as well as
+its equivalent hexadecimal value.
+
+== Transport Layer
+
+Conventional implementations of this protocol should use TCP for reliable
+communication; the Server should listen on TCP port 1735 for incoming
+connections.
+
+== Example Exchanges
+
+[[exchange-connect]]
+=== Client Connects to the Server
+
+Directly after client establishes a connection with the Server, the following
+procedure must be followed:
+
+. The Client sends a <<msg-client-hello>> message to the Server
+
+. The Server sends a <<msg-server-hello>> message.
+
+. The Server sends one <<msg-assign>> for every field it currently recognizes.
+
+. The Server sends a <<msg-server-hello-complete>> message.
+
+. For all Entries the Client recognizes that the Server did not identify with a
+Entry Assignment, the client follows the <<exchange-client-creates-entry>>
+protocol.
+
+. The Client sends a <<msg-client-hello-complete>> message.
+
+In the event that the Server does not support the protocol revision that the
+Client has requested in a Client Hello message, the Server must instead issue a
+<<msg-protocol-unsupported>> message to the joining client and close the
+connection.
+
+[[exchange-client-creates-entry]]
+=== Client Creates an Entry
+
+When User Code on a Client assigns a value to an Entry that the Server has not
+yet issued a Entry Assignment for, the following procedure must be followed:
+
+. The Client sends an <<msg-assign>> with an Entry ID of 0xFFFF.
+
+. The Server issues an <<msg-assign>> to all Clients (including the sender) for
+the new field containing a real Entry ID and Sequence Number for the new field.
+
+In the event that User Code on the Client updates the value of the
+to-be-announced field again before the expected Entry Assignment is received,
+then the Client must save the new value and take no other action (the most
+recent value of the field should be issued when the Entry Assignment arrives,
+if it differs from the value contained in the received Entry Assignment).
+
+In the event that the Client receives a Entry Assignment from the Server for
+the Entry that it intended to issue an Entry Assignment for, before it issued
+its own Entry Assignment, the procedure may end early.
+
+In the event that the Server receives a duplicate Entry Assignment from a
+Client (likely due to the client having not yet received the Server's Entry
+Assignment), the Server should ignore the duplicate Entry Assignment.
+
+[[exchange-client-updates-entry]]
+=== Client Updates an Entry
+
+When User Code on a Client updates the value of an Entry, the Client must send
+an <<msg-update>> message to the Server. The Sequence Number included in the
+Entry Update message must be the most recently received Sequence Number for the
+Entry to be updated incremented by one.
+
+.Example:
+
+. Client receives Entry Assignment message for Entry "a" with integer value 1,
+Entry ID of 0, and Sequence Number 1.
+
+. User Code on Client updates value of Entry "a" to 16 (arbitrary).
+
+. Client sends Entry Update message to Server for Entry 0 with a Sequence
+Number of 2 and a value of 16.
+
+When the Server receives an Entry Update message, it first checks the Sequence
+Number in the message against the Server's value for the Sequence Number
+associated with the Entry to be updated. If the received Sequence Number is
+strictly greater than (aside: see definition of "greater than" under the
+definition of Sequence Number) the Server's Sequence Number for the Entry to be
+updated, the Server must apply the new value for the indicated Entry and repeat
+the Entry Update message to all other connected Clients.
+
+If the received Sequence Number is less than or equal (see definition of "less
+than or equal" in RFC 1982) to the Server's Sequence Number for the Entry to be
+updated, this implies that the Client which issued the Entry Update message has
+not yet received one or more Entry Update message(s) that the Server recently
+sent to it; therefore, the Server must ignore the received Entry Update
+message. In the event that comparison between two Sequence Numbers is undefined
+(see RFC 1982), then the Server must always win (it ignores the Entry Update
+message under consideration).
+
+[[update-rate]]
+NOTE: If User Code modifies the value of an Entry too quickly, 1) users may not
+see every value appear on remote machines, and 2) the consistency protection
+offered by the Entry's Sequence Number may be lost (by overflowing before
+remote devices hear recent values). It is recommended that implementations
+detect when user code updates an Entry more frequently than once every 5
+milliseconds and print a warning message to the user (and/or offer some other
+means of informing User Code of this condition).
+
+[[exchange-client-updates-flags]]
+=== Client Updates an Entry's Flags
+
+When User Code on a Client updates an Entry's flags, the Client must apply the
+new flags to the Entry immediately, and send an <<msg-flags-update>> message to
+the Server.
+
+When the Server receives an Entry Flags Update message, it must apply the new
+flags to the indicated Entry and repeat the Entry Flags Update message to all
+other connected Clients.
+
+[[exchange-client-deletes-entry]]
+=== Client Deletes an Entry
+
+When User Code on a Client deletes an Entry, the Client must immediately delete
+the Entry, and send an <<msg-delete>> message to the Server.
+
+When the Server receives an Entry Delete message, it must delete the indicated
+Entry and repeat the Entry Delete message to all other connected Clients.
+
+[[exchange-server-creates-entry]]
+=== Server Creates an Entry
+
+When User Code on the Server assigns a value to a Entry which does not exist,
+the Server must issue an <<msg-assign>> message to all connected clients.
+
+[[exchange-server-updates-entry]]
+=== Server Updates an Entry
+
+When User Code on the Server updates the value of an Entry, the Server must
+apply the new value to the Entry immediately, increment the associated Entry's
+Sequence Number, and issue a <<msg-update>> message containing the new value
+and Sequence Number of the associated Entry to all connected Clients.
+
+NOTE: See <<update-rate,Note>> under <<exchange-client-updates-entry>>.
+
+[[exchange-server-updates-flags]]
+=== Server Updates an Entry's Flags
+
+When User Code on the Server updates an Entry's flags, the Server must apply
+the new flags to the Entry immediately, and issue a <<msg-flags-update>>
+message containing the new flags value to all connected Clients.
+
+[[exchange-server-deletes-entry]]
+=== Server Deletes an Entry
+
+When User Code on the Server deletes an Entry, the Server must immediately
+delete the Entry, and issue a <<msg-delete>> message to all connected Clients.
+
+[[exchange-keep-alive]]
+=== Keep Alive
+
+To maintain a connection and prove a socket is still open, a Client or Server
+may issue <<msg-keep-alive>> messages. Clients and the Server should ignore
+incoming Keep Alive messages.
+
+The intent is that by writing a Keep Alive to a socket, a Client forces its
+network layer (TCP) to reevaluate the state of the network connection as it
+attempts to deliver the Keep Alive message. In the event that a connection is
+no longer usable, a Client's network layer should inform the Client that it is
+no longer usable within a few attempts to send a Keep Alive message.
+
+To provide timely connection status information, Clients should send a Keep
+Alive message to the Server after every 1 second period of connection
+inactivity (i.e. no information is being sent to the Server). Clients should
+not send Keep Alive messages more frequently than once every 100 milliseconds.
+
+Since the Server does not require as timely information about the status of a
+connection, it is not required to send Keep Alive messages during a period of
+inactivity.
+
+[[bandwidth]]
+== Bandwidth and Latency Considerations
+
+To reduce unnecessary bandwidth usage, implementations of this protocol should:
+
+* Send an Entry Update if and only if the value of an Entry is changed to a
+value that is different from its prior value.
+
+* Buffer messages and transmit them in groups, when possible, to reduce
+transport protocol overhead.
+
+* Only send the most recent value of an Entry. When User Code updates the value
+of an Entry more than once before the new value is transmitted, only the latest
+value of the Entry should be sent.
+
+It is important to note that these behaviors will increase the latency between
+when a Client or Server updates the value of an Entry and when all Clients
+reflect the new value. The exact behavior of this buffering is left to
+implementations to determine, although the chosen scheme should reflect the
+needs of User Code. Implementations may include a method by which User Code can
+specify the maximum tolerable send latency.
+
+[[entry-types]]
+== Entry Types
+
+Entry Type must assume one the following values:
+
+[cols="1,3"]
+|===
+|Numeric Value |Type
+
+|0x00
+|Boolean
+
+|0x01
+|Double
+
+|0x02
+|String
+
+|0x03
+|Raw Data
+
+|0x10
+|Boolean Array
+
+|0x11
+|Double Array
+
+|0x12
+|String Array
+
+|0x20
+|Remote Procedure Call Definition
+|===
+
+[[entry-values]]
+== Entry Values
+
+Entry Value must assume the following structure as indicated by Entry Type:
+
+[cols="1,3"]
+|===
+|Entry Type |Entry Value Format
+
+|[[entry-value-boolean]]Boolean
+|1 byte, unsigned; True = 0x01, False = 0x00
+
+|[[entry-value-double]]Double
+|8 bytes, IEEE 754 floating-point "double format" bit layout; (big endian)
+
+|[[entry-value-string]]String
+|N bytes, unsigned <<leb128>> encoded length of the number of raw bytes to
+follow, followed by the string encoded in UTF-8
+
+|[[entry-value-raw]]Raw Data
+|N bytes, unsigned LEB128 encoded length of the number of raw bytes to follow,
+followed by the raw bytes.
+
+While the raw data definition is unspecified, it's recommended that users use
+the first byte of the raw data to "tag" the type of data actually being stored.
+
+|[[entry-value-boolean-array]]Boolean Array
+|1 byte, unsigned, number of elements within the array to follow
+
+N bytes - The raw bytes representing each Boolean element contained within the
+array, beginning with the item at index 0 within the array.
+
+|[[entry-value-double-array]]Double Array
+|1 byte, unsigned, number of elements within the array to follow
+
+N bytes - The raw bytes representing each Double element contained within the
+array, beginning with the item at index 0 within the array.
+
+|[[entry-value-string-array]]String Array
+|1 byte, unsigned, number of elements within the array to follow
+
+N bytes - The raw bytes representing each String element contained within the
+array, beginning with the item at index 0 within the array.
+
+|[[entry-value-rpc]]Remote Procedure Call Definition
+|N bytes, unsigned LEB128 encoded length of the number of raw bytes to follow.
+
+N bytes - data as defined in Remote Procedure Call Definition Data
+|===
+
+[[entry-flags]]
+== Entry Flags
+
+Entry Flags are as follows:
+
+[cols="1,3"]
+|===
+|Bit Mask |Bit Value Meaning
+
+|[[entry-flag-persistent]]0x01 (least significant bit) - Persistent
+
+|0x00: Entry is not persistent. The entry and its value will not be retained
+across a server restart.
+
+0x01: Entry is persistent. Updates to the value are automatically saved and
+the entry will be automatically created and the last known value restored when
+the server starts.
+
+|0xFE
+|Reserved
+|===
+
+== Message Structures
+
+All messages are of the following format:
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|Message Type
+|1 byte, unsigned
+
+|Message Data
+|N bytes (length determined by Message Type)
+|===
+
+[[msg-keep-alive]]
+=== Keep Alive
+
+Indicates that the remote party is checking the status of a network connection.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x00 - Keep Alive
+|1 byte, unsigned; Message Type
+|===
+
+[[msg-client-hello]]
+=== Client Hello
+
+A Client issues a Client Hello message when first establishing a connection.
+The Client Protocol Revision field specifies the Network Table protocol
+revision that the Client would like to use.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x01 - Client Hello
+|1 byte, unsigned; Message Type
+
+|Client Protocol Revision
+|2 bytes, Unsigned 16-bit integer (big-endian). See
+<<def-protocol-revision,Protocol Revision>>.
+
+|Client identity (name)
+|<<entry-value-string,String>>
+|===
+
+[[msg-protocol-unsupported]]
+=== Protocol Version Unsupported
+
+A Server issues a Protocol Version Unsupported message to a Client to inform it
+that the requested protocol revision is not supported. It also includes the
+most recent protocol revision which it supports, such that a Client may
+reconnect under a prior protocol revision if able.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x02 - Protocol Version Unsupported
+|1 byte, unsigned; Message Type
+
+|Server Supported Protocol Revision
+|2 bytes, Unsigned 16-bit integer (big-endian). See
+<<def-protocol-revision,Protocol Revision>>.
+|===
+
+[[msg-server-hello-complete]]
+=== Server Hello Complete
+
+A Server issues a Server Hello Complete message when it has finished informing
+a newly-connected client of all of the fields it currently recognizes.
+Following the receipt of this message, a Client should inform the Server of
+any/all additional fields that it recognizes that the Server did not announce.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x03 - Server Hello Complete
+|1 byte, unsigned; Message Type
+|===
+
+[[msg-server-hello]]
+=== Server Hello
+
+A Server issues a Server Hello message in response to a Client Hello message,
+immediately prior to informing a newly-connected client of all of the fields it
+currently recognizes.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x04 - Server Hello
+|1 byte, unsigned; Message Type
+
+|Flags
+a|1 byte, unsigned.
+
+Least Significant Bit (bit 0): reconnect flag
+
+* 0 if this is the first time (since server start) the server has seen the
+client
+
+* 1 if the server has previously seen (since server start) the client (as
+identified in the <<msg-client-hello,Client Hello>> message)
+
+Bits 1-7: Reserved, set to 0.
+
+|Server identity (name)
+|<<entry-value-string,String>>
+|===
+
+[[msg-client-hello-complete]]
+=== Client Hello Complete
+
+A Client issues a Client Hello Complete message when it has finished informing
+the Server of any/all of the additional fields it recognizes that the Server
+did not announce.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x05 - Client Hello Complete
+|1 byte, unsigned; Message Type
+|===
+
+[[msg-assign]]
+=== Entry Assignment
+
+A Entry Assignment message informs the remote party of a new Entry. An Entry
+Assignment's value field must be the most recent value of the field being
+assigned at the time that the Entry Assignment is sent.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x10 - Entry Assignment
+|1 byte, unsigned; Message Type
+
+|Entry Name
+|<<entry-value-string,String>>
+
+|Entry Type
+|1 byte, unsigned; see <<entry-types,Entry Types>>
+
+|Entry ID
+|2 bytes, unsigned
+
+|Entry Sequence Number
+|2 bytes, unsigned
+
+|Entry Flags
+|1 byte, unsigned; see <<entry-flags,Entry Flags>>
+
+|Entry Value
+|N bytes, length depends on Entry Type
+|===
+
+If the Entry ID is 0xFFFF, then this assignment represents a request from a
+Client to the Server. In this event, the Entry ID field and the Entry Sequence
+Number field must not be stored or relied upon as they otherwise would be.
+
+[[msg-update]]
+=== Entry Update
+
+An Entry Update message informs a remote party of a new value for an Entry.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x11 - Entry Update
+|1 byte, unsigned; Message Type
+
+|Entry ID
+|2 bytes, unsigned
+
+|Entry Sequence Number
+|2 bytes, unsigned
+
+|Entry Type
+|1 byte, unsigned; see <<entry-types,Entry Types>>.
+
+Note this type is only used to determine the length of the entry value, and
+does NOT change the stored entry type if it is different (due to an intervening
+Entry Assignment); Clients and Servers must ignore Entry Update messages with
+mismatching entry type.
+
+|Entry Value
+|N bytes, length dependent on value type
+|===
+
+[[msg-flags-update]]
+=== Entry Flags Update
+
+An Entry Flags Update message informs a remote party of new flags for an Entry.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x12 - Entry Flags Update
+|1 byte, unsigned; Message Type
+
+|Entry ID
+|2 bytes, unsigned
+
+|Entry Flags
+|1 byte, unsigned; see <<entry-flags,Entry Flags>>
+|===
+
+Entries may be globally deleted using the following messages. These messages
+must be rebroadcast by the server in the same fashion as the Entry Update
+message. Clients and servers must remove the requested entry/entries from
+their local tables. Update messages received after the Entry Delete message
+for the deleted Entry ID must be ignored by Clients and Servers until a new
+Assignment message for that Entry ID is issued.
+
+[[msg-delete]]
+=== Entry Delete
+
+Deletes a single entry or procedure.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x13 - Entry Delete
+|1 byte, unsigned; message type
+
+|Entry ID
+|2 bytes, unsigned
+|===
+
+[[msg-clear-all]]
+=== Clear All Entries
+
+Deletes all entries. The magic value is required to be exactly this value
+(this is to avoid accidental misinterpretation of the message).
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x14 - Clear All Entries
+|1 byte, unsigned; message type
+
+|Magic Value (0xD06CB27A)
+|4 bytes; exact value required (big endian)
+|===
+
+[[msg-rpc-execute]]
+=== Remote Procedure Call (RPC) Execute
+
+Executes a remote procedure. Intended for client to server use only.
+
+The client shall provide a value for every RPC parameter specified in the
+corresponding RPC entry definition.
+
+The server shall ignore any Execute RPC message whose decoding does not match
+the parameters defined in the corresponding RPC entry definition.
+
+Note that the parameter length is encoded the same way regardless of the RPC
+version and encapsulates the entirety of the parameters, so protocol layer
+decoders do not need to know the RPC details in order to process the message.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x20 - Execute RPC
+|1 byte, unsigned; message type
+
+|RPC Definition Entry ID
+|2 bytes, unsigned
+
+|Unique ID
+|2 bytes, unsigned; incremented value for matching return values to call.
+
+|Parameter Value Length
+|N bytes, unsigned <<leb128>> encoded length of:
+
+RPC definition version 0: total number of raw bytes in this message
+
+RPC definition version 1: total number of bytes of parameter values in this
+message
+|Parameter Value(s)
+|RPC definition version 0: N raw bytes.
+
+RPC definition version 1: Array of values; N bytes for each parameter (length
+dependent on the parameter type defined in the
+<<rpc-definition,RPC entry definition>>).
+|===
+
+[[msg-rpc-response]]
+=== RPC Response
+
+Return responses from a remote procedure call. Even calls with zero outputs
+will respond.
+
+Note that the result length is encoded the same way regardless of the RPC
+version and encapsulates the entirety of the result, so protocol layer decoders
+do not need to know the RPC details in order to process the message.
+
+[cols="1,3"]
+|===
+|Field Name |Field Type
+
+|0x21 - RPC Response
+|1 byte, unsigned; message type
+
+|RPC Definition Entry ID
+|2 bytes, unsigned
+
+|Unique ID
+|2 bytes, unsigned; matching ID from <<msg-rpc-execute,RPC Execute>> message
+
+|Result Value Length
+|N bytes, unsigned <<leb128>> encoded length of:
+
+RPC definition version 0: total number of raw bytes in this message
+
+RPC definition version 1: total number of bytes of result values in this
+message
+|Result Value(s)
+|RPC definition version 0: N raw bytes.
+
+RPC definition version 1: Array of values; N bytes for each result (length
+dependent on the result type defined in the
+<<rpc-definition,RPC entry definition>>).
+|===
+
+[[rpc-operation]]
+== Remote Procedure Call (RPC) Operation
+
+Remote procedure call entries shall only be assigned by the server.
+
+Remote procedure call execute messages will result in asynchronous execution of
+the corresponding function on the server.
+
+Client implementations shall not transmit an Execute RPC message and return an
+error to user code that attempts to call an undefined RPC, call one with
+incorrectly typed parameters, or attempts to make a call when the Client is not
+connected to a Server.
+
+Remote procedure calls cannot be persisted.
+
+[[rpc-definition]]
+=== Remote Procedure Call Definition Data
+
+There are currently two versions of RPC definitions: version 0 and version 1.
+The first byte in the RPC definition entry determines the version.
+
+[[rpc-definition-v0]]
+==== Version 0
+
+RPC version 0 is the most straightforward: the data provided in the RPC
+definition entry consists of just a single 0 byte (indicating RPC
+definition version 0).  RPC version 0 execute and response messages do
+not contain discrete parameter and result values respectively; instead the
+entire parameter value or result value is treated as a raw byte sequence; the
+interpretation of the raw bytes is application specific--users are encouraged
+to consider using encodings such as CBOR or MessagePack for more complex
+self-describing data structures.
+
+[cols="1,3"]
+|===
+|RPC Definition Version
+|1 byte, unsigned; set to 0, indicating version 0
+|===
+
+[[rpc-definition-v1]]
+==== Version 1
+
+The data provided in the RPC version 1 definition entry is more
+complex and consists of:
+
+[cols="1,3"]
+|===
+|RPC Definition Version
+|1 byte, unsigned; set to 1, indicating version 1
+
+|Procedure (Entry) Name
+|<<entry-value-string,String>>
+
+|Number of Parameters
+|1 byte, unsigned (may be 0)
+
+2+s|Parameter Specification (one set per input parameter)
+
+|Parameter Type
+|1 byte, unsigned; <<entry-types,Entry Type>> for parameter value
+
+|Parameter Name
+|<<entry-value-string,String>>
+
+|Parameter Default Value
+|N bytes; length based on parameter type (encoded consistent with corresponding
+<<entry-values,Entry Value>> definition)
+
+|Number of Output Results
+|1 byte, unsigned (may be 0)
+
+2+s|Result Specification (one set per output)
+
+|Result Type
+|1 byte, unsigned; <<entry-types,Entry Type>> for value
+
+|Result Name
+|<<entry-value-string,String>>
+|===
diff --git a/ntcore/manualTests/java/Client.java b/ntcore/manualTests/java/Client.java
new file mode 100644
index 0000000..1d5f181
--- /dev/null
+++ b/ntcore/manualTests/java/Client.java
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+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/ntcore/manualTests/java/Server.java b/ntcore/manualTests/java/Server.java
new file mode 100644
index 0000000..7f4dbc6
--- /dev/null
+++ b/ntcore/manualTests/java/Server.java
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+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) {}
+  }
+}
diff --git a/ntcore/manualTests/native/client.cpp b/ntcore/manualTests/native/client.cpp
new file mode 100644
index 0000000..3bcb7c0
--- /dev/null
+++ b/ntcore/manualTests/native/client.cpp
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <chrono>
+#include <climits>
+#include <cstdio>
+#include <thread>
+
+#include "ntcore.h"
+
+int main() {
+  auto inst = nt::GetDefaultInstance();
+  nt::AddLogger(inst,
+                [](const nt::LogMessage& msg) {
+                  std::fputs(msg.message.c_str(), stderr);
+                  std::fputc('\n', stderr);
+                },
+                0, UINT_MAX);
+  nt::StartClient(inst, "127.0.0.1", 10000);
+  std::this_thread::sleep_for(std::chrono::seconds(2));
+
+  auto foo = nt::GetEntry(inst, "/foo");
+  auto foo_val = nt::GetEntryValue(foo);
+  if (foo_val && foo_val->IsDouble())
+    std::printf("Got foo: %g\n", foo_val->GetDouble());
+
+  auto bar = nt::GetEntry(inst, "/bar");
+  nt::SetEntryValue(bar, nt::Value::MakeBoolean(false));
+  nt::SetEntryFlags(bar, NT_PERSISTENT);
+
+  auto bar2 = nt::GetEntry(inst, "/bar2");
+  nt::SetEntryValue(bar2, nt::Value::MakeBoolean(true));
+  nt::SetEntryValue(bar2, nt::Value::MakeBoolean(false));
+  nt::SetEntryValue(bar2, nt::Value::MakeBoolean(true));
+  std::this_thread::sleep_for(std::chrono::seconds(10));
+}
diff --git a/ntcore/manualTests/native/rpc_local.cpp b/ntcore/manualTests/native/rpc_local.cpp
new file mode 100644
index 0000000..b8352d6
--- /dev/null
+++ b/ntcore/manualTests/native/rpc_local.cpp
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <chrono>
+#include <climits>
+#include <cstdio>
+#include <thread>
+
+#include <support/json.h>
+
+#include "ntcore.h"
+
+void callback1(const nt::RpcAnswer& answer) {
+  wpi::json params;
+  try {
+    params = wpi::json::from_cbor(answer.params);
+  } catch (wpi::json::parse_error err) {
+    std::fputs("could not decode params?\n", stderr);
+    return;
+  }
+  if (!params.is_number()) {
+    std::fputs("did not get number\n", stderr);
+    return;
+  }
+  double val = params.get<double>();
+  std::fprintf(stderr, "called with %g\n", val);
+
+  answer.PostResponse(wpi::json::to_cbor(val + 1.2));
+}
+
+int main() {
+  auto inst = nt::GetDefaultInstance();
+  nt::AddLogger(inst,
+                [](const nt::LogMessage& msg) {
+                  std::fputs(msg.message.c_str(), stderr);
+                  std::fputc('\n', stderr);
+                },
+                0, UINT_MAX);
+
+  nt::StartServer(inst, "rpc_local.ini", "", 10000);
+  auto entry = nt::GetEntry(inst, "func1");
+  nt::CreateRpc(entry, nt::StringRef("", 1), callback1);
+  std::fputs("calling rpc\n", stderr);
+  unsigned int call1_uid = nt::CallRpc(entry, wpi::json::to_cbor(2.0));
+  std::string call1_result_str;
+  std::fputs("waiting for rpc result\n", stderr);
+  nt::GetRpcResult(entry, call1_uid, &call1_result_str);
+  wpi::json call1_result;
+  try {
+    call1_result = wpi::json::from_cbor(call1_result_str);
+  } catch (wpi::json::parse_error err) {
+    std::fputs("could not decode result?\n", stderr);
+    return 1;
+  }
+  if (!call1_result.is_number()) {
+    std::fputs("result is not number?\n", stderr);
+    return 1;
+  }
+  std::fprintf(stderr, "got %g\n", call1_result.get<double>());
+
+  return 0;
+}
diff --git a/ntcore/manualTests/native/rpc_speed.cpp b/ntcore/manualTests/native/rpc_speed.cpp
new file mode 100644
index 0000000..70558ef
--- /dev/null
+++ b/ntcore/manualTests/native/rpc_speed.cpp
@@ -0,0 +1,75 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <chrono>
+#include <climits>
+#include <cstdio>
+#include <iostream>
+#include <thread>
+
+#include <support/json.h>
+
+#include "ntcore.h"
+
+void callback1(const nt::RpcAnswer& answer) {
+  wpi::json params;
+  try {
+    params = wpi::json::from_cbor(answer.params);
+  } catch (wpi::json::parse_error err) {
+    std::fputs("could not decode params?\n", stderr);
+    return;
+  }
+  if (!params.is_number()) {
+    std::fputs("did not get number\n", stderr);
+    return;
+  }
+  double val = params.get<double>();
+  answer.PostResponse(wpi::json::to_cbor(val + 1.2));
+}
+
+int main() {
+  auto inst = nt::GetDefaultInstance();
+  nt::StartServer(inst, "rpc_speed.ini", "", 10000);
+  auto entry = nt::GetEntry(inst, "func1");
+  nt::CreateRpc(entry, nt::StringRef("", 1), callback1);
+  std::string call1_result_str;
+
+  auto start2 = std::chrono::high_resolution_clock::now();
+  auto start = nt::Now();
+  for (int i = 0; i < 10000; ++i) {
+    unsigned int call1_uid = nt::CallRpc(entry, wpi::json::to_cbor(i));
+    nt::GetRpcResult(entry, call1_uid, &call1_result_str);
+    wpi::json call1_result;
+    try {
+      call1_result = wpi::json::from_cbor(call1_result_str);
+    } catch (wpi::json::parse_error err) {
+      std::fputs("could not decode result?\n", stderr);
+      return 1;
+    }
+    if (!call1_result.is_number()) {
+      std::fputs("result is not number?\n", stderr);
+      return 1;
+    }
+  }
+  auto end2 = std::chrono::high_resolution_clock::now();
+  auto end = nt::Now();
+  std::cerr << "nt::Now start=" << start << " end=" << end << '\n';
+  std::cerr << "std::chrono start="
+            << std::chrono::duration_cast<std::chrono::nanoseconds>(
+                   start2.time_since_epoch())
+                   .count()
+            << " end="
+            << std::chrono::duration_cast<std::chrono::nanoseconds>(
+                   end2.time_since_epoch())
+                   .count()
+            << '\n';
+  std::fprintf(stderr, "time/call = %g us\n", (end - start) / 10.0 / 10000.0);
+  std::chrono::duration<double, std::micro> diff = end2 - start2;
+  std::cerr << "time/call = " << (diff.count() / 10000.0) << " us\n";
+
+  return 0;
+}
diff --git a/ntcore/manualTests/native/server.cpp b/ntcore/manualTests/native/server.cpp
new file mode 100644
index 0000000..9513bf8
--- /dev/null
+++ b/ntcore/manualTests/native/server.cpp
@@ -0,0 +1,37 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <chrono>
+#include <climits>
+#include <cstdio>
+#include <thread>
+
+#include "ntcore.h"
+
+int main() {
+  auto inst = nt::GetDefaultInstance();
+  nt::AddLogger(inst,
+                [](const nt::LogMessage& msg) {
+                  std::fputs(msg.message.c_str(), stderr);
+                  std::fputc('\n', stderr);
+                },
+                0, UINT_MAX);
+  nt::StartServer(inst, "persistent.ini", "", 10000);
+  std::this_thread::sleep_for(std::chrono::seconds(1));
+
+  auto foo = nt::GetEntry(inst, "/foo");
+  nt::SetEntryValue(foo, nt::Value::MakeDouble(0.5));
+  nt::SetEntryFlags(foo, NT_PERSISTENT);
+
+  auto foo2 = nt::GetEntry(inst, "/foo2");
+  nt::SetEntryValue(foo2, nt::Value::MakeDouble(0.5));
+  nt::SetEntryValue(foo2, nt::Value::MakeDouble(0.7));
+  nt::SetEntryValue(foo2, nt::Value::MakeDouble(0.6));
+  nt::SetEntryValue(foo2, nt::Value::MakeDouble(0.5));
+
+  std::this_thread::sleep_for(std::chrono::seconds(10));
+}
diff --git a/ntcore/ntcore-config.cmake.in b/ntcore/ntcore-config.cmake.in
new file mode 100644
index 0000000..fb677b3
--- /dev/null
+++ b/ntcore/ntcore-config.cmake.in
@@ -0,0 +1,5 @@
+include(CMakeFindDependencyMacro)
+@FILENAME_DEP_REPLACE@
+@WPIUTIL_DEP_REPLACE@
+
+include(${SELF_DIR}/ntcore.cmake)
diff --git a/ntcore/src/dev/java/edu/wpi/first/ntcore/DevMain.java b/ntcore/src/dev/java/edu/wpi/first/ntcore/DevMain.java
new file mode 100644
index 0000000..547af0a
--- /dev/null
+++ b/ntcore/src/dev/java/edu/wpi/first/ntcore/DevMain.java
@@ -0,0 +1,25 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.ntcore;
+
+import edu.wpi.first.networktables.NetworkTablesJNI;
+import edu.wpi.first.wpiutil.RuntimeDetector;
+
+public final class DevMain {
+  /**
+   * Main method.
+   */
+  public static void main(String[] args) {
+    System.out.println("Hello World!");
+    System.out.println(RuntimeDetector.getPlatformPath());
+    NetworkTablesJNI.flush(NetworkTablesJNI.getDefaultInstance());
+  }
+
+  private DevMain() {
+  }
+}
diff --git a/ntcore/src/dev/native/cpp/main.cpp b/ntcore/src/dev/native/cpp/main.cpp
new file mode 100644
index 0000000..1153347
--- /dev/null
+++ b/ntcore/src/dev/native/cpp/main.cpp
@@ -0,0 +1,18 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <iostream>
+
+#include "ntcore.h"
+
+int main() {
+  auto myValue = nt::GetEntry(nt::GetDefaultInstance(), "MyValue");
+
+  nt::SetEntryValue(myValue, nt::Value::MakeString("Hello World"));
+
+  std::cout << nt::GetEntryValue(myValue)->GetString() << std::endl;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java
new file mode 100644
index 0000000..b060f2f
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java
@@ -0,0 +1,64 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Connection information.
+ */
+public final class ConnectionInfo {
+  /**
+   * The remote identifier (as set on the remote node by
+   * {@link NetworkTableInstance#setNetworkIdentity(String)}).
+   */
+  @SuppressWarnings("MemberName")
+  public final String remote_id;
+
+  /**
+   * The IP address of the remote node.
+   */
+  @SuppressWarnings("MemberName")
+  public final String remote_ip;
+
+  /**
+   * The port number of the remote node.
+   */
+  @SuppressWarnings("MemberName")
+  public final int remote_port;
+
+  /**
+   * The last time any update was received from the remote node (same scale as
+   * returned by {@link NetworkTablesJNI#now()}).
+   */
+  @SuppressWarnings("MemberName")
+  public final long last_update;
+
+  /**
+   * The protocol version being used for this connection.  This is in protocol
+   * layer format, so 0x0200 = 2.0, 0x0300 = 3.0).
+   */
+  @SuppressWarnings("MemberName")
+  public final int protocol_version;
+
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param remoteId Remote identifier
+   * @param remoteIp Remote IP address
+   * @param remotePort Remote port number
+   * @param lastUpdate Last time an update was received
+   * @param protocolVersion The protocol version used for the connection
+   */
+  public ConnectionInfo(String remoteId, String remoteIp, int remotePort, long lastUpdate,
+                        int protocolVersion) {
+    remote_id = remoteId;
+    remote_ip = remoteIp;
+    remote_port = remotePort;
+    last_update = lastUpdate;
+    protocol_version = protocolVersion;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionNotification.java b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionNotification.java
new file mode 100644
index 0000000..129bf1a
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionNotification.java
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Connection notification.
+ */
+public final class ConnectionNotification {
+  /**
+   *  Listener that was triggered.
+   */
+  @SuppressWarnings("MemberName")
+  public final int listener;
+
+  /**
+   * True if event is due to connection being established.
+   */
+  @SuppressWarnings("MemberName")
+  public final boolean connected;
+
+  /**
+   * Connection information.
+   */
+  @SuppressWarnings("MemberName")
+  public final ConnectionInfo conn;
+
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param listener Listener that was triggered
+   * @param connected Connected if true
+   * @param conn Connection information
+   */
+  public ConnectionNotification(NetworkTableInstance inst, int listener, boolean connected,
+                                ConnectionInfo conn) {
+    this.m_inst = inst;
+    this.listener = listener;
+    this.connected = connected;
+    this.conn = conn;
+  }
+
+  private final NetworkTableInstance m_inst;
+
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/EntryInfo.java b/ntcore/src/main/java/edu/wpi/first/networktables/EntryInfo.java
new file mode 100644
index 0000000..b516cc7
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/EntryInfo.java
@@ -0,0 +1,71 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Entry information.
+ */
+public final class EntryInfo {
+  /** Entry handle. */
+  @SuppressWarnings("MemberName")
+  public final int entry;
+
+  /** Entry name. */
+  @SuppressWarnings("MemberName")
+  public final String name;
+
+  /** Entry type. */
+  @SuppressWarnings("MemberName")
+  public final NetworkTableType type;
+
+  /** Entry flags. */
+  @SuppressWarnings("MemberName")
+  public final int flags;
+
+  /** Timestamp of last change to entry (type or value). */
+  @SuppressWarnings("MemberName")
+  public final long last_change;
+
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param entry Entry handle
+   * @param name Name
+   * @param type Type (integer version of {@link NetworkTableType})
+   * @param flags Flags
+   * @param lastChange Timestamp of last change
+   */
+  public EntryInfo(NetworkTableInstance inst, int entry, String name, int type, int flags,
+                   long lastChange) {
+    this.m_inst = inst;
+    this.entry = entry;
+    this.name = name;
+    this.type = NetworkTableType.getFromInt(type);
+    this.flags = flags;
+    this.last_change = lastChange;
+  }
+
+  /* Network table instance. */
+  private final NetworkTableInstance m_inst;
+
+  /* Cached entry object. */
+  private NetworkTableEntry m_entryObject;
+
+  /**
+   * Get the entry as an object.
+   *
+   * @return NetworkTableEntry for this entry.
+   */
+  NetworkTableEntry getEntry() {
+    if (m_entryObject == null) {
+      m_entryObject = new NetworkTableEntry(m_inst, entry);
+    }
+    return m_entryObject;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/EntryListenerFlags.java b/ntcore/src/main/java/edu/wpi/first/networktables/EntryListenerFlags.java
new file mode 100644
index 0000000..9cdc0f0
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/EntryListenerFlags.java
@@ -0,0 +1,72 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * Flag values for use with entry listeners.
+ *
+ * <p>The flags are a bitmask and must be OR'ed together to indicate the
+ * combination of events desired to be received.
+ *
+ * <p>The constants kNew, kDelete, kUpdate, and kFlags represent different events
+ * that can occur to entries.
+ *
+ * <p>By default, notifications are only generated for remote changes occurring
+ * after the listener is created.  The constants kImmediate and kLocal are
+ * modifiers that cause notifications to be generated at other times.
+ */
+public interface EntryListenerFlags {
+  /**
+   * Initial listener addition.
+   *
+   * <p>Set this flag to receive immediate notification of entries matching the
+   * flag criteria (generally only useful when combined with kNew).
+   */
+  int kImmediate = 0x01;
+
+  /**
+   * Changed locally.
+   *
+   * <p>Set this flag to receive notification of both local changes and changes
+   * coming from remote nodes.  By default, notifications are only generated
+   * for remote changes.  Must be combined with some combination of kNew,
+   * kDelete, kUpdate, and kFlags to receive notifications of those respective
+   * events.
+   */
+  int kLocal = 0x02;
+
+  /**
+   * Newly created entry.
+   *
+   * <p>Set this flag to receive a notification when an entry is created.
+   */
+  int kNew = 0x04;
+
+  /**
+   * Entry was deleted.
+   *
+   * <p>Set this flag to receive a notification when an entry is deleted.
+   */
+  int kDelete = 0x08;
+
+  /**
+   * Entry's value changed.
+   *
+   * <p>Set this flag to receive a notification when an entry's value (or type)
+   * changes.
+   */
+  int kUpdate = 0x10;
+
+  /**
+   * Entry's flags changed.
+   *
+   * <p>Set this flag to receive a notification when an entry's flags value
+   * changes.
+   */
+  int kFlags = 0x20;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/EntryNotification.java b/ntcore/src/main/java/edu/wpi/first/networktables/EntryNotification.java
new file mode 100644
index 0000000..159b968
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/EntryNotification.java
@@ -0,0 +1,82 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Entry notification.
+ */
+public final class EntryNotification {
+  /**
+   * Listener that was triggered.
+   */
+  @SuppressWarnings("MemberName")
+  public final int listener;
+
+  /**
+   * Entry handle.
+   */
+  @SuppressWarnings("MemberName")
+  public final int entry;
+
+  /**
+   * Entry name.
+   */
+  @SuppressWarnings("MemberName")
+  public final String name;
+
+  /**
+   * The new value.
+   */
+  @SuppressWarnings("MemberName")
+  public final NetworkTableValue value;
+
+  /**
+   * Update flags.  For example, {@link EntryListenerFlags#kNew} if the key did
+   * not previously exist.
+   */
+  @SuppressWarnings("MemberName")
+  public final int flags;
+
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param listener Listener that was triggered
+   * @param entry Entry handle
+   * @param name Entry name
+   * @param value The new value
+   * @param flags Update flags
+   */
+  public EntryNotification(NetworkTableInstance inst, int listener, int entry, String name,
+                           NetworkTableValue value, int flags) {
+    this.m_inst = inst;
+    this.listener = listener;
+    this.entry = entry;
+    this.name = name;
+    this.value = value;
+    this.flags = flags;
+  }
+
+  /* Network table instance. */
+  private final NetworkTableInstance m_inst;
+
+  /* Cached entry object. */
+  NetworkTableEntry m_entryObject;
+
+  /**
+   * Get the entry as an object.
+   *
+   * @return NetworkTableEntry for this entry.
+   */
+  public NetworkTableEntry getEntry() {
+    if (m_entryObject == null) {
+      m_entryObject = new NetworkTableEntry(m_inst, entry);
+    }
+    return m_entryObject;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java b/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java
new file mode 100644
index 0000000..2cf22ec
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java
@@ -0,0 +1,82 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables log message.
+ */
+public final class LogMessage {
+  /**
+   * Logging levels.
+   */
+  public static final int kCritical = 50;
+  public static final int kError = 40;
+  public static final int kWarning = 30;
+  public static final int kInfo = 20;
+  public static final int kDebug = 10;
+  public static final int kDebug1 = 9;
+  public static final int kDebug2 = 8;
+  public static final int kDebug3 = 7;
+  public static final int kDebug4 = 6;
+
+  /**
+   * The logger that generated the message.
+   */
+  @SuppressWarnings("MemberName")
+  public final int logger;
+
+  /**
+   * Log level of the message.
+   */
+  @SuppressWarnings("MemberName")
+  public final int level;
+
+  /**
+   * The filename of the source file that generated the message.
+   */
+  @SuppressWarnings("MemberName")
+  public final String filename;
+
+  /**
+   * The line number in the source file that generated the message.
+   */
+  @SuppressWarnings("MemberName")
+  public final int line;
+
+  /**
+   * The message.
+   */
+  @SuppressWarnings("MemberName")
+  public final String message;
+
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param logger Logger
+   * @param level Log level
+   * @param filename Filename
+   * @param line Line number
+   * @param message Message
+   */
+  public LogMessage(NetworkTableInstance inst, int logger, int level, String filename, int line,
+                    String message) {
+    this.m_inst = inst;
+    this.logger = logger;
+    this.level = level;
+    this.filename = filename;
+    this.line = line;
+    this.message = message;
+  }
+
+  private final NetworkTableInstance m_inst;
+
+  NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java
new file mode 100644
index 0000000..ad25f23
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java
@@ -0,0 +1,423 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Consumer;
+
+/**
+ * A network table that knows its subtable path.
+ */
+public final class NetworkTable {
+  /**
+   * The path separator for sub-tables and keys.
+   */
+  public static final char PATH_SEPARATOR = '/';
+
+  private final String m_path;
+  private final String m_pathWithSep;
+  private final NetworkTableInstance m_inst;
+
+  /**
+   * Gets the "base name" of a key. For example, "/foo/bar" becomes "bar".
+   * If the key has a trailing slash, returns an empty string.
+   *
+   * @param key key
+   * @return base name
+   */
+  public static String basenameKey(String key) {
+    final int slash = key.lastIndexOf(PATH_SEPARATOR);
+    if (slash == -1) {
+      return key;
+    }
+    return key.substring(slash + 1);
+  }
+
+  /**
+   * Normalizes an network table key to contain no consecutive slashes and
+   * optionally start with a leading slash. For example:
+   *
+   * <pre><code>
+   * normalizeKey("/foo/bar", true)  == "/foo/bar"
+   * normalizeKey("foo/bar", true)   == "/foo/bar"
+   * normalizeKey("/foo/bar", false) == "foo/bar"
+   * normalizeKey("foo//bar", false) == "foo/bar"
+   * </code></pre>
+   *
+   * @param key              the key to normalize
+   * @param withLeadingSlash whether or not the normalized key should begin
+   *                         with a leading slash
+   * @return normalized key
+   */
+  public static String normalizeKey(String key, boolean withLeadingSlash) {
+    String normalized;
+    if (withLeadingSlash) {
+      normalized = PATH_SEPARATOR + key;
+    } else {
+      normalized = key;
+    }
+    normalized = normalized.replaceAll(PATH_SEPARATOR + "{2,}", String.valueOf(PATH_SEPARATOR));
+
+    if (!withLeadingSlash && normalized.charAt(0) == PATH_SEPARATOR) {
+      // remove leading slash, if present
+      normalized = normalized.substring(1);
+    }
+    return normalized;
+  }
+
+  /**
+   * Normalizes a network table key to start with exactly one leading slash
+   * ("/") and contain no consecutive slashes. For example,
+   * {@code "//foo/bar/"} becomes {@code "/foo/bar/"} and
+   * {@code "///a/b/c"} becomes {@code "/a/b/c"}.
+   *
+   * <p>This is equivalent to {@code normalizeKey(key, true)}
+   *
+   * @param key the key to normalize
+   * @return normalized key
+   */
+  public static String normalizeKey(String key) {
+    return normalizeKey(key, true);
+  }
+
+  /**
+   * Gets a list of the names of all the super tables of a given key. For
+   * example, the key "/foo/bar/baz" has a hierarchy of "/", "/foo",
+   * "/foo/bar", and "/foo/bar/baz".
+   *
+   * @param key the key
+   * @return List of super tables
+   */
+  public static List<String> getHierarchy(String key) {
+    final String normal = normalizeKey(key, true);
+    List<String> hierarchy = new ArrayList<>();
+    if (normal.length() == 1) {
+      hierarchy.add(normal);
+      return hierarchy;
+    }
+    for (int i = 1; ; i = normal.indexOf(PATH_SEPARATOR, i + 1)) {
+      if (i == -1) {
+        // add the full key
+        hierarchy.add(normal);
+        break;
+      } else {
+        hierarchy.add(normal.substring(0, i));
+      }
+    }
+    return hierarchy;
+  }
+
+  /**
+   * Constructor.  Use NetworkTableInstance.getTable() or getSubTable() instead.
+   */
+  NetworkTable(NetworkTableInstance inst, String path) {
+    m_path = path;
+    m_pathWithSep = path + PATH_SEPARATOR;
+    m_inst = inst;
+  }
+
+  /**
+   * Gets the instance for the table.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+
+  @Override
+  public String toString() {
+    return "NetworkTable: " + m_path;
+  }
+
+  private final ConcurrentMap<String, NetworkTableEntry> m_entries = new ConcurrentHashMap<>();
+
+  /**
+   * Gets the entry for a sub key.
+   *
+   * @param key the key name
+   * @return Network table entry.
+   */
+  public NetworkTableEntry getEntry(String key) {
+    NetworkTableEntry entry = m_entries.get(key);
+    if (entry == null) {
+      entry = m_inst.getEntry(m_pathWithSep + key);
+      m_entries.putIfAbsent(key, entry);
+    }
+    return entry;
+  }
+
+  /**
+   * Listen to keys only within this table.
+   *
+   * @param listener    listener to add
+   * @param flags       {@link EntryListenerFlags} bitmask
+   * @return Listener handle
+   */
+  public int addEntryListener(TableEntryListener listener, int flags) {
+    final int prefixLen = m_path.length() + 1;
+    return m_inst.addEntryListener(m_pathWithSep, event -> {
+      String relativeKey = event.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1) {
+        // part of a sub table
+        return;
+      }
+      listener.valueChanged(this, relativeKey, event.getEntry(), event.value, event.flags);
+    }, flags);
+  }
+
+  /**
+   * Listen to a single key.
+   *
+   * @param key         the key name
+   * @param listener    listener to add
+   * @param flags       {@link EntryListenerFlags} bitmask
+   * @return Listener handle
+   */
+  public int addEntryListener(String key, TableEntryListener listener, int flags) {
+    final NetworkTableEntry entry = getEntry(key);
+    return m_inst.addEntryListener(entry,
+        event -> listener.valueChanged(this, key, entry, event.value, event.flags), flags);
+  }
+
+  /**
+   * Remove an entry listener.
+   *
+   * @param listener    listener handle
+   */
+  public void removeEntryListener(int listener) {
+    m_inst.removeEntryListener(listener);
+  }
+
+  /**
+   * Listen for sub-table creation.
+   * This calls the listener once for each newly created sub-table.
+   * It immediately calls the listener for any existing sub-tables.
+   *
+   * @param listener        listener to add
+   * @param localNotify     notify local changes as well as remote
+   * @return Listener handle
+   */
+  public int addSubTableListener(TableListener listener, boolean localNotify) {
+    int flags = EntryListenerFlags.kNew | EntryListenerFlags.kImmediate;
+    if (localNotify) {
+      flags |= EntryListenerFlags.kLocal;
+    }
+
+    final int prefixLen = m_path.length() + 1;
+    final NetworkTable parent = this;
+
+    return m_inst.addEntryListener(m_pathWithSep, new Consumer<>() {
+      final Set<String> m_notifiedTables = new HashSet<>();
+
+      @Override
+      public void accept(EntryNotification event) {
+        String relativeKey = event.name.substring(prefixLen);
+        int endSubTable = relativeKey.indexOf(PATH_SEPARATOR);
+        if (endSubTable == -1) {
+          return;
+        }
+        String subTableKey = relativeKey.substring(0, endSubTable);
+        if (m_notifiedTables.contains(subTableKey)) {
+          return;
+        }
+        m_notifiedTables.add(subTableKey);
+        listener.tableCreated(parent, subTableKey, parent.getSubTable(subTableKey));
+      }
+    }, flags);
+  }
+
+  /**
+   * Remove a sub-table listener.
+   *
+   * @param listener    listener handle
+   */
+  public void removeTableListener(int listener) {
+    m_inst.removeEntryListener(listener);
+  }
+
+  /**
+   * 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 NetworkTable getSubTable(String key) {
+    return new NetworkTable(m_inst, m_pathWithSep + key);
+  }
+
+  /**
+   * 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) {
+    return !("".equals(key)) && getEntry(key).exists();
+  }
+
+  /**
+   * Checks the table and tells if it contains the specified sub table.
+   *
+   * @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) {
+    int[] handles = NetworkTablesJNI.getEntries(m_inst.getHandle(),
+        m_pathWithSep + key + PATH_SEPARATOR, 0);
+    return handles.length != 0;
+  }
+
+  /**
+   * Gets all keys in the table (not including sub-tables).
+   *
+   * @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<>();
+    int prefixLen = m_path.length() + 1;
+    for (EntryInfo info : m_inst.getEntryInfo(m_pathWithSep, types)) {
+      String relativeKey = info.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1) {
+        continue;
+      }
+      keys.add(relativeKey);
+      // populate entries as we go
+      if (m_entries.get(relativeKey) == null) {
+        m_entries.putIfAbsent(relativeKey, new NetworkTableEntry(m_inst, info.entry));
+      }
+    }
+    return keys;
+  }
+
+  /**
+   * Gets all keys in the table (not including sub-tables).
+   *
+   * @return keys currently in the table
+   */
+  public Set<String> getKeys() {
+    return getKeys(0);
+  }
+
+  /**
+   * Gets the names of all subtables in the table.
+   *
+   * @return subtables currently in the table
+   */
+  public Set<String> getSubTables() {
+    Set<String> keys = new HashSet<>();
+    int prefixLen = m_path.length() + 1;
+    for (EntryInfo info : m_inst.getEntryInfo(m_pathWithSep, 0)) {
+      String relativeKey = info.name.substring(prefixLen);
+      int endSubTable = relativeKey.indexOf(PATH_SEPARATOR);
+      if (endSubTable == -1) {
+        continue;
+      }
+      keys.add(relativeKey.substring(0, endSubTable));
+    }
+    return keys;
+  }
+
+  /**
+   * Deletes the specified key in this table. The key can
+   * not be null.
+   *
+   * @param key the key name
+   */
+  public void delete(String key) {
+    getEntry(key).delete();
+  }
+
+  /**
+   * 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
+   */
+  boolean putValue(String key, NetworkTableValue value) {
+    return getEntry(key).setValue(value);
+  }
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @return False if the table key exists with a different type
+   */
+  boolean setDefaultValue(String key, NetworkTableValue defaultValue) {
+    return getEntry(key).setDefaultValue(defaultValue);
+  }
+
+  /**
+   * Gets the value associated with a key as an object.
+   *
+   * @param key the key of the value to look up
+   * @return the value associated with the given key, or nullptr if the key does not exist
+   */
+  NetworkTableValue getValue(String key) {
+    return getEntry(key).getValue();
+  }
+
+  /**
+   * Get the path of the NetworkTable.
+   */
+  public String getPath() {
+    return m_path;
+  }
+
+  /**
+   * Save table values to a file.  The file format used is identical to
+   * that used for SavePersistent.
+   *
+   * @param filename  filename
+   * @throws PersistentException if error saving file
+   */
+  public void saveEntries(String filename) throws PersistentException {
+    m_inst.saveEntries(filename, m_pathWithSep);
+  }
+
+  /**
+   * Load table values from a file.  The file format used is identical to
+   * that used for SavePersistent / LoadPersistent.
+   *
+   * @param filename  filename
+   * @return List of warnings (errors result in an exception instead)
+   * @throws PersistentException if error saving file
+   */
+  public String[] loadEntries(String filename) throws PersistentException {
+    return m_inst.loadEntries(filename, m_pathWithSep);
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof NetworkTable)) {
+      return false;
+    }
+    NetworkTable ntOther = (NetworkTable) other;
+    return m_inst.equals(ntOther.m_inst) && m_path.equals(ntOther.m_path);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(m_inst, m_path);
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEntry.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEntry.java
new file mode 100644
index 0000000..6eea5ca
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEntry.java
@@ -0,0 +1,875 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.nio.ByteBuffer;
+import java.util.function.Consumer;
+
+/**
+ * NetworkTables Entry.
+ */
+public final class NetworkTableEntry {
+  /**
+   * Flag values (as returned by {@link #getFlags()}).
+   */
+  public static final int kPersistent = 0x01;
+
+  /**
+   * Construct from native handle.
+   *
+   * @param inst Instance
+   * @param handle Native handle
+   */
+  public NetworkTableEntry(NetworkTableInstance inst, int handle) {
+    m_inst = inst;
+    m_handle = handle;
+  }
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  public boolean isValid() {
+    return m_handle != 0;
+  }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  /**
+   * Gets the instance for the entry.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+
+  /**
+   * Determines if the entry currently exists.
+   *
+   * @return True if the entry exists, false otherwise.
+   */
+  public boolean exists() {
+    return NetworkTablesJNI.getType(m_handle) != 0;
+  }
+
+  /**
+   * Gets the name of the entry (the key).
+   *
+   * @return the entry's name
+   */
+  public String getName() {
+    return NetworkTablesJNI.getEntryName(m_handle);
+  }
+
+  /**
+   * Gets the type of the entry.
+   *
+   * @return the entry's type
+   */
+  public NetworkTableType getType() {
+    return NetworkTableType.getFromInt(NetworkTablesJNI.getType(m_handle));
+  }
+
+  /**
+   * Returns the flags.
+   *
+   * @return the flags (bitmask)
+   */
+  public int getFlags() {
+    return NetworkTablesJNI.getEntryFlags(m_handle);
+  }
+
+  /**
+   * Gets the last time the entry's value was changed.
+   *
+   * @return Entry last change time
+   */
+  public long getLastChange() {
+    return NetworkTablesJNI.getEntryLastChange(m_handle);
+  }
+
+  /**
+   * Gets combined information about the entry.
+   *
+   * @return Entry information
+   */
+  public EntryInfo getInfo() {
+    return NetworkTablesJNI.getEntryInfoHandle(m_inst, m_handle);
+  }
+
+  /**
+   * Gets the entry's value.
+   * Returns a value with type NetworkTableType.kUnassigned if the value
+   * does not exist.
+   *
+   * @return the entry's value
+   */
+  public NetworkTableValue getValue() {
+    return NetworkTablesJNI.getValue(m_handle);
+  }
+
+  /**
+   * Gets the entry's value as a boolean. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public boolean getBoolean(boolean defaultValue) {
+    return NetworkTablesJNI.getBoolean(m_handle, defaultValue);
+  }
+
+  /**
+   * Gets the entry's value as a double. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public double getDouble(double defaultValue) {
+    return NetworkTablesJNI.getDouble(m_handle, defaultValue);
+  }
+
+  /**
+   * Gets the entry's value as a double. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public Number getNumber(Number defaultValue) {
+    return NetworkTablesJNI.getDouble(m_handle, defaultValue.doubleValue());
+  }
+
+  /**
+   * Gets the entry's value as a string. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public String getString(String defaultValue) {
+    return NetworkTablesJNI.getString(m_handle, defaultValue);
+  }
+
+  /**
+   * Gets the entry's value as a raw value (byte array). If the entry does not
+   * exist or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public byte[] getRaw(byte[] defaultValue) {
+    return NetworkTablesJNI.getRaw(m_handle, defaultValue);
+  }
+
+  /**
+   * Gets the entry's value as a boolean array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public boolean[] getBooleanArray(boolean[] defaultValue) {
+    return NetworkTablesJNI.getBooleanArray(m_handle, defaultValue);
+  }
+
+  /**
+   * Gets the entry's value as a boolean array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public Boolean[] getBooleanArray(Boolean[] defaultValue) {
+    return NetworkTableValue.fromNative(NetworkTablesJNI.getBooleanArray(m_handle,
+        NetworkTableValue.toNative(defaultValue)));
+  }
+
+  /**
+   * Gets the entry's value as a double array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public double[] getDoubleArray(double[] defaultValue) {
+    return NetworkTablesJNI.getDoubleArray(m_handle, defaultValue);
+  }
+
+  /**
+   * Gets the entry's value as a double array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public Double[] getDoubleArray(Double[] defaultValue) {
+    return NetworkTableValue.fromNative(NetworkTablesJNI.getDoubleArray(m_handle,
+        NetworkTableValue.toNative(defaultValue)));
+  }
+
+  /**
+   * Gets the entry's value as a double array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public Number[] getNumberArray(Number[] defaultValue) {
+    return NetworkTableValue.fromNative(NetworkTablesJNI.getDoubleArray(m_handle,
+        NetworkTableValue.toNative(defaultValue)));
+  }
+
+  /**
+   * Gets the entry's value as a string array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  public String[] getStringArray(String[] defaultValue) {
+    return NetworkTablesJNI.getStringArray(m_handle, defaultValue);
+  }
+
+  /**
+   * Checks if a data value is of a type that can be placed in a NetworkTable entry.
+   *
+   * @param data the data to check
+   * @return true if the data can be placed in an entry, false if it cannot
+   */
+  public static boolean isValidDataType(Object data) {
+    return data instanceof Number
+        || data instanceof Boolean
+        || data instanceof String
+        || data instanceof double[]
+        || data instanceof Double[]
+        || data instanceof Number[]
+        || data instanceof boolean[]
+        || data instanceof Boolean[]
+        || data instanceof String[]
+        || data instanceof byte[]
+        || data instanceof Byte[];
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   * @throws IllegalArgumentException if the value is not a known type
+   */
+  public boolean setDefaultValue(Object defaultValue) {
+    if (defaultValue instanceof NetworkTableValue) {
+      long time = ((NetworkTableValue) defaultValue).getTime();
+      Object otherValue = ((NetworkTableValue) defaultValue).getValue();
+      switch (((NetworkTableValue) defaultValue).getType()) {
+        case kBoolean:
+          return NetworkTablesJNI.setDefaultBoolean(m_handle, time,
+              (Boolean) otherValue);
+        case kDouble:
+          return NetworkTablesJNI.setDefaultDouble(m_handle, time,
+              ((Number) otherValue).doubleValue());
+        case kString:
+          return NetworkTablesJNI.setDefaultString(m_handle, time, (String) otherValue);
+        case kRaw:
+          return NetworkTablesJNI.setDefaultRaw(m_handle, time, (byte[]) otherValue);
+        case kBooleanArray:
+          return NetworkTablesJNI.setDefaultBooleanArray(m_handle, time, (boolean[]) otherValue);
+        case kDoubleArray:
+          return NetworkTablesJNI.setDefaultDoubleArray(m_handle, time, (double[]) otherValue);
+        case kStringArray:
+          return NetworkTablesJNI.setDefaultStringArray(m_handle, time, (String[]) otherValue);
+        case kRpc:
+          // TODO
+        default:
+          return true;
+      }
+    } else if (defaultValue instanceof Boolean) {
+      return setDefaultBoolean((Boolean) defaultValue);
+    } else if (defaultValue instanceof Number) {
+      return setDefaultNumber((Number) defaultValue);
+    } else if (defaultValue instanceof String) {
+      return setDefaultString((String) defaultValue);
+    } else if (defaultValue instanceof byte[])  {
+      return setDefaultRaw((byte[]) defaultValue);
+    } else if (defaultValue instanceof boolean[])  {
+      return setDefaultBooleanArray((boolean[]) defaultValue);
+    } else if (defaultValue instanceof double[])  {
+      return setDefaultDoubleArray((double[]) defaultValue);
+    } else if (defaultValue instanceof Boolean[])  {
+      return setDefaultBooleanArray((Boolean[]) defaultValue);
+    } else if (defaultValue instanceof Number[])  {
+      return setDefaultNumberArray((Number[]) defaultValue);
+    } else if (defaultValue instanceof String[])  {
+      return setDefaultStringArray((String[]) defaultValue);
+    } else {
+      throw new IllegalArgumentException("Value of type " + defaultValue.getClass().getName()
+        + " cannot be put into a table");
+    }
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultBoolean(boolean defaultValue) {
+    return NetworkTablesJNI.setDefaultBoolean(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultDouble(double defaultValue) {
+    return NetworkTablesJNI.setDefaultDouble(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultNumber(Number defaultValue) {
+    return NetworkTablesJNI.setDefaultDouble(m_handle, 0, defaultValue.doubleValue());
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultString(String defaultValue) {
+    return NetworkTablesJNI.setDefaultString(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultRaw(byte[] defaultValue) {
+    return NetworkTablesJNI.setDefaultRaw(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultBooleanArray(boolean[] defaultValue) {
+    return NetworkTablesJNI.setDefaultBooleanArray(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultBooleanArray(Boolean[] defaultValue) {
+    return NetworkTablesJNI.setDefaultBooleanArray(m_handle,
+        0, NetworkTableValue.toNative(defaultValue));
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultDoubleArray(double[] defaultValue) {
+    return NetworkTablesJNI.setDefaultDoubleArray(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultNumberArray(Number[] defaultValue) {
+    return NetworkTablesJNI.setDefaultDoubleArray(m_handle,
+        0, NetworkTableValue.toNative(defaultValue));
+  }
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDefaultStringArray(String[] defaultValue) {
+    return NetworkTablesJNI.setDefaultStringArray(m_handle, 0, defaultValue);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value that will be assigned
+   * @return False if the table key already exists with a different type
+   * @throws IllegalArgumentException if the value is not a known type
+   */
+  public boolean setValue(Object value) {
+    if (value instanceof NetworkTableValue) {
+      long time = ((NetworkTableValue) value).getTime();
+      Object otherValue = ((NetworkTableValue) value).getValue();
+      switch (((NetworkTableValue) value).getType()) {
+        case kBoolean:
+          return NetworkTablesJNI.setBoolean(m_handle, time, (Boolean) otherValue,
+              false);
+        case kDouble:
+          return NetworkTablesJNI.setDouble(m_handle, time, ((Number) otherValue).doubleValue(),
+              false);
+        case kString:
+          return NetworkTablesJNI.setString(m_handle, time, (String) otherValue, false);
+        case kRaw:
+          return NetworkTablesJNI.setRaw(m_handle, time, (byte[]) otherValue, false);
+        case kBooleanArray:
+          return NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[]) otherValue, false);
+        case kDoubleArray:
+          return NetworkTablesJNI.setDoubleArray(m_handle, time, (double[]) otherValue, false);
+        case kStringArray:
+          return NetworkTablesJNI.setStringArray(m_handle, time, (String[]) otherValue, false);
+        case kRpc:
+          // TODO
+        default:
+          return true;
+      }
+    } else if (value instanceof Boolean) {
+      return setBoolean((Boolean) value);
+    } else if (value instanceof Number) {
+      return setNumber((Number) value);
+    } else if (value instanceof String) {
+      return setString((String) value);
+    } else if (value instanceof byte[]) {
+      return setRaw((byte[]) value);
+    } else if (value instanceof boolean[]) {
+      return setBooleanArray((boolean[]) value);
+    } else if (value instanceof double[]) {
+      return setDoubleArray((double[]) value);
+    } else if (value instanceof Boolean[]) {
+      return setBooleanArray((Boolean[]) value);
+    } else if (value instanceof Number[]) {
+      return setNumberArray((Number[]) value);
+    } else if (value instanceof String[]) {
+      return setStringArray((String[]) value);
+    } else {
+      throw new IllegalArgumentException("Value of type " + value.getClass().getName()
+        + " cannot be put into a table");
+    }
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setBoolean(boolean value) {
+    return NetworkTablesJNI.setBoolean(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDouble(double value) {
+    return NetworkTablesJNI.setDouble(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setNumber(Number value) {
+    return NetworkTablesJNI.setDouble(m_handle, 0, value.doubleValue(), false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setString(String value) {
+    return NetworkTablesJNI.setString(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setRaw(byte[] value) {
+    return NetworkTablesJNI.setRaw(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param len the length of the value
+   * @return False if the entry exists with a different type
+   */
+  public boolean setRaw(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.setRaw(m_handle, 0, value, len, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setBooleanArray(boolean[] value) {
+    return NetworkTablesJNI.setBooleanArray(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setBooleanArray(Boolean[] value) {
+    return NetworkTablesJNI.setBooleanArray(m_handle, 0, NetworkTableValue.toNative(value), false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setDoubleArray(double[] value) {
+    return NetworkTablesJNI.setDoubleArray(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setNumberArray(Number[] value) {
+    return NetworkTablesJNI.setDoubleArray(m_handle, 0, NetworkTableValue.toNative(value), false);
+  }
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean setStringArray(String[] value) {
+    return NetworkTablesJNI.setStringArray(m_handle, 0, value, false);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   * @throws IllegalArgumentException if the value is not a known type
+   */
+  public void forceSetValue(Object value) {
+    if (value instanceof NetworkTableValue) {
+      long time = ((NetworkTableValue) value).getTime();
+      Object otherValue = ((NetworkTableValue) value).getValue();
+      switch (((NetworkTableValue) value).getType()) {
+        case kBoolean:
+          NetworkTablesJNI.setBoolean(m_handle, time, (Boolean) otherValue, true);
+          return;
+        case kDouble:
+          NetworkTablesJNI.setDouble(m_handle, time, ((Number) otherValue).doubleValue(), true);
+          return;
+        case kString:
+          NetworkTablesJNI.setString(m_handle, time, (String) otherValue, true);
+          return;
+        case kRaw:
+          NetworkTablesJNI.setRaw(m_handle, time, (byte[]) otherValue, true);
+          return;
+        case kBooleanArray:
+          NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[]) otherValue, true);
+          return;
+        case kDoubleArray:
+          NetworkTablesJNI.setDoubleArray(m_handle, time, (double[]) otherValue, true);
+          return;
+        case kStringArray:
+          NetworkTablesJNI.setStringArray(m_handle, time, (String[]) otherValue, true);
+          return;
+        case kRpc:
+          // TODO
+        default:
+          return;
+      }
+    } else if (value instanceof Boolean) {
+      forceSetBoolean((Boolean) value);
+    } else if (value instanceof Number) {
+      forceSetNumber((Number) value);
+    } else if (value instanceof String) {
+      forceSetString((String) value);
+    } else if (value instanceof byte[]) {
+      forceSetRaw((byte[]) value);
+    } else if (value instanceof boolean[]) {
+      forceSetBooleanArray((boolean[]) value);
+    } else if (value instanceof double[]) {
+      forceSetDoubleArray((double[]) value);
+    } else if (value instanceof Boolean[]) {
+      forceSetBooleanArray((Boolean[]) value);
+    } else if (value instanceof Number[]) {
+      forceSetNumberArray((Number[]) value);
+    } else if (value instanceof String[]) {
+      forceSetStringArray((String[]) value);
+    } else {
+      throw new IllegalArgumentException("Value of type " + value.getClass().getName()
+        + " cannot be put into a table");
+    }
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetBoolean(boolean value) {
+    NetworkTablesJNI.setBoolean(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetDouble(double value) {
+    NetworkTablesJNI.setDouble(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetNumber(Number value) {
+    NetworkTablesJNI.setDouble(m_handle, 0, value.doubleValue(), true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetString(String value) {
+    NetworkTablesJNI.setString(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetRaw(byte[] value) {
+    NetworkTablesJNI.setRaw(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetBooleanArray(boolean[] value) {
+    NetworkTablesJNI.setBooleanArray(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetBooleanArray(Boolean[] value) {
+    NetworkTablesJNI.setBooleanArray(m_handle, 0, NetworkTableValue.toNative(value), true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetDoubleArray(double[] value) {
+    NetworkTablesJNI.setDoubleArray(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetNumberArray(Number[] value) {
+    NetworkTablesJNI.setDoubleArray(m_handle, 0, NetworkTableValue.toNative(value), true);
+  }
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  public void forceSetStringArray(String[] value) {
+    NetworkTablesJNI.setStringArray(m_handle, 0, value, true);
+  }
+
+  /**
+   * Sets flags.
+   *
+   * @param flags the flags to set (bitmask)
+   */
+  public void setFlags(int flags) {
+    NetworkTablesJNI.setEntryFlags(m_handle, getFlags() | flags);
+  }
+
+  /**
+   * Clears flags.
+   *
+   * @param flags the flags to clear (bitmask)
+   */
+  public void clearFlags(int flags) {
+    NetworkTablesJNI.setEntryFlags(m_handle, getFlags() & ~flags);
+  }
+
+  /**
+   * Make value persistent through program restarts.
+   */
+  public void setPersistent() {
+    setFlags(kPersistent);
+  }
+
+  /**
+   * Stop making value persistent through program restarts.
+   */
+  public void clearPersistent() {
+    clearFlags(kPersistent);
+  }
+
+  /**
+   * Returns whether the value is persistent through program restarts.
+   *
+   * @return True if the value is persistent.
+   */
+  public boolean isPersistent() {
+    return (getFlags() & kPersistent) != 0;
+  }
+
+  /**
+   * Deletes the entry.
+   */
+  public void delete() {
+    NetworkTablesJNI.deleteEntry(m_handle);
+  }
+
+  /**
+   * Create a callback-based RPC entry point.  Only valid to use on the server.
+   * The callback function will be called when the RPC is called.
+   * This function creates RPC version 0 definitions (raw data in and out).
+   *
+   * @param callback  callback function
+   */
+  public void createRpc(Consumer<RpcAnswer> callback) {
+    m_inst.createRpc(this, callback);
+  }
+
+  /**
+   * Call a RPC function.  May be used on either the client or server.
+   * This function is non-blocking.  Either {@link RpcCall#getResult()} or
+   * {@link RpcCall#cancelResult()} must be called on the return value to either
+   * get or ignore the result of the call.
+   *
+   * @param params      parameter
+   * @return RPC call object.
+   */
+  public RpcCall callRpc(byte[] params) {
+    return new RpcCall(this, NetworkTablesJNI.callRpc(m_handle, params));
+  }
+
+  /**
+   * Add a listener for changes to the entry.
+   *
+   * @param listener the listener to add
+   * @param flags bitmask specifying desired notifications
+   * @return listener handle
+   */
+  public int addListener(Consumer<EntryNotification> listener, int flags) {
+    return m_inst.addEntryListener(this, listener, flags);
+  }
+
+  /**
+   * Remove a listener from receiving entry events.
+   *
+   * @param listener the listener to be removed
+   */
+  public void removeListener(int listener) {
+    m_inst.removeEntryListener(listener);
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof NetworkTableEntry)) {
+      return false;
+    }
+
+    return m_handle == ((NetworkTableEntry) other).m_handle;
+  }
+
+  @Override
+  public int hashCode() {
+    return m_handle;
+  }
+
+  private NetworkTableInstance m_inst;
+  private int m_handle;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableInstance.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableInstance.java
new file mode 100644
index 0000000..06dad09
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableInstance.java
@@ -0,0 +1,1178 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+/**
+ * NetworkTables Instance.
+ *
+ * <p>Instances are completely independent from each other.  Table operations on
+ * one instance will not be visible to other instances unless the instances are
+ * connected via the network.  The main limitation on instances is that you
+ * cannot have two servers on the same network port.  The main utility of
+ * instances is for unit testing, but they can also enable one program to
+ * connect to two different NetworkTables networks.
+ *
+ * <p>The global "default" instance (as returned by {@link #getDefault()}) is
+ * always available, and is intended for the common case when there is only
+ * a single NetworkTables instance being used in the program.
+ *
+ * <p>Additional instances can be created with the {@link #create()} function.
+ * A reference must be kept to the NetworkTableInstance returned by this
+ * function to keep it from being garbage collected.
+ */
+public final class NetworkTableInstance implements AutoCloseable {
+  /**
+   * Client/server mode flag values (as returned by {@link #getNetworkMode()}).
+   * This is a bitmask.
+   */
+  public static final int kNetModeNone = 0x00;
+  public static final int kNetModeServer = 0x01;
+  public static final int kNetModeClient = 0x02;
+  public static final int kNetModeStarting = 0x04;
+  public static final int kNetModeFailure = 0x08;
+  public static final int kNetModeLocal = 0x10;
+
+  /**
+   * The default port that network tables operates on.
+   */
+  public static final int kDefaultPort = 1735;
+
+  /**
+   * Construct from native handle.
+   *
+   * @param handle Native handle
+   */
+  private NetworkTableInstance(int handle) {
+    m_owned = false;
+    m_handle = handle;
+  }
+
+  /**
+   * Destroys the instance (if created by {@link #create()}).
+   */
+  @Override
+  public synchronized void close() {
+    if (m_owned && m_handle != 0) {
+      NetworkTablesJNI.destroyInstance(m_handle);
+    }
+  }
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  public boolean isValid() {
+    return m_handle != 0;
+  }
+
+  /* The default instance. */
+  private static NetworkTableInstance s_defaultInstance;
+
+  /**
+   * Get global default instance.
+   *
+   * @return Global default instance
+   */
+  public static synchronized NetworkTableInstance getDefault() {
+    if (s_defaultInstance == null) {
+      s_defaultInstance = new NetworkTableInstance(NetworkTablesJNI.getDefaultInstance());
+    }
+    return s_defaultInstance;
+  }
+
+  /**
+   * Create an instance.
+   * Note: A reference to the returned instance must be retained to ensure the
+   * instance is not garbage collected.
+   *
+   * @return Newly created instance
+   */
+  public static NetworkTableInstance create() {
+    NetworkTableInstance inst = new NetworkTableInstance(NetworkTablesJNI.createInstance());
+    inst.m_owned = true;
+    return inst;
+  }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  /**
+   * Gets the entry for a key.
+   *
+   * @param name Key
+   * @return Network table entry.
+   */
+  public NetworkTableEntry getEntry(String name) {
+    return new NetworkTableEntry(this, NetworkTablesJNI.getEntry(m_handle, name));
+  }
+
+  /**
+   * Get entries starting with the given prefix.
+   * The results are optionally filtered by string prefix and entry type to
+   * only return a subset of all entries.
+   *
+   * @param prefix entry name required prefix; only entries whose name
+   *     starts with this string are returned
+   * @param types bitmask of types; 0 is treated as a "don't care"
+   * @return Array of entries.
+   */
+  public NetworkTableEntry[] getEntries(String prefix, int types) {
+    int[] handles = NetworkTablesJNI.getEntries(m_handle, prefix, types);
+    NetworkTableEntry[] entries = new NetworkTableEntry[handles.length];
+    for (int i = 0; i < handles.length; i++) {
+      entries[i] = new NetworkTableEntry(this, handles[i]);
+    }
+    return entries;
+  }
+
+  /**
+   * Get information about entries starting with the given prefix.
+   * The results are optionally filtered by string prefix and entry type to
+   * only return a subset of all entries.
+   *
+   * @param prefix entry name required prefix; only entries whose name
+   *     starts with this string are returned
+   * @param types bitmask of types; 0 is treated as a "don't care"
+   * @return Array of entry information.
+   */
+  public EntryInfo[] getEntryInfo(String prefix, int types) {
+    return NetworkTablesJNI.getEntryInfo(this, m_handle, prefix, types);
+  }
+
+  /* Cache of created tables. */
+  private final ConcurrentMap<String, NetworkTable> m_tables = new ConcurrentHashMap<>();
+
+  /**
+   * Gets the table with the specified key.
+   *
+   * @param key the key name
+   * @return The network table
+   */
+  public NetworkTable getTable(String key) {
+    // prepend leading / if not present
+    String theKey;
+    if (key.isEmpty() || key.equals("/")) {
+      theKey = "";
+    } else if (key.charAt(0) == NetworkTable.PATH_SEPARATOR) {
+      theKey = key;
+    } else {
+      theKey = NetworkTable.PATH_SEPARATOR + key;
+    }
+
+    // cache created tables
+    NetworkTable table = m_tables.get(theKey);
+    if (table == null) {
+      table = new NetworkTable(this, theKey);
+      NetworkTable oldTable = m_tables.putIfAbsent(theKey, table);
+      if (oldTable != null) {
+        table = oldTable;
+      }
+    }
+    return table;
+  }
+
+  /**
+   * Deletes ALL keys in ALL subtables (except persistent values).
+   * Use with caution!
+   */
+  public void deleteAllEntries() {
+    NetworkTablesJNI.deleteAllEntries(m_handle);
+  }
+
+  /*
+   * Callback Creation Functions
+   */
+
+  private static class EntryConsumer<T> {
+    final NetworkTableEntry m_entry;
+    final Consumer<T> m_consumer;
+
+    EntryConsumer(NetworkTableEntry entry, Consumer<T> consumer) {
+      m_entry = entry;
+      m_consumer = consumer;
+    }
+  }
+
+  private final ReentrantLock m_entryListenerLock = new ReentrantLock();
+  private final Map<Integer, EntryConsumer<EntryNotification>> m_entryListeners = new HashMap<>();
+  private Thread m_entryListenerThread;
+  private int m_entryListenerPoller;
+  private boolean m_entryListenerWaitQueue;
+  private final Condition m_entryListenerWaitQueueCond = m_entryListenerLock.newCondition();
+
+  private void startEntryListenerThread() {
+    m_entryListenerThread = new Thread(() -> {
+      boolean wasInterrupted = false;
+      while (!Thread.interrupted()) {
+        EntryNotification[] events;
+        try {
+          events = NetworkTablesJNI.pollEntryListener(this, m_entryListenerPoller);
+        } catch (InterruptedException ex) {
+          m_entryListenerLock.lock();
+          try {
+            if (m_entryListenerWaitQueue) {
+              m_entryListenerWaitQueue = false;
+              m_entryListenerWaitQueueCond.signalAll();
+              continue;
+            }
+          } finally {
+            m_entryListenerLock.unlock();
+          }
+          Thread.currentThread().interrupt();
+          // don't try to destroy poller, as its handle is likely no longer valid
+          wasInterrupted = true;
+          break;
+        }
+        for (EntryNotification event : events) {
+          EntryConsumer<EntryNotification> listener;
+          m_entryListenerLock.lock();
+          try {
+            listener = m_entryListeners.get(event.listener);
+          } finally {
+            m_entryListenerLock.unlock();
+          }
+          if (listener != null) {
+            event.m_entryObject = listener.m_entry;
+            try {
+              listener.m_consumer.accept(event);
+            } catch (Throwable throwable) {
+              System.err.println("Unhandled exception during entry listener callback: "
+                  + throwable.toString());
+              throwable.printStackTrace();
+            }
+          }
+        }
+      }
+      m_entryListenerLock.lock();
+      try {
+        if (!wasInterrupted) {
+          NetworkTablesJNI.destroyEntryListenerPoller(m_entryListenerPoller);
+        }
+        m_entryListenerPoller = 0;
+      } finally {
+        m_entryListenerLock.unlock();
+      }
+    }, "NTEntryListener");
+    m_entryListenerThread.setDaemon(true);
+    m_entryListenerThread.start();
+  }
+
+  /**
+   * Add a listener for all entries starting with a certain prefix.
+   *
+   * @param prefix            UTF-8 string prefix
+   * @param listener          listener to add
+   * @param flags             {@link EntryListenerFlags} bitmask
+   * @return Listener handle
+   */
+  public int addEntryListener(String prefix, Consumer<EntryNotification> listener, int flags) {
+    m_entryListenerLock.lock();
+    try {
+      if (m_entryListenerPoller == 0) {
+        m_entryListenerPoller = NetworkTablesJNI.createEntryListenerPoller(m_handle);
+        startEntryListenerThread();
+      }
+      int handle = NetworkTablesJNI.addPolledEntryListener(m_entryListenerPoller, prefix, flags);
+      m_entryListeners.put(handle, new EntryConsumer<>(null, listener));
+      return handle;
+    } finally {
+      m_entryListenerLock.unlock();
+    }
+  }
+
+  /**
+   * Add a listener for a particular entry.
+   *
+   * @param entry             the entry
+   * @param listener          listener to add
+   * @param flags             {@link EntryListenerFlags} bitmask
+   * @return Listener handle
+   */
+  public int addEntryListener(NetworkTableEntry entry,
+                              Consumer<EntryNotification> listener,
+                              int flags) {
+    if (!equals(entry.getInstance())) {
+      throw new IllegalArgumentException("entry does not belong to this instance");
+    }
+    m_entryListenerLock.lock();
+    try {
+      if (m_entryListenerPoller == 0) {
+        m_entryListenerPoller = NetworkTablesJNI.createEntryListenerPoller(m_handle);
+        startEntryListenerThread();
+      }
+      int handle = NetworkTablesJNI.addPolledEntryListener(m_entryListenerPoller, entry.getHandle(),
+          flags);
+      m_entryListeners.put(handle, new EntryConsumer<>(entry, listener));
+      return handle;
+    } finally {
+      m_entryListenerLock.unlock();
+    }
+  }
+
+  /**
+   * Remove an entry listener.
+   *
+   * @param listener Listener handle to remove
+   */
+  public void removeEntryListener(int listener) {
+    NetworkTablesJNI.removeEntryListener(listener);
+  }
+
+  /**
+   * Wait for the entry listener queue to be empty.  This is primarily useful
+   * for deterministic testing.  This blocks until either the entry listener
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+  */
+  public boolean waitForEntryListenerQueue(double timeout) {
+    if (!NetworkTablesJNI.waitForEntryListenerQueue(m_handle, timeout)) {
+      return false;
+    }
+    m_entryListenerLock.lock();
+    try {
+      if (m_entryListenerPoller != 0) {
+        m_entryListenerWaitQueue = true;
+        NetworkTablesJNI.cancelPollEntryListener(m_entryListenerPoller);
+        while (m_entryListenerWaitQueue) {
+          try {
+            if (timeout < 0) {
+              m_entryListenerWaitQueueCond.await();
+            } else {
+              return m_entryListenerWaitQueueCond.await((long) (timeout * 1e9),
+                  TimeUnit.NANOSECONDS);
+            }
+          } catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+            return true;
+          }
+        }
+      }
+    } finally {
+      m_entryListenerLock.unlock();
+    }
+    return true;
+  }
+
+  private final ReentrantLock m_connectionListenerLock = new ReentrantLock();
+  private final Map<Integer, Consumer<ConnectionNotification>> m_connectionListeners
+      = new HashMap<>();
+  private Thread m_connectionListenerThread;
+  private int m_connectionListenerPoller;
+  private boolean m_connectionListenerWaitQueue;
+  private final Condition m_connectionListenerWaitQueueCond
+      = m_connectionListenerLock.newCondition();
+
+  private void startConnectionListenerThread() {
+    m_connectionListenerThread = new Thread(() -> {
+      boolean wasInterrupted = false;
+      while (!Thread.interrupted()) {
+        ConnectionNotification[] events;
+        try {
+          events = NetworkTablesJNI.pollConnectionListener(this, m_connectionListenerPoller);
+        } catch (InterruptedException ex) {
+          m_connectionListenerLock.lock();
+          try {
+            if (m_connectionListenerWaitQueue) {
+              m_connectionListenerWaitQueue = false;
+              m_connectionListenerWaitQueueCond.signalAll();
+              continue;
+            }
+          } finally {
+            m_connectionListenerLock.unlock();
+          }
+          Thread.currentThread().interrupt();
+          // don't try to destroy poller, as its handle is likely no longer valid
+          wasInterrupted = true;
+          break;
+        }
+        for (ConnectionNotification event : events) {
+          Consumer<ConnectionNotification> listener;
+          m_connectionListenerLock.lock();
+          try {
+            listener = m_connectionListeners.get(event.listener);
+          } finally {
+            m_connectionListenerLock.unlock();
+          }
+          if (listener != null) {
+            try {
+              listener.accept(event);
+            } catch (Throwable throwable) {
+              System.err.println("Unhandled exception during connection listener callback: "
+                  + throwable.toString());
+              throwable.printStackTrace();
+            }
+          }
+        }
+      }
+      m_connectionListenerLock.lock();
+      try {
+        if (!wasInterrupted) {
+          NetworkTablesJNI.destroyConnectionListenerPoller(m_connectionListenerPoller);
+        }
+        m_connectionListenerPoller = 0;
+      } finally {
+        m_connectionListenerLock.unlock();
+      }
+    }, "NTConnectionListener");
+    m_connectionListenerThread.setDaemon(true);
+    m_connectionListenerThread.start();
+  }
+
+  /**
+   * Add a connection listener.
+   *
+   * @param listener Listener to add
+   * @param immediateNotify Notify listener of all existing connections
+   * @return Listener handle
+   */
+  public int addConnectionListener(Consumer<ConnectionNotification> listener,
+                                   boolean immediateNotify) {
+    m_connectionListenerLock.lock();
+    try {
+      if (m_connectionListenerPoller == 0) {
+        m_connectionListenerPoller = NetworkTablesJNI.createConnectionListenerPoller(m_handle);
+        startConnectionListenerThread();
+      }
+      int handle = NetworkTablesJNI.addPolledConnectionListener(m_connectionListenerPoller,
+          immediateNotify);
+      m_connectionListeners.put(handle, listener);
+      return handle;
+    } finally {
+      m_connectionListenerLock.unlock();
+    }
+  }
+
+  /**
+   * Remove a connection listener.
+   *
+   * @param listener Listener handle to remove
+   */
+  public void removeConnectionListener(int listener) {
+    m_connectionListenerLock.lock();
+    try {
+      m_connectionListeners.remove(listener);
+    } finally {
+      m_connectionListenerLock.unlock();
+    }
+    NetworkTablesJNI.removeConnectionListener(listener);
+  }
+
+  /**
+   * Wait for the connection listener queue to be empty.  This is primarily useful
+   * for deterministic testing.  This blocks until either the connection listener
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  public boolean waitForConnectionListenerQueue(double timeout) {
+    if (!NetworkTablesJNI.waitForConnectionListenerQueue(m_handle, timeout)) {
+      return false;
+    }
+    m_connectionListenerLock.lock();
+    try {
+      if (m_connectionListenerPoller != 0) {
+        m_connectionListenerWaitQueue = true;
+        NetworkTablesJNI.cancelPollConnectionListener(m_connectionListenerPoller);
+        while (m_connectionListenerWaitQueue) {
+          try {
+            if (timeout < 0) {
+              m_connectionListenerWaitQueueCond.await();
+            } else {
+              return m_connectionListenerWaitQueueCond.await((long) (timeout * 1e9),
+                  TimeUnit.NANOSECONDS);
+            }
+          } catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+            return true;
+          }
+        }
+      }
+    } finally {
+      m_connectionListenerLock.unlock();
+    }
+    return true;
+  }
+
+  /*
+   * Remote Procedure Call Functions
+   */
+
+  private final ReentrantLock m_rpcCallLock = new ReentrantLock();
+  private final Map<Integer, EntryConsumer<RpcAnswer>> m_rpcCalls = new HashMap<>();
+  private Thread m_rpcCallThread;
+  private int m_rpcCallPoller;
+  private boolean m_rpcCallWaitQueue;
+  private final Condition m_rpcCallWaitQueueCond = m_rpcCallLock.newCondition();
+
+  private void startRpcCallThread() {
+    m_rpcCallThread = new Thread(() -> {
+      boolean wasInterrupted = false;
+      while (!Thread.interrupted()) {
+        RpcAnswer[] events;
+        try {
+          events = NetworkTablesJNI.pollRpc(this, m_rpcCallPoller);
+        } catch (InterruptedException ex) {
+          m_rpcCallLock.lock();
+          try {
+            if (m_rpcCallWaitQueue) {
+              m_rpcCallWaitQueue = false;
+              m_rpcCallWaitQueueCond.signalAll();
+              continue;
+            }
+          } finally {
+            m_rpcCallLock.unlock();
+          }
+          Thread.currentThread().interrupt();
+          // don't try to destroy poller, as its handle is likely no longer valid
+          wasInterrupted = true;
+          break;
+        }
+        for (RpcAnswer event : events) {
+          EntryConsumer<RpcAnswer> listener;
+          m_rpcCallLock.lock();
+          try {
+            listener = m_rpcCalls.get(event.entry);
+          } finally {
+            m_rpcCallLock.unlock();
+          }
+          if (listener != null) {
+            event.m_entryObject = listener.m_entry;
+            try {
+              listener.m_consumer.accept(event);
+            } catch (Throwable throwable) {
+              System.err.println("Unhandled exception during RPC callback: "
+                  + throwable.toString());
+              throwable.printStackTrace();
+            }
+            event.finish();
+          }
+        }
+      }
+      m_rpcCallLock.lock();
+      try {
+        if (!wasInterrupted) {
+          NetworkTablesJNI.destroyRpcCallPoller(m_rpcCallPoller);
+        }
+        m_rpcCallPoller = 0;
+      } finally {
+        m_rpcCallLock.unlock();
+      }
+    }, "NTRpcCall");
+    m_rpcCallThread.setDaemon(true);
+    m_rpcCallThread.start();
+  }
+
+  private static final byte[] rev0def = new byte[] {0};
+
+  /**
+   * Create a callback-based RPC entry point.  Only valid to use on the server.
+   * The callback function will be called when the RPC is called.
+   * This function creates RPC version 0 definitions (raw data in and out).
+   *
+   * @param entry     the entry
+   * @param callback  callback function
+   */
+  public void createRpc(NetworkTableEntry entry, Consumer<RpcAnswer> callback) {
+    m_rpcCallLock.lock();
+    try {
+      if (m_rpcCallPoller == 0) {
+        m_rpcCallPoller = NetworkTablesJNI.createRpcCallPoller(m_handle);
+        startRpcCallThread();
+      }
+      NetworkTablesJNI.createPolledRpc(entry.getHandle(), rev0def, m_rpcCallPoller);
+      m_rpcCalls.put(entry.getHandle(), new EntryConsumer<>(entry, callback));
+    } finally {
+      m_rpcCallLock.unlock();
+    }
+  }
+
+  /**
+   * Wait for the incoming RPC call queue to be empty.  This is primarily useful
+   * for deterministic testing.  This blocks until either the RPC call
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  public boolean waitForRpcCallQueue(double timeout) {
+    if (!NetworkTablesJNI.waitForRpcCallQueue(m_handle, timeout)) {
+      return false;
+    }
+    m_rpcCallLock.lock();
+    try {
+      if (m_rpcCallPoller != 0) {
+        m_rpcCallWaitQueue = true;
+        NetworkTablesJNI.cancelPollRpc(m_rpcCallPoller);
+        while (m_rpcCallWaitQueue) {
+          try {
+            if (timeout < 0) {
+              m_rpcCallWaitQueueCond.await();
+            } else {
+              return m_rpcCallWaitQueueCond.await((long) (timeout * 1e9), TimeUnit.NANOSECONDS);
+            }
+          } catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+            return true;
+          }
+        }
+      }
+    } finally {
+      m_rpcCallLock.unlock();
+    }
+    return true;
+  }
+
+  /*
+   * Client/Server Functions
+   */
+
+  /**
+   * Set the network identity of this node.
+   * This is the name used during the initial connection handshake, and is
+   * visible through ConnectionInfo on the remote node.
+   *
+   * @param name      identity to advertise
+   */
+  public void setNetworkIdentity(String name) {
+    NetworkTablesJNI.setNetworkIdentity(m_handle, name);
+  }
+
+  /**
+   * Get the current network mode.
+   *
+   * @return Bitmask of NetworkMode.
+   */
+  public int getNetworkMode() {
+    return NetworkTablesJNI.getNetworkMode(m_handle);
+  }
+
+  /**
+   * Starts local-only operation.  Prevents calls to startServer or startClient
+   * from taking effect.  Has no effect if startServer or startClient
+   * has already been called.
+   */
+  public void startLocal() {
+    NetworkTablesJNI.startLocal(m_handle);
+  }
+
+  /**
+   * Stops local-only operation.  startServer or startClient can be called after
+   * this call to start a server or client.
+   */
+  public void stopLocal() {
+    NetworkTablesJNI.stopLocal(m_handle);
+  }
+
+  /**
+   * Starts a server using the networktables.ini as the persistent file,
+   * using the default listening address and port.
+   */
+  public void startServer() {
+    startServer("networktables.ini");
+  }
+
+  /**
+   * Starts a server using the specified persistent filename, using the default
+   * listening address and port.
+   *
+   * @param persistFilename  the name of the persist file to use
+   */
+  public void startServer(String persistFilename) {
+    startServer(persistFilename, "");
+  }
+
+  /**
+   * Starts a server using the specified filename and listening address,
+   * using the default port.
+   *
+   * @param persistFilename  the name of the persist file to use
+   * @param listenAddress    the address to listen on, or empty to listen on any
+   *                         address
+   */
+  public void startServer(String persistFilename, String listenAddress) {
+    startServer(persistFilename, listenAddress, kDefaultPort);
+  }
+
+  /**
+   * Starts a server using the specified filename, listening address, and port.
+   *
+   * @param persistFilename  the name of the persist file to use
+   * @param listenAddress    the address to listen on, or empty to listen on any
+   *                         address
+   * @param port             port to communicate over
+   */
+  public void startServer(String persistFilename, String listenAddress, int port) {
+    NetworkTablesJNI.startServer(m_handle, persistFilename, listenAddress, port);
+  }
+
+  /**
+   * Stops the server if it is running.
+   */
+  public void stopServer() {
+    NetworkTablesJNI.stopServer(m_handle);
+  }
+
+  /**
+   * Starts a client.  Use SetServer to set the server name and port.
+   */
+  public void startClient() {
+    NetworkTablesJNI.startClient(m_handle);
+  }
+
+  /**
+   * Starts a client using the specified server and the default port.
+   *
+   * @param serverName  server name
+   */
+  public void startClient(String serverName) {
+    startClient(serverName, kDefaultPort);
+  }
+
+  /**
+   * Starts a client using the specified server and port.
+   *
+   * @param serverName  server name
+   * @param port        port to communicate over
+   */
+  public void startClient(String serverName, int port) {
+    NetworkTablesJNI.startClient(m_handle, serverName, port);
+  }
+
+  /**
+   * Starts a client using the specified servers and default port.  The
+   * client will attempt to connect to each server in round robin fashion.
+   *
+   * @param serverNames   array of server names
+   */
+  public void startClient(String[] serverNames) {
+    startClient(serverNames, kDefaultPort);
+  }
+
+  /**
+   * Starts a client using the specified servers and port number.  The
+   * client will attempt to connect to each server in round robin fashion.
+   *
+   * @param serverNames   array of server names
+   * @param port          port to communicate over
+   */
+  public void startClient(String[] serverNames, int port) {
+    int[] ports = new int[serverNames.length];
+    for (int i = 0; i < serverNames.length; i++) {
+      ports[i] = port;
+    }
+    startClient(serverNames, ports);
+  }
+
+  /**
+   * Starts a client using the specified (server, port) combinations.  The
+   * client will attempt to connect to each server in round robin fashion.
+   *
+   * @param serverNames   array of server names
+   * @param ports         array of port numbers
+   */
+  public void startClient(String[] serverNames, int[] ports) {
+    NetworkTablesJNI.startClient(m_handle, serverNames, ports);
+  }
+
+  /**
+   * Starts a client using commonly known robot addresses for the specified
+   * team using the default port number.
+   *
+   * @param team        team number
+   */
+  public void startClientTeam(int team) {
+    startClientTeam(team, kDefaultPort);
+  }
+
+  /**
+   * Starts a client using commonly known robot addresses for the specified
+   * team.
+   *
+   * @param team        team number
+   * @param port        port to communicate over
+   */
+  public void startClientTeam(int team, int port) {
+    NetworkTablesJNI.startClientTeam(m_handle, team, port);
+  }
+
+  /**
+   * Stops the client if it is running.
+   */
+  public void stopClient() {
+    NetworkTablesJNI.stopClient(m_handle);
+  }
+
+  /**
+   * Sets server address and port for client (without restarting client).
+   * Changes the port to the default port.
+   *
+   * @param serverName  server name
+   */
+  public void setServer(String serverName) {
+    setServer(serverName, kDefaultPort);
+  }
+
+  /**
+   * Sets server address and port for client (without restarting client).
+   *
+   * @param serverName  server name
+   * @param port        port to communicate over
+   */
+  public void setServer(String serverName, int port) {
+    NetworkTablesJNI.setServer(m_handle, serverName, port);
+  }
+
+  /**
+   * Sets server addresses and port for client (without restarting client).
+   * Changes the port to the default port.  The client will attempt to connect
+   * to each server in round robin fashion.
+   *
+   * @param serverNames   array of server names
+   */
+  public void setServer(String[] serverNames) {
+    setServer(serverNames, kDefaultPort);
+  }
+
+  /**
+   * Sets server addresses and port for client (without restarting client).
+   * The client will attempt to connect to each server in round robin fashion.
+   *
+   * @param serverNames   array of server names
+   * @param port          port to communicate over
+   */
+  public void setServer(String[] serverNames, int port) {
+    int[] ports = new int[serverNames.length];
+    for (int i = 0; i < serverNames.length; i++) {
+      ports[i] = port;
+    }
+    setServer(serverNames, ports);
+  }
+
+  /**
+   * Sets server addresses and ports for client (without restarting client).
+   * The client will attempt to connect to each server in round robin fashion.
+   *
+   * @param serverNames   array of server names
+   * @param ports         array of port numbers
+   */
+  public void setServer(String[] serverNames, int[] ports) {
+    NetworkTablesJNI.setServer(m_handle, serverNames, ports);
+  }
+
+  /**
+   * Sets server addresses and port for client (without restarting client).
+   * Changes the port to the default port.  The client will attempt to connect
+   * to each server in round robin fashion.
+   *
+   * @param team        team number
+   */
+  public void setServerTeam(int team) {
+    setServerTeam(team, kDefaultPort);
+  }
+
+  /**
+   * Sets server addresses and port for client (without restarting client).
+   * Connects using commonly known robot addresses for the specified team.
+   *
+   * @param team        team number
+   * @param port        port to communicate over
+   */
+  public void setServerTeam(int team, int port) {
+    NetworkTablesJNI.setServerTeam(m_handle, team, port);
+  }
+
+  /**
+   * Starts requesting server address from Driver Station.
+   * This connects to the Driver Station running on localhost to obtain the
+   * server IP address, and connects with the default port.
+   */
+  public void startDSClient() {
+    startDSClient(kDefaultPort);
+  }
+
+  /**
+   * Starts requesting server address from Driver Station.
+   * This connects to the Driver Station running on localhost to obtain the
+   * server IP address.
+   *
+   * @param port server port to use in combination with IP from DS
+   */
+  public void startDSClient(int port) {
+    NetworkTablesJNI.startDSClient(m_handle, port);
+  }
+
+  /**
+   * Stops requesting server address from Driver Station.
+   */
+  public void stopDSClient() {
+    NetworkTablesJNI.stopDSClient(m_handle);
+  }
+
+  /**
+   * Set the periodic update rate.
+   * Sets how frequently updates are sent to other nodes over the network.
+   *
+   * @param interval update interval in seconds (range 0.01 to 1.0)
+   */
+  public void setUpdateRate(double interval) {
+    NetworkTablesJNI.setUpdateRate(m_handle, interval);
+  }
+
+  /**
+   * 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 void flush() {
+    NetworkTablesJNI.flush(m_handle);
+  }
+
+  /**
+   * Gets information on the currently established network connections.
+   * If operating as a client, this will return either zero or one values.
+   *
+   * @return array of connection information
+   */
+  public ConnectionInfo[] getConnections() {
+    return NetworkTablesJNI.getConnections(m_handle);
+  }
+
+  /**
+   * Return whether or not the instance is connected to another node.
+   *
+   * @return True if connected.
+   */
+  public boolean isConnected() {
+    return NetworkTablesJNI.isConnected(m_handle);
+  }
+
+  /**
+   * Saves persistent keys to a file.  The server does this automatically.
+   *
+   * @param filename file name
+   * @throws PersistentException if error saving file
+   */
+  public void savePersistent(String filename) throws PersistentException {
+    NetworkTablesJNI.savePersistent(m_handle, 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 String[] loadPersistent(String filename) throws PersistentException {
+    return NetworkTablesJNI.loadPersistent(m_handle, filename);
+  }
+
+  /**
+   * Save table values to a file.  The file format used is identical to
+   * that used for SavePersistent.
+   *
+   * @param filename  filename
+   * @param prefix    save only keys starting with this prefix
+   * @throws PersistentException if error saving file
+   */
+  public void saveEntries(String filename, String prefix) throws PersistentException {
+    NetworkTablesJNI.saveEntries(m_handle, filename, prefix);
+  }
+
+  /**
+   * Load table values from a file.  The file format used is identical to
+   * that used for SavePersistent / LoadPersistent.
+   *
+   * @param filename  filename
+   * @param prefix    load only keys starting with this prefix
+   * @return List of warnings (errors result in an exception instead)
+   * @throws PersistentException if error saving file
+   */
+  public String[] loadEntries(String filename, String prefix) throws PersistentException {
+    return NetworkTablesJNI.loadEntries(m_handle, filename, prefix);
+  }
+
+  private final ReentrantLock m_loggerLock = new ReentrantLock();
+  private final Map<Integer, Consumer<LogMessage>> m_loggers = new HashMap<>();
+  private Thread m_loggerThread;
+  private int m_loggerPoller;
+  private boolean m_loggerWaitQueue;
+  private final Condition m_loggerWaitQueueCond = m_loggerLock.newCondition();
+
+  private void startLogThread() {
+    m_loggerThread = new Thread(() -> {
+      boolean wasInterrupted = false;
+      while (!Thread.interrupted()) {
+        LogMessage[] events;
+        try {
+          events = NetworkTablesJNI.pollLogger(this, m_loggerPoller);
+        } catch (InterruptedException ex) {
+          Thread.currentThread().interrupt();
+          // don't try to destroy poller, as its handle is likely no longer valid
+          wasInterrupted = true;
+          break;
+        }
+        for (LogMessage event : events) {
+          Consumer<LogMessage> logger;
+          m_loggerLock.lock();
+          try {
+            logger = m_loggers.get(event.logger);
+          } finally {
+            m_loggerLock.unlock();
+          }
+          if (logger != null) {
+            try {
+              logger.accept(event);
+            } catch (Throwable throwable) {
+              System.err.println("Unhandled exception during logger callback: "
+                  + throwable.toString());
+              throwable.printStackTrace();
+            }
+          }
+        }
+      }
+      m_loggerLock.lock();
+      try {
+        if (!wasInterrupted) {
+          NetworkTablesJNI.destroyLoggerPoller(m_loggerPoller);
+        }
+        m_rpcCallPoller = 0;
+      } finally {
+        m_loggerLock.unlock();
+      }
+    }, "NTLogger");
+    m_loggerThread.setDaemon(true);
+    m_loggerThread.start();
+  }
+
+  /**
+   * Add logger callback function.  By default, log messages are sent to stderr;
+   * this function sends log messages with the specified levels to the provided
+   * callback function instead.  The callback function will only be called for
+   * log messages with level greater than or equal to minLevel and less than or
+   * equal to maxLevel; messages outside this range will be silently ignored.
+   *
+   * @param func        log callback function
+   * @param minLevel    minimum log level
+   * @param maxLevel    maximum log level
+   * @return Logger handle
+   */
+  public int addLogger(Consumer<LogMessage> func, int minLevel, int maxLevel) {
+    m_loggerLock.lock();
+    try {
+      if (m_loggerPoller == 0) {
+        m_loggerPoller = NetworkTablesJNI.createLoggerPoller(m_handle);
+        startLogThread();
+      }
+      int handle = NetworkTablesJNI.addPolledLogger(m_loggerPoller, minLevel, maxLevel);
+      m_loggers.put(handle, func);
+      return handle;
+    } finally {
+      m_loggerLock.unlock();
+    }
+  }
+
+  /**
+   * Remove a logger.
+   *
+   * @param logger Logger handle to remove
+   */
+  public void removeLogger(int logger) {
+    m_loggerLock.lock();
+    try {
+      m_loggers.remove(logger);
+    } finally {
+      m_loggerLock.unlock();
+    }
+    NetworkTablesJNI.removeLogger(logger);
+  }
+
+  /**
+   * Wait for the incoming log event queue to be empty.  This is primarily useful
+   * for deterministic testing.  This blocks until either the log event
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  public boolean waitForLoggerQueue(double timeout) {
+    if (!NetworkTablesJNI.waitForLoggerQueue(m_handle, timeout)) {
+      return false;
+    }
+    m_loggerLock.lock();
+    try {
+      if (m_loggerPoller != 0) {
+        m_loggerWaitQueue = true;
+        NetworkTablesJNI.cancelPollLogger(m_loggerPoller);
+        while (m_loggerWaitQueue) {
+          try {
+            if (timeout < 0) {
+              m_loggerWaitQueueCond.await();
+            } else {
+              return m_loggerWaitQueueCond.await((long) (timeout * 1e9), TimeUnit.NANOSECONDS);
+            }
+          } catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+            return true;
+          }
+        }
+      }
+    } finally {
+      m_loggerLock.unlock();
+    }
+    return true;
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof NetworkTableInstance)) {
+      return false;
+    }
+
+    return m_handle == ((NetworkTableInstance) other).m_handle;
+  }
+
+  @Override
+  public int hashCode() {
+    return m_handle;
+  }
+
+  private boolean m_owned;
+  private int m_handle;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableType.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableType.java
new file mode 100644
index 0000000..54a9f55
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableType.java
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * Network table data types.
+ */
+public enum NetworkTableType {
+  kUnassigned(0),
+  kBoolean(0x01),
+  kDouble(0x02),
+  kString(0x04),
+  kRaw(0x08),
+  kBooleanArray(0x10),
+  kDoubleArray(0x20),
+  kStringArray(0x40),
+  kRpc(0x80);
+
+  @SuppressWarnings("MemberName")
+  private final int value;
+
+  NetworkTableType(int value) {
+    this.value = value;
+  }
+
+  public int getValue() {
+    return value;
+  }
+
+  /**
+   * Convert from the numerical representation of type to an enum type.
+   *
+   * @param value The numerical representation of kind
+   * @return The kind
+   */
+  public static NetworkTableType getFromInt(int value) {
+    switch (value) {
+      case 0x01: return kBoolean;
+      case 0x02: return kDouble;
+      case 0x04: return kString;
+      case 0x08: return kRaw;
+      case 0x10: return kBooleanArray;
+      case 0x20: return kDoubleArray;
+      case 0x40: return kStringArray;
+      case 0x80: return kRpc;
+      default: return kUnassigned;
+    }
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableValue.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableValue.java
new file mode 100644
index 0000000..eb7e2c2
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableValue.java
@@ -0,0 +1,516 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.Objects;
+
+/**
+ * A network table entry value.
+ */
+public final class NetworkTableValue {
+  NetworkTableValue(NetworkTableType type, Object value, long time) {
+    m_type = type;
+    m_value = value;
+    m_time = time;
+  }
+
+  NetworkTableValue(NetworkTableType type, Object value) {
+    this(type, value, NetworkTablesJNI.now());
+  }
+
+  NetworkTableValue(int type, Object value, long time) {
+    this(NetworkTableType.getFromInt(type), value, time);
+  }
+
+  /**
+   * Get the data type.
+   *
+   * @return The type.
+   */
+  public NetworkTableType getType() {
+    return m_type;
+  }
+
+  /**
+   * Get the data value stored.
+   *
+   * @return The type.
+   */
+  public Object getValue() {
+    return m_value;
+  }
+
+  /**
+   * Get the creation time of the value.
+   *
+   * @return The time, in the units returned by NetworkTablesJNI.now().
+   */
+  public long getTime() {
+    return m_time;
+  }
+
+  /*
+   * Type Checkers
+   */
+
+  /**
+   * Determine if entry value contains a value or is unassigned.
+   *
+   * @return True if the entry value contains a value.
+   */
+  public boolean isValid() {
+    return m_type != NetworkTableType.kUnassigned;
+  }
+
+  /**
+   * Determine if entry value contains a boolean.
+   *
+   * @return True if the entry value is of boolean type.
+   */
+  public boolean isBoolean() {
+    return m_type == NetworkTableType.kBoolean;
+  }
+
+  /**
+   * Determine if entry value contains a double.
+   *
+   * @return True if the entry value is of double type.
+   */
+  public boolean isDouble() {
+    return m_type == NetworkTableType.kDouble;
+  }
+
+  /**
+   * Determine if entry value contains a string.
+   *
+   * @return True if the entry value is of string type.
+   */
+  public boolean isString() {
+    return m_type == NetworkTableType.kString;
+  }
+
+  /**
+   * Determine if entry value contains a raw.
+   *
+   * @return True if the entry value is of raw type.
+   */
+  public boolean isRaw() {
+    return m_type == NetworkTableType.kRaw;
+  }
+
+  /**
+   * Determine if entry value contains a rpc definition.
+   *
+   * @return True if the entry value is of rpc definition type.
+   */
+  public boolean isRpc() {
+    return m_type == NetworkTableType.kRpc;
+  }
+
+  /**
+   * Determine if entry value contains a boolean array.
+   *
+   * @return True if the entry value is of boolean array type.
+   */
+  public boolean isBooleanArray() {
+    return m_type == NetworkTableType.kBooleanArray;
+  }
+
+  /**
+   * Determine if entry value contains a double array.
+   *
+   * @return True if the entry value is of double array type.
+   */
+  public boolean isDoubleArray() {
+    return m_type == NetworkTableType.kDoubleArray;
+  }
+
+  /**
+   * Determine if entry value contains a string array.
+   *
+   * @return True if the entry value is of string array type.
+   */
+  public boolean isStringArray() {
+    return m_type == NetworkTableType.kStringArray;
+  }
+
+  /*
+   * Type-Safe Getters
+   */
+
+  /**
+   * Get the entry's boolean value.
+   *
+   * @return The boolean value.
+   * @throws ClassCastException if the entry value is not of boolean type.
+   */
+  public boolean getBoolean() {
+    if (m_type != NetworkTableType.kBoolean) {
+      throw new ClassCastException("cannot convert " + m_type + " to boolean");
+    }
+    return (Boolean) m_value;
+  }
+
+  /**
+   * Get the entry's double value.
+   *
+   * @return The double value.
+   * @throws ClassCastException if the entry value is not of double type.
+   */
+  public double getDouble() {
+    if (m_type != NetworkTableType.kDouble) {
+      throw new ClassCastException("cannot convert " + m_type + " to double");
+    }
+    return ((Number) m_value).doubleValue();
+  }
+
+  /**
+   * Get the entry's string value.
+   *
+   * @return The string value.
+   * @throws ClassCastException if the entry value is not of string type.
+   */
+  public String getString() {
+    if (m_type != NetworkTableType.kString) {
+      throw new ClassCastException("cannot convert " + m_type + " to string");
+    }
+    return (String) m_value;
+  }
+
+  /**
+   * Get the entry's raw value.
+   *
+   * @return The raw value.
+   * @throws ClassCastException if the entry value is not of raw type.
+   */
+  public byte[] getRaw() {
+    if (m_type != NetworkTableType.kRaw) {
+      throw new ClassCastException("cannot convert " + m_type + " to raw");
+    }
+    return (byte[]) m_value;
+  }
+
+  /**
+   * Get the entry's rpc definition value.
+   *
+   * @return The rpc definition value.
+   * @throws ClassCastException if the entry value is not of rpc definition type.
+   */
+  public byte[] getRpc() {
+    if (m_type != NetworkTableType.kRpc) {
+      throw new ClassCastException("cannot convert " + m_type + " to rpc");
+    }
+    return (byte[]) m_value;
+  }
+
+  /**
+   * Get the entry's boolean array value.
+   *
+   * @return The boolean array value.
+   * @throws ClassCastException if the entry value is not of boolean array type.
+   */
+  public boolean[] getBooleanArray() {
+    if (m_type != NetworkTableType.kBooleanArray) {
+      throw new ClassCastException("cannot convert " + m_type + " to boolean array");
+    }
+    return (boolean[]) m_value;
+  }
+
+  /**
+   * Get the entry's double array value.
+   *
+   * @return The double array value.
+   * @throws ClassCastException if the entry value is not of double array type.
+   */
+  public double[] getDoubleArray() {
+    if (m_type != NetworkTableType.kDoubleArray) {
+      throw new ClassCastException("cannot convert " + m_type + " to double array");
+    }
+    return (double[]) m_value;
+  }
+
+  /**
+   * Get the entry's string array value.
+   *
+   * @return The string array value.
+   * @throws ClassCastException if the entry value is not of string array type.
+   */
+  public String[] getStringArray() {
+    if (m_type != NetworkTableType.kStringArray) {
+      throw new ClassCastException("cannot convert " + m_type + " to string array");
+    }
+    return (String[]) m_value;
+  }
+
+  /*
+   * Factory functions.
+   */
+
+  /**
+   * Creates a boolean entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeBoolean(boolean value) {
+    return new NetworkTableValue(NetworkTableType.kBoolean, Boolean.valueOf(value));
+  }
+
+  /**
+   * Creates a boolean entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeBoolean(boolean value, long time) {
+    return new NetworkTableValue(NetworkTableType.kBoolean, Boolean.valueOf(value), time);
+  }
+
+  /**
+   * Creates a double entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeDouble(double value) {
+    return new NetworkTableValue(NetworkTableType.kDouble, Double.valueOf(value));
+  }
+
+  /**
+   * Creates a double entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeDouble(double value, long time) {
+    return new NetworkTableValue(NetworkTableType.kDouble, Double.valueOf(value), time);
+  }
+
+  /**
+   * Creates a string entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeString(String value) {
+    return new NetworkTableValue(NetworkTableType.kString, value);
+  }
+
+  /**
+   * Creates a string entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeString(String value, long time) {
+    return new NetworkTableValue(NetworkTableType.kString, value, time);
+  }
+
+  /**
+   * Creates a raw entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeRaw(byte[] value) {
+    return new NetworkTableValue(NetworkTableType.kRaw, value);
+  }
+
+  /**
+   * Creates a raw entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeRaw(byte[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kRaw, value, time);
+  }
+
+  /**
+   * Creates a rpc entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeRpc(byte[] value) {
+    return new NetworkTableValue(NetworkTableType.kRpc, value);
+  }
+
+  /**
+   * Creates a rpc entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeRpc(byte[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kRpc, value, time);
+  }
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeBooleanArray(boolean[] value) {
+    return new NetworkTableValue(NetworkTableType.kBooleanArray, value);
+  }
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeBooleanArray(boolean[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kBooleanArray, value, time);
+  }
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeBooleanArray(Boolean[] value) {
+    return new NetworkTableValue(NetworkTableType.kBooleanArray, toNative(value));
+  }
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeBooleanArray(Boolean[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kBooleanArray, toNative(value), time);
+  }
+
+  /**
+   * Creates a double array entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeDoubleArray(double[] value) {
+    return new NetworkTableValue(NetworkTableType.kDoubleArray, value);
+  }
+
+  /**
+   * Creates a double array entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeDoubleArray(double[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kDoubleArray, value, time);
+  }
+
+  /**
+   * Creates a double array entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeDoubleArray(Number[] value) {
+    return new NetworkTableValue(NetworkTableType.kDoubleArray, toNative(value));
+  }
+
+  /**
+   * Creates a double array entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeDoubleArray(Number[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kDoubleArray, toNative(value), time);
+  }
+
+  /**
+   * Creates a string array entry value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue makeStringArray(String[] value) {
+    return new NetworkTableValue(NetworkTableType.kStringArray, value);
+  }
+
+  /**
+   * Creates a string array entry value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue makeStringArray(String[] value, long time) {
+    return new NetworkTableValue(NetworkTableType.kStringArray, value, time);
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof NetworkTableValue)) {
+      return false;
+    }
+    NetworkTableValue ntOther = (NetworkTableValue) other;
+    return m_type == ntOther.m_type && m_value.equals(ntOther.m_value);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(m_type, m_value);
+  }
+
+  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;
+  }
+
+  static double[] toNative(Number[] arr) {
+    double[] out = new double[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i].doubleValue();
+    }
+    return out;
+  }
+
+  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;
+  }
+
+  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;
+  }
+
+  private NetworkTableType m_type;
+  private Object m_value;
+  private long m_time;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTablesJNI.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTablesJNI.java
new file mode 100644
index 0000000..742c0ca
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTablesJNI.java
@@ -0,0 +1,180 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import edu.wpi.first.wpiutil.RuntimeLoader;
+
+public final class NetworkTablesJNI {
+  static boolean libraryLoaded = false;
+  static RuntimeLoader<NetworkTablesJNI> loader = null;
+
+  public static class Helper {
+    private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
+
+    public static boolean getExtractOnStaticLoad() {
+      return extractOnStaticLoad.get();
+    }
+
+    public static void setExtractOnStaticLoad(boolean load) {
+      extractOnStaticLoad.set(load);
+    }
+  }
+
+  static {
+    if (Helper.getExtractOnStaticLoad()) {
+      try {
+        loader = new RuntimeLoader<>("ntcorejni", RuntimeLoader.getDefaultExtractionRoot(), NetworkTablesJNI.class);
+        loader.loadLibrary();
+      } catch (IOException ex) {
+        ex.printStackTrace();
+        System.exit(1);
+      }
+      libraryLoaded = true;
+    }
+  }
+
+  /**
+   * Force load the library.
+   */
+  public static synchronized void forceLoad() throws IOException {
+    if (libraryLoaded) {
+      return;
+    }
+    loader = new RuntimeLoader<>("ntcorejni", RuntimeLoader.getDefaultExtractionRoot(), NetworkTablesJNI.class);
+    loader.loadLibrary();
+    libraryLoaded = true;
+  }
+
+  public static native int getDefaultInstance();
+  public static native int createInstance();
+  public static native void destroyInstance(int inst);
+  public static native int getInstanceFromHandle(int handle);
+
+  public static native int getEntry(int inst, String key);
+  public static native int[] getEntries(int inst, String prefix, int types);
+  public static native String getEntryName(int entry);
+  public static native long getEntryLastChange(int entry);
+
+  public static native int getType(int entry);
+
+  public static native boolean setBoolean(int entry, long time, boolean value, boolean force);
+  public static native boolean setDouble(int entry, long time, double value, boolean force);
+  public static native boolean setString(int entry, long time, String value, boolean force);
+  public static native boolean setRaw(int entry, long time, byte[] value, boolean force);
+  public static native boolean setRaw(int entry, long time, ByteBuffer value, int len, boolean force);
+  public static native boolean setBooleanArray(int entry, long time, boolean[] value, boolean force);
+  public static native boolean setDoubleArray(int entry, long time, double[] value, boolean force);
+  public static native boolean setStringArray(int entry, long time, String[] value, boolean force);
+
+  public static native NetworkTableValue getValue(int entry);
+
+  public static native boolean getBoolean(int entry, boolean defaultValue);
+  public static native double getDouble(int entry, double defaultValue);
+  public static native String getString(int entry, String defaultValue);
+  public static native byte[] getRaw(int entry, byte[] defaultValue);
+  public static native boolean[] getBooleanArray(int entry, boolean[] defaultValue);
+  public static native double[] getDoubleArray(int entry, double[] defaultValue);
+  public static native String[] getStringArray(int entry, String[] defaultValue);
+  public static native boolean setDefaultBoolean(int entry, long time, boolean defaultValue);
+
+  public static native boolean setDefaultDouble(int entry, long time, double defaultValue);
+  public static native boolean setDefaultString(int entry, long time, String defaultValue);
+  public static native boolean setDefaultRaw(int entry, long time, byte[] defaultValue);
+  public static native boolean setDefaultBooleanArray(int entry, long time, boolean[] defaultValue);
+  public static native boolean setDefaultDoubleArray(int entry, long time, double[] defaultValue);
+  public static native boolean setDefaultStringArray(int entry, long time, String[] defaultValue);
+
+  public static native void setEntryFlags(int entry, int flags);
+  public static native int getEntryFlags(int entry);
+
+  public static native void deleteEntry(int entry);
+
+  public static native void deleteAllEntries(int inst);
+
+  public static native EntryInfo getEntryInfoHandle(NetworkTableInstance inst, int entry);
+  public static native EntryInfo[] getEntryInfo(NetworkTableInstance instObject, int inst, String prefix, int types);
+
+  public static native int createEntryListenerPoller(int inst);
+  public static native void destroyEntryListenerPoller(int poller);
+  public static native int addPolledEntryListener(int poller, String prefix, int flags);
+  public static native int addPolledEntryListener(int poller, int entry, int flags);
+  public static native EntryNotification[] pollEntryListener(NetworkTableInstance inst, int poller) throws InterruptedException;
+  public static native EntryNotification[] pollEntryListenerTimeout(NetworkTableInstance inst, int poller, double timeout) throws InterruptedException;
+  public static native void cancelPollEntryListener(int poller);
+  public static native void removeEntryListener(int entryListener);
+  public static native boolean waitForEntryListenerQueue(int inst, double timeout);
+
+  public static native int createConnectionListenerPoller(int inst);
+  public static native void destroyConnectionListenerPoller(int poller);
+  public static native int addPolledConnectionListener(int poller, boolean immediateNotify);
+  public static native ConnectionNotification[] pollConnectionListener(NetworkTableInstance inst, int poller) throws InterruptedException;
+  public static native ConnectionNotification[] pollConnectionListenerTimeout(NetworkTableInstance inst, int poller, double timeout) throws InterruptedException;
+  public static native void cancelPollConnectionListener(int poller);
+  public static native void removeConnectionListener(int connListener);
+  public static native boolean waitForConnectionListenerQueue(int inst, double timeout);
+
+  public static native int createRpcCallPoller(int inst);
+  public static native void destroyRpcCallPoller(int poller);
+  public static native void createPolledRpc(int entry, byte[] def, int poller);
+  public static native RpcAnswer[] pollRpc(NetworkTableInstance inst, int poller) throws InterruptedException;
+  public static native RpcAnswer[] pollRpcTimeout(NetworkTableInstance inst, int poller, double timeout) throws InterruptedException;
+  public static native void cancelPollRpc(int poller);
+  public static native boolean waitForRpcCallQueue(int inst, double timeout);
+  public static native boolean postRpcResponse(int entry, int call, byte[] result);
+  public static native int callRpc(int entry, byte[] params);
+  public static native byte[] getRpcResult(int entry, int call);
+  public static native byte[] getRpcResult(int entry, int call, double timeout);
+  public static native void cancelRpcResult(int entry, int call);
+
+  public static native byte[] getRpc(int entry, byte[] defaultValue);
+
+  public static native void setNetworkIdentity(int inst, String name);
+  public static native int getNetworkMode(int inst);
+  public static native void startLocal(int inst);
+  public static native void stopLocal(int inst);
+  public static native void startServer(int inst, String persistFilename, String listenAddress, int port);
+  public static native void stopServer(int inst);
+  public static native void startClient(int inst);
+  public static native void startClient(int inst, String serverName, int port);
+  public static native void startClient(int inst, String[] serverNames, int[] ports);
+  public static native void startClientTeam(int inst, int team, int port);
+  public static native void stopClient(int inst);
+  public static native void setServer(int inst, String serverName, int port);
+  public static native void setServer(int inst, String[] serverNames, int[] ports);
+  public static native void setServerTeam(int inst, int team, int port);
+  public static native void startDSClient(int inst, int port);
+  public static native void stopDSClient(int inst);
+  public static native void setUpdateRate(int inst, double interval);
+
+  public static native void flush(int inst);
+
+  public static native ConnectionInfo[] getConnections(int inst);
+
+  public static native boolean isConnected(int inst);
+
+  public static native void savePersistent(int inst, String filename) throws PersistentException;
+  public static native String[] loadPersistent(int inst, String filename) throws PersistentException;  // returns warnings
+
+  public static native void saveEntries(int inst, String filename, String prefix) throws PersistentException;
+  public static native String[] loadEntries(int inst, String filename, String prefix) throws PersistentException;  // returns warnings
+
+  public static native long now();
+
+  public static native int createLoggerPoller(int inst);
+  public static native void destroyLoggerPoller(int poller);
+  public static native int addPolledLogger(int poller, int minLevel, int maxLevel);
+  public static native LogMessage[] pollLogger(NetworkTableInstance inst, int poller) throws InterruptedException;
+  public static native LogMessage[] pollLoggerTimeout(NetworkTableInstance inst, int poller, double timeout) throws InterruptedException;
+  public static native void cancelPollLogger(int poller);
+  public static native void removeLogger(int logger);
+  public static native boolean waitForLoggerQueue(int inst, double timeout);
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/PersistentException.java b/ntcore/src/main/java/edu/wpi/first/networktables/PersistentException.java
new file mode 100644
index 0000000..205b015
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/PersistentException.java
@@ -0,0 +1,21 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.io.IOException;
+
+/**
+ * An exception thrown when persistent load/save fails in a {@link NetworkTable}.
+ */
+public final class PersistentException extends IOException {
+  public static final long serialVersionUID = 0;
+
+  public PersistentException(String message) {
+    super(message);
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/RpcAnswer.java b/ntcore/src/main/java/edu/wpi/first/networktables/RpcAnswer.java
new file mode 100644
index 0000000..91e1aa4
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/RpcAnswer.java
@@ -0,0 +1,105 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Remote Procedure Call (Server Side).
+ */
+public final class RpcAnswer {
+  /** Entry handle. */
+  @SuppressWarnings("MemberName")
+  public final int entry;
+
+  /** Call handle. */
+  @SuppressWarnings("MemberName")
+  public int call;
+
+  /** Entry name. */
+  @SuppressWarnings("MemberName")
+  public final String name;
+
+  /** Call raw parameters. */
+  @SuppressWarnings("MemberName")
+  public final byte[] params;
+
+  /** Connection that called the RPC. */
+  @SuppressWarnings("MemberName")
+  public final ConnectionInfo conn;
+
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param entry Entry handle
+   * @param call Call handle
+   * @param name Entry name
+   * @param params Call raw parameters
+   * @param conn Connection info
+   */
+  public RpcAnswer(NetworkTableInstance inst, int entry, int call, String name, byte[] params,
+                   ConnectionInfo conn) {
+    this.m_inst = inst;
+    this.entry = entry;
+    this.call = call;
+    this.name = name;
+    this.params = params;
+    this.conn = conn;
+  }
+
+  static final byte[] emptyResponse = new byte[] {};
+
+  /*
+   * Finishes an RPC answer by replying empty if the user did not respond.
+   * Called internally by the callback thread.
+   */
+  void finish() {
+    if (call != 0) {
+      NetworkTablesJNI.postRpcResponse(entry, call, emptyResponse);
+      call = 0;
+    }
+  }
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  public boolean isValid() {
+    return call != 0;
+  }
+
+  /**
+   * Post RPC response (return value) for a polled RPC.
+   *
+   * @param result  result raw data that will be provided to remote caller
+   * @return        true if the response was posted, otherwise false
+   */
+  public boolean postResponse(byte[] result) {
+    boolean ret = NetworkTablesJNI.postRpcResponse(entry, call, result);
+    call = 0;
+    return ret;
+  }
+
+  /* Network table instance. */
+  private final NetworkTableInstance m_inst;
+
+  /* Cached entry object. */
+  NetworkTableEntry m_entryObject;
+
+  /**
+   * Get the entry as an object.
+   *
+   * @return NetworkTableEntry for the RPC.
+   */
+  NetworkTableEntry getEntry() {
+    if (m_entryObject == null) {
+      m_entryObject = new NetworkTableEntry(m_inst, entry);
+    }
+    return m_entryObject;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/RpcCall.java b/ntcore/src/main/java/edu/wpi/first/networktables/RpcCall.java
new file mode 100644
index 0000000..b9148c9
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/RpcCall.java
@@ -0,0 +1,100 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Remote Procedure Call.
+ */
+public final class RpcCall implements AutoCloseable {
+  /** Constructor.
+   * This should generally only be used internally to NetworkTables.
+   *
+   * @param entry Entry
+   * @param call Call handle
+   */
+  public RpcCall(NetworkTableEntry entry, int call) {
+    m_entry = entry;
+    m_call = call;
+  }
+
+  /**
+   * Cancels the result if no other action taken.
+   */
+  @Override
+  public synchronized void close() {
+    if (m_call != 0) {
+      cancelResult();
+    }
+  }
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  public boolean isValid() {
+    return m_call != 0;
+  }
+
+  /**
+   * Get the RPC entry.
+   *
+   * @return NetworkTableEntry for the RPC.
+   */
+  public NetworkTableEntry getEntry() {
+    return m_entry;
+  }
+
+  /**
+   * Get the call native handle.
+   *
+   * @return Native handle.
+   */
+  public int getCall() {
+    return m_call;
+  }
+
+  /**
+   * Get the result (return value).  This function blocks until
+   * the result is received.
+   *
+   * @return Received result (output)
+   */
+  public byte[] getResult() {
+    byte[] result = NetworkTablesJNI.getRpcResult(m_entry.getHandle(), m_call);
+    if (result.length != 0) {
+      m_call = 0;
+    }
+    return result;
+  }
+
+  /**
+   * Get the result (return value).  This function blocks until
+   * the result is received or it times out.
+   *
+   * @param timeout     timeout, in seconds
+   * @return Received result (output)
+   */
+  public byte[] getResult(double timeout) {
+    byte[] result = NetworkTablesJNI.getRpcResult(m_entry.getHandle(), m_call, timeout);
+    if (result.length != 0) {
+      m_call = 0;
+    }
+    return result;
+  }
+
+  /**
+   * Ignore the result.  This function is non-blocking.
+   */
+  public void cancelResult() {
+    NetworkTablesJNI.cancelRpcResult(m_entry.getHandle(), m_call);
+  }
+
+  private final NetworkTableEntry m_entry;
+  private int m_call;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/TableEntryListener.java b/ntcore/src/main/java/edu/wpi/first/networktables/TableEntryListener.java
new file mode 100644
index 0000000..676e57e
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/TableEntryListener.java
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * A listener that listens to changes in values in a {@link NetworkTable}.
+ */
+@FunctionalInterface
+public interface TableEntryListener extends EntryListenerFlags {
+  /**
+   * Called when a key-value pair is changed in a {@link NetworkTable}.
+   *
+   * @param table the table the key-value pair exists in
+   * @param key the key associated with the value that changed
+   * @param entry the entry associated with the value that changed
+   * @param value the new value
+   * @param flags update flags; for example, EntryListenerFlags.kNew if the key
+   *     did not previously exist in the table
+   */
+  void valueChanged(NetworkTable table, String key, NetworkTableEntry entry,
+                    NetworkTableValue value, int flags);
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/TableListener.java b/ntcore/src/main/java/edu/wpi/first/networktables/TableListener.java
new file mode 100644
index 0000000..3c686e5
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/TableListener.java
@@ -0,0 +1,23 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+/**
+ * A listener that listens to new tables in a {@link NetworkTable}.
+ */
+@FunctionalInterface
+public interface TableListener {
+  /**
+   * Called when a new table is created within a {@link NetworkTable}.
+   *
+   * @param parent the parent of the table
+   * @param name the name of the new table
+   * @param table the new table
+   */
+  void tableCreated(NetworkTable parent, String name, NetworkTable table);
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTable.java b/ntcore/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTable.java
new file mode 100644
index 0000000..f360a19
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTable.java
@@ -0,0 +1,1189 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpilibj.networktables;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Consumer;
+
+import edu.wpi.first.networktables.ConnectionInfo;
+import edu.wpi.first.networktables.ConnectionNotification;
+import edu.wpi.first.networktables.EntryInfo;
+import edu.wpi.first.networktables.EntryNotification;
+import edu.wpi.first.networktables.NetworkTableEntry;
+import edu.wpi.first.networktables.NetworkTableInstance;
+import edu.wpi.first.networktables.NetworkTableType;
+import edu.wpi.first.networktables.NetworkTableValue;
+import edu.wpi.first.networktables.NetworkTablesJNI;
+import edu.wpi.first.networktables.PersistentException;
+import edu.wpi.first.wpilibj.tables.IRemote;
+import edu.wpi.first.wpilibj.tables.IRemoteConnectionListener;
+import edu.wpi.first.wpilibj.tables.ITable;
+import edu.wpi.first.wpilibj.tables.ITableListener;
+
+/**
+ * A network table that knows its subtable path.
+ * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable} instead.
+ */
+@Deprecated
+@SuppressWarnings("checkstyle:all")
+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 enableDS = true;
+  private static boolean running = false;
+  private static int port = DEFAULT_PORT;
+  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
+   * @deprecated Use {@link NetworkTableInstance#startServer()} or
+   * {@link NetworkTableInstance#startClient()} instead.
+   */
+  @Deprecated
+  public synchronized static void initialize() {
+    if (running)
+      shutdown();
+    NetworkTableInstance inst = NetworkTableInstance.getDefault();
+    if (client) {
+      inst.startClient();
+      if (enableDS)
+        inst.startDSClient(port);
+    } else
+      inst.startServer(persistentFilename, "", port);
+    running = true;
+  }
+
+  /**
+   * shuts down network tables
+   * @deprecated Use {@link NetworkTableInstance#stopServer()} or
+   * {@link NetworkTableInstance#stopClient()} instead.
+   */
+  @Deprecated
+  public synchronized static void shutdown() {
+    if (!running)
+      return;
+    NetworkTableInstance inst = NetworkTableInstance.getDefault();
+    if (client) {
+      inst.stopDSClient();
+      inst.stopClient();
+    } else
+      inst.stopServer();
+    running = false;
+  }
+
+  /**
+   * set that network tables should be a server
+   * This must be called before initialize or getTable
+   * @deprecated Use {@link NetworkTableInstance#startServer()} instead.
+   */
+  @Deprecated
+  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
+   * @deprecated Use {@link NetworkTableInstance#startClient()} instead.
+   */
+  @Deprecated
+  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
+   * @deprecated Use {@link NetworkTableInstance#setServerTeam(int)} or
+   * {@link NetworkTableInstance#startClientTeam(int)} instead.
+   */
+  @Deprecated
+  public synchronized static void setTeam(int team) {
+    NetworkTableInstance inst = NetworkTableInstance.getDefault();
+    inst.setServerTeam(team, port);
+    if (enableDS)
+      inst.startDSClient(port);
+  }
+
+  /**
+   * @param address the address that network tables will connect to in client
+   * mode
+   * @deprecated Use {@link NetworkTableInstance#setServer(String)} or
+   * {@link NetworkTableInstance#startClient(String)} instead.
+   */
+  @Deprecated
+  public synchronized static void setIPAddress(final String address) {
+    String[] addresses = new String[1];
+    addresses[0] = address;
+    setIPAddress(addresses);
+  }
+
+  /**
+   * @param addresses the adresses that network tables will connect to in
+   * client mode (in round robin order)
+   * @deprecated Use {@link NetworkTableInstance#setServer(String[])} or
+   * {@link NetworkTableInstance#startClient(String[])} instead.
+   */
+  @Deprecated
+  public synchronized static void setIPAddress(final String[] addresses) {
+    NetworkTableInstance inst = NetworkTableInstance.getDefault();
+    inst.setServer(addresses, port);
+
+    // Stop the DS client if we're explicitly connecting to localhost
+    if (addresses.length > 0 &&
+        (addresses[0].equals("localhost") || addresses[0].equals("127.0.0.1")))
+      inst.stopDSClient();
+    else if (enableDS)
+      inst.startDSClient(port);
+  }
+
+  /**
+   * Set the port number that network tables will connect to in client
+   * mode or listen to in server mode.
+   * @param aport the port number
+   * @deprecated Use the appropriate parameters to
+   * {@link NetworkTableInstance#setServer(String, int)},
+   * {@link NetworkTableInstance#startClient(String, int)},
+   * {@link NetworkTableInstance#startServer(String, String, int)}, and
+   * {@link NetworkTableInstance#startDSClient(int)} instead.
+   */
+  @Deprecated
+  public synchronized static void setPort(int aport) {
+    if (port == aport)
+      return;
+    checkInit();
+    port = aport;
+  }
+
+  /**
+   * Enable requesting the server address from the Driver Station.
+   * @param enabled whether to enable the connection to the local DS
+   * @deprecated Use {@link NetworkTableInstance#startDSClient()} and
+   * {@link NetworkTableInstance#stopDSClient()} instead.
+   */
+  @Deprecated
+  public synchronized static void setDSClientEnabled(boolean enabled) {
+    NetworkTableInstance inst = NetworkTableInstance.getDefault();
+    enableDS = enabled;
+    if (enableDS)
+      inst.startDSClient(port);
+    else
+      inst.stopDSClient();
+  }
+
+  /**
+   * Sets the persistent filename.
+   * @param filename the filename that the network tables server uses for
+   * automatic loading and saving of persistent values
+   * @deprecated Use the appropriate parameter to
+   * {@link NetworkTableInstance#startServer()} instead.
+   */
+  @Deprecated
+  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
+   * @deprecated Use {@link NetworkTableInstance#setNetworkIdentity(String)}
+   * instead.
+   */
+  @Deprecated
+  public static void setNetworkIdentity(String name) {
+    NetworkTableInstance.getDefault().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(Number[] arr) {
+    double[] out = new double[arr.length];
+    for (int i = 0; i < arr.length; i++)
+      out[i] = arr[i].doubleValue();
+    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
+   *
+   * @deprecated Use {@link NetworkTableInstance#getTable(String)} instead.
+   *
+   * @param key   the key name
+   * @return the network table requested
+   */
+  @Deprecated
+  public synchronized static NetworkTable getTable(String key) {
+    if (!running)
+      initialize();
+    String theKey;
+    if (key.isEmpty() || key.equals("/")) {
+      theKey = "";
+    } else if (key.charAt(0) == NetworkTable.PATH_SEPARATOR) {
+      theKey = key;
+    } else {
+      theKey = NetworkTable.PATH_SEPARATOR + key;
+    }
+    return new NetworkTable(NetworkTableInstance.getDefault(), theKey);
+  }
+
+  private final String path;
+  private final String pathWithSep;
+  private final NetworkTableInstance inst;
+
+  NetworkTable(NetworkTableInstance inst, String path) {
+    this.path = path;
+    this.pathWithSep = path + PATH_SEPARATOR;
+    this.inst = inst;
+  }
+
+  @Override
+  public String toString() { return "NetworkTable: " + path; }
+
+  private final ConcurrentMap<String, NetworkTableEntry> entries = new ConcurrentHashMap<String, NetworkTableEntry>();
+
+  /**
+   * Gets the entry for a subkey.
+   * @param key the key name
+   * @return Network table entry.
+   */
+  private NetworkTableEntry getEntry(String key) {
+    NetworkTableEntry entry = entries.get(key);
+    if (entry == null) {
+      entry = inst.getEntry(pathWithSep + key);
+      entries.putIfAbsent(key, entry);
+    }
+    return entry;
+  }
+
+  /**
+   * Gets the current network connections.
+   * @return An array of connection information.
+   * @deprecated Use {@link NetworkTableInstance#getConnections()} instead.
+   */
+  @Deprecated
+  public static ConnectionInfo[] connections() {
+    return NetworkTableInstance.getDefault().getConnections();
+  }
+
+  /**
+   * Determine whether or not a network connection is active.
+   * @return True if connected, false if not connected.
+   * @deprecated Use {@link NetworkTableInstance#isConnected()} instead.
+   */
+  @Override
+  @Deprecated
+  public boolean isConnected() {
+    return inst.isConnected();
+  }
+
+  /**
+   * Determine whether NetworkTables is operating as a server or as a client.
+   * @return True if operating as a server, false otherwise.
+   * @deprecated Use {@link NetworkTableInstance#getNetworkMode()} instead.
+   */
+  @Override
+  @Deprecated
+  public boolean isServer() {
+    return (inst.getNetworkMode() & NetworkTableInstance.kNetModeServer) != 0;
+  }
+
+  /* Backwards compatibility shims for IRemoteConnectionListener */
+  private static class ConnectionListenerAdapter implements Consumer<ConnectionNotification> {
+    public int uid;
+    private final IRemote targetSource;
+    private final IRemoteConnectionListener targetListener;
+
+    public ConnectionListenerAdapter(IRemote targetSource, IRemoteConnectionListener targetListener) {
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    @Override
+    public void accept(ConnectionNotification event) {
+      if (event.connected)
+        targetListener.connectedEx(targetSource, event.conn);
+      else
+        targetListener.disconnectedEx(targetSource, event.conn);
+    }
+  }
+
+  private static final HashMap<IRemoteConnectionListener,ConnectionListenerAdapter> globalConnectionListenerMap = new HashMap<IRemoteConnectionListener,ConnectionListenerAdapter>();
+
+  private static IRemote staticRemote = new IRemote() {
+    @Override
+    public void addConnectionListener(IRemoteConnectionListener listener, boolean immediateNotify) {
+      NetworkTable.addGlobalConnectionListener(listener, immediateNotify);
+    }
+    @Override
+    public void removeConnectionListener(IRemoteConnectionListener listener) {
+      NetworkTable.removeGlobalConnectionListener(listener);
+    }
+    @Override
+    public boolean isConnected() {
+      ConnectionInfo[] conns = NetworkTableInstance.getDefault().getConnections();
+      return conns.length > 0;
+    }
+    @Override
+    public boolean isServer() {
+      return (NetworkTableInstance.getDefault().getNetworkMode() & NetworkTableInstance.kNetModeServer) != 0;
+    }
+  };
+
+  private final HashMap<IRemoteConnectionListener,ConnectionListenerAdapter> connectionListenerMap = new HashMap<IRemoteConnectionListener,ConnectionListenerAdapter>();
+
+  /**
+   * Add a connection listener.
+   * @param listener connection listener
+   * @param immediateNotify call listener immediately for all existing connections
+   * @deprecated Use {@link NetworkTableInstance#addConnectionListener(Consumer, boolean)} instead.
+   */
+  @Deprecated
+  public static synchronized void addGlobalConnectionListener(IRemoteConnectionListener listener, boolean immediateNotify) {
+    ConnectionListenerAdapter adapter = new ConnectionListenerAdapter(staticRemote, listener);
+    if (globalConnectionListenerMap.putIfAbsent(listener, adapter) != null) {
+      throw new IllegalStateException("Cannot add the same listener twice");
+    }
+    adapter.uid = NetworkTableInstance.getDefault().addConnectionListener(adapter, immediateNotify);
+  }
+
+  /**
+   * Remove a connection listener.
+   * @param listener connection listener
+   * @deprecated Use {@link NetworkTableInstance#removeConnectionListener(int)} instead.
+   */
+  @Deprecated
+  public static synchronized void removeGlobalConnectionListener(IRemoteConnectionListener listener) {
+    ConnectionListenerAdapter adapter = globalConnectionListenerMap.remove(listener);
+    if (adapter != null) {
+      NetworkTableInstance.getDefault().removeConnectionListener(adapter.uid);
+    }
+  }
+
+  /**
+   * Add a connection listener.
+   * @param listener connection listener
+   * @param immediateNotify call listener immediately for all existing connections
+   * @deprecated Use {@link NetworkTableInstance#addConnectionListener(Consumer, boolean)} instead.
+   */
+  @Override
+  @Deprecated
+  public synchronized void addConnectionListener(IRemoteConnectionListener listener,
+                                                 boolean immediateNotify) {
+    ConnectionListenerAdapter adapter = new ConnectionListenerAdapter(this, listener);
+    if (connectionListenerMap.putIfAbsent(listener, adapter) != null) {
+      throw new IllegalStateException("Cannot add the same listener twice");
+    }
+    adapter.uid = inst.addConnectionListener(adapter, immediateNotify);
+  }
+
+  /**
+   * Remove a connection listener.
+   * @param listener connection listener
+   * @deprecated Use {@link NetworkTableInstance#removeConnectionListener(int)} instead.
+   */
+  @Override
+  @Deprecated
+  public synchronized void removeConnectionListener(IRemoteConnectionListener listener) {
+    ConnectionListenerAdapter adapter = connectionListenerMap.get(listener);
+    if (adapter != null && connectionListenerMap.remove(listener, adapter)) {
+      inst.removeConnectionListener(adapter.uid);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addEntryListener(TableEntryListener, int)} instead
+   * (with flags value of NOTIFY_NEW | NOTIFY_UPDATE).
+   */
+  @Override
+  @Deprecated
+  public void addTableListener(ITableListener listener) {
+    addTableListenerEx(listener, NOTIFY_NEW | NOTIFY_UPDATE);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addEntryListener(TableEntryListener, int)} instead
+   * (with flags value of NOTIFY_NEW | NOTIFY_UPDATE | NOTIFY_IMMEDIATE).
+   */
+  @Override
+  @Deprecated
+  public void addTableListener(ITableListener listener,
+                               boolean immediateNotify) {
+    int flags = NOTIFY_NEW | NOTIFY_UPDATE;
+    if (immediateNotify)
+      flags |= NOTIFY_IMMEDIATE;
+    addTableListenerEx(listener, flags);
+  }
+
+  /* Base class for listeners; stores uid to implement remove functions */
+  private static class ListenerBase {
+    public int uid;
+  }
+
+  private static class OldTableListenerAdapter extends ListenerBase implements Consumer<EntryNotification> {
+    private final int prefixLen;
+    private final ITable targetSource;
+    private final ITableListener targetListener;
+
+    public OldTableListenerAdapter(int prefixLen, ITable targetSource, ITableListener targetListener) {
+      this.prefixLen = prefixLen;
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    @Override
+    public void accept(EntryNotification event) {
+      String relativeKey = event.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1)
+        return;
+      targetListener.valueChangedEx(targetSource, relativeKey, event.value.getValue(), event.flags);
+    }
+  }
+
+  private final HashMap<ITableListener,List<ListenerBase>> oldListenerMap = new HashMap<ITableListener,List<ListenerBase>>();
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addEntryListener(TableEntryListener, int)} instead.
+   */
+  @Override
+  @Deprecated
+  public synchronized void addTableListenerEx(ITableListener listener,
+                                              int flags) {
+    List<ListenerBase> adapters = oldListenerMap.get(listener);
+    if (adapters == null) {
+      adapters = new ArrayList<ListenerBase>();
+      oldListenerMap.put(listener, adapters);
+    }
+    OldTableListenerAdapter adapter =
+        new OldTableListenerAdapter(path.length() + 1, this, listener);
+    adapter.uid = inst.addEntryListener(pathWithSep, adapter, flags);
+    adapters.add(adapter);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addEntryListener(String, TableEntryListener, int)}
+   * or {@link NetworkTableEntry#addListener(Consumer, int)} instead.
+   */
+  @Override
+  @Deprecated
+  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 static class OldKeyListenerAdapter extends ListenerBase implements Consumer<EntryNotification> {
+    private final String relativeKey;
+    private final ITable targetSource;
+    private final ITableListener targetListener;
+
+    public OldKeyListenerAdapter(String relativeKey, ITable targetSource, ITableListener targetListener) {
+      this.relativeKey = relativeKey;
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    @Override
+    public void accept(EntryNotification event) {
+      targetListener.valueChangedEx(targetSource, relativeKey, event.value.getValue(), event.flags);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addEntryListener(String, TableEntryListener, int)}
+   * or {@link NetworkTableEntry#addListener(Consumer, int)} instead.
+   */
+  @Override
+  @Deprecated
+  public synchronized void addTableListenerEx(String key,
+                                              ITableListener listener,
+                                              int flags) {
+    List<ListenerBase> adapters = oldListenerMap.get(listener);
+    if (adapters == null) {
+      adapters = new ArrayList<ListenerBase>();
+      oldListenerMap.put(listener, adapters);
+    }
+    OldKeyListenerAdapter adapter = new OldKeyListenerAdapter(key, this, listener);
+    adapter.uid = inst.addEntryListener(getEntry(key), adapter, flags);
+    adapters.add(adapter);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addSubTableListener(TableListener, boolean)}
+   * instead.
+   */
+  @Override
+  @Deprecated
+  public void addSubTableListener(final ITableListener listener) {
+    addSubTableListener(listener, false);
+  }
+
+  private static class OldSubListenerAdapter extends ListenerBase implements Consumer<EntryNotification> {
+    private final int prefixLen;
+    private final ITable targetSource;
+    private final ITableListener targetListener;
+    private final Set<String> notifiedTables = new HashSet<String>();
+
+    public OldSubListenerAdapter(int prefixLen, ITable targetSource, ITableListener targetListener) {
+      this.prefixLen = prefixLen;
+      this.targetSource = targetSource;
+      this.targetListener = targetListener;
+    }
+
+    @Override
+    public void accept(EntryNotification event) {
+      String relativeKey = event.name.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), event.flags);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#addSubTableListener(TableListener, boolean)}
+   * instead.
+   */
+  @Override
+  @Deprecated
+  public synchronized void addSubTableListener(final ITableListener listener,
+                                               boolean localNotify) {
+    List<ListenerBase> adapters = oldListenerMap.get(listener);
+    if (adapters == null) {
+      adapters = new ArrayList<ListenerBase>();
+      oldListenerMap.put(listener, adapters);
+    }
+    OldSubListenerAdapter adapter =
+        new OldSubListenerAdapter(path.length() + 1, this, listener);
+    int flags = NOTIFY_NEW | NOTIFY_IMMEDIATE;
+    if (localNotify)
+      flags |= NOTIFY_LOCAL;
+    adapter.uid = inst.addEntryListener(pathWithSep, adapter, flags);
+    adapters.add(adapter);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable#removeTableListener(int)} instead.
+   */
+  @Override
+  @Deprecated
+  public synchronized void removeTableListener(ITableListener listener) {
+    List<ListenerBase> adapters = oldListenerMap.remove(listener);
+    if (adapters != null) {
+      for (ListenerBase adapter : adapters)
+        inst.removeEntryListener(adapter.uid);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ITable getSubTable(String key) {
+    return new NetworkTable(inst, pathWithSep + key);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean containsKey(String key) {
+    return getEntry(key).exists();
+  }
+
+  @Override
+  public boolean containsSubTable(String key) {
+    int[] handles = NetworkTablesJNI.getEntries(inst.getHandle(), pathWithSep + key + PATH_SEPARATOR, 0);
+    return handles.length != 0;
+  }
+
+  /**
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return keys currently in the table
+   */
+  @Override
+  public Set<String> getKeys(int types) {
+    Set<String> keys = new HashSet<String>();
+    int prefixLen = path.length() + 1;
+    for (EntryInfo info : inst.getEntryInfo(pathWithSep, types)) {
+      String relativeKey = info.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1)
+        continue;
+      keys.add(relativeKey);
+      // populate entries as we go
+      if (entries.get(relativeKey) == null) {
+        entries.putIfAbsent(relativeKey, new NetworkTableEntry(inst, info.entry));
+      }
+    }
+    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 info : inst.getEntryInfo(pathWithSep, 0)) {
+      String relativeKey = info.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 getEntry(key).setNumber(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultNumber(String key, double defaultValue) {
+    return getEntry(key).setDefaultDouble(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public double getNumber(String key, double defaultValue) {
+    return getEntry(key).getDouble(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putString(String key, String value) {
+    return getEntry(key).setString(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultString(String key, String defaultValue) {
+    return getEntry(key).setDefaultString(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getString(String key, String defaultValue) {
+    return getEntry(key).getString(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putBoolean(String key, boolean value) {
+    return getEntry(key).setBoolean(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultBoolean(String key, boolean defaultValue) {
+    return getEntry(key).setDefaultBoolean(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean getBoolean(String key, boolean defaultValue) {
+    return getEntry(key).getBoolean(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putBooleanArray(String key, boolean[] value) {
+    return getEntry(key).setBooleanArray(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putBooleanArray(String key, Boolean[] value) {
+    return getEntry(key).setBooleanArray(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultBooleanArray(String key, boolean[] defaultValue) {
+    return getEntry(key).setDefaultBooleanArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultBooleanArray(String key, Boolean[] defaultValue) {
+    return getEntry(key).setDefaultBooleanArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean[] getBooleanArray(String key, boolean[] defaultValue) {
+    return getEntry(key).getBooleanArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Boolean[] getBooleanArray(String key, Boolean[] defaultValue) {
+    return getEntry(key).getBooleanArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putNumberArray(String key, double[] value) {
+    return getEntry(key).setDoubleArray(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putNumberArray(String key, Double[] value) {
+    return getEntry(key).setNumberArray(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultNumberArray(String key, double[] defaultValue) {
+    return getEntry(key).setDefaultDoubleArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultNumberArray(String key, Double[] defaultValue) {
+    return getEntry(key).setDefaultNumberArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public double[] getNumberArray(String key, double[] defaultValue) {
+    return getEntry(key).getDoubleArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Double[] getNumberArray(String key, Double[] defaultValue) {
+    return getEntry(key).getDoubleArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putStringArray(String key, String[] value) {
+    return getEntry(key).setStringArray(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultStringArray(String key, String[] defaultValue) {
+    return getEntry(key).setDefaultStringArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String[] getStringArray(String key, String[] defaultValue) {
+    return getEntry(key).getStringArray(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putRaw(String key, byte[] value) {
+    return getEntry(key).setRaw(value);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean setDefaultRaw(String key, byte[] defaultValue) {
+    return getEntry(key).setDefaultRaw(defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean putRaw(String key, ByteBuffer value, int len) {
+    return getEntry(key).setRaw(value, len);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public byte[] getRaw(String key, byte[] defaultValue) {
+    return getEntry(key).getRaw(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
+   */
+  public boolean putValue(String key, NetworkTableValue value) {
+    return getEntry(key).setValue(value);
+  }
+
+  /**
+   * Sets the current value in the table if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultValue(String key, NetworkTableValue defaultValue) {
+    return getEntry(key).setDefaultValue(defaultValue);
+  }
+
+  /**
+   * Gets the value associated with a key as a NetworkTableValue object.
+   * @param key the key of the value to look up
+   * @return the value associated with the given key
+   */
+  public NetworkTableValue getValue(String key) {
+    return getEntry(key).getValue();
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTableEntry#setValue(Object)}
+   * instead, e.g. `NetworkTable.getEntry(key).setValue(NetworkTableEntry.makeBoolean(false));`
+   * or `NetworkTable.getEntry(key).setValue(new Boolean(false));`
+   */
+  @Override
+  @Deprecated
+  public boolean putValue(String key, Object value) throws IllegalArgumentException {
+    if (value instanceof Boolean)
+      return putBoolean(key, ((Boolean)value).booleanValue());
+    else if (value instanceof Number)
+      return putDouble(key, ((Number)value).doubleValue());
+    else if (value instanceof String)
+      return putString(key, (String)value);
+    else if (value instanceof byte[])
+      return putRaw(key, (byte[])value);
+    else if (value instanceof boolean[])
+      return putBooleanArray(key, (boolean[])value);
+    else if (value instanceof double[])
+      return putNumberArray(key, (double[])value);
+    else if (value instanceof Boolean[])
+      return putBooleanArray(key, toNative((Boolean[])value));
+    else if (value instanceof Number[])
+      return putNumberArray(key, toNative((Number[])value));
+    else if (value instanceof String[])
+      return putStringArray(key, (String[])value);
+    else if (value instanceof NetworkTableValue)
+      return getEntry(key).setValue((NetworkTableValue)value);
+    else
+      throw new IllegalArgumentException("Value of type " + value.getClass().getName() + " cannot be put into a table");
+  }
+
+  /**
+   * {@inheritDoc}
+   * @deprecated Use {@link edu.wpi.first.networktables.NetworkTableEntry#getValue()}
+   * instead, e.g. `NetworkTable.getEntry(key).getValue();`
+   */
+  @Override
+  @Deprecated
+  public Object getValue(String key, Object defaultValue) {
+    NetworkTableValue value = getValue(key);
+    if (value.getType() == NetworkTableType.kUnassigned) {
+      return defaultValue;
+    }
+    return value.getValue();
+  }
+
+  /** The persistent flag value. */
+  public static final int PERSISTENT = 1;
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setPersistent(String key) {
+    getEntry(key).setPersistent();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void clearPersistent(String key) {
+    getEntry(key).clearPersistent();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean isPersistent(String key) {
+    return getEntry(key).isPersistent();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setFlags(String key, int flags) {
+    getEntry(key).setFlags(flags);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void clearFlags(String key, int flags) {
+    getEntry(key).clearFlags(flags);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int getFlags(String key) {
+    return getEntry(key).getFlags();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void delete(String key) {
+    getEntry(key).delete();
+  }
+
+  /**
+   * Deletes ALL keys in ALL subtables.  Use with caution!
+   * @deprecated Use {@link NetworkTableInstance#deleteAllEntries()} instead.
+   */
+  @Deprecated
+  public static void globalDeleteAll() {
+    NetworkTableInstance.getDefault().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.
+   * @deprecated Use {@link NetworkTableInstance#flush()} instead.
+   */
+  @Deprecated
+  public static void flush() {
+    NetworkTableInstance.getDefault().flush();
+  }
+
+  /**
+   * Set the periodic update rate.
+   *
+   * @param interval update interval in seconds (range 0.01 to 1.0)
+   * @deprecated Use {@link NetworkTableInstance#setUpdateRate(double)}
+   * instead.
+   */
+  @Deprecated
+  public static void setUpdateRate(double interval) {
+    NetworkTableInstance.getDefault().setUpdateRate(interval);
+  }
+
+  /**
+   * Saves persistent keys to a file.  The server does this automatically.
+   *
+   * @param filename file name
+   * @throws PersistentException if error saving file
+   * @deprecated Use {@link NetworkTableInstance#savePersistent(String)}
+   * instead.
+   */
+  @Deprecated
+  public static void savePersistent(String filename) throws PersistentException {
+    NetworkTableInstance.getDefault().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
+   * @deprecated Use {@link NetworkTableInstance#loadPersistent(String)}
+   * instead.
+   */
+  @Deprecated
+  public static String[] loadPersistent(String filename) throws PersistentException {
+    return NetworkTableInstance.getDefault().loadPersistent(filename);
+  }
+
+  /*
+   * Deprecated Methods
+   */
+
+  /**
+   * {@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, double defaultValue) {
+    return getNumber(key, defaultValue);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getPath() {
+    return path;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (!(o instanceof NetworkTable)) {
+      return false;
+    }
+    NetworkTable other = (NetworkTable) o;
+    return inst.equals(other.inst) && path.equals(other.path);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(inst, path);
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/IRemote.java b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/IRemote.java
new file mode 100644
index 0000000..22b6f96
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/IRemote.java
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpilibj.tables;
+
+
+/**
+ * Represents an object that has a remote connection.
+ * @deprecated Use {@link edu.wpi.first.networktables.NetworkTableInstance}.
+ */
+@Deprecated
+@SuppressWarnings("checkstyle:all")
+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/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java
new file mode 100644
index 0000000..a3ff118
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpilibj.tables;
+
+import edu.wpi.first.networktables.ConnectionInfo;
+
+/**
+ * A listener that listens for connection changes in a {@link IRemote} object.
+ * @deprecated Use Consumer&lt;{@link edu.wpi.first.networktables.ConnectionNotification}&gt;.
+ */
+@Deprecated
+@SuppressWarnings("checkstyle:all")
+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);
+  /**
+   * Extended version of connected called when an IRemote is connected.
+    * Contains the connection info of the connected remote
+   * @param remote the object that connected
+   * @param info the connection info for the connected remote
+   */
+  default public void connectedEx(IRemote remote, ConnectionInfo info) {
+    connected(remote);
+  }
+  /**
+   * Extended version of connected called when an IRemote is disconnected.
+   * Contains the connection info of the disconnected remote
+   * @param remote the object that disconnected
+   * @param info the connection info for the disconnected remote
+   */
+  default public void disconnectedEx(IRemote remote, ConnectionInfo info) {
+    disconnected(remote);
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/ITable.java b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/ITable.java
new file mode 100644
index 0000000..2d0d5d6
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/ITable.java
@@ -0,0 +1,488 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpilibj.tables;
+
+import java.nio.ByteBuffer;
+import java.util.Set;
+
+
+/**
+ * A table whose values can be read and written to.
+ * @deprecated Use {@link edu.wpi.first.networktables.NetworkTable}.
+ */
+@Deprecated
+@SuppressWarnings("checkstyle:all")
+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);
+
+  /**
+   * Gets all keys in the table (not including sub-tables).
+   * @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);
+
+  /**
+   * Gets all keys in the table (not including sub-tables).
+   * @return keys currently in the table
+   */
+  public Set<String> getKeys();
+
+  /**
+   * Gets the names of all subtables in the table.
+   * @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.
+   * 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;
+
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultNumber(String key, double defaultValue);
+
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultString(String key, String defaultValue);
+
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultBoolean(String key, boolean defaultValue);
+
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultBooleanArray(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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultBooleanArray(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);
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultNumberArray(String key, double[] 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultNumberArray(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);
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultStringArray(String key, String[] defaultValue);
+
+  /**
+   * 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);
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doens't exist.
+   * @return False if the table key exists with a different type
+   */
+  public boolean setDefaultRaw(String key, byte[] defaultValue);
+
+  /**
+   * 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. 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 putDouble(String key, double value);
+
+  /**
+   * 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);
+
+  /**
+   * Gets the full path of this table.  Does not include the trailing "/".
+   * @return The path to this table (e.g. "", "/foo").
+   */
+  public String getPath();
+
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/ITableListener.java b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/ITableListener.java
new file mode 100644
index 0000000..b08312b
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/wpilibj/tables/ITableListener.java
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpilibj.tables;
+
+/**
+ * A listener that listens to changes in values in a {@link ITable}.
+ * @deprecated Use Consumer&lt;{@link edu.wpi.first.networktables.EntryNotification}&gt;,
+ * {@link edu.wpi.first.networktables.TableEntryListener}, or
+ * {@link edu.wpi.first.networktables.TableListener} as appropriate.
+ */
+@FunctionalInterface
+@Deprecated
+@SuppressWarnings("checkstyle:all")
+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/ntcore/src/main/native/cpp/CallbackManager.h b/ntcore/src/main/native/cpp/CallbackManager.h
new file mode 100644
index 0000000..2d9b11d
--- /dev/null
+++ b/ntcore/src/main/native/cpp/CallbackManager.h
@@ -0,0 +1,328 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_CALLBACKMANAGER_H_
+#define NTCORE_CALLBACKMANAGER_H_
+
+#include <atomic>
+#include <climits>
+#include <functional>
+#include <memory>
+#include <queue>
+#include <utility>
+#include <vector>
+
+#include <wpi/SafeThread.h>
+#include <wpi/UidVector.h>
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+#include <wpi/raw_ostream.h>
+
+namespace nt {
+
+namespace impl {
+
+template <typename Callback>
+class ListenerData {
+ public:
+  ListenerData() = default;
+  explicit ListenerData(Callback callback_) : callback(callback_) {}
+  explicit ListenerData(unsigned int poller_uid_) : poller_uid(poller_uid_) {}
+
+  explicit operator bool() const { return callback || poller_uid != UINT_MAX; }
+
+  Callback callback;
+  unsigned int poller_uid = UINT_MAX;
+};
+
+// CRTP callback manager thread
+// @tparam Derived        derived class
+// @tparam NotifierData   data buffered for each callback
+// @tparam ListenerData   data stored for each listener
+// Derived must define the following functions:
+//   bool Matches(const ListenerData& listener, const NotifierData& data);
+//   void SetListener(NotifierData* data, unsigned int listener_uid);
+//   void DoCallback(Callback callback, const NotifierData& data);
+template <typename Derived, typename TUserInfo,
+          typename TListenerData =
+              ListenerData<std::function<void(const TUserInfo& info)>>,
+          typename TNotifierData = TUserInfo>
+class CallbackThread : public wpi::SafeThread {
+ public:
+  typedef TUserInfo UserInfo;
+  typedef TNotifierData NotifierData;
+  typedef TListenerData ListenerData;
+
+  ~CallbackThread() {
+    // Wake up any blocked pollers
+    for (size_t i = 0; i < m_pollers.size(); ++i) {
+      if (auto poller = m_pollers[i]) poller->Terminate();
+    }
+  }
+
+  void Main() override;
+
+  wpi::UidVector<ListenerData, 64> m_listeners;
+
+  std::queue<std::pair<unsigned int, NotifierData>> m_queue;
+  wpi::condition_variable m_queue_empty;
+
+  struct Poller {
+    void Terminate() {
+      {
+        std::scoped_lock lock(poll_mutex);
+        terminating = true;
+      }
+      poll_cond.notify_all();
+    }
+    std::queue<NotifierData> poll_queue;
+    wpi::mutex poll_mutex;
+    wpi::condition_variable poll_cond;
+    bool terminating = false;
+    bool cancelling = false;
+  };
+  wpi::UidVector<std::shared_ptr<Poller>, 64> m_pollers;
+
+  // Must be called with m_mutex held
+  template <typename... Args>
+  void SendPoller(unsigned int poller_uid, Args&&... args) {
+    if (poller_uid > m_pollers.size()) return;
+    auto poller = m_pollers[poller_uid];
+    if (!poller) return;
+    {
+      std::scoped_lock lock(poller->poll_mutex);
+      poller->poll_queue.emplace(std::forward<Args>(args)...);
+    }
+    poller->poll_cond.notify_one();
+  }
+};
+
+template <typename Derived, typename TUserInfo, typename TListenerData,
+          typename TNotifierData>
+void CallbackThread<Derived, TUserInfo, TListenerData, TNotifierData>::Main() {
+  std::unique_lock lock(m_mutex);
+  while (m_active) {
+    while (m_queue.empty()) {
+      m_cond.wait(lock);
+      if (!m_active) return;
+    }
+
+    while (!m_queue.empty()) {
+      if (!m_active) return;
+      auto item = std::move(m_queue.front());
+
+      if (item.first != UINT_MAX) {
+        if (item.first < m_listeners.size()) {
+          auto& listener = m_listeners[item.first];
+          if (listener &&
+              static_cast<Derived*>(this)->Matches(listener, item.second)) {
+            static_cast<Derived*>(this)->SetListener(&item.second, item.first);
+            if (listener.callback) {
+              lock.unlock();
+              static_cast<Derived*>(this)->DoCallback(listener.callback,
+                                                      item.second);
+              lock.lock();
+            } else if (listener.poller_uid != UINT_MAX) {
+              SendPoller(listener.poller_uid, std::move(item.second));
+            }
+          }
+        }
+      } else {
+        // Use index because iterator might get invalidated.
+        for (size_t i = 0; i < m_listeners.size(); ++i) {
+          auto& listener = m_listeners[i];
+          if (!listener) continue;
+          if (!static_cast<Derived*>(this)->Matches(listener, item.second))
+            continue;
+          static_cast<Derived*>(this)->SetListener(&item.second,
+                                                   static_cast<unsigned>(i));
+          if (listener.callback) {
+            lock.unlock();
+            static_cast<Derived*>(this)->DoCallback(listener.callback,
+                                                    item.second);
+            lock.lock();
+          } else if (listener.poller_uid != UINT_MAX) {
+            SendPoller(listener.poller_uid, item.second);
+          }
+        }
+      }
+      m_queue.pop();
+    }
+
+    m_queue_empty.notify_all();
+  }
+}
+
+}  // namespace impl
+
+// CRTP callback manager
+// @tparam Derived  derived class
+// @tparam Thread   custom thread (must be derived from impl::CallbackThread)
+//
+// Derived must define the following functions:
+//   void Start();
+template <typename Derived, typename Thread>
+class CallbackManager {
+  friend class RpcServerTest;
+
+ public:
+  void Stop() { m_owner.Stop(); }
+
+  void Remove(unsigned int listener_uid) {
+    auto thr = m_owner.GetThread();
+    if (!thr) return;
+    thr->m_listeners.erase(listener_uid);
+  }
+
+  unsigned int CreatePoller() {
+    static_cast<Derived*>(this)->Start();
+    auto thr = m_owner.GetThread();
+    return thr->m_pollers.emplace_back(
+        std::make_shared<typename Thread::Poller>());
+  }
+
+  void RemovePoller(unsigned int poller_uid) {
+    auto thr = m_owner.GetThread();
+    if (!thr) return;
+
+    // Remove any listeners that are associated with this poller
+    for (size_t i = 0; i < thr->m_listeners.size(); ++i) {
+      if (thr->m_listeners[i].poller_uid == poller_uid)
+        thr->m_listeners.erase(i);
+    }
+
+    // Wake up any blocked pollers
+    if (poller_uid >= thr->m_pollers.size()) return;
+    auto poller = thr->m_pollers[poller_uid];
+    if (!poller) return;
+    poller->Terminate();
+    return thr->m_pollers.erase(poller_uid);
+  }
+
+  bool WaitForQueue(double timeout) {
+    auto thr = m_owner.GetThread();
+    if (!thr) return true;
+
+    auto& lock = thr.GetLock();
+    auto timeout_time = std::chrono::steady_clock::now() +
+                        std::chrono::duration<double>(timeout);
+    while (!thr->m_queue.empty()) {
+      if (!thr->m_active) return true;
+      if (timeout == 0) return false;
+      if (timeout < 0) {
+        thr->m_queue_empty.wait(lock);
+      } else {
+        auto cond_timed_out = thr->m_queue_empty.wait_until(lock, timeout_time);
+        if (cond_timed_out == std::cv_status::timeout) return false;
+      }
+    }
+
+    return true;
+  }
+
+  std::vector<typename Thread::UserInfo> Poll(unsigned int poller_uid) {
+    bool timed_out = false;
+    return Poll(poller_uid, -1, &timed_out);
+  }
+
+  std::vector<typename Thread::UserInfo> Poll(unsigned int poller_uid,
+                                              double timeout, bool* timed_out) {
+    std::vector<typename Thread::UserInfo> infos;
+    std::shared_ptr<typename Thread::Poller> poller;
+    {
+      auto thr = m_owner.GetThread();
+      if (!thr) return infos;
+      if (poller_uid > thr->m_pollers.size()) return infos;
+      poller = thr->m_pollers[poller_uid];
+      if (!poller) return infos;
+    }
+
+    std::unique_lock lock(poller->poll_mutex);
+    auto timeout_time = std::chrono::steady_clock::now() +
+                        std::chrono::duration<double>(timeout);
+    *timed_out = false;
+    while (poller->poll_queue.empty()) {
+      if (poller->terminating) return infos;
+      if (poller->cancelling) {
+        // Note: this only works if there's a single thread calling this
+        // function for any particular poller, but that's the intended use.
+        poller->cancelling = false;
+        return infos;
+      }
+      if (timeout == 0) {
+        *timed_out = true;
+        return infos;
+      }
+      if (timeout < 0) {
+        poller->poll_cond.wait(lock);
+      } else {
+        auto cond_timed_out = poller->poll_cond.wait_until(lock, timeout_time);
+        if (cond_timed_out == std::cv_status::timeout) {
+          *timed_out = true;
+          return infos;
+        }
+      }
+    }
+
+    while (!poller->poll_queue.empty()) {
+      infos.emplace_back(std::move(poller->poll_queue.front()));
+      poller->poll_queue.pop();
+    }
+    return infos;
+  }
+
+  void CancelPoll(unsigned int poller_uid) {
+    std::shared_ptr<typename Thread::Poller> poller;
+    {
+      auto thr = m_owner.GetThread();
+      if (!thr) return;
+      if (poller_uid > thr->m_pollers.size()) return;
+      poller = thr->m_pollers[poller_uid];
+      if (!poller) return;
+    }
+
+    {
+      std::scoped_lock lock(poller->poll_mutex);
+      poller->cancelling = true;
+    }
+    poller->poll_cond.notify_one();
+  }
+
+ protected:
+  template <typename... Args>
+  void DoStart(Args&&... args) {
+    m_owner.Start(std::forward<Args>(args)...);
+  }
+
+  template <typename... Args>
+  unsigned int DoAdd(Args&&... args) {
+    static_cast<Derived*>(this)->Start();
+    auto thr = m_owner.GetThread();
+    return thr->m_listeners.emplace_back(std::forward<Args>(args)...);
+  }
+
+  template <typename... Args>
+  void Send(unsigned int only_listener, Args&&... args) {
+    auto thr = m_owner.GetThread();
+    if (!thr || thr->m_listeners.empty()) return;
+    thr->m_queue.emplace(std::piecewise_construct,
+                         std::make_tuple(only_listener),
+                         std::forward_as_tuple(std::forward<Args>(args)...));
+    thr->m_cond.notify_one();
+  }
+
+  typename wpi::SafeThreadOwner<Thread>::Proxy GetThread() const {
+    return m_owner.GetThread();
+  }
+
+ private:
+  wpi::SafeThreadOwner<Thread> m_owner;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_CALLBACKMANAGER_H_
diff --git a/ntcore/src/main/native/cpp/ConnectionNotifier.cpp b/ntcore/src/main/native/cpp/ConnectionNotifier.cpp
new file mode 100644
index 0000000..340aad0
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ConnectionNotifier.cpp
@@ -0,0 +1,29 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "ConnectionNotifier.h"
+
+using namespace nt;
+
+ConnectionNotifier::ConnectionNotifier(int inst) : m_inst(inst) {}
+
+void ConnectionNotifier::Start() { DoStart(m_inst); }
+
+unsigned int ConnectionNotifier::Add(
+    std::function<void(const ConnectionNotification& event)> callback) {
+  return DoAdd(callback);
+}
+
+unsigned int ConnectionNotifier::AddPolled(unsigned int poller_uid) {
+  return DoAdd(poller_uid);
+}
+
+void ConnectionNotifier::NotifyConnection(bool connected,
+                                          const ConnectionInfo& conn_info,
+                                          unsigned int only_listener) {
+  Send(only_listener, 0, connected, conn_info);
+}
diff --git a/ntcore/src/main/native/cpp/ConnectionNotifier.h b/ntcore/src/main/native/cpp/ConnectionNotifier.h
new file mode 100644
index 0000000..65eec06
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ConnectionNotifier.h
@@ -0,0 +1,72 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_CONNECTIONNOTIFIER_H_
+#define NTCORE_CONNECTIONNOTIFIER_H_
+
+#include "CallbackManager.h"
+#include "Handle.h"
+#include "IConnectionNotifier.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+namespace impl {
+
+class ConnectionNotifierThread
+    : public CallbackThread<ConnectionNotifierThread, ConnectionNotification> {
+ public:
+  explicit ConnectionNotifierThread(int inst) : m_inst(inst) {}
+
+  bool Matches(const ListenerData& /*listener*/,
+               const ConnectionNotification& /*data*/) {
+    return true;
+  }
+
+  void SetListener(ConnectionNotification* data, unsigned int listener_uid) {
+    data->listener =
+        Handle(m_inst, listener_uid, Handle::kConnectionListener).handle();
+  }
+
+  void DoCallback(
+      std::function<void(const ConnectionNotification& event)> callback,
+      const ConnectionNotification& data) {
+    callback(data);
+  }
+
+  int m_inst;
+};
+
+}  // namespace impl
+
+class ConnectionNotifier
+    : public IConnectionNotifier,
+      public CallbackManager<ConnectionNotifier,
+                             impl::ConnectionNotifierThread> {
+  friend class ConnectionNotifierTest;
+  friend class CallbackManager<ConnectionNotifier,
+                               impl::ConnectionNotifierThread>;
+
+ public:
+  explicit ConnectionNotifier(int inst);
+
+  void Start();
+
+  unsigned int Add(std::function<void(const ConnectionNotification& event)>
+                       callback) override;
+  unsigned int AddPolled(unsigned int poller_uid) override;
+
+  void NotifyConnection(bool connected, const ConnectionInfo& conn_info,
+                        unsigned int only_listener = UINT_MAX) override;
+
+ private:
+  int m_inst;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_CONNECTIONNOTIFIER_H_
diff --git a/ntcore/src/main/native/cpp/Dispatcher.cpp b/ntcore/src/main/native/cpp/Dispatcher.cpp
new file mode 100644
index 0000000..6d1ead0
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Dispatcher.cpp
@@ -0,0 +1,651 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "Dispatcher.h"
+
+#include <algorithm>
+#include <iterator>
+
+#include <wpi/TCPAcceptor.h>
+#include <wpi/TCPConnector.h>
+
+#include "IConnectionNotifier.h"
+#include "IStorage.h"
+#include "Log.h"
+#include "NetworkConnection.h"
+
+using namespace nt;
+
+void Dispatcher::StartServer(const Twine& persist_filename,
+                             const char* listen_address, unsigned int port) {
+  std::string listen_address_copy(StringRef(listen_address).trim());
+  DispatcherBase::StartServer(
+      persist_filename,
+      std::unique_ptr<wpi::NetworkAcceptor>(new wpi::TCPAcceptor(
+          static_cast<int>(port), listen_address_copy.c_str(), m_logger)));
+}
+
+void Dispatcher::SetServer(const char* server_name, unsigned int port) {
+  std::string server_name_copy(StringRef(server_name).trim());
+  SetConnector([=]() -> std::unique_ptr<wpi::NetworkStream> {
+    return wpi::TCPConnector::connect(server_name_copy.c_str(),
+                                      static_cast<int>(port), m_logger, 1);
+  });
+}
+
+void Dispatcher::SetServer(
+    ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  wpi::SmallVector<std::pair<std::string, int>, 16> servers_copy;
+  for (const auto& server : servers)
+    servers_copy.emplace_back(std::string{server.first.trim()},
+                              static_cast<int>(server.second));
+
+  SetConnector([=]() -> std::unique_ptr<wpi::NetworkStream> {
+    wpi::SmallVector<std::pair<const char*, int>, 16> servers_copy2;
+    for (const auto& server : servers_copy)
+      servers_copy2.emplace_back(server.first.c_str(), server.second);
+    return wpi::TCPConnector::connect_parallel(servers_copy2, m_logger, 1);
+  });
+}
+
+void Dispatcher::SetServerTeam(unsigned int team, unsigned int port) {
+  std::pair<StringRef, unsigned int> servers[5];
+
+  // 10.te.am.2
+  wpi::SmallString<32> fixed;
+  {
+    wpi::raw_svector_ostream oss{fixed};
+    oss << "10." << static_cast<int>(team / 100) << '.'
+        << static_cast<int>(team % 100) << ".2";
+    servers[0] = std::make_pair(oss.str(), port);
+  }
+
+  // 172.22.11.2
+  servers[1] = std::make_pair("172.22.11.2", port);
+
+  // roboRIO-<team>-FRC.local
+  wpi::SmallString<32> mdns;
+  {
+    wpi::raw_svector_ostream oss{mdns};
+    oss << "roboRIO-" << team << "-FRC.local";
+    servers[2] = std::make_pair(oss.str(), port);
+  }
+
+  // roboRIO-<team>-FRC.lan
+  wpi::SmallString<32> mdns_lan;
+  {
+    wpi::raw_svector_ostream oss{mdns_lan};
+    oss << "roboRIO-" << team << "-FRC.lan";
+    servers[3] = std::make_pair(oss.str(), port);
+  }
+
+  // roboRIO-<team>-FRC.frc-field.local
+  wpi::SmallString<64> field_local;
+  {
+    wpi::raw_svector_ostream oss{field_local};
+    oss << "roboRIO-" << team << "-FRC.frc-field.local";
+    servers[4] = std::make_pair(oss.str(), port);
+  }
+
+  SetServer(servers);
+}
+
+void Dispatcher::SetServerOverride(const char* server_name, unsigned int port) {
+  std::string server_name_copy(StringRef(server_name).trim());
+  SetConnectorOverride([=]() -> std::unique_ptr<wpi::NetworkStream> {
+    return wpi::TCPConnector::connect(server_name_copy.c_str(),
+                                      static_cast<int>(port), m_logger, 1);
+  });
+}
+
+void Dispatcher::ClearServerOverride() { ClearConnectorOverride(); }
+
+DispatcherBase::DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
+                               wpi::Logger& logger)
+    : m_storage(storage), m_notifier(notifier), m_logger(logger) {
+  m_active = false;
+  m_update_rate = 100;
+}
+
+DispatcherBase::~DispatcherBase() { Stop(); }
+
+unsigned int DispatcherBase::GetNetworkMode() const { return m_networkMode; }
+
+void DispatcherBase::StartLocal() {
+  {
+    std::scoped_lock lock(m_user_mutex);
+    if (m_active) return;
+    m_active = true;
+  }
+  m_networkMode = NT_NET_MODE_LOCAL;
+  m_storage.SetDispatcher(this, false);
+}
+
+void DispatcherBase::StartServer(
+    const Twine& persist_filename,
+    std::unique_ptr<wpi::NetworkAcceptor> acceptor) {
+  {
+    std::scoped_lock lock(m_user_mutex);
+    if (m_active) return;
+    m_active = true;
+  }
+  m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_STARTING;
+  m_persist_filename = persist_filename.str();
+  m_server_acceptor = std::move(acceptor);
+
+  // Load persistent file.  Ignore errors, but pass along warnings.
+  if (!persist_filename.isTriviallyEmpty() &&
+      (!persist_filename.isSingleStringRef() ||
+       !persist_filename.getSingleStringRef().empty())) {
+    bool first = true;
+    m_storage.LoadPersistent(
+        persist_filename, [&](size_t line, const char* msg) {
+          if (first) {
+            first = false;
+            WARNING("When reading initial persistent values from '"
+                    << persist_filename << "':");
+          }
+          WARNING(persist_filename << ":" << line << ": " << msg);
+        });
+  }
+
+  m_storage.SetDispatcher(this, true);
+
+  m_dispatch_thread = std::thread(&Dispatcher::DispatchThreadMain, this);
+  m_clientserver_thread = std::thread(&Dispatcher::ServerThreadMain, this);
+}
+
+void DispatcherBase::StartClient() {
+  {
+    std::scoped_lock lock(m_user_mutex);
+    if (m_active) return;
+    m_active = true;
+  }
+  m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_STARTING;
+  m_storage.SetDispatcher(this, false);
+
+  m_dispatch_thread = std::thread(&Dispatcher::DispatchThreadMain, this);
+  m_clientserver_thread = std::thread(&Dispatcher::ClientThreadMain, this);
+}
+
+void DispatcherBase::Stop() {
+  m_active = false;
+
+  // wake up dispatch thread with a flush
+  m_flush_cv.notify_one();
+
+  // wake up client thread with a reconnect
+  {
+    std::scoped_lock lock(m_user_mutex);
+    m_client_connector = nullptr;
+  }
+  ClientReconnect();
+
+  // wake up server thread by shutting down the socket
+  if (m_server_acceptor) m_server_acceptor->shutdown();
+
+  // join threads, with timeout
+  if (m_dispatch_thread.joinable()) m_dispatch_thread.join();
+  if (m_clientserver_thread.joinable()) m_clientserver_thread.join();
+
+  std::vector<std::shared_ptr<INetworkConnection>> conns;
+  {
+    std::scoped_lock lock(m_user_mutex);
+    conns.swap(m_connections);
+  }
+
+  // close all connections
+  conns.resize(0);
+}
+
+void DispatcherBase::SetUpdateRate(double interval) {
+  // don't allow update rates faster than 10 ms or slower than 1 second
+  if (interval < 0.01)
+    interval = 0.01;
+  else if (interval > 1.0)
+    interval = 1.0;
+  m_update_rate = static_cast<unsigned int>(interval * 1000);
+}
+
+void DispatcherBase::SetIdentity(const Twine& name) {
+  std::scoped_lock lock(m_user_mutex);
+  m_identity = name.str();
+}
+
+void DispatcherBase::Flush() {
+  auto now = std::chrono::steady_clock::now();
+  {
+    std::scoped_lock lock(m_flush_mutex);
+    // don't allow flushes more often than every 10 ms
+    if ((now - m_last_flush) < std::chrono::milliseconds(10)) return;
+    m_last_flush = now;
+    m_do_flush = true;
+  }
+  m_flush_cv.notify_one();
+}
+
+std::vector<ConnectionInfo> DispatcherBase::GetConnections() const {
+  std::vector<ConnectionInfo> conns;
+  if (!m_active) return conns;
+
+  std::scoped_lock lock(m_user_mutex);
+  for (auto& conn : m_connections) {
+    if (conn->state() != NetworkConnection::kActive) continue;
+    conns.emplace_back(conn->info());
+  }
+
+  return conns;
+}
+
+bool DispatcherBase::IsConnected() const {
+  if (!m_active) return false;
+
+  std::scoped_lock lock(m_user_mutex);
+  for (auto& conn : m_connections) {
+    if (conn->state() == NetworkConnection::kActive) return true;
+  }
+
+  return false;
+}
+
+unsigned int DispatcherBase::AddListener(
+    std::function<void(const ConnectionNotification& event)> callback,
+    bool immediate_notify) const {
+  std::scoped_lock lock(m_user_mutex);
+  unsigned int uid = m_notifier.Add(callback);
+  // perform immediate notifications
+  if (immediate_notify) {
+    for (auto& conn : m_connections) {
+      if (conn->state() != NetworkConnection::kActive) continue;
+      m_notifier.NotifyConnection(true, conn->info(), uid);
+    }
+  }
+  return uid;
+}
+
+unsigned int DispatcherBase::AddPolledListener(unsigned int poller_uid,
+                                               bool immediate_notify) const {
+  std::scoped_lock lock(m_user_mutex);
+  unsigned int uid = m_notifier.AddPolled(poller_uid);
+  // perform immediate notifications
+  if (immediate_notify) {
+    for (auto& conn : m_connections) {
+      if (conn->state() != NetworkConnection::kActive) continue;
+      m_notifier.NotifyConnection(true, conn->info(), uid);
+    }
+  }
+  return uid;
+}
+
+void DispatcherBase::SetConnector(Connector connector) {
+  std::scoped_lock lock(m_user_mutex);
+  m_client_connector = std::move(connector);
+}
+
+void DispatcherBase::SetConnectorOverride(Connector connector) {
+  std::scoped_lock lock(m_user_mutex);
+  m_client_connector_override = std::move(connector);
+}
+
+void DispatcherBase::ClearConnectorOverride() {
+  std::scoped_lock lock(m_user_mutex);
+  m_client_connector_override = nullptr;
+}
+
+void DispatcherBase::DispatchThreadMain() {
+  auto timeout_time = std::chrono::steady_clock::now();
+
+  static const auto save_delta_time = std::chrono::seconds(1);
+  auto next_save_time = timeout_time + save_delta_time;
+
+  int count = 0;
+
+  while (m_active) {
+    // handle loop taking too long
+    auto start = std::chrono::steady_clock::now();
+    if (start > timeout_time) timeout_time = start;
+
+    // wait for periodic or when flushed
+    timeout_time += std::chrono::milliseconds(m_update_rate);
+    std::unique_lock<wpi::mutex> flush_lock(m_flush_mutex);
+    m_flush_cv.wait_until(flush_lock, timeout_time,
+                          [&] { return !m_active || m_do_flush; });
+    m_do_flush = false;
+    flush_lock.unlock();
+    if (!m_active) break;  // in case we were woken up to terminate
+
+    // perform periodic persistent save
+    if ((m_networkMode & NT_NET_MODE_SERVER) != 0 &&
+        !m_persist_filename.empty() && start > next_save_time) {
+      next_save_time += save_delta_time;
+      // handle loop taking too long
+      if (start > next_save_time) next_save_time = start + save_delta_time;
+      const char* err = m_storage.SavePersistent(m_persist_filename, true);
+      if (err) WARNING("periodic persistent save: " << err);
+    }
+
+    {
+      std::scoped_lock user_lock(m_user_mutex);
+      bool reconnect = false;
+
+      if (++count > 10) {
+        DEBUG0("dispatch running " << m_connections.size() << " connections");
+        count = 0;
+      }
+
+      for (auto& conn : m_connections) {
+        // post outgoing messages if connection is active
+        // only send keep-alives on client
+        if (conn->state() == NetworkConnection::kActive)
+          conn->PostOutgoing((m_networkMode & NT_NET_MODE_CLIENT) != 0);
+
+        // if client, reconnect if connection died
+        if ((m_networkMode & NT_NET_MODE_CLIENT) != 0 &&
+            conn->state() == NetworkConnection::kDead)
+          reconnect = true;
+      }
+      // reconnect if we disconnected (and a reconnect is not in progress)
+      if (reconnect && !m_do_reconnect) {
+        m_do_reconnect = true;
+        m_reconnect_cv.notify_one();
+      }
+    }
+  }
+}
+
+void DispatcherBase::QueueOutgoing(std::shared_ptr<Message> msg,
+                                   INetworkConnection* only,
+                                   INetworkConnection* except) {
+  std::scoped_lock user_lock(m_user_mutex);
+  for (auto& conn : m_connections) {
+    if (conn.get() == except) continue;
+    if (only && conn.get() != only) continue;
+    auto state = conn->state();
+    if (state != NetworkConnection::kSynchronized &&
+        state != NetworkConnection::kActive)
+      continue;
+    conn->QueueOutgoing(msg);
+  }
+}
+
+void DispatcherBase::ServerThreadMain() {
+  if (m_server_acceptor->start() != 0) {
+    m_active = false;
+    m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_FAILURE;
+    return;
+  }
+  m_networkMode = NT_NET_MODE_SERVER;
+  while (m_active) {
+    auto stream = m_server_acceptor->accept();
+    if (!stream) {
+      m_active = false;
+      return;
+    }
+    if (!m_active) {
+      m_networkMode = NT_NET_MODE_NONE;
+      return;
+    }
+    DEBUG0("server: client connection from " << stream->getPeerIP() << " port "
+                                             << stream->getPeerPort());
+
+    // add to connections list
+    using namespace std::placeholders;
+    auto conn = std::make_shared<NetworkConnection>(
+        ++m_connections_uid, std::move(stream), m_notifier, m_logger,
+        std::bind(&Dispatcher::ServerHandshake, this, _1, _2, _3),
+        std::bind(&IStorage::GetMessageEntryType, &m_storage, _1));
+    conn->set_process_incoming(
+        std::bind(&IStorage::ProcessIncoming, &m_storage, _1, _2,
+                  std::weak_ptr<NetworkConnection>(conn)));
+    {
+      std::scoped_lock lock(m_user_mutex);
+      // reuse dead connection slots
+      bool placed = false;
+      for (auto& c : m_connections) {
+        if (c->state() == NetworkConnection::kDead) {
+          c = conn;
+          placed = true;
+          break;
+        }
+      }
+      if (!placed) m_connections.emplace_back(conn);
+      conn->Start();
+    }
+  }
+  m_networkMode = NT_NET_MODE_NONE;
+}
+
+void DispatcherBase::ClientThreadMain() {
+  while (m_active) {
+    // sleep between retries
+    std::this_thread::sleep_for(std::chrono::milliseconds(250));
+    Connector connect;
+
+    // get next server to connect to
+    {
+      std::scoped_lock lock(m_user_mutex);
+      if (m_client_connector_override) {
+        connect = m_client_connector_override;
+      } else {
+        if (!m_client_connector) {
+          m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_FAILURE;
+          continue;
+        }
+        connect = m_client_connector;
+      }
+    }
+
+    // try to connect (with timeout)
+    DEBUG0("client trying to connect");
+    auto stream = connect();
+    if (!stream) {
+      m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_FAILURE;
+      continue;  // keep retrying
+    }
+    DEBUG0("client connected");
+    m_networkMode = NT_NET_MODE_CLIENT;
+
+    std::unique_lock lock(m_user_mutex);
+    using namespace std::placeholders;
+    auto conn = std::make_shared<NetworkConnection>(
+        ++m_connections_uid, std::move(stream), m_notifier, m_logger,
+        std::bind(&Dispatcher::ClientHandshake, this, _1, _2, _3),
+        std::bind(&IStorage::GetMessageEntryType, &m_storage, _1));
+    conn->set_process_incoming(
+        std::bind(&IStorage::ProcessIncoming, &m_storage, _1, _2,
+                  std::weak_ptr<NetworkConnection>(conn)));
+    m_connections.resize(0);  // disconnect any current
+    m_connections.emplace_back(conn);
+    conn->set_proto_rev(m_reconnect_proto_rev);
+    conn->Start();
+
+    // reconnect the next time starting with latest protocol revision
+    m_reconnect_proto_rev = 0x0300;
+
+    // block until told to reconnect
+    m_do_reconnect = false;
+    m_reconnect_cv.wait(lock, [&] { return !m_active || m_do_reconnect; });
+  }
+  m_networkMode = NT_NET_MODE_NONE;
+}
+
+bool DispatcherBase::ClientHandshake(
+    NetworkConnection& conn, std::function<std::shared_ptr<Message>()> get_msg,
+    std::function<void(wpi::ArrayRef<std::shared_ptr<Message>>)> send_msgs) {
+  // get identity
+  std::string self_id;
+  {
+    std::scoped_lock lock(m_user_mutex);
+    self_id = m_identity;
+  }
+
+  // send client hello
+  DEBUG0("client: sending hello");
+  send_msgs(Message::ClientHello(self_id));
+
+  // wait for response
+  auto msg = get_msg();
+  if (!msg) {
+    // disconnected, retry
+    DEBUG0("client: server disconnected before first response");
+    return false;
+  }
+
+  if (msg->Is(Message::kProtoUnsup)) {
+    if (msg->id() == 0x0200) ClientReconnect(0x0200);
+    return false;
+  }
+
+  bool new_server = true;
+  if (conn.proto_rev() >= 0x0300) {
+    // should be server hello; if not, disconnect.
+    if (!msg->Is(Message::kServerHello)) return false;
+    conn.set_remote_id(msg->str());
+    if ((msg->flags() & 1) != 0) new_server = false;
+    // get the next message
+    msg = get_msg();
+  }
+
+  // receive initial assignments
+  std::vector<std::shared_ptr<Message>> incoming;
+  for (;;) {
+    if (!msg) {
+      // disconnected, retry
+      DEBUG0("client: server disconnected during initial entries");
+      return false;
+    }
+    DEBUG4("received init str=" << msg->str() << " id=" << msg->id()
+                                << " seq_num=" << msg->seq_num_uid());
+    if (msg->Is(Message::kServerHelloDone)) break;
+    // shouldn't receive a keep alive, but handle gracefully
+    if (msg->Is(Message::kKeepAlive)) {
+      msg = get_msg();
+      continue;
+    }
+    if (!msg->Is(Message::kEntryAssign)) {
+      // unexpected message
+      DEBUG0("client: received message ("
+             << msg->type()
+             << ") other than entry assignment during initial handshake");
+      return false;
+    }
+    incoming.emplace_back(std::move(msg));
+    // get the next message
+    msg = get_msg();
+  }
+
+  // generate outgoing assignments
+  NetworkConnection::Outgoing outgoing;
+
+  m_storage.ApplyInitialAssignments(conn, incoming, new_server, &outgoing);
+
+  if (conn.proto_rev() >= 0x0300)
+    outgoing.emplace_back(Message::ClientHelloDone());
+
+  if (!outgoing.empty()) send_msgs(outgoing);
+
+  INFO("client: CONNECTED to server " << conn.stream().getPeerIP() << " port "
+                                      << conn.stream().getPeerPort());
+  return true;
+}
+
+bool DispatcherBase::ServerHandshake(
+    NetworkConnection& conn, std::function<std::shared_ptr<Message>()> get_msg,
+    std::function<void(wpi::ArrayRef<std::shared_ptr<Message>>)> send_msgs) {
+  // Wait for the client to send us a hello.
+  auto msg = get_msg();
+  if (!msg) {
+    DEBUG0("server: client disconnected before sending hello");
+    return false;
+  }
+  if (!msg->Is(Message::kClientHello)) {
+    DEBUG0("server: client initial message was not client hello");
+    return false;
+  }
+
+  // Check that the client requested version is not too high.
+  unsigned int proto_rev = msg->id();
+  if (proto_rev > 0x0300) {
+    DEBUG0("server: client requested proto > 0x0300");
+    send_msgs(Message::ProtoUnsup());
+    return false;
+  }
+
+  if (proto_rev >= 0x0300) conn.set_remote_id(msg->str());
+
+  // Set the proto version to the client requested version
+  DEBUG0("server: client protocol " << proto_rev);
+  conn.set_proto_rev(proto_rev);
+
+  // Send initial set of assignments
+  NetworkConnection::Outgoing outgoing;
+
+  // Start with server hello.  TODO: initial connection flag
+  if (proto_rev >= 0x0300) {
+    std::scoped_lock lock(m_user_mutex);
+    outgoing.emplace_back(Message::ServerHello(0u, m_identity));
+  }
+
+  // Get snapshot of initial assignments
+  m_storage.GetInitialAssignments(conn, &outgoing);
+
+  // Finish with server hello done
+  outgoing.emplace_back(Message::ServerHelloDone());
+
+  // Batch transmit
+  DEBUG0("server: sending initial assignments");
+  send_msgs(outgoing);
+
+  // In proto rev 3.0 and later, the handshake concludes with a client hello
+  // done message, so we can batch the assigns before marking the connection
+  // active.  In pre-3.0, we need to just immediately mark it active and hand
+  // off control to the dispatcher to assign them as they arrive.
+  if (proto_rev >= 0x0300) {
+    // receive client initial assignments
+    std::vector<std::shared_ptr<Message>> incoming;
+    msg = get_msg();
+    for (;;) {
+      if (!msg) {
+        // disconnected, retry
+        DEBUG0("server: disconnected waiting for initial entries");
+        return false;
+      }
+      if (msg->Is(Message::kClientHelloDone)) break;
+      // shouldn't receive a keep alive, but handle gracefully
+      if (msg->Is(Message::kKeepAlive)) {
+        msg = get_msg();
+        continue;
+      }
+      if (!msg->Is(Message::kEntryAssign)) {
+        // unexpected message
+        DEBUG0("server: received message ("
+               << msg->type()
+               << ") other than entry assignment during initial handshake");
+        return false;
+      }
+      incoming.push_back(msg);
+      // get the next message (blocks)
+      msg = get_msg();
+    }
+    for (auto& msg : incoming)
+      m_storage.ProcessIncoming(msg, &conn, std::weak_ptr<NetworkConnection>());
+  }
+
+  INFO("server: client CONNECTED: " << conn.stream().getPeerIP() << " port "
+                                    << conn.stream().getPeerPort());
+  return true;
+}
+
+void DispatcherBase::ClientReconnect(unsigned int proto_rev) {
+  if ((m_networkMode & NT_NET_MODE_SERVER) != 0) return;
+  {
+    std::scoped_lock lock(m_user_mutex);
+    m_reconnect_proto_rev = proto_rev;
+    m_do_reconnect = true;
+  }
+  m_reconnect_cv.notify_one();
+}
diff --git a/ntcore/src/main/native/cpp/Dispatcher.h b/ntcore/src/main/native/cpp/Dispatcher.h
new file mode 100644
index 0000000..bfddae7
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Dispatcher.h
@@ -0,0 +1,152 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_DISPATCHER_H_
+#define NTCORE_DISPATCHER_H_
+
+#include <atomic>
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
+
+#include <wpi/StringRef.h>
+#include <wpi/Twine.h>
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+
+#include "IDispatcher.h"
+#include "INetworkConnection.h"
+
+namespace wpi {
+class Logger;
+class NetworkAcceptor;
+class NetworkStream;
+}  // namespace wpi
+
+namespace nt {
+
+class IConnectionNotifier;
+class IStorage;
+class NetworkConnection;
+
+class DispatcherBase : public IDispatcher {
+  friend class DispatcherTest;
+
+ public:
+  typedef std::function<std::unique_ptr<wpi::NetworkStream>()> Connector;
+
+  DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
+                 wpi::Logger& logger);
+  virtual ~DispatcherBase();
+
+  unsigned int GetNetworkMode() const;
+  void StartLocal();
+  void StartServer(const Twine& persist_filename,
+                   std::unique_ptr<wpi::NetworkAcceptor> acceptor);
+  void StartClient();
+  void Stop();
+  void SetUpdateRate(double interval);
+  void SetIdentity(const Twine& name);
+  void Flush();
+  std::vector<ConnectionInfo> GetConnections() const;
+  bool IsConnected() const;
+
+  unsigned int AddListener(
+      std::function<void(const ConnectionNotification& event)> callback,
+      bool immediate_notify) const;
+  unsigned int AddPolledListener(unsigned int poller_uid,
+                                 bool immediate_notify) const;
+
+  void SetConnector(Connector connector);
+  void SetConnectorOverride(Connector connector);
+  void ClearConnectorOverride();
+
+  bool active() const { return m_active; }
+
+  DispatcherBase(const DispatcherBase&) = delete;
+  DispatcherBase& operator=(const DispatcherBase&) = delete;
+
+ private:
+  void DispatchThreadMain();
+  void ServerThreadMain();
+  void ClientThreadMain();
+
+  bool ClientHandshake(
+      NetworkConnection& conn,
+      std::function<std::shared_ptr<Message>()> get_msg,
+      std::function<void(wpi::ArrayRef<std::shared_ptr<Message>>)> send_msgs);
+  bool ServerHandshake(
+      NetworkConnection& conn,
+      std::function<std::shared_ptr<Message>()> get_msg,
+      std::function<void(wpi::ArrayRef<std::shared_ptr<Message>>)> send_msgs);
+
+  void ClientReconnect(unsigned int proto_rev = 0x0300);
+
+  void QueueOutgoing(std::shared_ptr<Message> msg, INetworkConnection* only,
+                     INetworkConnection* except) override;
+
+  IStorage& m_storage;
+  IConnectionNotifier& m_notifier;
+  unsigned int m_networkMode = NT_NET_MODE_NONE;
+  std::string m_persist_filename;
+  std::thread m_dispatch_thread;
+  std::thread m_clientserver_thread;
+
+  std::unique_ptr<wpi::NetworkAcceptor> m_server_acceptor;
+  Connector m_client_connector_override;
+  Connector m_client_connector;
+  uint8_t m_connections_uid = 0;
+
+  // Mutex for user-accessible items
+  mutable wpi::mutex m_user_mutex;
+  std::vector<std::shared_ptr<INetworkConnection>> m_connections;
+  std::string m_identity;
+
+  std::atomic_bool m_active;       // set to false to terminate threads
+  std::atomic_uint m_update_rate;  // periodic dispatch update rate, in ms
+
+  // Condition variable for forced dispatch wakeup (flush)
+  wpi::mutex m_flush_mutex;
+  wpi::condition_variable m_flush_cv;
+  std::chrono::steady_clock::time_point m_last_flush;
+  bool m_do_flush = false;
+
+  // Condition variable for client reconnect (uses user mutex)
+  wpi::condition_variable m_reconnect_cv;
+  unsigned int m_reconnect_proto_rev = 0x0300;
+  bool m_do_reconnect = true;
+
+ protected:
+  wpi::Logger& m_logger;
+};
+
+class Dispatcher : public DispatcherBase {
+  friend class DispatcherTest;
+
+ public:
+  Dispatcher(IStorage& storage, IConnectionNotifier& notifier,
+             wpi::Logger& logger)
+      : DispatcherBase(storage, notifier, logger) {}
+
+  void StartServer(const Twine& persist_filename, const char* listen_address,
+                   unsigned int port);
+
+  void SetServer(const char* server_name, unsigned int port);
+  void SetServer(ArrayRef<std::pair<StringRef, unsigned int>> servers);
+  void SetServerTeam(unsigned int team, unsigned int port);
+
+  void SetServerOverride(const char* server_name, unsigned int port);
+  void ClearServerOverride();
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_DISPATCHER_H_
diff --git a/ntcore/src/main/native/cpp/DsClient.cpp b/ntcore/src/main/native/cpp/DsClient.cpp
new file mode 100644
index 0000000..32a756f
--- /dev/null
+++ b/ntcore/src/main/native/cpp/DsClient.cpp
@@ -0,0 +1,153 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "DsClient.h"
+
+#include <wpi/SmallString.h>
+#include <wpi/TCPConnector.h>
+#include <wpi/raw_ostream.h>
+#include <wpi/raw_socket_istream.h>
+
+#include "Dispatcher.h"
+#include "Log.h"
+
+using namespace nt;
+
+class DsClient::Thread : public wpi::SafeThread {
+ public:
+  Thread(Dispatcher& dispatcher, wpi::Logger& logger, unsigned int port)
+      : m_dispatcher(dispatcher), m_logger(logger), m_port(port) {}
+
+  void Main();
+
+  Dispatcher& m_dispatcher;
+  wpi::Logger& m_logger;
+  unsigned int m_port;
+  std::unique_ptr<wpi::NetworkStream> m_stream;
+};
+
+DsClient::DsClient(Dispatcher& dispatcher, wpi::Logger& logger)
+    : m_dispatcher(dispatcher), m_logger(logger) {}
+
+void DsClient::Start(unsigned int port) {
+  auto thr = m_owner.GetThread();
+  if (!thr)
+    m_owner.Start(m_dispatcher, m_logger, port);
+  else
+    thr->m_port = port;
+}
+
+void DsClient::Stop() {
+  {
+    // Close the stream so the read (if any) terminates.
+    auto thr = m_owner.GetThread();
+    if (thr) {
+      thr->m_active = false;
+      if (thr->m_stream) thr->m_stream->close();
+    }
+  }
+  m_owner.Stop();
+}
+
+void DsClient::Thread::Main() {
+  unsigned int oldip = 0;
+  wpi::Logger nolog;  // to silence log messages from TCPConnector
+
+  while (m_active) {
+    // wait for periodic reconnect or termination
+    auto timeout_time =
+        std::chrono::steady_clock::now() + std::chrono::milliseconds(500);
+    unsigned int port;
+    {
+      std::unique_lock lock(m_mutex);
+      m_cond.wait_until(lock, timeout_time, [&] { return !m_active; });
+      port = m_port;
+    }
+    if (!m_active) goto done;
+
+    // Try to connect to DS on the local machine
+    m_stream = wpi::TCPConnector::connect("127.0.0.1", 1742, nolog, 1);
+    if (!m_active) goto done;
+    if (!m_stream) continue;
+
+    DEBUG3("connected to DS");
+    wpi::raw_socket_istream is(*m_stream);
+
+    while (m_active && !is.has_error()) {
+      // Read JSON "{...}".  This is very limited, does not handle quoted "}" or
+      // nested {}, but is sufficient for this purpose.
+      wpi::SmallString<128> json;
+      char ch;
+
+      // Throw away characters until {
+      do {
+        is.read(ch);
+        if (is.has_error()) break;
+        if (!m_active) goto done;
+      } while (ch != '{');
+      json += '{';
+
+      if (is.has_error()) {
+        m_stream = nullptr;
+        break;
+      }
+
+      // Read characters until }
+      do {
+        is.read(ch);
+        if (is.has_error()) break;
+        if (!m_active) goto done;
+        json += ch;
+      } while (ch != '}');
+
+      if (is.has_error()) {
+        m_stream = nullptr;
+        break;
+      }
+      DEBUG3("json=" << json);
+
+      // Look for "robotIP":12345, and get 12345 portion
+      size_t pos = json.find("\"robotIP\"");
+      if (pos == wpi::StringRef::npos) continue;  // could not find?
+      pos += 9;
+      pos = json.find(':', pos);
+      if (pos == wpi::StringRef::npos) continue;  // could not find?
+      size_t endpos = json.find_first_not_of("0123456789", pos + 1);
+      DEBUG3("found robotIP=" << json.slice(pos + 1, endpos));
+
+      // Parse into number
+      unsigned int ip = 0;
+      if (json.slice(pos + 1, endpos).getAsInteger(10, ip)) continue;  // error
+
+      // If zero, clear the server override
+      if (ip == 0) {
+        m_dispatcher.ClearServerOverride();
+        oldip = 0;
+        continue;
+      }
+
+      // If unchanged, don't reconnect
+      if (ip == oldip) continue;
+      oldip = ip;
+
+      // Convert number into dotted quad
+      json.clear();
+      wpi::raw_svector_ostream os{json};
+      os << ((ip >> 24) & 0xff) << "." << ((ip >> 16) & 0xff) << "."
+         << ((ip >> 8) & 0xff) << "." << (ip & 0xff);
+      INFO("client: DS overriding server IP to " << os.str());
+      m_dispatcher.SetServerOverride(json.c_str(), port);
+    }
+
+    // We disconnected from the DS, clear the server override
+    m_dispatcher.ClearServerOverride();
+    oldip = 0;
+  }
+
+done:
+  m_dispatcher.ClearServerOverride();
+}
diff --git a/ntcore/src/main/native/cpp/DsClient.h b/ntcore/src/main/native/cpp/DsClient.h
new file mode 100644
index 0000000..ad13d25
--- /dev/null
+++ b/ntcore/src/main/native/cpp/DsClient.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_DSCLIENT_H_
+#define NTCORE_DSCLIENT_H_
+
+#include <wpi/SafeThread.h>
+
+#include "Log.h"
+
+namespace nt {
+
+class Dispatcher;
+
+class DsClient {
+ public:
+  DsClient(Dispatcher& dispatcher, wpi::Logger& logger);
+  ~DsClient() = default;
+
+  void Start(unsigned int port);
+  void Stop();
+
+ private:
+  class Thread;
+  wpi::SafeThreadOwner<Thread> m_owner;
+  Dispatcher& m_dispatcher;
+  wpi::Logger& m_logger;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_DSCLIENT_H_
diff --git a/ntcore/src/main/native/cpp/EntryNotifier.cpp b/ntcore/src/main/native/cpp/EntryNotifier.cpp
new file mode 100644
index 0000000..c8f8d76
--- /dev/null
+++ b/ntcore/src/main/native/cpp/EntryNotifier.cpp
@@ -0,0 +1,89 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "EntryNotifier.h"
+
+#include "Log.h"
+
+using namespace nt;
+
+EntryNotifier::EntryNotifier(int inst, wpi::Logger& logger)
+    : m_inst(inst), m_logger(logger) {
+  m_local_notifiers = false;
+}
+
+void EntryNotifier::Start() { DoStart(m_inst); }
+
+bool EntryNotifier::local_notifiers() const { return m_local_notifiers; }
+
+bool impl::EntryNotifierThread::Matches(const EntryListenerData& listener,
+                                        const EntryNotification& data) {
+  if (!data.value) return false;
+
+  // Flags must be within requested flag set for this listener.
+  // Because assign messages can result in both a value and flags update,
+  // we handle that case specially.
+  unsigned int listen_flags =
+      listener.flags & ~(NT_NOTIFY_IMMEDIATE | NT_NOTIFY_LOCAL);
+  unsigned int flags = data.flags & ~(NT_NOTIFY_IMMEDIATE | NT_NOTIFY_LOCAL);
+  unsigned int assign_both = NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS;
+  if ((flags & assign_both) == assign_both) {
+    if ((listen_flags & assign_both) == 0) return false;
+    listen_flags &= ~assign_both;
+    flags &= ~assign_both;
+  }
+  if ((flags & ~listen_flags) != 0) return false;
+
+  // must match local id or prefix
+  if (listener.entry != 0 && data.entry != listener.entry) return false;
+  if (listener.entry == 0 &&
+      !wpi::StringRef(data.name).startswith(listener.prefix))
+    return false;
+
+  return true;
+}
+
+unsigned int EntryNotifier::Add(
+    std::function<void(const EntryNotification& event)> callback,
+    StringRef prefix, unsigned int flags) {
+  if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
+  return DoAdd(callback, prefix, flags);
+}
+
+unsigned int EntryNotifier::Add(
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int local_id, unsigned int flags) {
+  if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
+  return DoAdd(callback, Handle(m_inst, local_id, Handle::kEntry), flags);
+}
+
+unsigned int EntryNotifier::AddPolled(unsigned int poller_uid,
+                                      wpi::StringRef prefix,
+                                      unsigned int flags) {
+  if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
+  return DoAdd(poller_uid, prefix, flags);
+}
+
+unsigned int EntryNotifier::AddPolled(unsigned int poller_uid,
+                                      unsigned int local_id,
+                                      unsigned int flags) {
+  if ((flags & NT_NOTIFY_LOCAL) != 0) m_local_notifiers = true;
+  return DoAdd(poller_uid, Handle(m_inst, local_id, Handle::kEntry), flags);
+}
+
+void EntryNotifier::NotifyEntry(unsigned int local_id, StringRef name,
+                                std::shared_ptr<Value> value,
+                                unsigned int flags,
+                                unsigned int only_listener) {
+  // optimization: don't generate needless local queue entries if we have
+  // no local listeners (as this is a common case on the server side)
+  if ((flags & NT_NOTIFY_LOCAL) != 0 && !m_local_notifiers) return;
+  DEBUG0("notifying '" << name << "' (local=" << local_id
+                       << "), flags=" << flags);
+  Send(only_listener, 0, Handle(m_inst, local_id, Handle::kEntry).handle(),
+       name, value, flags);
+}
diff --git a/ntcore/src/main/native/cpp/EntryNotifier.h b/ntcore/src/main/native/cpp/EntryNotifier.h
new file mode 100644
index 0000000..3ccf9ff
--- /dev/null
+++ b/ntcore/src/main/native/cpp/EntryNotifier.h
@@ -0,0 +1,109 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_ENTRYNOTIFIER_H_
+#define NTCORE_ENTRYNOTIFIER_H_
+
+#include <atomic>
+#include <memory>
+#include <string>
+
+#include "CallbackManager.h"
+#include "Handle.h"
+#include "IEntryNotifier.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt {
+
+namespace impl {
+
+struct EntryListenerData
+    : public ListenerData<std::function<void(const EntryNotification& event)>> {
+  EntryListenerData() = default;
+  EntryListenerData(
+      std::function<void(const EntryNotification& event)> callback_,
+      StringRef prefix_, unsigned int flags_)
+      : ListenerData(callback_), prefix(prefix_), flags(flags_) {}
+  EntryListenerData(
+      std::function<void(const EntryNotification& event)> callback_,
+      NT_Entry entry_, unsigned int flags_)
+      : ListenerData(callback_), entry(entry_), flags(flags_) {}
+  EntryListenerData(unsigned int poller_uid_, StringRef prefix_,
+                    unsigned int flags_)
+      : ListenerData(poller_uid_), prefix(prefix_), flags(flags_) {}
+  EntryListenerData(unsigned int poller_uid_, NT_Entry entry_,
+                    unsigned int flags_)
+      : ListenerData(poller_uid_), entry(entry_), flags(flags_) {}
+
+  std::string prefix;
+  NT_Entry entry = 0;
+  unsigned int flags;
+};
+
+class EntryNotifierThread
+    : public CallbackThread<EntryNotifierThread, EntryNotification,
+                            EntryListenerData> {
+ public:
+  explicit EntryNotifierThread(int inst) : m_inst(inst) {}
+
+  bool Matches(const EntryListenerData& listener,
+               const EntryNotification& data);
+
+  void SetListener(EntryNotification* data, unsigned int listener_uid) {
+    data->listener =
+        Handle(m_inst, listener_uid, Handle::kEntryListener).handle();
+  }
+
+  void DoCallback(std::function<void(const EntryNotification& event)> callback,
+                  const EntryNotification& data) {
+    callback(data);
+  }
+
+  int m_inst;
+};
+
+}  // namespace impl
+
+class EntryNotifier
+    : public IEntryNotifier,
+      public CallbackManager<EntryNotifier, impl::EntryNotifierThread> {
+  friend class EntryNotifierTest;
+  friend class CallbackManager<EntryNotifier, impl::EntryNotifierThread>;
+
+ public:
+  explicit EntryNotifier(int inst, wpi::Logger& logger);
+
+  void Start();
+
+  bool local_notifiers() const override;
+
+  unsigned int Add(std::function<void(const EntryNotification& event)> callback,
+                   wpi::StringRef prefix, unsigned int flags) override;
+  unsigned int Add(std::function<void(const EntryNotification& event)> callback,
+                   unsigned int local_id, unsigned int flags) override;
+  unsigned int AddPolled(unsigned int poller_uid, wpi::StringRef prefix,
+                         unsigned int flags) override;
+  unsigned int AddPolled(unsigned int poller_uid, unsigned int local_id,
+                         unsigned int flags) override;
+
+  void NotifyEntry(unsigned int local_id, StringRef name,
+                   std::shared_ptr<Value> value, unsigned int flags,
+                   unsigned int only_listener = UINT_MAX) override;
+
+ private:
+  int m_inst;
+  wpi::Logger& m_logger;
+  std::atomic_bool m_local_notifiers;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_ENTRYNOTIFIER_H_
diff --git a/ntcore/src/main/native/cpp/Handle.h b/ntcore/src/main/native/cpp/Handle.h
new file mode 100644
index 0000000..47b5edf
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Handle.h
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_HANDLE_H_
+#define NTCORE_HANDLE_H_
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+// Handle data layout:
+// Bits 30-28: Type
+// Bits 27-20: Instance index
+// Bits 19-0:  Handle index (0/unused for instance handles)
+
+class Handle {
+ public:
+  enum Type {
+    kConnectionListener = 1,
+    kConnectionListenerPoller,
+    kEntry,
+    kEntryListener,
+    kEntryListenerPoller,
+    kInstance,
+    kLogger,
+    kLoggerPoller,
+    kRpcCall,
+    kRpcCallPoller
+  };
+  enum { kIndexMax = 0xfffff };
+
+  explicit Handle(NT_Handle handle) : m_handle(handle) {}
+  operator NT_Handle() const { return m_handle; }
+
+  NT_Handle handle() const { return m_handle; }
+
+  Handle(int inst, int index, Type type) {
+    if (inst < 0 || index < 0) {
+      m_handle = 0;
+      return;
+    }
+    m_handle = ((static_cast<int>(type) & 0xf) << 27) | ((inst & 0x7f) << 20) |
+               (index & 0xfffff);
+  }
+
+  int GetIndex() const { return static_cast<int>(m_handle) & 0xfffff; }
+  Type GetType() const {
+    return static_cast<Type>((static_cast<int>(m_handle) >> 27) & 0xf);
+  }
+  int GetInst() const { return (static_cast<int>(m_handle) >> 20) & 0x7f; }
+  bool IsType(Type type) const { return type == GetType(); }
+  int GetTypedIndex(Type type) const { return IsType(type) ? GetIndex() : -1; }
+  int GetTypedInst(Type type) const { return IsType(type) ? GetInst() : -1; }
+
+ private:
+  NT_Handle m_handle;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_HANDLE_H_
diff --git a/ntcore/src/main/native/cpp/IConnectionNotifier.h b/ntcore/src/main/native/cpp/IConnectionNotifier.h
new file mode 100644
index 0000000..7a165f2
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IConnectionNotifier.h
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_ICONNECTIONNOTIFIER_H_
+#define NTCORE_ICONNECTIONNOTIFIER_H_
+
+#include <climits>
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IConnectionNotifier {
+ public:
+  IConnectionNotifier() = default;
+  IConnectionNotifier(const IConnectionNotifier&) = delete;
+  IConnectionNotifier& operator=(const IConnectionNotifier&) = delete;
+  virtual ~IConnectionNotifier() = default;
+  virtual unsigned int Add(
+      std::function<void(const ConnectionNotification& event)> callback) = 0;
+  virtual unsigned int AddPolled(unsigned int poller_uid) = 0;
+  virtual void NotifyConnection(bool connected, const ConnectionInfo& conn_info,
+                                unsigned int only_listener = UINT_MAX) = 0;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_ICONNECTIONNOTIFIER_H_
diff --git a/ntcore/src/main/native/cpp/IDispatcher.h b/ntcore/src/main/native/cpp/IDispatcher.h
new file mode 100644
index 0000000..aace766
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IDispatcher.h
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_IDISPATCHER_H_
+#define NTCORE_IDISPATCHER_H_
+
+#include <memory>
+
+#include "Message.h"
+
+namespace nt {
+
+class INetworkConnection;
+
+// Interface for generation of outgoing messages to break a dependency loop
+// between Storage and Dispatcher.
+class IDispatcher {
+ public:
+  IDispatcher() = default;
+  IDispatcher(const IDispatcher&) = delete;
+  IDispatcher& operator=(const IDispatcher&) = delete;
+  virtual ~IDispatcher() = default;
+  virtual void QueueOutgoing(std::shared_ptr<Message> msg,
+                             INetworkConnection* only,
+                             INetworkConnection* except) = 0;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_IDISPATCHER_H_
diff --git a/ntcore/src/main/native/cpp/IEntryNotifier.h b/ntcore/src/main/native/cpp/IEntryNotifier.h
new file mode 100644
index 0000000..80ed97e
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IEntryNotifier.h
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_IENTRYNOTIFIER_H_
+#define NTCORE_IENTRYNOTIFIER_H_
+
+#include <climits>
+#include <memory>
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IEntryNotifier {
+ public:
+  IEntryNotifier() = default;
+  IEntryNotifier(const IEntryNotifier&) = delete;
+  IEntryNotifier& operator=(const IEntryNotifier&) = delete;
+  virtual ~IEntryNotifier() = default;
+  virtual bool local_notifiers() const = 0;
+
+  virtual unsigned int Add(
+      std::function<void(const EntryNotification& event)> callback,
+      wpi::StringRef prefix, unsigned int flags) = 0;
+  virtual unsigned int Add(
+      std::function<void(const EntryNotification& event)> callback,
+      unsigned int local_id, unsigned int flags) = 0;
+  virtual unsigned int AddPolled(unsigned int poller_uid, wpi::StringRef prefix,
+                                 unsigned int flags) = 0;
+  virtual unsigned int AddPolled(unsigned int poller_uid, unsigned int local_id,
+                                 unsigned int flags) = 0;
+
+  virtual void NotifyEntry(unsigned int local_id, StringRef name,
+                           std::shared_ptr<Value> value, unsigned int flags,
+                           unsigned int only_listener = UINT_MAX) = 0;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_IENTRYNOTIFIER_H_
diff --git a/ntcore/src/main/native/cpp/INetworkConnection.h b/ntcore/src/main/native/cpp/INetworkConnection.h
new file mode 100644
index 0000000..0387cc9
--- /dev/null
+++ b/ntcore/src/main/native/cpp/INetworkConnection.h
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_INETWORKCONNECTION_H_
+#define NTCORE_INETWORKCONNECTION_H_
+
+#include <memory>
+
+#include "Message.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class INetworkConnection {
+ public:
+  enum State { kCreated, kInit, kHandshake, kSynchronized, kActive, kDead };
+
+  INetworkConnection() = default;
+  INetworkConnection(const INetworkConnection&) = delete;
+  INetworkConnection& operator=(const INetworkConnection&) = delete;
+  virtual ~INetworkConnection() = default;
+
+  virtual ConnectionInfo info() const = 0;
+
+  virtual void QueueOutgoing(std::shared_ptr<Message> msg) = 0;
+  virtual void PostOutgoing(bool keep_alive) = 0;
+
+  virtual unsigned int proto_rev() const = 0;
+  virtual void set_proto_rev(unsigned int proto_rev) = 0;
+
+  virtual State state() const = 0;
+  virtual void set_state(State state) = 0;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_INETWORKCONNECTION_H_
diff --git a/ntcore/src/main/native/cpp/IRpcServer.h b/ntcore/src/main/native/cpp/IRpcServer.h
new file mode 100644
index 0000000..dc8b0a6
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IRpcServer.h
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_IRPCSERVER_H_
+#define NTCORE_IRPCSERVER_H_
+
+#include <memory>
+
+#include "Message.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IRpcServer {
+ public:
+  typedef std::function<void(StringRef result)> SendResponseFunc;
+
+  IRpcServer() = default;
+  IRpcServer(const IRpcServer&) = delete;
+  IRpcServer& operator=(const IRpcServer&) = delete;
+  virtual ~IRpcServer() = default;
+
+  virtual void RemoveRpc(unsigned int rpc_uid) = 0;
+
+  virtual void ProcessRpc(unsigned int local_id, unsigned int call_uid,
+                          StringRef name, StringRef params,
+                          const ConnectionInfo& conn,
+                          SendResponseFunc send_response,
+                          unsigned int rpc_uid) = 0;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_IRPCSERVER_H_
diff --git a/ntcore/src/main/native/cpp/IStorage.h b/ntcore/src/main/native/cpp/IStorage.h
new file mode 100644
index 0000000..0fb3a0b
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IStorage.h
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_ISTORAGE_H_
+#define NTCORE_ISTORAGE_H_
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <wpi/ArrayRef.h>
+#include <wpi/Twine.h>
+
+#include "Message.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IDispatcher;
+class INetworkConnection;
+
+class IStorage {
+ public:
+  IStorage() = default;
+  IStorage(const IStorage&) = delete;
+  IStorage& operator=(const IStorage&) = delete;
+  virtual ~IStorage() = default;
+
+  // Accessors required by Dispatcher.  An interface is used for
+  // generation of outgoing messages to break a dependency loop between
+  // Storage and Dispatcher.
+  virtual void SetDispatcher(IDispatcher* dispatcher, bool server) = 0;
+  virtual void ClearDispatcher() = 0;
+
+  // Required for wire protocol 2.0 to get the entry type of an entry when
+  // receiving entry updates (because the length/type is not provided in the
+  // message itself).  Not used in wire protocol 3.0.
+  virtual NT_Type GetMessageEntryType(unsigned int id) const = 0;
+
+  virtual void ProcessIncoming(std::shared_ptr<Message> msg,
+                               INetworkConnection* conn,
+                               std::weak_ptr<INetworkConnection> conn_weak) = 0;
+  virtual void GetInitialAssignments(
+      INetworkConnection& conn,
+      std::vector<std::shared_ptr<Message>>* msgs) = 0;
+  virtual void ApplyInitialAssignments(
+      INetworkConnection& conn, wpi::ArrayRef<std::shared_ptr<Message>> msgs,
+      bool new_server, std::vector<std::shared_ptr<Message>>* out_msgs) = 0;
+
+  // Filename-based save/load functions.  Used both by periodic saves and
+  // accessible directly via the user API.
+  virtual const char* SavePersistent(const Twine& filename,
+                                     bool periodic) const = 0;
+  virtual const char* LoadPersistent(
+      const Twine& filename,
+      std::function<void(size_t line, const char* msg)> warn) = 0;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_ISTORAGE_H_
diff --git a/ntcore/src/main/native/cpp/InstanceImpl.cpp b/ntcore/src/main/native/cpp/InstanceImpl.cpp
new file mode 100644
index 0000000..cd35fb0
--- /dev/null
+++ b/ntcore/src/main/native/cpp/InstanceImpl.cpp
@@ -0,0 +1,109 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "InstanceImpl.h"
+
+using namespace nt;
+
+std::atomic<int> InstanceImpl::s_default{-1};
+std::atomic<InstanceImpl*> InstanceImpl::s_fast_instances[10];
+wpi::UidVector<InstanceImpl*, 10> InstanceImpl::s_instances;
+wpi::mutex InstanceImpl::s_mutex;
+
+using namespace std::placeholders;
+
+InstanceImpl::InstanceImpl(int inst)
+    : logger_impl(inst),
+      logger(std::bind(&LoggerImpl::Log, &logger_impl, _1, _2, _3, _4)),
+      connection_notifier(inst),
+      entry_notifier(inst, logger),
+      rpc_server(inst, logger),
+      storage(entry_notifier, rpc_server, logger),
+      dispatcher(storage, connection_notifier, logger),
+      ds_client(dispatcher, logger) {
+  logger.set_min_level(logger_impl.GetMinLevel());
+}
+
+InstanceImpl::~InstanceImpl() { logger.SetLogger(nullptr); }
+
+InstanceImpl* InstanceImpl::GetDefault() { return Get(GetDefaultIndex()); }
+
+InstanceImpl* InstanceImpl::Get(int inst) {
+  if (inst < 0) return nullptr;
+
+  // fast path, just an atomic read
+  if (static_cast<unsigned int>(inst) <
+      (sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
+    InstanceImpl* ptr = s_fast_instances[inst];
+    if (ptr) return ptr;
+  }
+
+  // slow path
+  std::scoped_lock lock(s_mutex);
+
+  // static fast-path block
+  if (static_cast<unsigned int>(inst) <
+      (sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
+    // double-check
+    return s_fast_instances[inst];
+  }
+
+  // vector
+  if (static_cast<unsigned int>(inst) < s_instances.size()) {
+    return s_instances[inst];
+  }
+
+  // doesn't exist
+  return nullptr;
+}
+
+int InstanceImpl::GetDefaultIndex() {
+  int inst = s_default;
+  if (inst >= 0) return inst;
+
+  // slow path
+  std::scoped_lock lock(s_mutex);
+
+  // double-check
+  inst = s_default;
+  if (inst >= 0) return inst;
+
+  // alloc and save
+  inst = AllocImpl();
+  s_default = inst;
+  return inst;
+}
+
+int InstanceImpl::Alloc() {
+  std::scoped_lock lock(s_mutex);
+  return AllocImpl();
+}
+
+int InstanceImpl::AllocImpl() {
+  unsigned int inst = s_instances.emplace_back(nullptr);
+  InstanceImpl* ptr = new InstanceImpl(inst);
+  s_instances[inst] = ptr;
+
+  if (inst < (sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
+    s_fast_instances[inst] = ptr;
+  }
+
+  return static_cast<int>(inst);
+}
+
+void InstanceImpl::Destroy(int inst) {
+  std::scoped_lock lock(s_mutex);
+  if (inst < 0 || static_cast<unsigned int>(inst) >= s_instances.size()) return;
+
+  if (static_cast<unsigned int>(inst) <
+      (sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
+    s_fast_instances[inst] = nullptr;
+  }
+
+  delete s_instances[inst];
+  s_instances.erase(inst);
+}
diff --git a/ntcore/src/main/native/cpp/InstanceImpl.h b/ntcore/src/main/native/cpp/InstanceImpl.h
new file mode 100644
index 0000000..6e732d8
--- /dev/null
+++ b/ntcore/src/main/native/cpp/InstanceImpl.h
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_INSTANCEIMPL_H_
+#define NTCORE_INSTANCEIMPL_H_
+
+#include <atomic>
+#include <memory>
+
+#include <wpi/UidVector.h>
+#include <wpi/mutex.h>
+
+#include "ConnectionNotifier.h"
+#include "Dispatcher.h"
+#include "DsClient.h"
+#include "EntryNotifier.h"
+#include "Log.h"
+#include "LoggerImpl.h"
+#include "RpcServer.h"
+#include "Storage.h"
+
+namespace nt {
+
+class InstanceImpl {
+ public:
+  explicit InstanceImpl(int inst);
+  ~InstanceImpl();
+
+  // Instance repository
+  static InstanceImpl* GetDefault();
+  static InstanceImpl* Get(int inst);
+  static int GetDefaultIndex();
+  static int Alloc();
+  static void Destroy(int inst);
+
+  LoggerImpl logger_impl;
+  wpi::Logger logger;
+  ConnectionNotifier connection_notifier;
+  EntryNotifier entry_notifier;
+  RpcServer rpc_server;
+  Storage storage;
+  Dispatcher dispatcher;
+  DsClient ds_client;
+
+ private:
+  static int AllocImpl();
+
+  static std::atomic<int> s_default;
+  static std::atomic<InstanceImpl*> s_fast_instances[10];
+  static wpi::UidVector<InstanceImpl*, 10> s_instances;
+  static wpi::mutex s_mutex;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_INSTANCEIMPL_H_
diff --git a/ntcore/src/main/native/cpp/Log.h b/ntcore/src/main/native/cpp/Log.h
new file mode 100644
index 0000000..eba8f04
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Log.h
@@ -0,0 +1,26 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_LOG_H_
+#define NTCORE_LOG_H_
+
+#include <wpi/Logger.h>
+
+#define LOG(level, x) WPI_LOG(m_logger, level, x)
+
+#undef ERROR
+#define ERROR(x) WPI_ERROR(m_logger, x)
+#define WARNING(x) WPI_WARNING(m_logger, x)
+#define INFO(x) WPI_INFO(m_logger, x)
+
+#define DEBUG0(x) WPI_DEBUG(m_logger, x)
+#define DEBUG1(x) WPI_DEBUG1(m_logger, x)
+#define DEBUG2(x) WPI_DEBUG2(m_logger, x)
+#define DEBUG3(x) WPI_DEBUG3(m_logger, x)
+#define DEBUG4(x) WPI_DEBUG4(m_logger, x)
+
+#endif  // NTCORE_LOG_H_
diff --git a/ntcore/src/main/native/cpp/LoggerImpl.cpp b/ntcore/src/main/native/cpp/LoggerImpl.cpp
new file mode 100644
index 0000000..b2c6786
--- /dev/null
+++ b/ntcore/src/main/native/cpp/LoggerImpl.cpp
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "LoggerImpl.h"
+
+#include <wpi/Path.h>
+#include <wpi/SmallString.h>
+#include <wpi/StringRef.h>
+#include <wpi/raw_ostream.h>
+
+using namespace nt;
+
+static void DefaultLogger(unsigned int level, const char* file,
+                          unsigned int line, const char* msg) {
+  wpi::SmallString<128> buf;
+  wpi::raw_svector_ostream oss(buf);
+  if (level == 20) {
+    oss << "NT: " << msg << '\n';
+    wpi::errs() << oss.str();
+    return;
+  }
+
+  wpi::StringRef levelmsg;
+  if (level >= 50)
+    levelmsg = "CRITICAL: ";
+  else if (level >= 40)
+    levelmsg = "ERROR: ";
+  else if (level >= 30)
+    levelmsg = "WARNING: ";
+  else
+    return;
+  oss << "NT: " << levelmsg << msg << " (" << file << ':' << line << ")\n";
+  wpi::errs() << oss.str();
+}
+
+LoggerImpl::LoggerImpl(int inst) : m_inst(inst) {}
+
+void LoggerImpl::Start() { DoStart(m_inst); }
+
+unsigned int LoggerImpl::Add(
+    std::function<void(const LogMessage& msg)> callback, unsigned int min_level,
+    unsigned int max_level) {
+  return DoAdd(callback, min_level, max_level);
+}
+
+unsigned int LoggerImpl::AddPolled(unsigned int poller_uid,
+                                   unsigned int min_level,
+                                   unsigned int max_level) {
+  return DoAdd(poller_uid, min_level, max_level);
+}
+
+unsigned int LoggerImpl::GetMinLevel() {
+  auto thr = GetThread();
+  if (!thr) return NT_LOG_INFO;
+  unsigned int level = NT_LOG_INFO;
+  for (size_t i = 0; i < thr->m_listeners.size(); ++i) {
+    const auto& listener = thr->m_listeners[i];
+    if (listener && listener.min_level < level) level = listener.min_level;
+  }
+  return level;
+}
+
+void LoggerImpl::Log(unsigned int level, const char* file, unsigned int line,
+                     const char* msg) {
+  // this is safe because it's null terminated and always the end
+  const char* filename = wpi::sys::path::filename(file).data();
+  {
+    auto thr = GetThread();
+    if (!thr || thr->m_listeners.empty())
+      DefaultLogger(level, filename, line, msg);
+  }
+  Send(UINT_MAX, 0, level, filename, line, msg);
+}
diff --git a/ntcore/src/main/native/cpp/LoggerImpl.h b/ntcore/src/main/native/cpp/LoggerImpl.h
new file mode 100644
index 0000000..3ac0295
--- /dev/null
+++ b/ntcore/src/main/native/cpp/LoggerImpl.h
@@ -0,0 +1,83 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_LOGGERIMPL_H_
+#define NTCORE_LOGGERIMPL_H_
+
+#include "CallbackManager.h"
+#include "Handle.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+namespace impl {
+
+struct LoggerListenerData
+    : public ListenerData<std::function<void(const LogMessage& msg)>> {
+  LoggerListenerData() = default;
+  LoggerListenerData(std::function<void(const LogMessage& msg)> callback_,
+                     unsigned int min_level_, unsigned int max_level_)
+      : ListenerData(callback_), min_level(min_level_), max_level(max_level_) {}
+  LoggerListenerData(unsigned int poller_uid_, unsigned int min_level_,
+                     unsigned int max_level_)
+      : ListenerData(poller_uid_),
+        min_level(min_level_),
+        max_level(max_level_) {}
+
+  unsigned int min_level;
+  unsigned int max_level;
+};
+
+class LoggerThread
+    : public CallbackThread<LoggerThread, LogMessage, LoggerListenerData> {
+ public:
+  explicit LoggerThread(int inst) : m_inst(inst) {}
+
+  bool Matches(const LoggerListenerData& listener, const LogMessage& data) {
+    return data.level >= listener.min_level && data.level <= listener.max_level;
+  }
+
+  void SetListener(LogMessage* data, unsigned int listener_uid) {
+    data->logger = Handle(m_inst, listener_uid, Handle::kLogger).handle();
+  }
+
+  void DoCallback(std::function<void(const LogMessage& msg)> callback,
+                  const LogMessage& data) {
+    callback(data);
+  }
+
+  int m_inst;
+};
+
+}  // namespace impl
+
+class LoggerImpl : public CallbackManager<LoggerImpl, impl::LoggerThread> {
+  friend class LoggerTest;
+  friend class CallbackManager<LoggerImpl, impl::LoggerThread>;
+
+ public:
+  explicit LoggerImpl(int inst);
+
+  void Start();
+
+  unsigned int Add(std::function<void(const LogMessage& msg)> callback,
+                   unsigned int min_level, unsigned int max_level);
+  unsigned int AddPolled(unsigned int poller_uid, unsigned int min_level,
+                         unsigned int max_level);
+
+  unsigned int GetMinLevel();
+
+  void Log(unsigned int level, const char* file, unsigned int line,
+           const char* msg);
+
+ private:
+  int m_inst;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_LOGGERIMPL_H_
diff --git a/ntcore/src/main/native/cpp/Message.cpp b/ntcore/src/main/native/cpp/Message.cpp
new file mode 100644
index 0000000..576e444
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Message.cpp
@@ -0,0 +1,301 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "Message.h"
+
+#include <stdint.h>
+
+#include "Log.h"
+#include "WireDecoder.h"
+#include "WireEncoder.h"
+
+#define kClearAllMagic 0xD06CB27Aul
+
+using namespace nt;
+
+std::shared_ptr<Message> Message::Read(WireDecoder& decoder,
+                                       GetEntryTypeFunc get_entry_type) {
+  unsigned int msg_type = 0;
+  if (!decoder.Read8(&msg_type)) return nullptr;
+  auto msg =
+      std::make_shared<Message>(static_cast<MsgType>(msg_type), private_init());
+  switch (msg_type) {
+    case kKeepAlive:
+      break;
+    case kClientHello: {
+      unsigned int proto_rev;
+      if (!decoder.Read16(&proto_rev)) return nullptr;
+      msg->m_id = proto_rev;
+      // This intentionally uses the provided proto_rev instead of
+      // decoder.proto_rev().
+      if (proto_rev >= 0x0300u) {
+        if (!decoder.ReadString(&msg->m_str)) return nullptr;
+      }
+      break;
+    }
+    case kProtoUnsup: {
+      if (!decoder.Read16(&msg->m_id)) return nullptr;  // proto rev
+      break;
+    }
+    case kServerHelloDone:
+      break;
+    case kServerHello:
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received SERVER_HELLO in protocol < 3.0");
+        return nullptr;
+      }
+      if (!decoder.Read8(&msg->m_flags)) return nullptr;
+      if (!decoder.ReadString(&msg->m_str)) return nullptr;
+      break;
+    case kClientHelloDone:
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received CLIENT_HELLO_DONE in protocol < 3.0");
+        return nullptr;
+      }
+      break;
+    case kEntryAssign: {
+      if (!decoder.ReadString(&msg->m_str)) return nullptr;  // name
+      NT_Type type;
+      if (!decoder.ReadType(&type)) return nullptr;              // entry type
+      if (!decoder.Read16(&msg->m_id)) return nullptr;           // id
+      if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr;  // seq num
+      if (decoder.proto_rev() >= 0x0300u) {
+        if (!decoder.Read8(&msg->m_flags)) return nullptr;  // flags
+      }
+      msg->m_value = decoder.ReadValue(type);
+      if (!msg->m_value) return nullptr;
+      break;
+    }
+    case kEntryUpdate: {
+      if (!decoder.Read16(&msg->m_id)) return nullptr;           // id
+      if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr;  // seq num
+      NT_Type type;
+      if (decoder.proto_rev() >= 0x0300u) {
+        if (!decoder.ReadType(&type)) return nullptr;
+      } else {
+        type = get_entry_type(msg->m_id);
+      }
+      WPI_DEBUG4(decoder.logger(), "update message data type: " << type);
+      msg->m_value = decoder.ReadValue(type);
+      if (!msg->m_value) return nullptr;
+      break;
+    }
+    case kFlagsUpdate: {
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received FLAGS_UPDATE in protocol < 3.0");
+        return nullptr;
+      }
+      if (!decoder.Read16(&msg->m_id)) return nullptr;
+      if (!decoder.Read8(&msg->m_flags)) return nullptr;
+      break;
+    }
+    case kEntryDelete: {
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received ENTRY_DELETE in protocol < 3.0");
+        return nullptr;
+      }
+      if (!decoder.Read16(&msg->m_id)) return nullptr;
+      break;
+    }
+    case kClearEntries: {
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received CLEAR_ENTRIES in protocol < 3.0");
+        return nullptr;
+      }
+      uint32_t magic;
+      if (!decoder.Read32(&magic)) return nullptr;
+      if (magic != kClearAllMagic) {
+        decoder.set_error(
+            "received incorrect CLEAR_ENTRIES magic value, ignoring");
+        return nullptr;
+      }
+      break;
+    }
+    case kExecuteRpc: {
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received EXECUTE_RPC in protocol < 3.0");
+        return nullptr;
+      }
+      if (!decoder.Read16(&msg->m_id)) return nullptr;
+      if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr;  // uid
+      uint64_t size;
+      if (!decoder.ReadUleb128(&size)) return nullptr;
+      const char* params;
+      if (!decoder.Read(&params, size)) return nullptr;
+      msg->m_str = wpi::StringRef(params, size);
+      break;
+    }
+    case kRpcResponse: {
+      if (decoder.proto_rev() < 0x0300u) {
+        decoder.set_error("received RPC_RESPONSE in protocol < 3.0");
+        return nullptr;
+      }
+      if (!decoder.Read16(&msg->m_id)) return nullptr;
+      if (!decoder.Read16(&msg->m_seq_num_uid)) return nullptr;  // uid
+      uint64_t size;
+      if (!decoder.ReadUleb128(&size)) return nullptr;
+      const char* results;
+      if (!decoder.Read(&results, size)) return nullptr;
+      msg->m_str = wpi::StringRef(results, size);
+      break;
+    }
+    default:
+      decoder.set_error("unrecognized message type");
+      WPI_INFO(decoder.logger(), "unrecognized message type: " << msg_type);
+      return nullptr;
+  }
+  return msg;
+}
+
+std::shared_ptr<Message> Message::ClientHello(wpi::StringRef self_id) {
+  auto msg = std::make_shared<Message>(kClientHello, private_init());
+  msg->m_str = self_id;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::ServerHello(unsigned int flags,
+                                              wpi::StringRef self_id) {
+  auto msg = std::make_shared<Message>(kServerHello, private_init());
+  msg->m_str = self_id;
+  msg->m_flags = flags;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::EntryAssign(wpi::StringRef name,
+                                              unsigned int id,
+                                              unsigned int seq_num,
+                                              std::shared_ptr<Value> value,
+                                              unsigned int flags) {
+  auto msg = std::make_shared<Message>(kEntryAssign, private_init());
+  msg->m_str = name;
+  msg->m_value = value;
+  msg->m_id = id;
+  msg->m_flags = flags;
+  msg->m_seq_num_uid = seq_num;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::EntryUpdate(unsigned int id,
+                                              unsigned int seq_num,
+                                              std::shared_ptr<Value> value) {
+  auto msg = std::make_shared<Message>(kEntryUpdate, private_init());
+  msg->m_value = value;
+  msg->m_id = id;
+  msg->m_seq_num_uid = seq_num;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::FlagsUpdate(unsigned int id,
+                                              unsigned int flags) {
+  auto msg = std::make_shared<Message>(kFlagsUpdate, private_init());
+  msg->m_id = id;
+  msg->m_flags = flags;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::EntryDelete(unsigned int id) {
+  auto msg = std::make_shared<Message>(kEntryDelete, private_init());
+  msg->m_id = id;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::ExecuteRpc(unsigned int id, unsigned int uid,
+                                             wpi::StringRef params) {
+  auto msg = std::make_shared<Message>(kExecuteRpc, private_init());
+  msg->m_str = params;
+  msg->m_id = id;
+  msg->m_seq_num_uid = uid;
+  return msg;
+}
+
+std::shared_ptr<Message> Message::RpcResponse(unsigned int id, unsigned int uid,
+                                              wpi::StringRef result) {
+  auto msg = std::make_shared<Message>(kRpcResponse, private_init());
+  msg->m_str = result;
+  msg->m_id = id;
+  msg->m_seq_num_uid = uid;
+  return msg;
+}
+
+void Message::Write(WireEncoder& encoder) const {
+  switch (m_type) {
+    case kKeepAlive:
+      encoder.Write8(kKeepAlive);
+      break;
+    case kClientHello:
+      encoder.Write8(kClientHello);
+      encoder.Write16(encoder.proto_rev());
+      if (encoder.proto_rev() < 0x0300u) return;
+      encoder.WriteString(m_str);
+      break;
+    case kProtoUnsup:
+      encoder.Write8(kProtoUnsup);
+      encoder.Write16(encoder.proto_rev());
+      break;
+    case kServerHelloDone:
+      encoder.Write8(kServerHelloDone);
+      break;
+    case kServerHello:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kServerHello);
+      encoder.Write8(m_flags);
+      encoder.WriteString(m_str);
+      break;
+    case kClientHelloDone:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kClientHelloDone);
+      break;
+    case kEntryAssign:
+      encoder.Write8(kEntryAssign);
+      encoder.WriteString(m_str);
+      encoder.WriteType(m_value->type());
+      encoder.Write16(m_id);
+      encoder.Write16(m_seq_num_uid);
+      if (encoder.proto_rev() >= 0x0300u) encoder.Write8(m_flags);
+      encoder.WriteValue(*m_value);
+      break;
+    case kEntryUpdate:
+      encoder.Write8(kEntryUpdate);
+      encoder.Write16(m_id);
+      encoder.Write16(m_seq_num_uid);
+      if (encoder.proto_rev() >= 0x0300u) encoder.WriteType(m_value->type());
+      encoder.WriteValue(*m_value);
+      break;
+    case kFlagsUpdate:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kFlagsUpdate);
+      encoder.Write16(m_id);
+      encoder.Write8(m_flags);
+      break;
+    case kEntryDelete:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kEntryDelete);
+      encoder.Write16(m_id);
+      break;
+    case kClearEntries:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kClearEntries);
+      encoder.Write32(kClearAllMagic);
+      break;
+    case kExecuteRpc:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kExecuteRpc);
+      encoder.Write16(m_id);
+      encoder.Write16(m_seq_num_uid);
+      encoder.WriteString(m_str);
+      break;
+    case kRpcResponse:
+      if (encoder.proto_rev() < 0x0300u) return;  // new message in version 3.0
+      encoder.Write8(kRpcResponse);
+      encoder.Write16(m_id);
+      encoder.Write16(m_seq_num_uid);
+      encoder.WriteString(m_str);
+      break;
+    default:
+      break;
+  }
+}
diff --git a/ntcore/src/main/native/cpp/Message.h b/ntcore/src/main/native/cpp/Message.h
new file mode 100644
index 0000000..9b25abf
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Message.h
@@ -0,0 +1,117 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MESSAGE_H_
+#define NTCORE_MESSAGE_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "networktables/NetworkTableValue.h"
+
+namespace nt {
+
+class WireDecoder;
+class WireEncoder;
+
+class Message {
+  struct private_init {};
+
+ public:
+  enum MsgType {
+    kUnknown = -1,
+    kKeepAlive = 0x00,
+    kClientHello = 0x01,
+    kProtoUnsup = 0x02,
+    kServerHelloDone = 0x03,
+    kServerHello = 0x04,
+    kClientHelloDone = 0x05,
+    kEntryAssign = 0x10,
+    kEntryUpdate = 0x11,
+    kFlagsUpdate = 0x12,
+    kEntryDelete = 0x13,
+    kClearEntries = 0x14,
+    kExecuteRpc = 0x20,
+    kRpcResponse = 0x21
+  };
+  typedef std::function<NT_Type(unsigned int id)> GetEntryTypeFunc;
+
+  Message() : m_type(kUnknown), m_id(0), m_flags(0), m_seq_num_uid(0) {}
+  Message(MsgType type, const private_init&)
+      : m_type(type), m_id(0), m_flags(0), m_seq_num_uid(0) {}
+
+  MsgType type() const { return m_type; }
+  bool Is(MsgType type) const { return type == m_type; }
+
+  // Message data accessors.  Callers are responsible for knowing what data is
+  // actually provided for a particular message.
+  wpi::StringRef str() const { return m_str; }
+  std::shared_ptr<Value> value() const { return m_value; }
+  unsigned int id() const { return m_id; }
+  unsigned int flags() const { return m_flags; }
+  unsigned int seq_num_uid() const { return m_seq_num_uid; }
+
+  // Read and write from wire representation
+  void Write(WireEncoder& encoder) const;
+  static std::shared_ptr<Message> Read(WireDecoder& decoder,
+                                       GetEntryTypeFunc get_entry_type);
+
+  // Create messages without data
+  static std::shared_ptr<Message> KeepAlive() {
+    return std::make_shared<Message>(kKeepAlive, private_init());
+  }
+  static std::shared_ptr<Message> ProtoUnsup() {
+    return std::make_shared<Message>(kProtoUnsup, private_init());
+  }
+  static std::shared_ptr<Message> ServerHelloDone() {
+    return std::make_shared<Message>(kServerHelloDone, private_init());
+  }
+  static std::shared_ptr<Message> ClientHelloDone() {
+    return std::make_shared<Message>(kClientHelloDone, private_init());
+  }
+  static std::shared_ptr<Message> ClearEntries() {
+    return std::make_shared<Message>(kClearEntries, private_init());
+  }
+
+  // Create messages with data
+  static std::shared_ptr<Message> ClientHello(wpi::StringRef self_id);
+  static std::shared_ptr<Message> ServerHello(unsigned int flags,
+                                              wpi::StringRef self_id);
+  static std::shared_ptr<Message> EntryAssign(wpi::StringRef name,
+                                              unsigned int id,
+                                              unsigned int seq_num,
+                                              std::shared_ptr<Value> value,
+                                              unsigned int flags);
+  static std::shared_ptr<Message> EntryUpdate(unsigned int id,
+                                              unsigned int seq_num,
+                                              std::shared_ptr<Value> value);
+  static std::shared_ptr<Message> FlagsUpdate(unsigned int id,
+                                              unsigned int flags);
+  static std::shared_ptr<Message> EntryDelete(unsigned int id);
+  static std::shared_ptr<Message> ExecuteRpc(unsigned int id, unsigned int uid,
+                                             wpi::StringRef params);
+  static std::shared_ptr<Message> RpcResponse(unsigned int id, unsigned int uid,
+                                              wpi::StringRef result);
+
+  Message(const Message&) = delete;
+  Message& operator=(const Message&) = delete;
+
+ private:
+  MsgType m_type;
+
+  // Message data.  Use varies by message type.
+  std::string m_str;
+  std::shared_ptr<Value> m_value;
+  unsigned int m_id;  // also used for proto_rev
+  unsigned int m_flags;
+  unsigned int m_seq_num_uid;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_MESSAGE_H_
diff --git a/ntcore/src/main/native/cpp/NetworkConnection.cpp b/ntcore/src/main/native/cpp/NetworkConnection.cpp
new file mode 100644
index 0000000..8cc8312
--- /dev/null
+++ b/ntcore/src/main/native/cpp/NetworkConnection.cpp
@@ -0,0 +1,334 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "NetworkConnection.h"
+
+#include <wpi/NetworkStream.h>
+#include <wpi/raw_socket_istream.h>
+#include <wpi/timestamp.h>
+
+#include "IConnectionNotifier.h"
+#include "Log.h"
+#include "WireDecoder.h"
+#include "WireEncoder.h"
+
+using namespace nt;
+
+NetworkConnection::NetworkConnection(unsigned int uid,
+                                     std::unique_ptr<wpi::NetworkStream> stream,
+                                     IConnectionNotifier& notifier,
+                                     wpi::Logger& logger,
+                                     HandshakeFunc handshake,
+                                     Message::GetEntryTypeFunc get_entry_type)
+    : m_uid(uid),
+      m_stream(std::move(stream)),
+      m_notifier(notifier),
+      m_logger(logger),
+      m_handshake(handshake),
+      m_get_entry_type(get_entry_type),
+      m_state(kCreated) {
+  m_active = false;
+  m_proto_rev = 0x0300;
+  m_last_update = 0;
+
+  // turn off Nagle algorithm; we bundle packets for transmission
+  m_stream->setNoDelay();
+}
+
+NetworkConnection::~NetworkConnection() { Stop(); }
+
+void NetworkConnection::Start() {
+  if (m_active) return;
+  m_active = true;
+  set_state(kInit);
+  // clear queue
+  while (!m_outgoing.empty()) m_outgoing.pop();
+  // reset shutdown flags
+  {
+    std::scoped_lock lock(m_shutdown_mutex);
+    m_read_shutdown = false;
+    m_write_shutdown = false;
+  }
+  // start threads
+  m_write_thread = std::thread(&NetworkConnection::WriteThreadMain, this);
+  m_read_thread = std::thread(&NetworkConnection::ReadThreadMain, this);
+}
+
+void NetworkConnection::Stop() {
+  DEBUG2("NetworkConnection stopping (" << this << ")");
+  set_state(kDead);
+  m_active = false;
+  // closing the stream so the read thread terminates
+  if (m_stream) m_stream->close();
+  // send an empty outgoing message set so the write thread terminates
+  m_outgoing.push(Outgoing());
+  // wait for threads to terminate, with timeout
+  if (m_write_thread.joinable()) {
+    std::unique_lock lock(m_shutdown_mutex);
+    auto timeout_time =
+        std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
+    if (m_write_shutdown_cv.wait_until(lock, timeout_time,
+                                       [&] { return m_write_shutdown; }))
+      m_write_thread.join();
+    else
+      m_write_thread.detach();  // timed out, detach it
+  }
+  if (m_read_thread.joinable()) {
+    std::unique_lock lock(m_shutdown_mutex);
+    auto timeout_time =
+        std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
+    if (m_read_shutdown_cv.wait_until(lock, timeout_time,
+                                      [&] { return m_read_shutdown; }))
+      m_read_thread.join();
+    else
+      m_read_thread.detach();  // timed out, detach it
+  }
+  // clear queue
+  while (!m_outgoing.empty()) m_outgoing.pop();
+}
+
+ConnectionInfo NetworkConnection::info() const {
+  return ConnectionInfo{remote_id(), m_stream->getPeerIP(),
+                        static_cast<unsigned int>(m_stream->getPeerPort()),
+                        m_last_update, m_proto_rev};
+}
+
+unsigned int NetworkConnection::proto_rev() const { return m_proto_rev; }
+
+void NetworkConnection::set_proto_rev(unsigned int proto_rev) {
+  m_proto_rev = proto_rev;
+}
+
+NetworkConnection::State NetworkConnection::state() const {
+  std::scoped_lock lock(m_state_mutex);
+  return m_state;
+}
+
+void NetworkConnection::set_state(State state) {
+  std::scoped_lock lock(m_state_mutex);
+  // Don't update state any more once we've died
+  if (m_state == kDead) return;
+  // One-shot notify state changes
+  if (m_state != kActive && state == kActive)
+    m_notifier.NotifyConnection(true, info());
+  if (m_state != kDead && state == kDead)
+    m_notifier.NotifyConnection(false, info());
+  m_state = state;
+}
+
+std::string NetworkConnection::remote_id() const {
+  std::scoped_lock lock(m_remote_id_mutex);
+  return m_remote_id;
+}
+
+void NetworkConnection::set_remote_id(StringRef remote_id) {
+  std::scoped_lock lock(m_remote_id_mutex);
+  m_remote_id = remote_id;
+}
+
+void NetworkConnection::ReadThreadMain() {
+  wpi::raw_socket_istream is(*m_stream);
+  WireDecoder decoder(is, m_proto_rev, m_logger);
+
+  set_state(kHandshake);
+  if (!m_handshake(*this,
+                   [&] {
+                     decoder.set_proto_rev(m_proto_rev);
+                     auto msg = Message::Read(decoder, m_get_entry_type);
+                     if (!msg && decoder.error())
+                       DEBUG0(
+                           "error reading in handshake: " << decoder.error());
+                     return msg;
+                   },
+                   [&](wpi::ArrayRef<std::shared_ptr<Message>> msgs) {
+                     m_outgoing.emplace(msgs);
+                   })) {
+    set_state(kDead);
+    m_active = false;
+    goto done;
+  }
+
+  set_state(kActive);
+  while (m_active) {
+    if (!m_stream) break;
+    decoder.set_proto_rev(m_proto_rev);
+    decoder.Reset();
+    auto msg = Message::Read(decoder, m_get_entry_type);
+    if (!msg) {
+      if (decoder.error()) INFO("read error: " << decoder.error());
+      // terminate connection on bad message
+      if (m_stream) m_stream->close();
+      break;
+    }
+    DEBUG3("received type=" << msg->type() << " with str=" << msg->str()
+                            << " id=" << msg->id()
+                            << " seq_num=" << msg->seq_num_uid());
+    m_last_update = Now();
+    m_process_incoming(std::move(msg), this);
+  }
+  DEBUG2("read thread died (" << this << ")");
+  set_state(kDead);
+  m_active = false;
+  m_outgoing.push(Outgoing());  // also kill write thread
+
+done:
+  // use condition variable to signal thread shutdown
+  {
+    std::scoped_lock lock(m_shutdown_mutex);
+    m_read_shutdown = true;
+    m_read_shutdown_cv.notify_one();
+  }
+}
+
+void NetworkConnection::WriteThreadMain() {
+  WireEncoder encoder(m_proto_rev);
+
+  while (m_active) {
+    auto msgs = m_outgoing.pop();
+    DEBUG4("write thread woke up");
+    if (msgs.empty()) continue;
+    encoder.set_proto_rev(m_proto_rev);
+    encoder.Reset();
+    DEBUG3("sending " << msgs.size() << " messages");
+    for (auto& msg : msgs) {
+      if (msg) {
+        DEBUG3("sending type=" << msg->type() << " with str=" << msg->str()
+                               << " id=" << msg->id()
+                               << " seq_num=" << msg->seq_num_uid());
+        msg->Write(encoder);
+      }
+    }
+    wpi::NetworkStream::Error err;
+    if (!m_stream) break;
+    if (encoder.size() == 0) continue;
+    if (m_stream->send(encoder.data(), encoder.size(), &err) == 0) break;
+    DEBUG4("sent " << encoder.size() << " bytes");
+  }
+  DEBUG2("write thread died (" << this << ")");
+  set_state(kDead);
+  m_active = false;
+  if (m_stream) m_stream->close();  // also kill read thread
+
+  // use condition variable to signal thread shutdown
+  {
+    std::scoped_lock lock(m_shutdown_mutex);
+    m_write_shutdown = true;
+    m_write_shutdown_cv.notify_one();
+  }
+}
+
+void NetworkConnection::QueueOutgoing(std::shared_ptr<Message> msg) {
+  std::scoped_lock lock(m_pending_mutex);
+
+  // Merge with previous.  One case we don't combine: delete/assign loop.
+  switch (msg->type()) {
+    case Message::kEntryAssign:
+    case Message::kEntryUpdate: {
+      // don't do this for unassigned id's
+      unsigned int id = msg->id();
+      if (id == 0xffff) {
+        m_pending_outgoing.push_back(msg);
+        break;
+      }
+      if (id < m_pending_update.size() && m_pending_update[id].first != 0) {
+        // overwrite the previous one for this id
+        auto& oldmsg = m_pending_outgoing[m_pending_update[id].first - 1];
+        if (oldmsg && oldmsg->Is(Message::kEntryAssign) &&
+            msg->Is(Message::kEntryUpdate)) {
+          // need to update assignment with new seq_num and value
+          oldmsg = Message::EntryAssign(oldmsg->str(), id, msg->seq_num_uid(),
+                                        msg->value(), oldmsg->flags());
+        } else {
+          oldmsg = msg;  // easy update
+        }
+      } else {
+        // new, but remember it
+        size_t pos = m_pending_outgoing.size();
+        m_pending_outgoing.push_back(msg);
+        if (id >= m_pending_update.size()) m_pending_update.resize(id + 1);
+        m_pending_update[id].first = pos + 1;
+      }
+      break;
+    }
+    case Message::kEntryDelete: {
+      // don't do this for unassigned id's
+      unsigned int id = msg->id();
+      if (id == 0xffff) {
+        m_pending_outgoing.push_back(msg);
+        break;
+      }
+
+      // clear previous updates
+      if (id < m_pending_update.size()) {
+        if (m_pending_update[id].first != 0) {
+          m_pending_outgoing[m_pending_update[id].first - 1].reset();
+          m_pending_update[id].first = 0;
+        }
+        if (m_pending_update[id].second != 0) {
+          m_pending_outgoing[m_pending_update[id].second - 1].reset();
+          m_pending_update[id].second = 0;
+        }
+      }
+
+      // add deletion
+      m_pending_outgoing.push_back(msg);
+      break;
+    }
+    case Message::kFlagsUpdate: {
+      // don't do this for unassigned id's
+      unsigned int id = msg->id();
+      if (id == 0xffff) {
+        m_pending_outgoing.push_back(msg);
+        break;
+      }
+      if (id < m_pending_update.size() && m_pending_update[id].second != 0) {
+        // overwrite the previous one for this id
+        m_pending_outgoing[m_pending_update[id].second - 1] = msg;
+      } else {
+        // new, but remember it
+        size_t pos = m_pending_outgoing.size();
+        m_pending_outgoing.push_back(msg);
+        if (id >= m_pending_update.size()) m_pending_update.resize(id + 1);
+        m_pending_update[id].second = pos + 1;
+      }
+      break;
+    }
+    case Message::kClearEntries: {
+      // knock out all previous assigns/updates!
+      for (auto& i : m_pending_outgoing) {
+        if (!i) continue;
+        auto t = i->type();
+        if (t == Message::kEntryAssign || t == Message::kEntryUpdate ||
+            t == Message::kFlagsUpdate || t == Message::kEntryDelete ||
+            t == Message::kClearEntries)
+          i.reset();
+      }
+      m_pending_update.resize(0);
+      m_pending_outgoing.push_back(msg);
+      break;
+    }
+    default:
+      m_pending_outgoing.push_back(msg);
+      break;
+  }
+}
+
+void NetworkConnection::PostOutgoing(bool keep_alive) {
+  std::scoped_lock lock(m_pending_mutex);
+  auto now = std::chrono::steady_clock::now();
+  if (m_pending_outgoing.empty()) {
+    if (!keep_alive) return;
+    // send keep-alives once a second (if no other messages have been sent)
+    if ((now - m_last_post) < std::chrono::seconds(1)) return;
+    m_outgoing.emplace(Outgoing{Message::KeepAlive()});
+  } else {
+    m_outgoing.emplace(std::move(m_pending_outgoing));
+    m_pending_outgoing.resize(0);
+    m_pending_update.resize(0);
+  }
+  m_last_post = now;
+}
diff --git a/ntcore/src/main/native/cpp/NetworkConnection.h b/ntcore/src/main/native/cpp/NetworkConnection.h
new file mode 100644
index 0000000..91ad64e
--- /dev/null
+++ b/ntcore/src/main/native/cpp/NetworkConnection.h
@@ -0,0 +1,127 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKCONNECTION_H_
+#define NTCORE_NETWORKCONNECTION_H_
+
+#include <stdint.h>
+
+#include <atomic>
+#include <chrono>
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
+
+#include <wpi/ConcurrentQueue.h>
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+
+#include "INetworkConnection.h"
+#include "Message.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class Logger;
+class NetworkStream;
+}  // namespace wpi
+
+namespace nt {
+
+class IConnectionNotifier;
+
+class NetworkConnection : public INetworkConnection {
+ public:
+  typedef std::function<bool(
+      NetworkConnection& conn,
+      std::function<std::shared_ptr<Message>()> get_msg,
+      std::function<void(wpi::ArrayRef<std::shared_ptr<Message>>)> send_msgs)>
+      HandshakeFunc;
+  typedef std::function<void(std::shared_ptr<Message> msg,
+                             NetworkConnection* conn)>
+      ProcessIncomingFunc;
+  typedef std::vector<std::shared_ptr<Message>> Outgoing;
+  typedef wpi::ConcurrentQueue<Outgoing> OutgoingQueue;
+
+  NetworkConnection(unsigned int uid,
+                    std::unique_ptr<wpi::NetworkStream> stream,
+                    IConnectionNotifier& notifier, wpi::Logger& logger,
+                    HandshakeFunc handshake,
+                    Message::GetEntryTypeFunc get_entry_type);
+  ~NetworkConnection();
+
+  // Set the input processor function.  This must be called before Start().
+  void set_process_incoming(ProcessIncomingFunc func) {
+    m_process_incoming = func;
+  }
+
+  void Start();
+  void Stop();
+
+  ConnectionInfo info() const override;
+
+  bool active() const { return m_active; }
+  wpi::NetworkStream& stream() { return *m_stream; }
+
+  void QueueOutgoing(std::shared_ptr<Message> msg) override;
+  void PostOutgoing(bool keep_alive) override;
+
+  unsigned int uid() const { return m_uid; }
+
+  unsigned int proto_rev() const override;
+  void set_proto_rev(unsigned int proto_rev) override;
+
+  State state() const override;
+  void set_state(State state) override;
+
+  std::string remote_id() const;
+  void set_remote_id(StringRef remote_id);
+
+  uint64_t last_update() const { return m_last_update; }
+
+  NetworkConnection(const NetworkConnection&) = delete;
+  NetworkConnection& operator=(const NetworkConnection&) = delete;
+
+ private:
+  void ReadThreadMain();
+  void WriteThreadMain();
+
+  unsigned int m_uid;
+  std::unique_ptr<wpi::NetworkStream> m_stream;
+  IConnectionNotifier& m_notifier;
+  wpi::Logger& m_logger;
+  OutgoingQueue m_outgoing;
+  HandshakeFunc m_handshake;
+  Message::GetEntryTypeFunc m_get_entry_type;
+  ProcessIncomingFunc m_process_incoming;
+  std::thread m_read_thread;
+  std::thread m_write_thread;
+  std::atomic_bool m_active;
+  std::atomic_uint m_proto_rev;
+  mutable wpi::mutex m_state_mutex;
+  State m_state;
+  mutable wpi::mutex m_remote_id_mutex;
+  std::string m_remote_id;
+  std::atomic_ullong m_last_update;
+  std::chrono::steady_clock::time_point m_last_post;
+
+  wpi::mutex m_pending_mutex;
+  Outgoing m_pending_outgoing;
+  std::vector<std::pair<size_t, size_t>> m_pending_update;
+
+  // Condition variables for shutdown
+  wpi::mutex m_shutdown_mutex;
+  wpi::condition_variable m_read_shutdown_cv;
+  wpi::condition_variable m_write_shutdown_cv;
+  bool m_read_shutdown = false;
+  bool m_write_shutdown = false;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_NETWORKCONNECTION_H_
diff --git a/ntcore/src/main/native/cpp/RpcServer.cpp b/ntcore/src/main/native/cpp/RpcServer.cpp
new file mode 100644
index 0000000..0c6811c
--- /dev/null
+++ b/ntcore/src/main/native/cpp/RpcServer.cpp
@@ -0,0 +1,49 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "RpcServer.h"
+
+using namespace nt;
+
+RpcServer::RpcServer(int inst, wpi::Logger& logger)
+    : m_inst(inst), m_logger(logger) {}
+
+void RpcServer::Start() { DoStart(m_inst, m_logger); }
+
+unsigned int RpcServer::Add(
+    std::function<void(const RpcAnswer& answer)> callback) {
+  return DoAdd(callback);
+}
+
+unsigned int RpcServer::AddPolled(unsigned int poller_uid) {
+  return DoAdd(poller_uid);
+}
+
+void RpcServer::RemoveRpc(unsigned int rpc_uid) { Remove(rpc_uid); }
+
+void RpcServer::ProcessRpc(unsigned int local_id, unsigned int call_uid,
+                           StringRef name, StringRef params,
+                           const ConnectionInfo& conn,
+                           SendResponseFunc send_response,
+                           unsigned int rpc_uid) {
+  Send(rpc_uid, Handle(m_inst, local_id, Handle::kEntry).handle(),
+       Handle(m_inst, call_uid, Handle::kRpcCall).handle(), name, params, conn,
+       send_response);
+}
+
+bool RpcServer::PostRpcResponse(unsigned int local_id, unsigned int call_uid,
+                                wpi::StringRef result) {
+  auto thr = GetThread();
+  auto i = thr->m_response_map.find(impl::RpcIdPair{local_id, call_uid});
+  if (i == thr->m_response_map.end()) {
+    WARNING("posting RPC response to nonexistent call (or duplicate response)");
+    return false;
+  }
+  (i->getSecond())(result);
+  thr->m_response_map.erase(i);
+  return true;
+}
diff --git a/ntcore/src/main/native/cpp/RpcServer.h b/ntcore/src/main/native/cpp/RpcServer.h
new file mode 100644
index 0000000..cca490f
--- /dev/null
+++ b/ntcore/src/main/native/cpp/RpcServer.h
@@ -0,0 +1,113 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_RPCSERVER_H_
+#define NTCORE_RPCSERVER_H_
+
+#include <utility>
+
+#include <wpi/DenseMap.h>
+#include <wpi/mutex.h>
+
+#include "CallbackManager.h"
+#include "Handle.h"
+#include "IRpcServer.h"
+#include "Log.h"
+
+namespace nt {
+
+namespace impl {
+
+typedef std::pair<unsigned int, unsigned int> RpcIdPair;
+
+struct RpcNotifierData : public RpcAnswer {
+  RpcNotifierData(NT_Entry entry_, NT_RpcCall call_, StringRef name_,
+                  StringRef params_, const ConnectionInfo& conn_,
+                  IRpcServer::SendResponseFunc send_response_)
+      : RpcAnswer{entry_, call_, name_, params_, conn_},
+        send_response{send_response_} {}
+
+  IRpcServer::SendResponseFunc send_response;
+};
+
+using RpcListenerData =
+    ListenerData<std::function<void(const RpcAnswer& answer)>>;
+
+class RpcServerThread
+    : public CallbackThread<RpcServerThread, RpcAnswer, RpcListenerData,
+                            RpcNotifierData> {
+ public:
+  RpcServerThread(int inst, wpi::Logger& logger)
+      : m_inst(inst), m_logger(logger) {}
+
+  bool Matches(const RpcListenerData& /*listener*/,
+               const RpcNotifierData& data) {
+    return !data.name.empty() && data.send_response;
+  }
+
+  void SetListener(RpcNotifierData* data, unsigned int /*listener_uid*/) {
+    unsigned int local_id = Handle{data->entry}.GetIndex();
+    unsigned int call_uid = Handle{data->call}.GetIndex();
+    RpcIdPair lookup_uid{local_id, call_uid};
+    m_response_map.insert(std::make_pair(lookup_uid, data->send_response));
+  }
+
+  void DoCallback(std::function<void(const RpcAnswer& call)> callback,
+                  const RpcNotifierData& data) {
+    DEBUG4("rpc calling " << data.name);
+    unsigned int local_id = Handle{data.entry}.GetIndex();
+    unsigned int call_uid = Handle{data.call}.GetIndex();
+    RpcIdPair lookup_uid{local_id, call_uid};
+    callback(data);
+    {
+      std::scoped_lock lock(m_mutex);
+      auto i = m_response_map.find(lookup_uid);
+      if (i != m_response_map.end()) {
+        // post an empty response and erase it
+        (i->getSecond())("");
+        m_response_map.erase(i);
+      }
+    }
+  }
+
+  int m_inst;
+  wpi::Logger& m_logger;
+  wpi::DenseMap<RpcIdPair, IRpcServer::SendResponseFunc> m_response_map;
+};
+
+}  // namespace impl
+
+class RpcServer : public IRpcServer,
+                  public CallbackManager<RpcServer, impl::RpcServerThread> {
+  friend class RpcServerTest;
+  friend class CallbackManager<RpcServer, impl::RpcServerThread>;
+
+ public:
+  RpcServer(int inst, wpi::Logger& logger);
+
+  void Start();
+
+  unsigned int Add(std::function<void(const RpcAnswer& answer)> callback);
+  unsigned int AddPolled(unsigned int poller_uid);
+  void RemoveRpc(unsigned int rpc_uid) override;
+
+  void ProcessRpc(unsigned int local_id, unsigned int call_uid, StringRef name,
+                  StringRef params, const ConnectionInfo& conn,
+                  SendResponseFunc send_response,
+                  unsigned int rpc_uid) override;
+
+  bool PostRpcResponse(unsigned int local_id, unsigned int call_uid,
+                       wpi::StringRef result);
+
+ private:
+  int m_inst;
+  wpi::Logger& m_logger;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_RPCSERVER_H_
diff --git a/ntcore/src/main/native/cpp/SequenceNumber.cpp b/ntcore/src/main/native/cpp/SequenceNumber.cpp
new file mode 100644
index 0000000..6d61331
--- /dev/null
+++ b/ntcore/src/main/native/cpp/SequenceNumber.cpp
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "SequenceNumber.h"
+
+namespace nt {
+
+bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs) {
+  if (lhs.m_value < rhs.m_value)
+    return (rhs.m_value - lhs.m_value) < (1u << 15);
+  else if (lhs.m_value > rhs.m_value)
+    return (lhs.m_value - rhs.m_value) > (1u << 15);
+  else
+    return false;
+}
+
+bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs) {
+  if (lhs.m_value < rhs.m_value)
+    return (rhs.m_value - lhs.m_value) > (1u << 15);
+  else if (lhs.m_value > rhs.m_value)
+    return (lhs.m_value - rhs.m_value) < (1u << 15);
+  else
+    return false;
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/SequenceNumber.h b/ntcore/src/main/native/cpp/SequenceNumber.h
new file mode 100644
index 0000000..11d9953
--- /dev/null
+++ b/ntcore/src/main/native/cpp/SequenceNumber.h
@@ -0,0 +1,63 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_SEQUENCENUMBER_H_
+#define NTCORE_SEQUENCENUMBER_H_
+
+namespace nt {
+
+/* A sequence number per RFC 1982 */
+class SequenceNumber {
+ public:
+  SequenceNumber() : m_value(0) {}
+  explicit SequenceNumber(unsigned int value) : m_value(value) {}
+  unsigned int value() const { return m_value; }
+
+  SequenceNumber& operator++() {
+    ++m_value;
+    if (m_value > 0xffff) m_value = 0;
+    return *this;
+  }
+  SequenceNumber operator++(int) {
+    SequenceNumber tmp(*this);
+    operator++();
+    return tmp;
+  }
+
+  friend bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs);
+  friend bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs);
+  friend bool operator<=(const SequenceNumber& lhs, const SequenceNumber& rhs);
+  friend bool operator>=(const SequenceNumber& lhs, const SequenceNumber& rhs);
+  friend bool operator==(const SequenceNumber& lhs, const SequenceNumber& rhs);
+  friend bool operator!=(const SequenceNumber& lhs, const SequenceNumber& rhs);
+
+ private:
+  unsigned int m_value;
+};
+
+bool operator<(const SequenceNumber& lhs, const SequenceNumber& rhs);
+bool operator>(const SequenceNumber& lhs, const SequenceNumber& rhs);
+
+inline bool operator<=(const SequenceNumber& lhs, const SequenceNumber& rhs) {
+  return lhs == rhs || lhs < rhs;
+}
+
+inline bool operator>=(const SequenceNumber& lhs, const SequenceNumber& rhs) {
+  return lhs == rhs || lhs > rhs;
+}
+
+inline bool operator==(const SequenceNumber& lhs, const SequenceNumber& rhs) {
+  return lhs.m_value == rhs.m_value;
+}
+
+inline bool operator!=(const SequenceNumber& lhs, const SequenceNumber& rhs) {
+  return lhs.m_value != rhs.m_value;
+}
+
+}  // namespace nt
+
+#endif  // NTCORE_SEQUENCENUMBER_H_
diff --git a/ntcore/src/main/native/cpp/Storage.cpp b/ntcore/src/main/native/cpp/Storage.cpp
new file mode 100644
index 0000000..cf0d26c
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Storage.cpp
@@ -0,0 +1,1131 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "Storage.h"
+
+#include <wpi/timestamp.h>
+
+#include "Handle.h"
+#include "IDispatcher.h"
+#include "IEntryNotifier.h"
+#include "INetworkConnection.h"
+#include "IRpcServer.h"
+#include "Log.h"
+
+using namespace nt;
+
+Storage::Storage(IEntryNotifier& notifier, IRpcServer& rpc_server,
+                 wpi::Logger& logger)
+    : m_notifier(notifier), m_rpc_server(rpc_server), m_logger(logger) {
+  m_terminating = false;
+}
+
+Storage::~Storage() {
+  m_terminating = true;
+  m_rpc_results_cond.notify_all();
+}
+
+void Storage::SetDispatcher(IDispatcher* dispatcher, bool server) {
+  std::scoped_lock lock(m_mutex);
+  m_dispatcher = dispatcher;
+  m_server = server;
+}
+
+void Storage::ClearDispatcher() { m_dispatcher = nullptr; }
+
+NT_Type Storage::GetMessageEntryType(unsigned int id) const {
+  std::scoped_lock lock(m_mutex);
+  if (id >= m_idmap.size()) return NT_UNASSIGNED;
+  Entry* entry = m_idmap[id];
+  if (!entry || !entry->value) return NT_UNASSIGNED;
+  return entry->value->type();
+}
+
+void Storage::ProcessIncoming(std::shared_ptr<Message> msg,
+                              INetworkConnection* conn,
+                              std::weak_ptr<INetworkConnection> conn_weak) {
+  switch (msg->type()) {
+    case Message::kKeepAlive:
+      break;  // ignore
+    case Message::kClientHello:
+    case Message::kProtoUnsup:
+    case Message::kServerHelloDone:
+    case Message::kServerHello:
+    case Message::kClientHelloDone:
+      // shouldn't get these, but ignore if we do
+      break;
+    case Message::kEntryAssign:
+      ProcessIncomingEntryAssign(std::move(msg), conn);
+      break;
+    case Message::kEntryUpdate:
+      ProcessIncomingEntryUpdate(std::move(msg), conn);
+      break;
+    case Message::kFlagsUpdate:
+      ProcessIncomingFlagsUpdate(std::move(msg), conn);
+      break;
+    case Message::kEntryDelete:
+      ProcessIncomingEntryDelete(std::move(msg), conn);
+      break;
+    case Message::kClearEntries:
+      ProcessIncomingClearEntries(std::move(msg), conn);
+      break;
+    case Message::kExecuteRpc:
+      ProcessIncomingExecuteRpc(std::move(msg), conn, std::move(conn_weak));
+      break;
+    case Message::kRpcResponse:
+      ProcessIncomingRpcResponse(std::move(msg), conn);
+      break;
+    default:
+      break;
+  }
+}
+
+void Storage::ProcessIncomingEntryAssign(std::shared_ptr<Message> msg,
+                                         INetworkConnection* conn) {
+  std::unique_lock lock(m_mutex);
+  unsigned int id = msg->id();
+  StringRef name = msg->str();
+  Entry* entry;
+  bool may_need_update = false;
+  SequenceNumber seq_num(msg->seq_num_uid());
+  if (m_server) {
+    // if we're a server, id=0xffff requests are requests for an id
+    // to be assigned, and we need to send the new assignment back to
+    // the sender as well as all other connections.
+    if (id == 0xffff) {
+      entry = GetOrNew(name);
+      // see if it was already assigned; ignore if so.
+      if (entry->id != 0xffff) return;
+
+      entry->flags = msg->flags();
+      entry->seq_num = seq_num;
+      SetEntryValueImpl(entry, msg->value(), lock, false);
+      return;
+    }
+    if (id >= m_idmap.size() || !m_idmap[id]) {
+      // ignore arbitrary entry assignments
+      // this can happen due to e.g. assignment to deleted entry
+      lock.unlock();
+      DEBUG0("server: received assignment to unknown entry");
+      return;
+    }
+    entry = m_idmap[id];
+  } else {
+    // clients simply accept new assignments
+    if (id == 0xffff) {
+      lock.unlock();
+      DEBUG0("client: received entry assignment request?");
+      return;
+    }
+    if (id >= m_idmap.size()) m_idmap.resize(id + 1);
+    entry = m_idmap[id];
+    if (!entry) {
+      // create local
+      entry = GetOrNew(name);
+      entry->id = id;
+      m_idmap[id] = entry;
+      if (!entry->value) {
+        // didn't exist at all (rather than just being a response to a
+        // id assignment request)
+        entry->value = msg->value();
+        entry->flags = msg->flags();
+        entry->seq_num = seq_num;
+
+        // notify
+        m_notifier.NotifyEntry(entry->local_id, name, entry->value,
+                               NT_NOTIFY_NEW);
+        return;
+      }
+      may_need_update = true;  // we may need to send an update message
+
+      // if the received flags don't match what we sent, we most likely
+      // updated flags locally in the interim; send flags update message.
+      if (msg->flags() != entry->flags) {
+        auto dispatcher = m_dispatcher;
+        auto outmsg = Message::FlagsUpdate(id, entry->flags);
+        lock.unlock();
+        dispatcher->QueueOutgoing(outmsg, nullptr, nullptr);
+        lock.lock();
+      }
+    }
+  }
+
+  // common client and server handling
+
+  // already exists; ignore if sequence number not higher than local
+  if (seq_num < entry->seq_num) {
+    if (may_need_update) {
+      auto dispatcher = m_dispatcher;
+      auto outmsg =
+          Message::EntryUpdate(entry->id, entry->seq_num.value(), entry->value);
+      lock.unlock();
+      dispatcher->QueueOutgoing(outmsg, nullptr, nullptr);
+    }
+    return;
+  }
+
+  // sanity check: name should match id
+  if (msg->str() != entry->name) {
+    lock.unlock();
+    DEBUG0("entry assignment for same id with different name?");
+    return;
+  }
+
+  unsigned int notify_flags = NT_NOTIFY_UPDATE;
+
+  // don't update flags from a <3.0 remote (not part of message)
+  // don't update flags if this is a server response to a client id request
+  if (!may_need_update && conn->proto_rev() >= 0x0300) {
+    // update persistent dirty flag if persistent flag changed
+    if ((entry->flags & NT_PERSISTENT) != (msg->flags() & NT_PERSISTENT))
+      m_persistent_dirty = true;
+    if (entry->flags != msg->flags()) notify_flags |= NT_NOTIFY_FLAGS;
+    entry->flags = msg->flags();
+  }
+
+  // update persistent dirty flag if the value changed and it's persistent
+  if (entry->IsPersistent() && *entry->value != *msg->value())
+    m_persistent_dirty = true;
+
+  // update local
+  entry->value = msg->value();
+  entry->seq_num = seq_num;
+
+  // notify
+  m_notifier.NotifyEntry(entry->local_id, name, entry->value, notify_flags);
+
+  // broadcast to all other connections (note for client there won't
+  // be any other connections, so don't bother)
+  if (m_server && m_dispatcher) {
+    auto dispatcher = m_dispatcher;
+    auto outmsg = Message::EntryAssign(entry->name, id, msg->seq_num_uid(),
+                                       msg->value(), entry->flags);
+    lock.unlock();
+    dispatcher->QueueOutgoing(outmsg, nullptr, conn);
+  }
+}
+
+void Storage::ProcessIncomingEntryUpdate(std::shared_ptr<Message> msg,
+                                         INetworkConnection* conn) {
+  std::unique_lock lock(m_mutex);
+  unsigned int id = msg->id();
+  if (id >= m_idmap.size() || !m_idmap[id]) {
+    // ignore arbitrary entry updates;
+    // this can happen due to deleted entries
+    lock.unlock();
+    DEBUG0("received update to unknown entry");
+    return;
+  }
+  Entry* entry = m_idmap[id];
+
+  // ignore if sequence number not higher than local
+  SequenceNumber seq_num(msg->seq_num_uid());
+  if (seq_num <= entry->seq_num) return;
+
+  // update local
+  entry->value = msg->value();
+  entry->seq_num = seq_num;
+
+  // update persistent dirty flag if it's a persistent value
+  if (entry->IsPersistent()) m_persistent_dirty = true;
+
+  // notify
+  m_notifier.NotifyEntry(entry->local_id, entry->name, entry->value,
+                         NT_NOTIFY_UPDATE);
+
+  // broadcast to all other connections (note for client there won't
+  // be any other connections, so don't bother)
+  if (m_server && m_dispatcher) {
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, conn);
+  }
+}
+
+void Storage::ProcessIncomingFlagsUpdate(std::shared_ptr<Message> msg,
+                                         INetworkConnection* conn) {
+  std::unique_lock lock(m_mutex);
+  unsigned int id = msg->id();
+  if (id >= m_idmap.size() || !m_idmap[id]) {
+    // ignore arbitrary entry updates;
+    // this can happen due to deleted entries
+    lock.unlock();
+    DEBUG0("received flags update to unknown entry");
+    return;
+  }
+
+  // update local
+  SetEntryFlagsImpl(m_idmap[id], msg->flags(), lock, false);
+
+  // broadcast to all other connections (note for client there won't
+  // be any other connections, so don't bother)
+  if (m_server && m_dispatcher) {
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, conn);
+  }
+}
+
+void Storage::ProcessIncomingEntryDelete(std::shared_ptr<Message> msg,
+                                         INetworkConnection* conn) {
+  std::unique_lock lock(m_mutex);
+  unsigned int id = msg->id();
+  if (id >= m_idmap.size() || !m_idmap[id]) {
+    // ignore arbitrary entry updates;
+    // this can happen due to deleted entries
+    lock.unlock();
+    DEBUG0("received delete to unknown entry");
+    return;
+  }
+
+  // update local
+  DeleteEntryImpl(m_idmap[id], lock, false);
+
+  // broadcast to all other connections (note for client there won't
+  // be any other connections, so don't bother)
+  if (m_server && m_dispatcher) {
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, conn);
+  }
+}
+
+void Storage::ProcessIncomingClearEntries(std::shared_ptr<Message> msg,
+                                          INetworkConnection* conn) {
+  std::unique_lock lock(m_mutex);
+  // update local
+  DeleteAllEntriesImpl(false);
+
+  // broadcast to all other connections (note for client there won't
+  // be any other connections, so don't bother)
+  if (m_server && m_dispatcher) {
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, conn);
+  }
+}
+
+void Storage::ProcessIncomingExecuteRpc(
+    std::shared_ptr<Message> msg, INetworkConnection* /*conn*/,
+    std::weak_ptr<INetworkConnection> conn_weak) {
+  std::unique_lock lock(m_mutex);
+  if (!m_server) return;  // only process on server
+  unsigned int id = msg->id();
+  if (id >= m_idmap.size() || !m_idmap[id]) {
+    // ignore call to non-existent RPC
+    // this can happen due to deleted entries
+    lock.unlock();
+    DEBUG0("received RPC call to unknown entry");
+    return;
+  }
+  Entry* entry = m_idmap[id];
+  if (!entry->value || !entry->value->IsRpc()) {
+    lock.unlock();
+    DEBUG0("received RPC call to non-RPC entry");
+    return;
+  }
+  ConnectionInfo conn_info;
+  auto c = conn_weak.lock();
+  if (c) {
+    conn_info = c->info();
+  } else {
+    conn_info.remote_id = "";
+    conn_info.remote_ip = "";
+    conn_info.remote_port = 0;
+    conn_info.last_update = 0;
+    conn_info.protocol_version = 0;
+  }
+  unsigned int call_uid = msg->seq_num_uid();
+  m_rpc_server.ProcessRpc(
+      entry->local_id, call_uid, entry->name, msg->str(), conn_info,
+      [=](StringRef result) {
+        auto c = conn_weak.lock();
+        if (c) c->QueueOutgoing(Message::RpcResponse(id, call_uid, result));
+      },
+      entry->rpc_uid);
+}
+
+void Storage::ProcessIncomingRpcResponse(std::shared_ptr<Message> msg,
+                                         INetworkConnection* /*conn*/) {
+  std::unique_lock lock(m_mutex);
+  if (m_server) return;  // only process on client
+  unsigned int id = msg->id();
+  if (id >= m_idmap.size() || !m_idmap[id]) {
+    // ignore response to non-existent RPC
+    // this can happen due to deleted entries
+    lock.unlock();
+    DEBUG0("received rpc response to unknown entry");
+    return;
+  }
+  Entry* entry = m_idmap[id];
+  if (!entry->value || !entry->value->IsRpc()) {
+    lock.unlock();
+    DEBUG0("received RPC response to non-RPC entry");
+    return;
+  }
+  m_rpc_results.insert(std::make_pair(
+      RpcIdPair{entry->local_id, msg->seq_num_uid()}, msg->str()));
+  m_rpc_results_cond.notify_all();
+}
+
+void Storage::GetInitialAssignments(
+    INetworkConnection& conn, std::vector<std::shared_ptr<Message>>* msgs) {
+  std::scoped_lock lock(m_mutex);
+  conn.set_state(INetworkConnection::kSynchronized);
+  for (auto& i : m_entries) {
+    Entry* entry = i.getValue();
+    if (!entry->value) continue;
+    msgs->emplace_back(Message::EntryAssign(i.getKey(), entry->id,
+                                            entry->seq_num.value(),
+                                            entry->value, entry->flags));
+  }
+}
+
+void Storage::ApplyInitialAssignments(
+    INetworkConnection& conn, wpi::ArrayRef<std::shared_ptr<Message>> msgs,
+    bool /*new_server*/, std::vector<std::shared_ptr<Message>>* out_msgs) {
+  std::unique_lock lock(m_mutex);
+  if (m_server) return;  // should not do this on server
+
+  conn.set_state(INetworkConnection::kSynchronized);
+
+  std::vector<std::shared_ptr<Message>> update_msgs;
+
+  // clear existing id's
+  for (auto& i : m_entries) i.getValue()->id = 0xffff;
+
+  // clear existing idmap
+  m_idmap.resize(0);
+
+  // apply assignments
+  for (auto& msg : msgs) {
+    if (!msg->Is(Message::kEntryAssign)) {
+      DEBUG0("client: received non-entry assignment request?");
+      continue;
+    }
+
+    unsigned int id = msg->id();
+    if (id == 0xffff) {
+      DEBUG0("client: received entry assignment request?");
+      continue;
+    }
+
+    SequenceNumber seq_num(msg->seq_num_uid());
+    StringRef name = msg->str();
+
+    Entry* entry = GetOrNew(name);
+    entry->seq_num = seq_num;
+    entry->id = id;
+    if (!entry->value) {
+      // doesn't currently exist
+      entry->value = msg->value();
+      entry->flags = msg->flags();
+      // notify
+      m_notifier.NotifyEntry(entry->local_id, name, entry->value,
+                             NT_NOTIFY_NEW);
+    } else {
+      // if we have written the value locally and the value is not persistent,
+      // then we don't update the local value and instead send it back to the
+      // server as an update message
+      if (entry->local_write && !entry->IsPersistent()) {
+        ++entry->seq_num;
+        update_msgs.emplace_back(Message::EntryUpdate(
+            entry->id, entry->seq_num.value(), entry->value));
+      } else {
+        entry->value = msg->value();
+        unsigned int notify_flags = NT_NOTIFY_UPDATE;
+        // don't update flags from a <3.0 remote (not part of message)
+        if (conn.proto_rev() >= 0x0300) {
+          if (entry->flags != msg->flags()) notify_flags |= NT_NOTIFY_FLAGS;
+          entry->flags = msg->flags();
+        }
+        // notify
+        m_notifier.NotifyEntry(entry->local_id, name, entry->value,
+                               notify_flags);
+      }
+    }
+
+    // save to idmap
+    if (id >= m_idmap.size()) m_idmap.resize(id + 1);
+    m_idmap[id] = entry;
+  }
+
+  // delete or generate assign messages for unassigned local entries
+  DeleteAllEntriesImpl(false, [&](Entry* entry) -> bool {
+    // was assigned by the server, don't delete
+    if (entry->id != 0xffff) return false;
+    // if we have written the value locally, we send an assign message to the
+    // server instead of deleting
+    if (entry->local_write) {
+      out_msgs->emplace_back(Message::EntryAssign(entry->name, entry->id,
+                                                  entry->seq_num.value(),
+                                                  entry->value, entry->flags));
+      return false;
+    }
+    // otherwise delete
+    return true;
+  });
+  auto dispatcher = m_dispatcher;
+  lock.unlock();
+  for (auto& msg : update_msgs)
+    dispatcher->QueueOutgoing(msg, nullptr, nullptr);
+}
+
+std::shared_ptr<Value> Storage::GetEntryValue(StringRef name) const {
+  std::scoped_lock lock(m_mutex);
+  auto i = m_entries.find(name);
+  if (i == m_entries.end()) return nullptr;
+  return i->getValue()->value;
+}
+
+std::shared_ptr<Value> Storage::GetEntryValue(unsigned int local_id) const {
+  std::scoped_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return nullptr;
+  return m_localmap[local_id]->value;
+}
+
+bool Storage::SetDefaultEntryValue(StringRef name,
+                                   std::shared_ptr<Value> value) {
+  if (name.empty()) return false;
+  if (!value) return false;
+  std::unique_lock lock(m_mutex);
+  Entry* entry = GetOrNew(name);
+
+  // we return early if value already exists; if types match return true
+  if (entry->value) return entry->value->type() == value->type();
+
+  SetEntryValueImpl(entry, value, lock, true);
+  return true;
+}
+
+bool Storage::SetDefaultEntryValue(unsigned int local_id,
+                                   std::shared_ptr<Value> value) {
+  if (!value) return false;
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return false;
+  Entry* entry = m_localmap[local_id].get();
+
+  // we return early if value already exists; if types match return true
+  if (entry->value) return entry->value->type() == value->type();
+
+  SetEntryValueImpl(entry, value, lock, true);
+  return true;
+}
+
+bool Storage::SetEntryValue(StringRef name, std::shared_ptr<Value> value) {
+  if (name.empty()) return true;
+  if (!value) return true;
+  std::unique_lock lock(m_mutex);
+  Entry* entry = GetOrNew(name);
+
+  if (entry->value && entry->value->type() != value->type())
+    return false;  // error on type mismatch
+
+  SetEntryValueImpl(entry, value, lock, true);
+  return true;
+}
+
+bool Storage::SetEntryValue(unsigned int local_id,
+                            std::shared_ptr<Value> value) {
+  if (!value) return true;
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return true;
+  Entry* entry = m_localmap[local_id].get();
+
+  if (entry->value && entry->value->type() != value->type())
+    return false;  // error on type mismatch
+
+  SetEntryValueImpl(entry, value, lock, true);
+  return true;
+}
+
+void Storage::SetEntryValueImpl(Entry* entry, std::shared_ptr<Value> value,
+                                std::unique_lock<wpi::mutex>& lock,
+                                bool local) {
+  if (!value) return;
+  auto old_value = entry->value;
+  entry->value = value;
+
+  // if we're the server, assign an id if it doesn't have one
+  if (m_server && entry->id == 0xffff) {
+    unsigned int id = m_idmap.size();
+    entry->id = id;
+    m_idmap.push_back(entry);
+  }
+
+  // update persistent dirty flag if value changed and it's persistent
+  if (entry->IsPersistent() && (!old_value || *old_value != *value))
+    m_persistent_dirty = true;
+
+  // notify
+  if (!old_value)
+    m_notifier.NotifyEntry(entry->local_id, entry->name, value,
+                           NT_NOTIFY_NEW | (local ? NT_NOTIFY_LOCAL : 0));
+  else if (*old_value != *value)
+    m_notifier.NotifyEntry(entry->local_id, entry->name, value,
+                           NT_NOTIFY_UPDATE | (local ? NT_NOTIFY_LOCAL : 0));
+
+  // remember local changes
+  if (local) entry->local_write = true;
+
+  // generate message
+  if (!m_dispatcher || (!local && !m_server)) return;
+  auto dispatcher = m_dispatcher;
+  if (!old_value || old_value->type() != value->type()) {
+    if (local) ++entry->seq_num;
+    auto msg = Message::EntryAssign(
+        entry->name, entry->id, entry->seq_num.value(), value, entry->flags);
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, nullptr);
+  } else if (*old_value != *value) {
+    if (local) ++entry->seq_num;
+    // don't send an update if we don't have an assigned id yet
+    if (entry->id != 0xffff) {
+      auto msg = Message::EntryUpdate(entry->id, entry->seq_num.value(), value);
+      lock.unlock();
+      dispatcher->QueueOutgoing(msg, nullptr, nullptr);
+    }
+  }
+}
+
+void Storage::SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value) {
+  if (name.empty()) return;
+  if (!value) return;
+  std::unique_lock lock(m_mutex);
+  Entry* entry = GetOrNew(name);
+
+  SetEntryValueImpl(entry, value, lock, true);
+}
+
+void Storage::SetEntryTypeValue(unsigned int local_id,
+                                std::shared_ptr<Value> value) {
+  if (!value) return;
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return;
+  Entry* entry = m_localmap[local_id].get();
+  if (!entry) return;
+
+  SetEntryValueImpl(entry, value, lock, true);
+}
+
+void Storage::SetEntryFlags(StringRef name, unsigned int flags) {
+  if (name.empty()) return;
+  std::unique_lock lock(m_mutex);
+  auto i = m_entries.find(name);
+  if (i == m_entries.end()) return;
+  SetEntryFlagsImpl(i->getValue(), flags, lock, true);
+}
+
+void Storage::SetEntryFlags(unsigned int id_local, unsigned int flags) {
+  std::unique_lock lock(m_mutex);
+  if (id_local >= m_localmap.size()) return;
+  SetEntryFlagsImpl(m_localmap[id_local].get(), flags, lock, true);
+}
+
+void Storage::SetEntryFlagsImpl(Entry* entry, unsigned int flags,
+                                std::unique_lock<wpi::mutex>& lock,
+                                bool local) {
+  if (!entry->value || entry->flags == flags) return;
+
+  // update persistent dirty flag if persistent flag changed
+  if ((entry->flags & NT_PERSISTENT) != (flags & NT_PERSISTENT))
+    m_persistent_dirty = true;
+
+  entry->flags = flags;
+
+  // notify
+  m_notifier.NotifyEntry(entry->local_id, entry->name, entry->value,
+                         NT_NOTIFY_FLAGS | (local ? NT_NOTIFY_LOCAL : 0));
+
+  // generate message
+  if (!local || !m_dispatcher) return;
+  auto dispatcher = m_dispatcher;
+  unsigned int id = entry->id;
+  // don't send an update if we don't have an assigned id yet
+  if (id != 0xffff) {
+    lock.unlock();
+    dispatcher->QueueOutgoing(Message::FlagsUpdate(id, flags), nullptr,
+                              nullptr);
+  }
+}
+
+unsigned int Storage::GetEntryFlags(StringRef name) const {
+  std::scoped_lock lock(m_mutex);
+  auto i = m_entries.find(name);
+  if (i == m_entries.end()) return 0;
+  return i->getValue()->flags;
+}
+
+unsigned int Storage::GetEntryFlags(unsigned int local_id) const {
+  std::scoped_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return 0;
+  return m_localmap[local_id]->flags;
+}
+
+void Storage::DeleteEntry(StringRef name) {
+  std::unique_lock lock(m_mutex);
+  auto i = m_entries.find(name);
+  if (i == m_entries.end()) return;
+  DeleteEntryImpl(i->getValue(), lock, true);
+}
+
+void Storage::DeleteEntry(unsigned int local_id) {
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return;
+  DeleteEntryImpl(m_localmap[local_id].get(), lock, true);
+}
+
+void Storage::DeleteEntryImpl(Entry* entry, std::unique_lock<wpi::mutex>& lock,
+                              bool local) {
+  unsigned int id = entry->id;
+
+  // Erase entry from id mapping.
+  if (id < m_idmap.size()) m_idmap[id] = nullptr;
+
+  // empty the value and reset id and local_write flag
+  std::shared_ptr<Value> old_value;
+  old_value.swap(entry->value);
+  entry->id = 0xffff;
+  entry->local_write = false;
+
+  // remove RPC if there was one
+  if (entry->rpc_uid != UINT_MAX) {
+    m_rpc_server.RemoveRpc(entry->rpc_uid);
+    entry->rpc_uid = UINT_MAX;
+  }
+
+  // update persistent dirty flag if it's a persistent value
+  if (entry->IsPersistent()) m_persistent_dirty = true;
+
+  // reset flags
+  entry->flags = 0;
+
+  if (!old_value) return;  // was not previously assigned
+
+  // notify
+  m_notifier.NotifyEntry(entry->local_id, entry->name, old_value,
+                         NT_NOTIFY_DELETE | (local ? NT_NOTIFY_LOCAL : 0));
+
+  // if it had a value, generate message
+  // don't send an update if we don't have an assigned id yet
+  if (local && id != 0xffff) {
+    if (!m_dispatcher) return;
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    dispatcher->QueueOutgoing(Message::EntryDelete(id), nullptr, nullptr);
+  }
+}
+
+template <typename F>
+void Storage::DeleteAllEntriesImpl(bool local, F should_delete) {
+  for (auto& i : m_entries) {
+    Entry* entry = i.getValue();
+    if (entry->value && should_delete(entry)) {
+      // notify it's being deleted
+      m_notifier.NotifyEntry(entry->local_id, i.getKey(), entry->value,
+                             NT_NOTIFY_DELETE | (local ? NT_NOTIFY_LOCAL : 0));
+      // remove it from idmap
+      if (entry->id < m_idmap.size()) m_idmap[entry->id] = nullptr;
+      entry->id = 0xffff;
+      entry->local_write = false;
+      entry->value.reset();
+      continue;
+    }
+  }
+}
+
+void Storage::DeleteAllEntriesImpl(bool local) {
+  // only delete non-persistent values
+  DeleteAllEntriesImpl(local,
+                       [](Entry* entry) { return !entry->IsPersistent(); });
+}
+
+void Storage::DeleteAllEntries() {
+  std::unique_lock lock(m_mutex);
+  if (m_entries.empty()) return;
+
+  DeleteAllEntriesImpl(true);
+
+  // generate message
+  if (!m_dispatcher) return;
+  auto dispatcher = m_dispatcher;
+  lock.unlock();
+  dispatcher->QueueOutgoing(Message::ClearEntries(), nullptr, nullptr);
+}
+
+Storage::Entry* Storage::GetOrNew(const Twine& name) {
+  wpi::SmallString<128> nameBuf;
+  StringRef nameStr = name.toStringRef(nameBuf);
+  auto& entry = m_entries[nameStr];
+  if (!entry) {
+    m_localmap.emplace_back(new Entry(nameStr));
+    entry = m_localmap.back().get();
+    entry->local_id = m_localmap.size() - 1;
+  }
+  return entry;
+}
+
+unsigned int Storage::GetEntry(const Twine& name) {
+  if (name.isTriviallyEmpty() ||
+      (name.isSingleStringRef() && name.getSingleStringRef().empty()))
+    return UINT_MAX;
+  std::unique_lock lock(m_mutex);
+  return GetOrNew(name)->local_id;
+}
+
+std::vector<unsigned int> Storage::GetEntries(const Twine& prefix,
+                                              unsigned int types) {
+  wpi::SmallString<128> prefixBuf;
+  StringRef prefixStr = prefix.toStringRef(prefixBuf);
+  std::scoped_lock lock(m_mutex);
+  std::vector<unsigned int> ids;
+  for (auto& i : m_entries) {
+    Entry* entry = i.getValue();
+    auto value = entry->value.get();
+    if (!value || !i.getKey().startswith(prefixStr)) continue;
+    if (types != 0 && (types & value->type()) == 0) continue;
+    ids.push_back(entry->local_id);
+  }
+  return ids;
+}
+
+EntryInfo Storage::GetEntryInfo(int inst, unsigned int local_id) const {
+  EntryInfo info;
+  info.entry = 0;
+  info.type = NT_UNASSIGNED;
+  info.flags = 0;
+  info.last_change = 0;
+
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return info;
+  Entry* entry = m_localmap[local_id].get();
+  if (!entry->value) return info;
+
+  info.entry = Handle(inst, local_id, Handle::kEntry);
+  info.name = entry->name;
+  info.type = entry->value->type();
+  info.flags = entry->flags;
+  info.last_change = entry->value->last_change();
+  return info;
+}
+
+std::string Storage::GetEntryName(unsigned int local_id) const {
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return std::string{};
+  return m_localmap[local_id]->name;
+}
+
+NT_Type Storage::GetEntryType(unsigned int local_id) const {
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return NT_UNASSIGNED;
+  Entry* entry = m_localmap[local_id].get();
+  if (!entry->value) return NT_UNASSIGNED;
+  return entry->value->type();
+}
+
+uint64_t Storage::GetEntryLastChange(unsigned int local_id) const {
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return 0;
+  Entry* entry = m_localmap[local_id].get();
+  if (!entry->value) return 0;
+  return entry->value->last_change();
+}
+
+std::vector<EntryInfo> Storage::GetEntryInfo(int inst, const Twine& prefix,
+                                             unsigned int types) {
+  wpi::SmallString<128> prefixBuf;
+  StringRef prefixStr = prefix.toStringRef(prefixBuf);
+  std::scoped_lock lock(m_mutex);
+  std::vector<EntryInfo> infos;
+  for (auto& i : m_entries) {
+    Entry* entry = i.getValue();
+    auto value = entry->value.get();
+    if (!value || !i.getKey().startswith(prefixStr)) continue;
+    if (types != 0 && (types & value->type()) == 0) continue;
+    EntryInfo info;
+    info.entry = Handle(inst, entry->local_id, Handle::kEntry);
+    info.name = i.getKey();
+    info.type = value->type();
+    info.flags = entry->flags;
+    info.last_change = value->last_change();
+    infos.push_back(std::move(info));
+  }
+  return infos;
+}
+
+unsigned int Storage::AddListener(
+    const Twine& prefix,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags) const {
+  wpi::SmallString<128> prefixBuf;
+  StringRef prefixStr = prefix.toStringRef(prefixBuf);
+  std::scoped_lock lock(m_mutex);
+  unsigned int uid = m_notifier.Add(callback, prefixStr, flags);
+  // perform immediate notifications
+  if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0) {
+    for (auto& i : m_entries) {
+      Entry* entry = i.getValue();
+      if (!entry->value || !i.getKey().startswith(prefixStr)) continue;
+      m_notifier.NotifyEntry(entry->local_id, i.getKey(), entry->value,
+                             NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, uid);
+    }
+  }
+  return uid;
+}
+
+unsigned int Storage::AddListener(
+    unsigned int local_id,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags) const {
+  std::scoped_lock lock(m_mutex);
+  unsigned int uid = m_notifier.Add(callback, local_id, flags);
+  // perform immediate notifications
+  if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0 &&
+      local_id < m_localmap.size()) {
+    Entry* entry = m_localmap[local_id].get();
+    if (entry->value) {
+      m_notifier.NotifyEntry(local_id, entry->name, entry->value,
+                             NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, uid);
+    }
+  }
+  return uid;
+}
+
+unsigned int Storage::AddPolledListener(unsigned int poller,
+                                        const Twine& prefix,
+                                        unsigned int flags) const {
+  wpi::SmallString<128> prefixBuf;
+  StringRef prefixStr = prefix.toStringRef(prefixBuf);
+  std::scoped_lock lock(m_mutex);
+  unsigned int uid = m_notifier.AddPolled(poller, prefixStr, flags);
+  // perform immediate notifications
+  if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0) {
+    for (auto& i : m_entries) {
+      if (!i.getKey().startswith(prefixStr)) continue;
+      Entry* entry = i.getValue();
+      if (!entry->value) continue;
+      m_notifier.NotifyEntry(entry->local_id, i.getKey(), entry->value,
+                             NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, uid);
+    }
+  }
+  return uid;
+}
+
+unsigned int Storage::AddPolledListener(unsigned int poller,
+                                        unsigned int local_id,
+                                        unsigned int flags) const {
+  std::scoped_lock lock(m_mutex);
+  unsigned int uid = m_notifier.AddPolled(poller, local_id, flags);
+  // perform immediate notifications
+  if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0 &&
+      local_id < m_localmap.size()) {
+    Entry* entry = m_localmap[local_id].get();
+    // if no value, don't notify
+    if (entry->value) {
+      m_notifier.NotifyEntry(local_id, entry->name, entry->value,
+                             NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, uid);
+    }
+  }
+  return uid;
+}
+
+bool Storage::GetPersistentEntries(
+    bool periodic,
+    std::vector<std::pair<std::string, std::shared_ptr<Value>>>* entries)
+    const {
+  // copy values out of storage as quickly as possible so lock isn't held
+  {
+    std::scoped_lock lock(m_mutex);
+    // for periodic, don't re-save unless something has changed
+    if (periodic && !m_persistent_dirty) return false;
+    m_persistent_dirty = false;
+    entries->reserve(m_entries.size());
+    for (auto& i : m_entries) {
+      Entry* entry = i.getValue();
+      // only write persistent-flagged values
+      if (!entry->value || !entry->IsPersistent()) continue;
+      entries->emplace_back(i.getKey(), entry->value);
+    }
+  }
+
+  // sort in name order
+  std::sort(entries->begin(), entries->end(),
+            [](const std::pair<std::string, std::shared_ptr<Value>>& a,
+               const std::pair<std::string, std::shared_ptr<Value>>& b) {
+              return a.first < b.first;
+            });
+  return true;
+}
+
+bool Storage::GetEntries(
+    const Twine& prefix,
+    std::vector<std::pair<std::string, std::shared_ptr<Value>>>* entries)
+    const {
+  wpi::SmallString<128> prefixBuf;
+  StringRef prefixStr = prefix.toStringRef(prefixBuf);
+  // copy values out of storage as quickly as possible so lock isn't held
+  {
+    std::scoped_lock lock(m_mutex);
+    entries->reserve(m_entries.size());
+    for (auto& i : m_entries) {
+      Entry* entry = i.getValue();
+      // only write values with given prefix
+      if (!entry->value || !i.getKey().startswith(prefixStr)) continue;
+      entries->emplace_back(i.getKey(), entry->value);
+    }
+  }
+
+  // sort in name order
+  std::sort(entries->begin(), entries->end(),
+            [](const std::pair<std::string, std::shared_ptr<Value>>& a,
+               const std::pair<std::string, std::shared_ptr<Value>>& b) {
+              return a.first < b.first;
+            });
+  return true;
+}
+
+void Storage::CreateRpc(unsigned int local_id, StringRef def,
+                        unsigned int rpc_uid) {
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return;
+  Entry* entry = m_localmap[local_id].get();
+
+  auto old_value = entry->value;
+  auto value = Value::MakeRpc(def);
+  entry->value = value;
+
+  // set up the RPC info
+  entry->rpc_uid = rpc_uid;
+
+  if (old_value && *old_value == *value) return;
+
+  // assign an id if it doesn't have one
+  if (entry->id == 0xffff) {
+    unsigned int id = m_idmap.size();
+    entry->id = id;
+    m_idmap.push_back(entry);
+  }
+
+  // generate message
+  if (!m_dispatcher) return;
+  auto dispatcher = m_dispatcher;
+  if (!old_value || old_value->type() != value->type()) {
+    ++entry->seq_num;
+    auto msg = Message::EntryAssign(
+        entry->name, entry->id, entry->seq_num.value(), value, entry->flags);
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, nullptr);
+  } else {
+    ++entry->seq_num;
+    auto msg = Message::EntryUpdate(entry->id, entry->seq_num.value(), value);
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, nullptr);
+  }
+}
+
+unsigned int Storage::CallRpc(unsigned int local_id, StringRef params) {
+  std::unique_lock lock(m_mutex);
+  if (local_id >= m_localmap.size()) return 0;
+  Entry* entry = m_localmap[local_id].get();
+
+  if (!entry->value || !entry->value->IsRpc()) return 0;
+
+  ++entry->rpc_call_uid;
+  if (entry->rpc_call_uid > 0xffff) entry->rpc_call_uid = 0;
+  unsigned int call_uid = entry->rpc_call_uid;
+
+  auto msg = Message::ExecuteRpc(entry->id, call_uid, params);
+  StringRef name{entry->name};
+
+  if (m_server) {
+    // RPCs are unlikely to be used locally on the server, but handle it
+    // gracefully anyway.
+    auto rpc_uid = entry->rpc_uid;
+    lock.unlock();
+    ConnectionInfo conn_info;
+    conn_info.remote_id = "Server";
+    conn_info.remote_ip = "localhost";
+    conn_info.remote_port = 0;
+    conn_info.last_update = wpi::Now();
+    conn_info.protocol_version = 0x0300;
+    unsigned int call_uid = msg->seq_num_uid();
+    m_rpc_server.ProcessRpc(local_id, call_uid, name, msg->str(), conn_info,
+                            [=](StringRef result) {
+                              std::scoped_lock lock(m_mutex);
+                              m_rpc_results.insert(std::make_pair(
+                                  RpcIdPair{local_id, call_uid}, result));
+                              m_rpc_results_cond.notify_all();
+                            },
+                            rpc_uid);
+  } else {
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    dispatcher->QueueOutgoing(msg, nullptr, nullptr);
+  }
+  return call_uid;
+}
+
+bool Storage::GetRpcResult(unsigned int local_id, unsigned int call_uid,
+                           std::string* result) {
+  bool timed_out = false;
+  return GetRpcResult(local_id, call_uid, result, -1, &timed_out);
+}
+
+bool Storage::GetRpcResult(unsigned int local_id, unsigned int call_uid,
+                           std::string* result, double timeout,
+                           bool* timed_out) {
+  std::unique_lock lock(m_mutex);
+
+  RpcIdPair call_pair{local_id, call_uid};
+
+  // only allow one blocking call per rpc call uid
+  if (!m_rpc_blocking_calls.insert(call_pair).second) return false;
+
+  auto timeout_time =
+      std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+  *timed_out = false;
+  for (;;) {
+    auto i = m_rpc_results.find(call_pair);
+    if (i == m_rpc_results.end()) {
+      if (timeout == 0 || m_terminating) {
+        m_rpc_blocking_calls.erase(call_pair);
+        return false;
+      }
+      if (timeout < 0) {
+        m_rpc_results_cond.wait(lock);
+      } else {
+        auto cond_timed_out = m_rpc_results_cond.wait_until(lock, timeout_time);
+        if (cond_timed_out == std::cv_status::timeout) {
+          m_rpc_blocking_calls.erase(call_pair);
+          *timed_out = true;
+          return false;
+        }
+      }
+      // if element does not exist, we have been canceled
+      if (m_rpc_blocking_calls.count(call_pair) == 0) {
+        return false;
+      }
+      if (m_terminating) {
+        m_rpc_blocking_calls.erase(call_pair);
+        return false;
+      }
+      continue;
+    }
+    result->swap(i->getSecond());
+    // safe to erase even if id does not exist
+    m_rpc_blocking_calls.erase(call_pair);
+    m_rpc_results.erase(i);
+    return true;
+  }
+}
+
+void Storage::CancelRpcResult(unsigned int local_id, unsigned int call_uid) {
+  std::unique_lock lock(m_mutex);
+  // safe to erase even if id does not exist
+  m_rpc_blocking_calls.erase(RpcIdPair{local_id, call_uid});
+  m_rpc_results_cond.notify_all();
+}
diff --git a/ntcore/src/main/native/cpp/Storage.h b/ntcore/src/main/native/cpp/Storage.h
new file mode 100644
index 0000000..fa9b2bf
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Storage.h
@@ -0,0 +1,262 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_STORAGE_H_
+#define NTCORE_STORAGE_H_
+
+#include <stdint.h>
+
+#include <atomic>
+#include <cstddef>
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <wpi/DenseMap.h>
+#include <wpi/SmallSet.h>
+#include <wpi/StringMap.h>
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+
+#include "IStorage.h"
+#include "Message.h"
+#include "SequenceNumber.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class Logger;
+class raw_istream;
+class raw_ostream;
+}  // namespace wpi
+
+namespace nt {
+
+class IEntryNotifier;
+class INetworkConnection;
+class IRpcServer;
+class IStorageTest;
+
+class Storage : public IStorage {
+  friend class StorageTest;
+
+ public:
+  Storage(IEntryNotifier& notifier, IRpcServer& rpcserver, wpi::Logger& logger);
+  Storage(const Storage&) = delete;
+  Storage& operator=(const Storage&) = delete;
+
+  ~Storage();
+
+  // Accessors required by Dispatcher.  An interface is used for
+  // generation of outgoing messages to break a dependency loop between
+  // Storage and Dispatcher.
+  void SetDispatcher(IDispatcher* dispatcher, bool server) override;
+  void ClearDispatcher() override;
+
+  // Required for wire protocol 2.0 to get the entry type of an entry when
+  // receiving entry updates (because the length/type is not provided in the
+  // message itself).  Not used in wire protocol 3.0.
+  NT_Type GetMessageEntryType(unsigned int id) const override;
+
+  void ProcessIncoming(std::shared_ptr<Message> msg, INetworkConnection* conn,
+                       std::weak_ptr<INetworkConnection> conn_weak) override;
+  void GetInitialAssignments(
+      INetworkConnection& conn,
+      std::vector<std::shared_ptr<Message>>* msgs) override;
+  void ApplyInitialAssignments(
+      INetworkConnection& conn, wpi::ArrayRef<std::shared_ptr<Message>> msgs,
+      bool new_server,
+      std::vector<std::shared_ptr<Message>>* out_msgs) override;
+
+  // User functions.  These are the actual implementations of the corresponding
+  // user API functions in ntcore_cpp.
+  std::shared_ptr<Value> GetEntryValue(StringRef name) const;
+  std::shared_ptr<Value> GetEntryValue(unsigned int local_id) const;
+
+  bool SetDefaultEntryValue(StringRef name, std::shared_ptr<Value> value);
+  bool SetDefaultEntryValue(unsigned int local_id,
+                            std::shared_ptr<Value> value);
+
+  bool SetEntryValue(StringRef name, std::shared_ptr<Value> value);
+  bool SetEntryValue(unsigned int local_id, std::shared_ptr<Value> value);
+
+  void SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value);
+  void SetEntryTypeValue(unsigned int local_id, std::shared_ptr<Value> value);
+
+  void SetEntryFlags(StringRef name, unsigned int flags);
+  void SetEntryFlags(unsigned int local_id, unsigned int flags);
+
+  unsigned int GetEntryFlags(StringRef name) const;
+  unsigned int GetEntryFlags(unsigned int local_id) const;
+
+  void DeleteEntry(StringRef name);
+  void DeleteEntry(unsigned int local_id);
+
+  void DeleteAllEntries();
+
+  std::vector<EntryInfo> GetEntryInfo(int inst, const Twine& prefix,
+                                      unsigned int types);
+
+  unsigned int AddListener(
+      const Twine& prefix,
+      std::function<void(const EntryNotification& event)> callback,
+      unsigned int flags) const;
+  unsigned int AddListener(
+      unsigned int local_id,
+      std::function<void(const EntryNotification& event)> callback,
+      unsigned int flags) const;
+
+  unsigned int AddPolledListener(unsigned int poller_uid, const Twine& prefix,
+                                 unsigned int flags) const;
+  unsigned int AddPolledListener(unsigned int poller_uid, unsigned int local_id,
+                                 unsigned int flags) const;
+
+  // Index-only
+  unsigned int GetEntry(const Twine& name);
+  std::vector<unsigned int> GetEntries(const Twine& prefix, unsigned int types);
+  EntryInfo GetEntryInfo(int inst, unsigned int local_id) const;
+  std::string GetEntryName(unsigned int local_id) const;
+  NT_Type GetEntryType(unsigned int local_id) const;
+  uint64_t GetEntryLastChange(unsigned int local_id) const;
+
+  // Filename-based save/load functions.  Used both by periodic saves and
+  // accessible directly via the user API.
+  const char* SavePersistent(const Twine& filename,
+                             bool periodic) const override;
+  const char* LoadPersistent(
+      const Twine& filename,
+      std::function<void(size_t line, const char* msg)> warn) override;
+
+  const char* SaveEntries(const Twine& filename, const Twine& prefix) const;
+  const char* LoadEntries(
+      const Twine& filename, const Twine& prefix,
+      std::function<void(size_t line, const char* msg)> warn);
+
+  // Stream-based save/load functions (exposed for testing purposes).  These
+  // implement the guts of the filename-based functions.
+  void SavePersistent(wpi::raw_ostream& os, bool periodic) const;
+  bool LoadEntries(wpi::raw_istream& is, const Twine& prefix, bool persistent,
+                   std::function<void(size_t line, const char* msg)> warn);
+
+  void SaveEntries(wpi::raw_ostream& os, const Twine& prefix) const;
+
+  // RPC configuration needs to come through here as RPC definitions are
+  // actually special Storage value types.
+  void CreateRpc(unsigned int local_id, StringRef def, unsigned int rpc_uid);
+  unsigned int CallRpc(unsigned int local_id, StringRef params);
+  bool GetRpcResult(unsigned int local_id, unsigned int call_uid,
+                    std::string* result);
+  bool GetRpcResult(unsigned int local_id, unsigned int call_uid,
+                    std::string* result, double timeout, bool* timed_out);
+  void CancelRpcResult(unsigned int local_id, unsigned int call_uid);
+
+ private:
+  // Data for each table entry.
+  struct Entry {
+    explicit Entry(wpi::StringRef name_) : name(name_) {}
+    bool IsPersistent() const { return (flags & NT_PERSISTENT) != 0; }
+
+    // We redundantly store the name so that it's available when accessing the
+    // raw Entry* via the ID map.
+    std::string name;
+
+    // The current value and flags.
+    std::shared_ptr<Value> value;
+    unsigned int flags{0};
+
+    // Unique ID for this entry as used in network messages.  The value is
+    // assigned by the server, so on the client this is 0xffff until an
+    // entry assignment is received back from the server.
+    unsigned int id{0xffff};
+
+    // Local ID.
+    unsigned int local_id{UINT_MAX};
+
+    // Sequence number for update resolution.
+    SequenceNumber seq_num;
+
+    // If value has been written locally.  Used during initial handshake
+    // on client to determine whether or not to accept remote changes.
+    bool local_write{false};
+
+    // RPC handle.
+    unsigned int rpc_uid{UINT_MAX};
+
+    // Last UID used when calling this RPC (primarily for client use).  This
+    // is incremented for each call.
+    unsigned int rpc_call_uid{0};
+  };
+
+  typedef wpi::StringMap<Entry*> EntriesMap;
+  typedef std::vector<Entry*> IdMap;
+  typedef std::vector<std::unique_ptr<Entry>> LocalMap;
+  typedef std::pair<unsigned int, unsigned int> RpcIdPair;
+  typedef wpi::DenseMap<RpcIdPair, std::string> RpcResultMap;
+  typedef wpi::SmallSet<RpcIdPair, 12> RpcBlockingCallSet;
+
+  mutable wpi::mutex m_mutex;
+  EntriesMap m_entries;
+  IdMap m_idmap;
+  LocalMap m_localmap;
+  RpcResultMap m_rpc_results;
+  RpcBlockingCallSet m_rpc_blocking_calls;
+  // If any persistent values have changed
+  mutable bool m_persistent_dirty = false;
+
+  // condition variable and termination flag for blocking on a RPC result
+  std::atomic_bool m_terminating;
+  wpi::condition_variable m_rpc_results_cond;
+
+  // configured by dispatcher at startup
+  IDispatcher* m_dispatcher = nullptr;
+  bool m_server = true;
+
+  IEntryNotifier& m_notifier;
+  IRpcServer& m_rpc_server;
+  wpi::Logger& m_logger;
+
+  void ProcessIncomingEntryAssign(std::shared_ptr<Message> msg,
+                                  INetworkConnection* conn);
+  void ProcessIncomingEntryUpdate(std::shared_ptr<Message> msg,
+                                  INetworkConnection* conn);
+  void ProcessIncomingFlagsUpdate(std::shared_ptr<Message> msg,
+                                  INetworkConnection* conn);
+  void ProcessIncomingEntryDelete(std::shared_ptr<Message> msg,
+                                  INetworkConnection* conn);
+  void ProcessIncomingClearEntries(std::shared_ptr<Message> msg,
+                                   INetworkConnection* conn);
+  void ProcessIncomingExecuteRpc(std::shared_ptr<Message> msg,
+                                 INetworkConnection* conn,
+                                 std::weak_ptr<INetworkConnection> conn_weak);
+  void ProcessIncomingRpcResponse(std::shared_ptr<Message> msg,
+                                  INetworkConnection* conn);
+
+  bool GetPersistentEntries(
+      bool periodic,
+      std::vector<std::pair<std::string, std::shared_ptr<Value>>>* entries)
+      const;
+  bool GetEntries(const Twine& prefix,
+                  std::vector<std::pair<std::string, std::shared_ptr<Value>>>*
+                      entries) const;
+  void SetEntryValueImpl(Entry* entry, std::shared_ptr<Value> value,
+                         std::unique_lock<wpi::mutex>& lock, bool local);
+  void SetEntryFlagsImpl(Entry* entry, unsigned int flags,
+                         std::unique_lock<wpi::mutex>& lock, bool local);
+  void DeleteEntryImpl(Entry* entry, std::unique_lock<wpi::mutex>& lock,
+                       bool local);
+
+  // Must be called with m_mutex held
+  template <typename F>
+  void DeleteAllEntriesImpl(bool local, F should_delete);
+  void DeleteAllEntriesImpl(bool local);
+  Entry* GetOrNew(const Twine& name);
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_STORAGE_H_
diff --git a/ntcore/src/main/native/cpp/Storage_load.cpp b/ntcore/src/main/native/cpp/Storage_load.cpp
new file mode 100644
index 0000000..69eb173
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Storage_load.cpp
@@ -0,0 +1,449 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <cctype>
+#include <string>
+
+#include <wpi/Base64.h>
+#include <wpi/SmallString.h>
+#include <wpi/StringExtras.h>
+#include <wpi/raw_istream.h>
+
+#include "IDispatcher.h"
+#include "IEntryNotifier.h"
+#include "Storage.h"
+
+using namespace nt;
+
+namespace {
+
+class LoadPersistentImpl {
+ public:
+  typedef std::pair<std::string, std::shared_ptr<Value>> Entry;
+  typedef std::function<void(size_t line, const char* msg)> WarnFunc;
+
+  LoadPersistentImpl(wpi::raw_istream& is, WarnFunc warn)
+      : m_is(is), m_warn(warn) {}
+
+  bool Load(StringRef prefix, std::vector<Entry>* entries);
+
+ private:
+  bool ReadLine();
+  bool ReadHeader();
+  NT_Type ReadType();
+  wpi::StringRef ReadName(wpi::SmallVectorImpl<char>& buf);
+  std::shared_ptr<Value> ReadValue(NT_Type type);
+  std::shared_ptr<Value> ReadBooleanValue();
+  std::shared_ptr<Value> ReadDoubleValue();
+  std::shared_ptr<Value> ReadStringValue();
+  std::shared_ptr<Value> ReadRawValue();
+  std::shared_ptr<Value> ReadBooleanArrayValue();
+  std::shared_ptr<Value> ReadDoubleArrayValue();
+  std::shared_ptr<Value> ReadStringArrayValue();
+
+  void Warn(const char* msg) {
+    if (m_warn) m_warn(m_line_num, msg);
+  }
+
+  wpi::raw_istream& m_is;
+  WarnFunc m_warn;
+
+  wpi::StringRef m_line;
+  wpi::SmallString<128> m_line_buf;
+  size_t m_line_num = 0;
+
+  std::vector<int> m_buf_boolean_array;
+  std::vector<double> m_buf_double_array;
+  std::vector<std::string> m_buf_string_array;
+};
+
+}  // namespace
+
+/* Extracts an escaped string token.  Does not unescape the string.
+ * If a string cannot be matched, an empty string is returned.
+ * If the string is unterminated, an empty tail string is returned.
+ * The returned token includes the starting and trailing quotes (unless the
+ * string is unterminated).
+ * Returns a pair containing the extracted token (if any) and the remaining
+ * tail string.
+ */
+static std::pair<wpi::StringRef, wpi::StringRef> ReadStringToken(
+    wpi::StringRef source) {
+  // Match opening quote
+  if (source.empty() || source.front() != '"')
+    return std::make_pair(wpi::StringRef(), source);
+
+  // Scan for ending double quote, checking for escaped as we go.
+  size_t size = source.size();
+  size_t pos;
+  for (pos = 1; pos < size; ++pos) {
+    if (source[pos] == '"' && source[pos - 1] != '\\') {
+      ++pos;  // we want to include the trailing quote in the result
+      break;
+    }
+  }
+  return std::make_pair(source.slice(0, pos), source.substr(pos));
+}
+
+static int fromxdigit(char ch) {
+  if (ch >= 'a' && ch <= 'f')
+    return (ch - 'a' + 10);
+  else if (ch >= 'A' && ch <= 'F')
+    return (ch - 'A' + 10);
+  else
+    return ch - '0';
+}
+
+static wpi::StringRef UnescapeString(wpi::StringRef source,
+                                     wpi::SmallVectorImpl<char>& buf) {
+  assert(source.size() >= 2 && source.front() == '"' && source.back() == '"');
+  buf.clear();
+  buf.reserve(source.size() - 2);
+  for (auto s = source.begin() + 1, end = source.end() - 1; s != end; ++s) {
+    if (*s != '\\') {
+      buf.push_back(*s);
+      continue;
+    }
+    switch (*++s) {
+      case 't':
+        buf.push_back('\t');
+        break;
+      case 'n':
+        buf.push_back('\n');
+        break;
+      case 'x': {
+        if (!isxdigit(*(s + 1))) {
+          buf.push_back('x');  // treat it like a unknown escape
+          break;
+        }
+        int ch = fromxdigit(*++s);
+        if (std::isxdigit(*(s + 1))) {
+          ch <<= 4;
+          ch |= fromxdigit(*++s);
+        }
+        buf.push_back(static_cast<char>(ch));
+        break;
+      }
+      default:
+        buf.push_back(*s);
+        break;
+    }
+  }
+  return wpi::StringRef{buf.data(), buf.size()};
+}
+
+bool LoadPersistentImpl::Load(StringRef prefix, std::vector<Entry>* entries) {
+  if (!ReadHeader()) return false;  // header
+
+  while (ReadLine()) {
+    // type
+    NT_Type type = ReadType();
+    if (type == NT_UNASSIGNED) {
+      Warn("unrecognized type");
+      continue;
+    }
+
+    // name
+    wpi::SmallString<128> buf;
+    wpi::StringRef name = ReadName(buf);
+    if (name.empty() || !name.startswith(prefix)) continue;
+
+    // =
+    m_line = m_line.ltrim(" \t");
+    if (m_line.empty() || m_line.front() != '=') {
+      Warn("expected = after name");
+      continue;
+    }
+    m_line = m_line.drop_front().ltrim(" \t");
+
+    // value
+    auto value = ReadValue(type);
+
+    // move to entries
+    if (value) entries->emplace_back(name, std::move(value));
+  }
+  return true;
+}
+
+bool LoadPersistentImpl::ReadLine() {
+  // ignore blank lines and lines that start with ; or # (comments)
+  while (!m_is.has_error()) {
+    ++m_line_num;
+    m_line = m_is.getline(m_line_buf, INT_MAX).trim();
+    if (!m_line.empty() && m_line.front() != ';' && m_line.front() != '#')
+      return true;
+  }
+  return false;
+}
+
+bool LoadPersistentImpl::ReadHeader() {
+  // header
+  if (!ReadLine() || m_line != "[NetworkTables Storage 3.0]") {
+    Warn("header line mismatch, ignoring rest of file");
+    return false;
+  }
+  return true;
+}
+
+NT_Type LoadPersistentImpl::ReadType() {
+  wpi::StringRef tok;
+  std::tie(tok, m_line) = m_line.split(' ');
+  if (tok == "boolean") {
+    return NT_BOOLEAN;
+  } else if (tok == "double") {
+    return NT_DOUBLE;
+  } else if (tok == "string") {
+    return NT_STRING;
+  } else if (tok == "raw") {
+    return NT_RAW;
+  } else if (tok == "array") {
+    wpi::StringRef array_tok;
+    std::tie(array_tok, m_line) = m_line.split(' ');
+    if (array_tok == "boolean")
+      return NT_BOOLEAN_ARRAY;
+    else if (array_tok == "double")
+      return NT_DOUBLE_ARRAY;
+    else if (array_tok == "string")
+      return NT_STRING_ARRAY;
+  }
+  return NT_UNASSIGNED;
+}
+
+wpi::StringRef LoadPersistentImpl::ReadName(wpi::SmallVectorImpl<char>& buf) {
+  wpi::StringRef tok;
+  std::tie(tok, m_line) = ReadStringToken(m_line);
+  if (tok.empty()) {
+    Warn("missing name");
+    return wpi::StringRef{};
+  }
+  if (tok.back() != '"') {
+    Warn("unterminated name string");
+    return wpi::StringRef{};
+  }
+  return UnescapeString(tok, buf);
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadValue(NT_Type type) {
+  switch (type) {
+    case NT_BOOLEAN:
+      return ReadBooleanValue();
+    case NT_DOUBLE:
+      return ReadDoubleValue();
+    case NT_STRING:
+      return ReadStringValue();
+    case NT_RAW:
+      return ReadRawValue();
+    case NT_BOOLEAN_ARRAY:
+      return ReadBooleanArrayValue();
+    case NT_DOUBLE_ARRAY:
+      return ReadDoubleArrayValue();
+    case NT_STRING_ARRAY:
+      return ReadStringArrayValue();
+    default:
+      return nullptr;
+  }
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadBooleanValue() {
+  // only true or false is accepted
+  if (m_line == "true") return Value::MakeBoolean(true);
+  if (m_line == "false") return Value::MakeBoolean(false);
+  Warn("unrecognized boolean value, not 'true' or 'false'");
+  return nullptr;
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadDoubleValue() {
+  // need to convert to null-terminated string for std::strtod()
+  wpi::SmallString<64> buf = m_line;
+  char* end;
+  double v = std::strtod(buf.c_str(), &end);
+  if (*end != '\0') {
+    Warn("invalid double value");
+    return nullptr;
+  }
+  return Value::MakeDouble(v);
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadStringValue() {
+  wpi::StringRef tok;
+  std::tie(tok, m_line) = ReadStringToken(m_line);
+  if (tok.empty()) {
+    Warn("missing string value");
+    return nullptr;
+  }
+  if (tok.back() != '"') {
+    Warn("unterminated string value");
+    return nullptr;
+  }
+  wpi::SmallString<128> buf;
+  return Value::MakeString(UnescapeString(tok, buf));
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadRawValue() {
+  wpi::SmallString<128> buf;
+  size_t nr;
+  return Value::MakeRaw(wpi::Base64Decode(m_line, &nr, buf));
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadBooleanArrayValue() {
+  m_buf_boolean_array.clear();
+  while (!m_line.empty()) {
+    wpi::StringRef tok;
+    std::tie(tok, m_line) = m_line.split(',');
+    tok = tok.trim(" \t");
+    if (tok == "true") {
+      m_buf_boolean_array.push_back(1);
+    } else if (tok == "false") {
+      m_buf_boolean_array.push_back(0);
+    } else {
+      Warn("unrecognized boolean value, not 'true' or 'false'");
+      return nullptr;
+    }
+  }
+  return Value::MakeBooleanArray(std::move(m_buf_boolean_array));
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadDoubleArrayValue() {
+  m_buf_double_array.clear();
+  while (!m_line.empty()) {
+    wpi::StringRef tok;
+    std::tie(tok, m_line) = m_line.split(',');
+    tok = tok.trim(" \t");
+    // need to convert to null-terminated string for std::strtod()
+    wpi::SmallString<64> buf = tok;
+    char* end;
+    double v = std::strtod(buf.c_str(), &end);
+    if (*end != '\0') {
+      Warn("invalid double value");
+      return nullptr;
+    }
+    m_buf_double_array.push_back(v);
+  }
+
+  return Value::MakeDoubleArray(std::move(m_buf_double_array));
+}
+
+std::shared_ptr<Value> LoadPersistentImpl::ReadStringArrayValue() {
+  m_buf_string_array.clear();
+  while (!m_line.empty()) {
+    wpi::StringRef tok;
+    std::tie(tok, m_line) = ReadStringToken(m_line);
+    if (tok.empty()) {
+      Warn("missing string value");
+      return nullptr;
+    }
+    if (tok.back() != '"') {
+      Warn("unterminated string value");
+      return nullptr;
+    }
+
+    wpi::SmallString<128> buf;
+    m_buf_string_array.push_back(UnescapeString(tok, buf));
+
+    m_line = m_line.ltrim(" \t");
+    if (m_line.empty()) break;
+    if (m_line.front() != ',') {
+      Warn("expected comma between strings");
+      return nullptr;
+    }
+    m_line = m_line.drop_front().ltrim(" \t");
+  }
+
+  return Value::MakeStringArray(std::move(m_buf_string_array));
+}
+
+bool Storage::LoadEntries(
+    wpi::raw_istream& is, const Twine& prefix, bool persistent,
+    std::function<void(size_t line, const char* msg)> warn) {
+  wpi::SmallString<128> prefixBuf;
+  StringRef prefixStr = prefix.toStringRef(prefixBuf);
+
+  // entries to add
+  std::vector<LoadPersistentImpl::Entry> entries;
+
+  // load file
+  if (!LoadPersistentImpl(is, warn).Load(prefixStr, &entries)) return false;
+
+  // copy values into storage as quickly as possible so lock isn't held
+  std::vector<std::shared_ptr<Message>> msgs;
+  std::unique_lock lock(m_mutex);
+  for (auto& i : entries) {
+    Entry* entry = GetOrNew(i.first);
+    auto old_value = entry->value;
+    entry->value = i.second;
+    bool was_persist = entry->IsPersistent();
+    if (!was_persist && persistent) entry->flags |= NT_PERSISTENT;
+
+    // if we're the server, assign an id if it doesn't have one
+    if (m_server && entry->id == 0xffff) {
+      unsigned int id = m_idmap.size();
+      entry->id = id;
+      m_idmap.push_back(entry);
+    }
+
+    // notify (for local listeners)
+    if (m_notifier.local_notifiers()) {
+      if (!old_value) {
+        m_notifier.NotifyEntry(entry->local_id, i.first, i.second,
+                               NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
+      } else if (*old_value != *i.second) {
+        unsigned int notify_flags = NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL;
+        if (!was_persist && persistent) notify_flags |= NT_NOTIFY_FLAGS;
+        m_notifier.NotifyEntry(entry->local_id, i.first, i.second,
+                               notify_flags);
+      } else if (!was_persist && persistent) {
+        m_notifier.NotifyEntry(entry->local_id, i.first, i.second,
+                               NT_NOTIFY_FLAGS | NT_NOTIFY_LOCAL);
+      }
+    }
+
+    if (!m_dispatcher) continue;  // shortcut
+    ++entry->seq_num;
+
+    // put on update queue
+    if (!old_value || old_value->type() != i.second->type()) {
+      msgs.emplace_back(Message::EntryAssign(
+          i.first, entry->id, entry->seq_num.value(), i.second, entry->flags));
+    } else if (entry->id != 0xffff) {
+      // don't send an update if we don't have an assigned id yet
+      if (*old_value != *i.second)
+        msgs.emplace_back(
+            Message::EntryUpdate(entry->id, entry->seq_num.value(), i.second));
+      if (!was_persist)
+        msgs.emplace_back(Message::FlagsUpdate(entry->id, entry->flags));
+    }
+  }
+
+  if (m_dispatcher) {
+    auto dispatcher = m_dispatcher;
+    lock.unlock();
+    for (auto& msg : msgs)
+      dispatcher->QueueOutgoing(std::move(msg), nullptr, nullptr);
+  }
+
+  return true;
+}
+
+const char* Storage::LoadPersistent(
+    const Twine& filename,
+    std::function<void(size_t line, const char* msg)> warn) {
+  std::error_code ec;
+  wpi::raw_fd_istream is(filename, ec);
+  if (ec.value() != 0) return "could not open file";
+  if (!LoadEntries(is, "", true, warn)) return "error reading file";
+  return nullptr;
+}
+
+const char* Storage::LoadEntries(
+    const Twine& filename, const Twine& prefix,
+    std::function<void(size_t line, const char* msg)> warn) {
+  std::error_code ec;
+  wpi::raw_fd_istream is(filename, ec);
+  if (ec.value() != 0) return "could not open file";
+  if (!LoadEntries(is, prefix, false, warn)) return "error reading file";
+  return nullptr;
+}
diff --git a/ntcore/src/main/native/cpp/Storage_save.cpp b/ntcore/src/main/native/cpp/Storage_save.cpp
new file mode 100644
index 0000000..797eb8b
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Storage_save.cpp
@@ -0,0 +1,272 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <cctype>
+#include <string>
+
+#include <wpi/Base64.h>
+#include <wpi/FileSystem.h>
+#include <wpi/Format.h>
+#include <wpi/SmallString.h>
+#include <wpi/StringExtras.h>
+#include <wpi/raw_ostream.h>
+
+#include "Log.h"
+#include "Storage.h"
+
+using namespace nt;
+
+namespace {
+
+class SavePersistentImpl {
+ public:
+  typedef std::pair<std::string, std::shared_ptr<Value>> Entry;
+
+  explicit SavePersistentImpl(wpi::raw_ostream& os) : m_os(os) {}
+
+  void Save(wpi::ArrayRef<Entry> entries);
+
+ private:
+  void WriteString(wpi::StringRef str);
+  void WriteHeader();
+  void WriteEntries(wpi::ArrayRef<Entry> entries);
+  void WriteEntry(wpi::StringRef name, const Value& value);
+  bool WriteType(NT_Type type);
+  void WriteValue(const Value& value);
+
+  wpi::raw_ostream& m_os;
+};
+
+}  // namespace
+
+/* Escapes and writes a string, including start and end double quotes */
+void SavePersistentImpl::WriteString(wpi::StringRef str) {
+  m_os << '"';
+  for (auto c : str) {
+    switch (c) {
+      case '\\':
+        m_os << "\\\\";
+        break;
+      case '\t':
+        m_os << "\\t";
+        break;
+      case '\n':
+        m_os << "\\n";
+        break;
+      case '"':
+        m_os << "\\\"";
+        break;
+      default:
+        if (std::isprint(c) && c != '=') {
+          m_os << c;
+          break;
+        }
+
+        // Write out the escaped representation.
+        m_os << "\\x";
+        m_os << wpi::hexdigit((c >> 4) & 0xF);
+        m_os << wpi::hexdigit((c >> 0) & 0xF);
+    }
+  }
+  m_os << '"';
+}
+
+void SavePersistentImpl::Save(wpi::ArrayRef<Entry> entries) {
+  WriteHeader();
+  WriteEntries(entries);
+}
+
+void SavePersistentImpl::WriteHeader() {
+  m_os << "[NetworkTables Storage 3.0]\n";
+}
+
+void SavePersistentImpl::WriteEntries(wpi::ArrayRef<Entry> entries) {
+  for (auto& i : entries) {
+    if (!i.second) continue;
+    WriteEntry(i.first, *i.second);
+  }
+}
+
+void SavePersistentImpl::WriteEntry(wpi::StringRef name, const Value& value) {
+  if (!WriteType(value.type())) return;  // type
+  WriteString(name);                     // name
+  m_os << '=';                           // '='
+  WriteValue(value);                     // value
+  m_os << '\n';                          // eol
+}
+
+bool SavePersistentImpl::WriteType(NT_Type type) {
+  switch (type) {
+    case NT_BOOLEAN:
+      m_os << "boolean ";
+      break;
+    case NT_DOUBLE:
+      m_os << "double ";
+      break;
+    case NT_STRING:
+      m_os << "string ";
+      break;
+    case NT_RAW:
+      m_os << "raw ";
+      break;
+    case NT_BOOLEAN_ARRAY:
+      m_os << "array boolean ";
+      break;
+    case NT_DOUBLE_ARRAY:
+      m_os << "array double ";
+      break;
+    case NT_STRING_ARRAY:
+      m_os << "array string ";
+      break;
+    default:
+      return false;
+  }
+  return true;
+}
+
+void SavePersistentImpl::WriteValue(const Value& value) {
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      m_os << (value.GetBoolean() ? "true" : "false");
+      break;
+    case NT_DOUBLE:
+      m_os << wpi::format("%g", value.GetDouble());
+      break;
+    case NT_STRING:
+      WriteString(value.GetString());
+      break;
+    case NT_RAW: {
+      wpi::Base64Encode(m_os, value.GetRaw());
+      break;
+    }
+    case NT_BOOLEAN_ARRAY: {
+      bool first = true;
+      for (auto elem : value.GetBooleanArray()) {
+        if (!first) m_os << ',';
+        first = false;
+        m_os << (elem ? "true" : "false");
+      }
+      break;
+    }
+    case NT_DOUBLE_ARRAY: {
+      bool first = true;
+      for (auto elem : value.GetDoubleArray()) {
+        if (!first) m_os << ',';
+        first = false;
+        m_os << wpi::format("%g", elem);
+      }
+      break;
+    }
+    case NT_STRING_ARRAY: {
+      bool first = true;
+      for (auto& elem : value.GetStringArray()) {
+        if (!first) m_os << ',';
+        first = false;
+        WriteString(elem);
+      }
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+void Storage::SavePersistent(wpi::raw_ostream& os, bool periodic) const {
+  std::vector<SavePersistentImpl::Entry> entries;
+  if (!GetPersistentEntries(periodic, &entries)) return;
+  SavePersistentImpl(os).Save(entries);
+}
+
+const char* Storage::SavePersistent(const Twine& filename,
+                                    bool periodic) const {
+  wpi::SmallString<128> fn;
+  filename.toVector(fn);
+  wpi::SmallString<128> tmp = fn;
+  tmp += ".tmp";
+  wpi::SmallString<128> bak = fn;
+  bak += ".bak";
+
+  // Get entries before creating file
+  std::vector<SavePersistentImpl::Entry> entries;
+  if (!GetPersistentEntries(periodic, &entries)) return nullptr;
+
+  const char* err = nullptr;
+
+  // start by writing to temporary file
+  std::error_code ec;
+  wpi::raw_fd_ostream os(tmp, ec, wpi::sys::fs::F_Text);
+  if (ec.value() != 0) {
+    err = "could not open file";
+    goto done;
+  }
+  DEBUG0("saving persistent file '" << filename << "'");
+  SavePersistentImpl(os).Save(entries);
+  os.close();
+  if (os.has_error()) {
+    std::remove(tmp.c_str());
+    err = "error saving file";
+    goto done;
+  }
+
+  // Safely move to real file.  We ignore any failures related to the backup.
+  std::remove(bak.c_str());
+  std::rename(fn.c_str(), bak.c_str());
+  if (std::rename(tmp.c_str(), fn.c_str()) != 0) {
+    std::rename(bak.c_str(), fn.c_str());  // attempt to restore backup
+    err = "could not rename temp file to real file";
+    goto done;
+  }
+
+done:
+  // try again if there was an error
+  if (err && periodic) m_persistent_dirty = true;
+  return err;
+}
+
+void Storage::SaveEntries(wpi::raw_ostream& os, const Twine& prefix) const {
+  std::vector<SavePersistentImpl::Entry> entries;
+  if (!GetEntries(prefix, &entries)) return;
+  SavePersistentImpl(os).Save(entries);
+}
+
+const char* Storage::SaveEntries(const Twine& filename,
+                                 const Twine& prefix) const {
+  wpi::SmallString<128> fn;
+  filename.toVector(fn);
+  wpi::SmallString<128> tmp = fn;
+  tmp += ".tmp";
+  wpi::SmallString<128> bak = fn;
+  bak += ".bak";
+
+  // Get entries before creating file
+  std::vector<SavePersistentImpl::Entry> entries;
+  if (!GetEntries(prefix, &entries)) return nullptr;
+
+  // start by writing to temporary file
+  std::error_code ec;
+  wpi::raw_fd_ostream os(tmp, ec, wpi::sys::fs::F_Text);
+  if (ec.value() != 0) {
+    return "could not open file";
+  }
+  DEBUG0("saving file '" << filename << "'");
+  SavePersistentImpl(os).Save(entries);
+  os.close();
+  if (os.has_error()) {
+    std::remove(tmp.c_str());
+    return "error saving file";
+  }
+
+  // Safely move to real file.  We ignore any failures related to the backup.
+  std::remove(bak.c_str());
+  std::rename(fn.c_str(), bak.c_str());
+  if (std::rename(tmp.c_str(), fn.c_str()) != 0) {
+    std::rename(bak.c_str(), fn.c_str());  // attempt to restore backup
+    return "could not rename temp file to real file";
+  }
+
+  return nullptr;
+}
diff --git a/ntcore/src/main/native/cpp/Value.cpp b/ntcore/src/main/native/cpp/Value.cpp
new file mode 100644
index 0000000..3f58b73
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Value.cpp
@@ -0,0 +1,228 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <stdint.h>
+
+#include <wpi/MemAlloc.h>
+#include <wpi/timestamp.h>
+
+#include "Value_internal.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace nt;
+
+Value::Value() {
+  m_val.type = NT_UNASSIGNED;
+  m_val.last_change = wpi::Now();
+}
+
+Value::Value(NT_Type type, uint64_t time, const private_init&) {
+  m_val.type = type;
+  if (time == 0)
+    m_val.last_change = wpi::Now();
+  else
+    m_val.last_change = time;
+  if (m_val.type == NT_BOOLEAN_ARRAY)
+    m_val.data.arr_boolean.arr = nullptr;
+  else if (m_val.type == NT_DOUBLE_ARRAY)
+    m_val.data.arr_double.arr = nullptr;
+  else if (m_val.type == NT_STRING_ARRAY)
+    m_val.data.arr_string.arr = nullptr;
+}
+
+Value::~Value() {
+  if (m_val.type == NT_BOOLEAN_ARRAY)
+    delete[] m_val.data.arr_boolean.arr;
+  else if (m_val.type == NT_DOUBLE_ARRAY)
+    delete[] m_val.data.arr_double.arr;
+  else if (m_val.type == NT_STRING_ARRAY)
+    delete[] m_val.data.arr_string.arr;
+}
+
+std::shared_ptr<Value> Value::MakeBooleanArray(wpi::ArrayRef<bool> value,
+                                               uint64_t time) {
+  auto val = std::make_shared<Value>(NT_BOOLEAN_ARRAY, time, private_init());
+  val->m_val.data.arr_boolean.arr = new int[value.size()];
+  val->m_val.data.arr_boolean.size = value.size();
+  std::copy(value.begin(), value.end(), val->m_val.data.arr_boolean.arr);
+  return val;
+}
+
+std::shared_ptr<Value> Value::MakeBooleanArray(wpi::ArrayRef<int> value,
+                                               uint64_t time) {
+  auto val = std::make_shared<Value>(NT_BOOLEAN_ARRAY, time, private_init());
+  val->m_val.data.arr_boolean.arr = new int[value.size()];
+  val->m_val.data.arr_boolean.size = value.size();
+  std::copy(value.begin(), value.end(), val->m_val.data.arr_boolean.arr);
+  return val;
+}
+
+std::shared_ptr<Value> Value::MakeDoubleArray(wpi::ArrayRef<double> value,
+                                              uint64_t time) {
+  auto val = std::make_shared<Value>(NT_DOUBLE_ARRAY, time, private_init());
+  val->m_val.data.arr_double.arr = new double[value.size()];
+  val->m_val.data.arr_double.size = value.size();
+  std::copy(value.begin(), value.end(), val->m_val.data.arr_double.arr);
+  return val;
+}
+
+std::shared_ptr<Value> Value::MakeStringArray(wpi::ArrayRef<std::string> value,
+                                              uint64_t time) {
+  auto val = std::make_shared<Value>(NT_STRING_ARRAY, time, private_init());
+  val->m_string_array = value;
+  // point NT_Value to the contents in the vector.
+  val->m_val.data.arr_string.arr = new NT_String[value.size()];
+  val->m_val.data.arr_string.size = val->m_string_array.size();
+  for (size_t i = 0; i < value.size(); ++i) {
+    val->m_val.data.arr_string.arr[i].str = const_cast<char*>(value[i].c_str());
+    val->m_val.data.arr_string.arr[i].len = value[i].size();
+  }
+  return val;
+}
+
+std::shared_ptr<Value> Value::MakeStringArray(std::vector<std::string>&& value,
+                                              uint64_t time) {
+  auto val = std::make_shared<Value>(NT_STRING_ARRAY, time, private_init());
+  val->m_string_array = std::move(value);
+  value.clear();
+  // point NT_Value to the contents in the vector.
+  val->m_val.data.arr_string.arr = new NT_String[val->m_string_array.size()];
+  val->m_val.data.arr_string.size = val->m_string_array.size();
+  for (size_t i = 0; i < val->m_string_array.size(); ++i) {
+    val->m_val.data.arr_string.arr[i].str =
+        const_cast<char*>(val->m_string_array[i].c_str());
+    val->m_val.data.arr_string.arr[i].len = val->m_string_array[i].size();
+  }
+  return val;
+}
+
+void nt::ConvertToC(const Value& in, NT_Value* out) {
+  out->type = NT_UNASSIGNED;
+  switch (in.type()) {
+    case NT_UNASSIGNED:
+      return;
+    case NT_BOOLEAN:
+      out->data.v_boolean = in.GetBoolean() ? 1 : 0;
+      break;
+    case NT_DOUBLE:
+      out->data.v_double = in.GetDouble();
+      break;
+    case NT_STRING:
+      ConvertToC(in.GetString(), &out->data.v_string);
+      break;
+    case NT_RAW:
+      ConvertToC(in.GetRaw(), &out->data.v_raw);
+      break;
+    case NT_RPC:
+      ConvertToC(in.GetRpc(), &out->data.v_raw);
+      break;
+    case NT_BOOLEAN_ARRAY: {
+      auto v = in.GetBooleanArray();
+      out->data.arr_boolean.arr =
+          static_cast<int*>(wpi::safe_malloc(v.size() * sizeof(int)));
+      out->data.arr_boolean.size = v.size();
+      std::copy(v.begin(), v.end(), out->data.arr_boolean.arr);
+      break;
+    }
+    case NT_DOUBLE_ARRAY: {
+      auto v = in.GetDoubleArray();
+      out->data.arr_double.arr =
+          static_cast<double*>(wpi::safe_malloc(v.size() * sizeof(double)));
+      out->data.arr_double.size = v.size();
+      std::copy(v.begin(), v.end(), out->data.arr_double.arr);
+      break;
+    }
+    case NT_STRING_ARRAY: {
+      auto v = in.GetStringArray();
+      out->data.arr_string.arr = static_cast<NT_String*>(
+          wpi::safe_malloc(v.size() * sizeof(NT_String)));
+      for (size_t i = 0; i < v.size(); ++i)
+        ConvertToC(v[i], &out->data.arr_string.arr[i]);
+      out->data.arr_string.size = v.size();
+      break;
+    }
+    default:
+      // assert(false && "unknown value type");
+      return;
+  }
+  out->type = in.type();
+}
+
+void nt::ConvertToC(wpi::StringRef in, NT_String* out) {
+  out->len = in.size();
+  out->str = static_cast<char*>(wpi::safe_malloc(in.size() + 1));
+  std::memcpy(out->str, in.data(), in.size());
+  out->str[in.size()] = '\0';
+}
+
+std::shared_ptr<Value> nt::ConvertFromC(const NT_Value& value) {
+  switch (value.type) {
+    case NT_UNASSIGNED:
+      return nullptr;
+    case NT_BOOLEAN:
+      return Value::MakeBoolean(value.data.v_boolean != 0);
+    case NT_DOUBLE:
+      return Value::MakeDouble(value.data.v_double);
+    case NT_STRING:
+      return Value::MakeString(ConvertFromC(value.data.v_string));
+    case NT_RAW:
+      return Value::MakeRaw(ConvertFromC(value.data.v_raw));
+    case NT_RPC:
+      return Value::MakeRpc(ConvertFromC(value.data.v_raw));
+    case NT_BOOLEAN_ARRAY:
+      return Value::MakeBooleanArray(wpi::ArrayRef<int>(
+          value.data.arr_boolean.arr, value.data.arr_boolean.size));
+    case NT_DOUBLE_ARRAY:
+      return Value::MakeDoubleArray(wpi::ArrayRef<double>(
+          value.data.arr_double.arr, value.data.arr_double.size));
+    case NT_STRING_ARRAY: {
+      std::vector<std::string> v;
+      v.reserve(value.data.arr_string.size);
+      for (size_t i = 0; i < value.data.arr_string.size; ++i)
+        v.push_back(ConvertFromC(value.data.arr_string.arr[i]));
+      return Value::MakeStringArray(std::move(v));
+    }
+    default:
+      // assert(false && "unknown value type");
+      return nullptr;
+  }
+}
+
+bool nt::operator==(const Value& lhs, const Value& rhs) {
+  if (lhs.type() != rhs.type()) return false;
+  switch (lhs.type()) {
+    case NT_UNASSIGNED:
+      return true;  // XXX: is this better being false instead?
+    case NT_BOOLEAN:
+      return lhs.m_val.data.v_boolean == rhs.m_val.data.v_boolean;
+    case NT_DOUBLE:
+      return lhs.m_val.data.v_double == rhs.m_val.data.v_double;
+    case NT_STRING:
+    case NT_RAW:
+    case NT_RPC:
+      return lhs.m_string == rhs.m_string;
+    case NT_BOOLEAN_ARRAY:
+      if (lhs.m_val.data.arr_boolean.size != rhs.m_val.data.arr_boolean.size)
+        return false;
+      return std::memcmp(lhs.m_val.data.arr_boolean.arr,
+                         rhs.m_val.data.arr_boolean.arr,
+                         lhs.m_val.data.arr_boolean.size *
+                             sizeof(lhs.m_val.data.arr_boolean.arr[0])) == 0;
+    case NT_DOUBLE_ARRAY:
+      if (lhs.m_val.data.arr_double.size != rhs.m_val.data.arr_double.size)
+        return false;
+      return std::memcmp(lhs.m_val.data.arr_double.arr,
+                         rhs.m_val.data.arr_double.arr,
+                         lhs.m_val.data.arr_double.size *
+                             sizeof(lhs.m_val.data.arr_double.arr[0])) == 0;
+    case NT_STRING_ARRAY:
+      return lhs.m_string_array == rhs.m_string_array;
+    default:
+      // assert(false && "unknown value type");
+      return false;
+  }
+}
diff --git a/ntcore/src/main/native/cpp/Value_internal.h b/ntcore/src/main/native/cpp/Value_internal.h
new file mode 100644
index 0000000..ea25777
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Value_internal.h
@@ -0,0 +1,31 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_VALUE_INTERNAL_H_
+#define NTCORE_VALUE_INTERNAL_H_
+
+#include <memory>
+#include <string>
+
+#include <wpi/StringRef.h>
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+class Value;
+
+void ConvertToC(const Value& in, NT_Value* out);
+std::shared_ptr<Value> ConvertFromC(const NT_Value& value);
+void ConvertToC(wpi::StringRef in, NT_String* out);
+inline wpi::StringRef ConvertFromC(const NT_String& str) {
+  return wpi::StringRef(str.str, str.len);
+}
+
+}  // namespace nt
+
+#endif  // NTCORE_VALUE_INTERNAL_H_
diff --git a/ntcore/src/main/native/cpp/WireDecoder.cpp b/ntcore/src/main/native/cpp/WireDecoder.cpp
new file mode 100644
index 0000000..07c85d2
--- /dev/null
+++ b/ntcore/src/main/native/cpp/WireDecoder.cpp
@@ -0,0 +1,208 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "WireDecoder.h"
+
+#include <stdint.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+#include <wpi/MathExtras.h>
+#include <wpi/MemAlloc.h>
+#include <wpi/leb128.h>
+
+using namespace nt;
+
+static double ReadDouble(const char*& buf) {
+  // Fast but non-portable!
+  uint64_t val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  val <<= 8;
+  val |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+  ++buf;
+  return wpi::BitsToDouble(val);
+}
+
+WireDecoder::WireDecoder(wpi::raw_istream& is, unsigned int proto_rev,
+                         wpi::Logger& logger)
+    : m_is(is), m_logger(logger) {
+  // Start with a 1K temporary buffer.  Use malloc instead of new so we can
+  // realloc.
+  m_allocated = 1024;
+  m_buf = static_cast<char*>(wpi::safe_malloc(m_allocated));
+  m_proto_rev = proto_rev;
+  m_error = nullptr;
+}
+
+WireDecoder::~WireDecoder() { std::free(m_buf); }
+
+bool WireDecoder::ReadDouble(double* val) {
+  const char* buf;
+  if (!Read(&buf, 8)) return false;
+  *val = ::ReadDouble(buf);
+  return true;
+}
+
+void WireDecoder::Realloc(size_t len) {
+  // Double current buffer size until we have enough space.
+  if (m_allocated >= len) return;
+  size_t newlen = m_allocated * 2;
+  while (newlen < len) newlen *= 2;
+  m_buf = static_cast<char*>(wpi::safe_realloc(m_buf, newlen));
+  m_allocated = newlen;
+}
+
+bool WireDecoder::ReadType(NT_Type* type) {
+  unsigned int itype;
+  if (!Read8(&itype)) return false;
+  // Convert from byte value to enum
+  switch (itype) {
+    case 0x00:
+      *type = NT_BOOLEAN;
+      break;
+    case 0x01:
+      *type = NT_DOUBLE;
+      break;
+    case 0x02:
+      *type = NT_STRING;
+      break;
+    case 0x03:
+      *type = NT_RAW;
+      break;
+    case 0x10:
+      *type = NT_BOOLEAN_ARRAY;
+      break;
+    case 0x11:
+      *type = NT_DOUBLE_ARRAY;
+      break;
+    case 0x12:
+      *type = NT_STRING_ARRAY;
+      break;
+    case 0x20:
+      *type = NT_RPC;
+      break;
+    default:
+      *type = NT_UNASSIGNED;
+      m_error = "unrecognized value type";
+      return false;
+  }
+  return true;
+}
+
+std::shared_ptr<Value> WireDecoder::ReadValue(NT_Type type) {
+  switch (type) {
+    case NT_BOOLEAN: {
+      unsigned int v;
+      if (!Read8(&v)) return nullptr;
+      return Value::MakeBoolean(v != 0);
+    }
+    case NT_DOUBLE: {
+      double v;
+      if (!ReadDouble(&v)) return nullptr;
+      return Value::MakeDouble(v);
+    }
+    case NT_STRING: {
+      std::string v;
+      if (!ReadString(&v)) return nullptr;
+      return Value::MakeString(std::move(v));
+    }
+    case NT_RAW: {
+      if (m_proto_rev < 0x0300u) {
+        m_error = "received raw value in protocol < 3.0";
+        return nullptr;
+      }
+      std::string v;
+      if (!ReadString(&v)) return nullptr;
+      return Value::MakeRaw(std::move(v));
+    }
+    case NT_RPC: {
+      if (m_proto_rev < 0x0300u) {
+        m_error = "received RPC value in protocol < 3.0";
+        return nullptr;
+      }
+      std::string v;
+      if (!ReadString(&v)) return nullptr;
+      return Value::MakeRpc(std::move(v));
+    }
+    case NT_BOOLEAN_ARRAY: {
+      // size
+      unsigned int size;
+      if (!Read8(&size)) return nullptr;
+
+      // array values
+      const char* buf;
+      if (!Read(&buf, size)) return nullptr;
+      std::vector<int> v(size);
+      for (unsigned int i = 0; i < size; ++i) v[i] = buf[i] ? 1 : 0;
+      return Value::MakeBooleanArray(std::move(v));
+    }
+    case NT_DOUBLE_ARRAY: {
+      // size
+      unsigned int size;
+      if (!Read8(&size)) return nullptr;
+
+      // array values
+      const char* buf;
+      if (!Read(&buf, size * 8)) return nullptr;
+      std::vector<double> v(size);
+      for (unsigned int i = 0; i < size; ++i) v[i] = ::ReadDouble(buf);
+      return Value::MakeDoubleArray(std::move(v));
+    }
+    case NT_STRING_ARRAY: {
+      // size
+      unsigned int size;
+      if (!Read8(&size)) return nullptr;
+
+      // array values
+      std::vector<std::string> v(size);
+      for (unsigned int i = 0; i < size; ++i) {
+        if (!ReadString(&v[i])) return nullptr;
+      }
+      return Value::MakeStringArray(std::move(v));
+    }
+    default:
+      m_error = "invalid type when trying to read value";
+      return nullptr;
+  }
+}
+
+bool WireDecoder::ReadString(std::string* str) {
+  size_t len;
+  if (m_proto_rev < 0x0300u) {
+    unsigned int v;
+    if (!Read16(&v)) return false;
+    len = v;
+  } else {
+    uint64_t v;
+    if (!ReadUleb128(&v)) return false;
+    len = v;
+  }
+  const char* buf;
+  if (!Read(&buf, len)) return false;
+  *str = wpi::StringRef(buf, len);
+  return true;
+}
diff --git a/ntcore/src/main/native/cpp/WireDecoder.h b/ntcore/src/main/native/cpp/WireDecoder.h
new file mode 100644
index 0000000..6b4483b
--- /dev/null
+++ b/ntcore/src/main/native/cpp/WireDecoder.h
@@ -0,0 +1,158 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_WIREDECODER_H_
+#define NTCORE_WIREDECODER_H_
+
+#include <stdint.h>
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include <wpi/leb128.h>
+#include <wpi/raw_istream.h>
+
+#include "Log.h"
+#include "networktables/NetworkTableValue.h"
+
+namespace nt {
+
+/* Decodes network data into native representation.
+ * This class is designed to read from a raw_istream, which provides a blocking
+ * read interface.  There are no provisions in this class for resuming a read
+ * that was interrupted partway.  Read functions return false if
+ * raw_istream.read() returned false (indicating the end of the input data
+ * stream).
+ */
+class WireDecoder {
+ public:
+  WireDecoder(wpi::raw_istream& is, unsigned int proto_rev,
+              wpi::Logger& logger);
+  ~WireDecoder();
+
+  void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
+
+  /* Get the active protocol revision. */
+  unsigned int proto_rev() const { return m_proto_rev; }
+
+  /* Get the logger. */
+  wpi::Logger& logger() const { return m_logger; }
+
+  /* Clears error indicator. */
+  void Reset() { m_error = nullptr; }
+
+  /* Returns error indicator (a string describing the error).  Returns nullptr
+   * if no error has occurred.
+   */
+  const char* error() const { return m_error; }
+
+  void set_error(const char* error) { m_error = error; }
+
+  /* Reads the specified number of bytes.
+   * @param buf pointer to read data (output parameter)
+   * @param len number of bytes to read
+   * Caution: the buffer is only temporarily valid.
+   */
+  bool Read(const char** buf, size_t len) {
+    if (len > m_allocated) Realloc(len);
+    *buf = m_buf;
+    m_is.read(m_buf, len);
+#if 0
+    if (m_logger.min_level() <= NT_LOG_DEBUG4 && m_logger.HasLogger()) {
+      std::ostringstream oss;
+      oss << "read " << len << " bytes:" << std::hex;
+      if (!rv) {
+        oss << "error";
+      } else {
+        for (size_t i = 0; i < len; ++i)
+          oss << ' ' << static_cast<unsigned int>((*buf)[i]);
+      }
+      m_logger.Log(NT_LOG_DEBUG4, __FILE__, __LINE__, oss.str().c_str());
+    }
+#endif
+    return !m_is.has_error();
+  }
+
+  /* Reads a single byte. */
+  bool Read8(unsigned int* val) {
+    const char* buf;
+    if (!Read(&buf, 1)) return false;
+    *val = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    return true;
+  }
+
+  /* Reads a 16-bit word. */
+  bool Read16(unsigned int* val) {
+    const char* buf;
+    if (!Read(&buf, 2)) return false;
+    unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    *val = v;
+    return true;
+  }
+
+  /* Reads a 32-bit word. */
+  bool Read32(uint32_t* val) {
+    const char* buf;
+    if (!Read(&buf, 4)) return false;
+    unsigned int v = (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    ++buf;
+    v <<= 8;
+    v |= (*reinterpret_cast<const unsigned char*>(buf)) & 0xff;
+    *val = v;
+    return true;
+  }
+
+  /* Reads a double. */
+  bool ReadDouble(double* val);
+
+  /* Reads an ULEB128-encoded unsigned integer. */
+  bool ReadUleb128(uint64_t* val) { return wpi::ReadUleb128(m_is, val); }
+
+  bool ReadType(NT_Type* type);
+  bool ReadString(std::string* str);
+  std::shared_ptr<Value> ReadValue(NT_Type type);
+
+  WireDecoder(const WireDecoder&) = delete;
+  WireDecoder& operator=(const WireDecoder&) = delete;
+
+ protected:
+  /* The protocol revision.  E.g. 0x0200 for version 2.0. */
+  unsigned int m_proto_rev;
+
+  /* Error indicator. */
+  const char* m_error;
+
+ private:
+  /* Reallocate temporary buffer to specified length. */
+  void Realloc(size_t len);
+
+  /* input stream */
+  wpi::raw_istream& m_is;
+
+  /* logger */
+  wpi::Logger& m_logger;
+
+  /* temporary buffer */
+  char* m_buf;
+
+  /* allocated size of temporary buffer */
+  size_t m_allocated;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_WIREDECODER_H_
diff --git a/ntcore/src/main/native/cpp/WireEncoder.cpp b/ntcore/src/main/native/cpp/WireEncoder.cpp
new file mode 100644
index 0000000..6538349
--- /dev/null
+++ b/ntcore/src/main/native/cpp/WireEncoder.cpp
@@ -0,0 +1,199 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "WireEncoder.h"
+
+#include <stdint.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+#include <wpi/MathExtras.h>
+#include <wpi/leb128.h>
+
+using namespace nt;
+
+WireEncoder::WireEncoder(unsigned int proto_rev) {
+  m_proto_rev = proto_rev;
+  m_error = nullptr;
+}
+
+void WireEncoder::WriteDouble(double val) {
+  // The highest performance way to do this, albeit non-portable.
+  uint64_t v = wpi::DoubleToBits(val);
+  m_data.append(
+      {static_cast<char>((v >> 56) & 0xff), static_cast<char>((v >> 48) & 0xff),
+       static_cast<char>((v >> 40) & 0xff), static_cast<char>((v >> 32) & 0xff),
+       static_cast<char>((v >> 24) & 0xff), static_cast<char>((v >> 16) & 0xff),
+       static_cast<char>((v >> 8) & 0xff), static_cast<char>(v & 0xff)});
+}
+
+void WireEncoder::WriteUleb128(uint32_t val) { wpi::WriteUleb128(m_data, val); }
+
+void WireEncoder::WriteType(NT_Type type) {
+  char ch;
+  // Convert from enum to actual byte value.
+  switch (type) {
+    case NT_BOOLEAN:
+      ch = 0x00;
+      break;
+    case NT_DOUBLE:
+      ch = 0x01;
+      break;
+    case NT_STRING:
+      ch = 0x02;
+      break;
+    case NT_RAW:
+      if (m_proto_rev < 0x0300u) {
+        m_error = "raw type not supported in protocol < 3.0";
+        return;
+      }
+      ch = 0x03;
+      break;
+    case NT_BOOLEAN_ARRAY:
+      ch = 0x10;
+      break;
+    case NT_DOUBLE_ARRAY:
+      ch = 0x11;
+      break;
+    case NT_STRING_ARRAY:
+      ch = 0x12;
+      break;
+    case NT_RPC:
+      if (m_proto_rev < 0x0300u) {
+        m_error = "RPC type not supported in protocol < 3.0";
+        return;
+      }
+      ch = 0x20;
+      break;
+    default:
+      m_error = "unrecognized type";
+      return;
+  }
+  m_data.push_back(ch);
+}
+
+size_t WireEncoder::GetValueSize(const Value& value) const {
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      return 1;
+    case NT_DOUBLE:
+      return 8;
+    case NT_STRING:
+      return GetStringSize(value.GetString());
+    case NT_RAW:
+      if (m_proto_rev < 0x0300u) return 0;
+      return GetStringSize(value.GetRaw());
+    case NT_RPC:
+      if (m_proto_rev < 0x0300u) return 0;
+      return GetStringSize(value.GetRpc());
+    case NT_BOOLEAN_ARRAY: {
+      // 1-byte size, 1 byte per element
+      size_t size = value.GetBooleanArray().size();
+      if (size > 0xff) size = 0xff;  // size is only 1 byte, truncate
+      return 1 + size;
+    }
+    case NT_DOUBLE_ARRAY: {
+      // 1-byte size, 8 bytes per element
+      size_t size = value.GetDoubleArray().size();
+      if (size > 0xff) size = 0xff;  // size is only 1 byte, truncate
+      return 1 + size * 8;
+    }
+    case NT_STRING_ARRAY: {
+      auto v = value.GetStringArray();
+      size_t size = v.size();
+      if (size > 0xff) size = 0xff;  // size is only 1 byte, truncate
+      size_t len = 1;                // 1-byte size
+      for (size_t i = 0; i < size; ++i) len += GetStringSize(v[i]);
+      return len;
+    }
+    default:
+      return 0;
+  }
+}
+
+void WireEncoder::WriteValue(const Value& value) {
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      Write8(value.GetBoolean() ? 1 : 0);
+      break;
+    case NT_DOUBLE:
+      WriteDouble(value.GetDouble());
+      break;
+    case NT_STRING:
+      WriteString(value.GetString());
+      break;
+    case NT_RAW:
+      if (m_proto_rev < 0x0300u) {
+        m_error = "raw values not supported in protocol < 3.0";
+        return;
+      }
+      WriteString(value.GetRaw());
+      break;
+    case NT_RPC:
+      if (m_proto_rev < 0x0300u) {
+        m_error = "RPC values not supported in protocol < 3.0";
+        return;
+      }
+      WriteString(value.GetRpc());
+      break;
+    case NT_BOOLEAN_ARRAY: {
+      auto v = value.GetBooleanArray();
+      size_t size = v.size();
+      if (size > 0xff) size = 0xff;  // size is only 1 byte, truncate
+      Write8(size);
+
+      for (size_t i = 0; i < size; ++i) Write8(v[i] ? 1 : 0);
+      break;
+    }
+    case NT_DOUBLE_ARRAY: {
+      auto v = value.GetDoubleArray();
+      size_t size = v.size();
+      if (size > 0xff) size = 0xff;  // size is only 1 byte, truncate
+      Write8(size);
+
+      for (size_t i = 0; i < size; ++i) WriteDouble(v[i]);
+      break;
+    }
+    case NT_STRING_ARRAY: {
+      auto v = value.GetStringArray();
+      size_t size = v.size();
+      if (size > 0xff) size = 0xff;  // size is only 1 byte, truncate
+      Write8(size);
+
+      for (size_t i = 0; i < size; ++i) WriteString(v[i]);
+      break;
+    }
+    default:
+      m_error = "unrecognized type when writing value";
+      return;
+  }
+}
+
+size_t WireEncoder::GetStringSize(wpi::StringRef str) const {
+  if (m_proto_rev < 0x0300u) {
+    size_t len = str.size();
+    if (len > 0xffff) len = 0xffff;  // Limited to 64K length; truncate
+    return 2 + len;
+  }
+  return wpi::SizeUleb128(str.size()) + str.size();
+}
+
+void WireEncoder::WriteString(wpi::StringRef str) {
+  // length
+  size_t len = str.size();
+  if (m_proto_rev < 0x0300u) {
+    if (len > 0xffff) len = 0xffff;  // Limited to 64K length; truncate
+    Write16(len);
+  } else {
+    WriteUleb128(len);
+  }
+
+  // contents
+  m_data.append(str.data(), str.data() + len);
+}
diff --git a/ntcore/src/main/native/cpp/WireEncoder.h b/ntcore/src/main/native/cpp/WireEncoder.h
new file mode 100644
index 0000000..c4f769c
--- /dev/null
+++ b/ntcore/src/main/native/cpp/WireEncoder.h
@@ -0,0 +1,111 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_WIREENCODER_H_
+#define NTCORE_WIREENCODER_H_
+
+#include <stdint.h>
+
+#include <cassert>
+#include <cstddef>
+
+#include <wpi/SmallVector.h>
+#include <wpi/StringRef.h>
+
+#include "networktables/NetworkTableValue.h"
+
+namespace nt {
+
+/* Encodes native data for network transmission.
+ * This class maintains an internal memory buffer for written data so that
+ * it can be efficiently bursted to the network after a number of writes
+ * have been performed.  For this reason, all operations are non-blocking.
+ */
+class WireEncoder {
+ public:
+  explicit WireEncoder(unsigned int proto_rev);
+
+  /* Change the protocol revision (mostly affects value encoding). */
+  void set_proto_rev(unsigned int proto_rev) { m_proto_rev = proto_rev; }
+
+  /* Get the active protocol revision. */
+  unsigned int proto_rev() const { return m_proto_rev; }
+
+  /* Clears buffer and error indicator. */
+  void Reset() {
+    m_data.clear();
+    m_error = nullptr;
+  }
+
+  /* Returns error indicator (a string describing the error).  Returns nullptr
+   * if no error has occurred.
+   */
+  const char* error() const { return m_error; }
+
+  /* Returns pointer to start of memory buffer with written data. */
+  const char* data() const { return m_data.data(); }
+
+  /* Returns number of bytes written to memory buffer. */
+  size_t size() const { return m_data.size(); }
+
+  wpi::StringRef ToStringRef() const {
+    return wpi::StringRef(m_data.data(), m_data.size());
+  }
+
+  /* Writes a single byte. */
+  void Write8(unsigned int val) {
+    m_data.push_back(static_cast<char>(val & 0xff));
+  }
+
+  /* Writes a 16-bit word. */
+  void Write16(unsigned int val) {
+    m_data.append(
+        {static_cast<char>((val >> 8) & 0xff), static_cast<char>(val & 0xff)});
+  }
+
+  /* Writes a 32-bit word. */
+  void Write32(uint32_t val) {
+    m_data.append({static_cast<char>((val >> 24) & 0xff),
+                   static_cast<char>((val >> 16) & 0xff),
+                   static_cast<char>((val >> 8) & 0xff),
+                   static_cast<char>(val & 0xff)});
+  }
+
+  /* Writes a double. */
+  void WriteDouble(double val);
+
+  /* Writes an ULEB128-encoded unsigned integer. */
+  void WriteUleb128(uint32_t val);
+
+  void WriteType(NT_Type type);
+  void WriteValue(const Value& value);
+  void WriteString(wpi::StringRef str);
+
+  /* Utility function to get the written size of a value (without actually
+   * writing it).
+   */
+  size_t GetValueSize(const Value& value) const;
+
+  /* Utility function to get the written size of a string (without actually
+   * writing it).
+   */
+  size_t GetStringSize(wpi::StringRef str) const;
+
+ protected:
+  /* The protocol revision.  E.g. 0x0200 for version 2.0. */
+  unsigned int m_proto_rev;
+
+  /* Error indicator. */
+  const char* m_error;
+
+ private:
+  wpi::SmallVector<char, 256> m_data;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_WIREENCODER_H_
diff --git a/ntcore/src/main/native/cpp/jni/NetworkTablesJNI.cpp b/ntcore/src/main/native/cpp/jni/NetworkTablesJNI.cpp
new file mode 100644
index 0000000..ac00a3c
--- /dev/null
+++ b/ntcore/src/main/native/cpp/jni/NetworkTablesJNI.cpp
@@ -0,0 +1,1898 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <jni.h>
+
+#include <cassert>
+
+#include <wpi/ConvertUTF.h>
+#include <wpi/SmallString.h>
+#include <wpi/jni_util.h>
+#include <wpi/raw_ostream.h>
+
+#include "edu_wpi_first_networktables_NetworkTablesJNI.h"
+#include "ntcore.h"
+
+using namespace wpi::java;
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+//
+// Globals and load/unload
+//
+
+// Used for callback.
+static JavaVM* jvm = nullptr;
+static JClass booleanCls;
+static JClass connectionInfoCls;
+static JClass connectionNotificationCls;
+static JClass doubleCls;
+static JClass entryInfoCls;
+static JClass entryNotificationCls;
+static JClass logMessageCls;
+static JClass rpcAnswerCls;
+static JClass valueCls;
+static JException illegalArgEx;
+static JException interruptedEx;
+static JException nullPointerEx;
+static JException persistentEx;
+
+static const JClassInit classes[] = {
+    {"java/lang/Boolean", &booleanCls},
+    {"edu/wpi/first/networktables/ConnectionInfo", &connectionInfoCls},
+    {"edu/wpi/first/networktables/ConnectionNotification",
+     &connectionNotificationCls},
+    {"java/lang/Double", &doubleCls},
+    {"edu/wpi/first/networktables/EntryInfo", &entryInfoCls},
+    {"edu/wpi/first/networktables/EntryNotification", &entryNotificationCls},
+    {"edu/wpi/first/networktables/LogMessage", &logMessageCls},
+    {"edu/wpi/first/networktables/RpcAnswer", &rpcAnswerCls},
+    {"edu/wpi/first/networktables/NetworkTableValue", &valueCls}};
+
+static const JExceptionInit exceptions[] = {
+    {"java/lang/IllegalArgumentException", &illegalArgEx},
+    {"java/lang/InterruptedException", &interruptedEx},
+    {"java/lang/NullPointerException", &nullPointerEx},
+    {"edu/wpi/first/networktables/PersistentException", &persistentEx}};
+
+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
+  for (auto& c : classes) {
+    *c.cls = JClass(env, c.name);
+    if (!*c.cls) return JNI_ERR;
+  }
+
+  for (auto& c : exceptions) {
+    *c.cls = JException(env, c.name);
+    if (!*c.cls) return JNI_ERR;
+  }
+
+  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
+  for (auto& c : classes) {
+    c.cls->free(env);
+  }
+  for (auto& c : exceptions) {
+    c.cls->free(env);
+  }
+  jvm = nullptr;
+}
+
+}  // extern "C"
+
+//
+// Conversions from Java objects to C++
+//
+
+inline std::shared_ptr<nt::Value> FromJavaRaw(JNIEnv* env, jbyteArray jarr,
+                                              jlong time) {
+  CriticalJByteArrayRef ref{env, jarr};
+  if (!ref) return nullptr;
+  return nt::Value::MakeRaw(ref, time);
+}
+
+inline std::shared_ptr<nt::Value> FromJavaRawBB(JNIEnv* env, jobject jbb,
+                                                int len, jlong time) {
+  JByteArrayRef ref{env, jbb, len};
+  if (!ref) return nullptr;
+  return nt::Value::MakeRaw(ref.str(), time);
+}
+
+inline std::shared_ptr<nt::Value> FromJavaRpc(JNIEnv* env, jbyteArray jarr,
+                                              jlong time) {
+  CriticalJByteArrayRef ref{env, jarr};
+  if (!ref) return nullptr;
+  return nt::Value::MakeRpc(ref.str(), time);
+}
+
+std::shared_ptr<nt::Value> FromJavaBooleanArray(JNIEnv* env, jbooleanArray jarr,
+                                                jlong time) {
+  CriticalJBooleanArrayRef ref{env, jarr};
+  if (!ref) return nullptr;
+  wpi::ArrayRef<jboolean> elements{ref};
+  size_t len = elements.size();
+  std::vector<int> arr;
+  arr.reserve(len);
+  for (size_t i = 0; i < len; ++i) arr.push_back(elements[i]);
+  return nt::Value::MakeBooleanArray(arr, time);
+}
+
+std::shared_ptr<nt::Value> FromJavaDoubleArray(JNIEnv* env, jdoubleArray jarr,
+                                               jlong time) {
+  CriticalJDoubleArrayRef ref{env, jarr};
+  if (!ref) return nullptr;
+  return nt::Value::MakeDoubleArray(ref, time);
+}
+
+std::shared_ptr<nt::Value> FromJavaStringArray(JNIEnv* env, jobjectArray jarr,
+                                               jlong time) {
+  size_t len = env->GetArrayLength(jarr);
+  std::vector<std::string> arr;
+  arr.reserve(len);
+  for (size_t i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(jarr, i))};
+    if (!elem) return nullptr;
+    arr.push_back(JStringRef{env, elem}.str());
+  }
+  return nt::Value::MakeStringArray(std::move(arr), time);
+}
+
+//
+// Conversions from C++ to Java objects
+//
+
+static jobject MakeJObject(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 MakeJString(env, value.GetString());
+    case NT_RAW:
+      return MakeJByteArray(env, value.GetRaw());
+    case NT_BOOLEAN_ARRAY:
+      return MakeJBooleanArray(env, value.GetBooleanArray());
+    case NT_DOUBLE_ARRAY:
+      return MakeJDoubleArray(env, value.GetDoubleArray());
+    case NT_STRING_ARRAY:
+      return MakeJStringArray(env, value.GetStringArray());
+    case NT_RPC:
+      return MakeJByteArray(env, value.GetRpc());
+    default:
+      return nullptr;
+  }
+}
+
+static jobject MakeJValue(JNIEnv* env, const nt::Value* value) {
+  static jmethodID constructor =
+      env->GetMethodID(valueCls, "<init>", "(ILjava/lang/Object;J)V");
+  if (!value)
+    return env->NewObject(valueCls, constructor, (jint)NT_UNASSIGNED, nullptr,
+                          (jlong)0);
+  return env->NewObject(valueCls, constructor, (jint)value->type(),
+                        MakeJObject(env, *value), (jlong)value->time());
+}
+
+static jobject MakeJObject(JNIEnv* env, const nt::ConnectionInfo& info) {
+  static jmethodID constructor =
+      env->GetMethodID(connectionInfoCls, "<init>",
+                       "(Ljava/lang/String;Ljava/lang/String;IJI)V");
+  JLocal<jstring> remote_id{env, MakeJString(env, info.remote_id)};
+  JLocal<jstring> remote_ip{env, MakeJString(env, info.remote_ip)};
+  return env->NewObject(connectionInfoCls, constructor, remote_id.obj(),
+                        remote_ip.obj(), (jint)info.remote_port,
+                        (jlong)info.last_update, (jint)info.protocol_version);
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst,
+                           const nt::ConnectionNotification& notification) {
+  static jmethodID constructor = env->GetMethodID(
+      connectionNotificationCls, "<init>",
+      "(Ledu/wpi/first/networktables/NetworkTableInstance;IZLedu/wpi/first/"
+      "networktables/ConnectionInfo;)V");
+  JLocal<jobject> conn{env, MakeJObject(env, notification.conn)};
+  return env->NewObject(connectionNotificationCls, constructor, inst,
+                        (jint)notification.listener,
+                        (jboolean)notification.connected, conn.obj());
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst,
+                           const nt::EntryInfo& info) {
+  static jmethodID constructor =
+      env->GetMethodID(entryInfoCls, "<init>",
+                       "(Ledu/wpi/first/networktables/"
+                       "NetworkTableInstance;ILjava/lang/String;IIJ)V");
+  JLocal<jstring> name{env, MakeJString(env, info.name)};
+  return env->NewObject(entryInfoCls, constructor, inst, (jint)info.entry,
+                        name.obj(), (jint)info.type, (jint)info.flags,
+                        (jlong)info.last_change);
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst,
+                           const nt::EntryNotification& notification) {
+  static jmethodID constructor = env->GetMethodID(
+      entryNotificationCls, "<init>",
+      "(Ledu/wpi/first/networktables/NetworkTableInstance;IILjava/lang/"
+      "String;Ledu/wpi/first/networktables/NetworkTableValue;I)V");
+  JLocal<jstring> name{env, MakeJString(env, notification.name)};
+  JLocal<jobject> value{env, MakeJValue(env, notification.value.get())};
+  return env->NewObject(entryNotificationCls, constructor, inst,
+                        (jint)notification.listener, (jint)notification.entry,
+                        name.obj(), value.obj(), (jint)notification.flags);
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst,
+                           const nt::LogMessage& msg) {
+  static jmethodID constructor = env->GetMethodID(
+      logMessageCls, "<init>",
+      "(Ledu/wpi/first/networktables/NetworkTableInstance;IILjava/lang/"
+      "String;ILjava/lang/String;)V");
+  JLocal<jstring> filename{env, MakeJString(env, msg.filename)};
+  JLocal<jstring> message{env, MakeJString(env, msg.message)};
+  return env->NewObject(logMessageCls, constructor, inst, (jint)msg.logger,
+                        (jint)msg.level, filename.obj(), (jint)msg.line,
+                        message.obj());
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst,
+                           const nt::RpcAnswer& answer) {
+  static jmethodID constructor =
+      env->GetMethodID(rpcAnswerCls, "<init>",
+                       "(Ledu/wpi/first/networktables/"
+                       "NetworkTableInstance;IILjava/lang/String;[B"
+                       "Ledu/wpi/first/networktables/ConnectionInfo;)V");
+  JLocal<jstring> name{env, MakeJString(env, answer.name)};
+  JLocal<jbyteArray> params{env, MakeJByteArray(env, answer.params)};
+  JLocal<jobject> conn{env, MakeJObject(env, answer.conn)};
+  return env->NewObject(rpcAnswerCls, constructor, inst, (jint)answer.entry,
+                        (jint)answer.call, name.obj(), params.obj(),
+                        conn.obj());
+}
+
+static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
+                                wpi::ArrayRef<nt::ConnectionNotification> arr) {
+  jobjectArray jarr =
+      env->NewObjectArray(arr.size(), connectionNotificationCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+
+static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
+                                wpi::ArrayRef<nt::EntryNotification> arr) {
+  jobjectArray jarr =
+      env->NewObjectArray(arr.size(), entryNotificationCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+
+static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
+                                wpi::ArrayRef<nt::LogMessage> arr) {
+  jobjectArray jarr = env->NewObjectArray(arr.size(), logMessageCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+
+static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
+                                wpi::ArrayRef<nt::RpcAnswer> arr) {
+  jobjectArray jarr = env->NewObjectArray(arr.size(), rpcAnswerCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+
+extern "C" {
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getDefaultInstance
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getDefaultInstance
+  (JNIEnv*, jclass)
+{
+  return nt::GetDefaultInstance();
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    createInstance
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance
+  (JNIEnv*, jclass)
+{
+  return nt::CreateInstance();
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    destroyInstance
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyInstance
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::DestroyInstance(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getInstanceFromHandle
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getInstanceFromHandle
+  (JNIEnv*, jclass, jint handle)
+{
+  return nt::GetInstanceFromHandle(handle);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntry
+ * Signature: (ILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntry
+  (JNIEnv* env, jclass, jint inst, jstring key)
+{
+  if (!key) {
+    nullPointerEx.Throw(env, "key cannot be null");
+    return false;
+  }
+  return nt::GetEntry(inst, JStringRef{env, key}.str());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntries
+ * Signature: (ILjava/lang/String;I)[I
+ */
+JNIEXPORT jintArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntries
+  (JNIEnv* env, jclass, jint inst, jstring prefix, jint types)
+{
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
+  }
+  return MakeJIntArray(
+      env, nt::GetEntries(inst, JStringRef{env, prefix}.str(), types));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntryName
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryName
+  (JNIEnv* env, jclass, jint entry)
+{
+  return MakeJString(env, nt::GetEntryName(entry));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntryLastChange
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryLastChange
+  (JNIEnv*, jclass, jint entry)
+{
+  return nt::GetEntryLastChange(entry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getType
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getType
+  (JNIEnv*, jclass, jint entry)
+{
+  return nt::GetEntryType(entry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setBoolean
+ * Signature: (IJZZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setBoolean
+  (JNIEnv*, jclass, jint entry, jlong time, jboolean value, jboolean force)
+{
+  if (force) {
+    nt::SetEntryTypeValue(entry,
+                          nt::Value::MakeBoolean(value != JNI_FALSE, time));
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry,
+                           nt::Value::MakeBoolean(value != JNI_FALSE, time));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDouble
+ * Signature: (IJDZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDouble
+  (JNIEnv*, jclass, jint entry, jlong time, jdouble value, jboolean force)
+{
+  if (force) {
+    nt::SetEntryTypeValue(entry, nt::Value::MakeDouble(value, time));
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry, nt::Value::MakeDouble(value, time));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setString
+ * Signature: (IJLjava/lang/String;Z)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setString
+  (JNIEnv* env, jclass, jint entry, jlong time, jstring value, jboolean force)
+{
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+  if (force) {
+    nt::SetEntryTypeValue(
+        entry, nt::Value::MakeString(JStringRef{env, value}.str(), time));
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(
+      entry, nt::Value::MakeString(JStringRef{env, value}.str(), time));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setRaw
+ * Signature: (IJ[BZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw__IJ_3BZ
+  (JNIEnv* env, jclass, jint entry, jlong time, jbyteArray value,
+   jboolean force)
+{
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+  auto v = FromJavaRaw(env, value, time);
+  if (!v) return false;
+  if (force) {
+    nt::SetEntryTypeValue(entry, v);
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setRaw
+ * Signature: (IJLjava/lang/Object;IZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw__IJLjava_nio_ByteBuffer_2IZ
+  (JNIEnv* env, jclass, jint entry, jlong time, jobject value, jint len,
+   jboolean force)
+{
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+  auto v = FromJavaRawBB(env, value, len, time);
+  if (!v) return false;
+  if (force) {
+    nt::SetEntryTypeValue(entry, v);
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setBooleanArray
+ * Signature: (IJ[ZZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setBooleanArray
+  (JNIEnv* env, jclass, jint entry, jlong time, jbooleanArray value,
+   jboolean force)
+{
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+  auto v = FromJavaBooleanArray(env, value, time);
+  if (!v) return false;
+  if (force) {
+    nt::SetEntryTypeValue(entry, v);
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDoubleArray
+ * Signature: (IJ[DZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDoubleArray
+  (JNIEnv* env, jclass, jint entry, jlong time, jdoubleArray value,
+   jboolean force)
+{
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+  auto v = FromJavaDoubleArray(env, value, time);
+  if (!v) return false;
+  if (force) {
+    nt::SetEntryTypeValue(entry, v);
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setStringArray
+ * Signature: (IJ[Ljava/lang/Object;Z)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setStringArray
+  (JNIEnv* env, jclass, jint entry, jlong time, jobjectArray value,
+   jboolean force)
+{
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+  auto v = FromJavaStringArray(env, value, time);
+  if (!v) return false;
+  if (force) {
+    nt::SetEntryTypeValue(entry, v);
+    return JNI_TRUE;
+  }
+  return nt::SetEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getValue
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getValue
+  (JNIEnv* env, jclass, jint entry)
+{
+  auto val = nt::GetEntryValue(entry);
+  return MakeJValue(env, val.get());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getBoolean
+ * Signature: (IZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getBoolean
+  (JNIEnv*, jclass, jint entry, jboolean defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsBoolean()) return defaultValue;
+  return val->GetBoolean();
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getDouble
+ * Signature: (ID)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getDouble
+  (JNIEnv*, jclass, jint entry, jdouble defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsDouble()) return defaultValue;
+  return val->GetDouble();
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getString
+ * Signature: (ILjava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getString
+  (JNIEnv* env, jclass, jint entry, jstring defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsString()) return defaultValue;
+  return MakeJString(env, val->GetString());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getRaw
+ * Signature: (I[B)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getRaw
+  (JNIEnv* env, jclass, jint entry, jbyteArray defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsRaw()) return defaultValue;
+  return MakeJByteArray(env, val->GetRaw());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getBooleanArray
+ * Signature: (I[Z)[Z
+ */
+JNIEXPORT jbooleanArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getBooleanArray
+  (JNIEnv* env, jclass, jint entry, jbooleanArray defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsBooleanArray()) return defaultValue;
+  return MakeJBooleanArray(env, val->GetBooleanArray());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getDoubleArray
+ * Signature: (I[D)[D
+ */
+JNIEXPORT jdoubleArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getDoubleArray
+  (JNIEnv* env, jclass, jint entry, jdoubleArray defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsDoubleArray()) return defaultValue;
+  return MakeJDoubleArray(env, val->GetDoubleArray());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getStringArray
+ * Signature: (I[Ljava/lang/Object;)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getStringArray
+  (JNIEnv* env, jclass, jint entry, jobjectArray defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsStringArray()) return defaultValue;
+  return MakeJStringArray(env, val->GetStringArray());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultBoolean
+ * Signature: (IJZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultBoolean
+  (JNIEnv*, jclass, jint entry, jlong time, jboolean defaultValue)
+{
+  return nt::SetDefaultEntryValue(
+      entry, nt::Value::MakeBoolean(defaultValue != JNI_FALSE, time));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultDouble
+ * Signature: (IJD)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultDouble
+  (JNIEnv*, jclass, jint entry, jlong time, jdouble defaultValue)
+{
+  return nt::SetDefaultEntryValue(entry,
+                                  nt::Value::MakeDouble(defaultValue, time));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultString
+ * Signature: (IJLjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultString
+  (JNIEnv* env, jclass, jint entry, jlong time, jstring defaultValue)
+{
+  if (!defaultValue) {
+    nullPointerEx.Throw(env, "defaultValue cannot be null");
+    return false;
+  }
+  return nt::SetDefaultEntryValue(
+      entry, nt::Value::MakeString(JStringRef{env, defaultValue}.str(), time));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultRaw
+ * Signature: (IJ[B)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultRaw
+  (JNIEnv* env, jclass, jint entry, jlong time, jbyteArray defaultValue)
+{
+  if (!defaultValue) {
+    nullPointerEx.Throw(env, "defaultValue cannot be null");
+    return false;
+  }
+  auto v = FromJavaRaw(env, defaultValue, time);
+  return nt::SetDefaultEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultBooleanArray
+ * Signature: (IJ[Z)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultBooleanArray
+  (JNIEnv* env, jclass, jint entry, jlong time, jbooleanArray defaultValue)
+{
+  if (!defaultValue) {
+    nullPointerEx.Throw(env, "defaultValue cannot be null");
+    return false;
+  }
+  auto v = FromJavaBooleanArray(env, defaultValue, time);
+  return nt::SetDefaultEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultDoubleArray
+ * Signature: (IJ[D)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultDoubleArray
+  (JNIEnv* env, jclass, jint entry, jlong time, jdoubleArray defaultValue)
+{
+  if (!defaultValue) {
+    nullPointerEx.Throw(env, "defaultValue cannot be null");
+    return false;
+  }
+  auto v = FromJavaDoubleArray(env, defaultValue, time);
+  return nt::SetDefaultEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefaultStringArray
+ * Signature: (IJ[Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultStringArray
+  (JNIEnv* env, jclass, jint entry, jlong time, jobjectArray defaultValue)
+{
+  if (!defaultValue) {
+    nullPointerEx.Throw(env, "defaultValue cannot be null");
+    return false;
+  }
+  auto v = FromJavaStringArray(env, defaultValue, time);
+  return nt::SetDefaultEntryValue(entry, v);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setEntryFlags
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setEntryFlags
+  (JNIEnv*, jclass, jint entry, jint flags)
+{
+  nt::SetEntryFlags(entry, flags);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntryFlags
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryFlags
+  (JNIEnv*, jclass, jint entry)
+{
+  return nt::GetEntryFlags(entry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    deleteEntry
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_deleteEntry
+  (JNIEnv*, jclass, jint entry)
+{
+  nt::DeleteEntry(entry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    deleteAllEntries
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_deleteAllEntries
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::DeleteAllEntries(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntryInfoHandle
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryInfoHandle
+  (JNIEnv* env, jclass, jobject inst, jint entry)
+{
+  return MakeJObject(env, inst, nt::GetEntryInfo(entry));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntryInfo
+ * Signature: (Ljava/lang/Object;ILjava/lang/String;I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryInfo
+  (JNIEnv* env, jclass, jobject instObject, jint inst, jstring prefix,
+   jint types)
+{
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
+  }
+  auto arr = nt::GetEntryInfo(inst, JStringRef{env, prefix}.str(), types);
+  jobjectArray jarr = env->NewObjectArray(arr.size(), entryInfoCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> jelem{env, MakeJObject(env, instObject, arr[i])};
+    env->SetObjectArrayElement(jarr, i, jelem);
+  }
+  return jarr;
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    createEntryListenerPoller
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createEntryListenerPoller
+  (JNIEnv*, jclass, jint inst)
+{
+  return nt::CreateEntryListenerPoller(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    destroyEntryListenerPoller
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyEntryListenerPoller
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::DestroyEntryListenerPoller(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    addPolledEntryListener
+ * Signature: (ILjava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addPolledEntryListener__ILjava_lang_String_2I
+  (JNIEnv* env, jclass, jint poller, jstring prefix, jint flags)
+{
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return 0;
+  }
+  return nt::AddPolledEntryListener(poller, JStringRef{env, prefix}.str(),
+                                    flags);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    addPolledEntryListener
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addPolledEntryListener__III
+  (JNIEnv* env, jclass, jint poller, jint entry, jint flags)
+{
+  return nt::AddPolledEntryListener(poller, entry, flags);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollEntryListener
+ * Signature: (Ljava/lang/Object;I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollEntryListener
+  (JNIEnv* env, jclass, jobject inst, jint poller)
+{
+  auto events = nt::PollEntryListener(poller);
+  if (events.empty()) {
+    interruptedEx.Throw(env, "PollEntryListener interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, events);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollEntryListenerTimeout
+ * Signature: (Ljava/lang/Object;ID)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollEntryListenerTimeout
+  (JNIEnv* env, jclass, jobject inst, jint poller, jdouble timeout)
+{
+  bool timed_out = false;
+  auto events = nt::PollEntryListener(poller, timeout, &timed_out);
+  if (events.empty() && !timed_out) {
+    interruptedEx.Throw(env, "PollEntryListener interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, events);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    cancelPollEntryListener
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_cancelPollEntryListener
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::CancelPollEntryListener(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    removeEntryListener
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_removeEntryListener
+  (JNIEnv*, jclass, jint entryListenerUid)
+{
+  nt::RemoveEntryListener(entryListenerUid);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    waitForEntryListenerQueue
+ * Signature: (ID)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_waitForEntryListenerQueue
+  (JNIEnv*, jclass, jint inst, jdouble timeout)
+{
+  return nt::WaitForEntryListenerQueue(inst, timeout);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    createConnectionListenerPoller
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createConnectionListenerPoller
+  (JNIEnv*, jclass, jint inst)
+{
+  return nt::CreateConnectionListenerPoller(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    destroyConnectionListenerPoller
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyConnectionListenerPoller
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::DestroyConnectionListenerPoller(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    addPolledConnectionListener
+ * Signature: (IZ)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addPolledConnectionListener
+  (JNIEnv* env, jclass, jint poller, jboolean immediateNotify)
+{
+  return nt::AddPolledConnectionListener(poller, immediateNotify);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollConnectionListener
+ * Signature: (Ljava/lang/Object;I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollConnectionListener
+  (JNIEnv* env, jclass, jobject inst, jint poller)
+{
+  auto events = nt::PollConnectionListener(poller);
+  if (events.empty()) {
+    interruptedEx.Throw(env, "PollConnectionListener interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, events);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollConnectionListenerTimeout
+ * Signature: (Ljava/lang/Object;ID)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollConnectionListenerTimeout
+  (JNIEnv* env, jclass, jobject inst, jint poller, jdouble timeout)
+{
+  bool timed_out = false;
+  auto events = nt::PollConnectionListener(poller, timeout, &timed_out);
+  if (events.empty() && !timed_out) {
+    interruptedEx.Throw(env, "PollConnectionListener interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, events);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    cancelPollConnectionListener
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_cancelPollConnectionListener
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::CancelPollConnectionListener(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    removeConnectionListener
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_removeConnectionListener
+  (JNIEnv*, jclass, jint connListenerUid)
+{
+  nt::RemoveConnectionListener(connListenerUid);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    waitForConnectionListenerQueue
+ * Signature: (ID)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_waitForConnectionListenerQueue
+  (JNIEnv*, jclass, jint inst, jdouble timeout)
+{
+  return nt::WaitForConnectionListenerQueue(inst, timeout);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    createRpcCallPoller
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createRpcCallPoller
+  (JNIEnv*, jclass, jint inst)
+{
+  return nt::CreateRpcCallPoller(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    destroyRpcCallPoller
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyRpcCallPoller
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::DestroyRpcCallPoller(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    createPolledRpc
+ * Signature: (I[BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createPolledRpc
+  (JNIEnv* env, jclass, jint entry, jbyteArray def, jint poller)
+{
+  if (!def) {
+    nullPointerEx.Throw(env, "def cannot be null");
+    return;
+  }
+  nt::CreatePolledRpc(entry, JByteArrayRef{env, def}, poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollRpc
+ * Signature: (Ljava/lang/Object;I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollRpc
+  (JNIEnv* env, jclass, jobject inst, jint poller)
+{
+  auto infos = nt::PollRpc(poller);
+  if (infos.empty()) {
+    interruptedEx.Throw(env, "PollRpc interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, infos);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollRpcTimeout
+ * Signature: (Ljava/lang/Object;ID)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollRpcTimeout
+  (JNIEnv* env, jclass, jobject inst, jint poller, jdouble timeout)
+{
+  bool timed_out = false;
+  auto infos = nt::PollRpc(poller, timeout, &timed_out);
+  if (infos.empty() && !timed_out) {
+    interruptedEx.Throw(env, "PollRpc interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, infos);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    cancelPollRpc
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_cancelPollRpc
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::CancelPollRpc(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    waitForRpcCallQueue
+ * Signature: (ID)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_waitForRpcCallQueue
+  (JNIEnv*, jclass, jint inst, jdouble timeout)
+{
+  return nt::WaitForRpcCallQueue(inst, timeout);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    postRpcResponse
+ * Signature: (II[B)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_postRpcResponse
+  (JNIEnv* env, jclass, jint entry, jint call, jbyteArray result)
+{
+  if (!result) {
+    nullPointerEx.Throw(env, "result cannot be null");
+    return false;
+  }
+  return nt::PostRpcResponse(entry, call, JByteArrayRef{env, result});
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    callRpc
+ * Signature: (I[B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_callRpc
+  (JNIEnv* env, jclass, jint entry, jbyteArray params)
+{
+  if (!params) {
+    nullPointerEx.Throw(env, "params cannot be null");
+    return 0;
+  }
+  return nt::CallRpc(entry, JByteArrayRef{env, params});
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getRpcResult
+ * Signature: (II)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getRpcResult__II
+  (JNIEnv* env, jclass, jint entry, jint call)
+{
+  std::string result;
+  if (!nt::GetRpcResult(entry, call, &result)) return nullptr;
+  return MakeJByteArray(env, result);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getRpcResult
+ * Signature: (IID)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getRpcResult__IID
+  (JNIEnv* env, jclass, jint entry, jint call, jdouble timeout)
+{
+  std::string result;
+  bool timed_out = false;
+  if (!nt::GetRpcResult(entry, call, &result, timeout, &timed_out))
+    return nullptr;
+  return MakeJByteArray(env, result);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    cancelRpcResult
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_cancelRpcResult
+  (JNIEnv*, jclass, jint entry, jint call)
+{
+  nt::CancelRpcResult(entry, call);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getRpc
+ * Signature: (I[B)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getRpc
+  (JNIEnv* env, jclass, jint entry, jbyteArray defaultValue)
+{
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val->IsRpc()) return defaultValue;
+  return MakeJByteArray(env, val->GetRpc());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setNetworkIdentity
+ * Signature: (ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setNetworkIdentity
+  (JNIEnv* env, jclass, jint inst, jstring name)
+{
+  if (!name) {
+    nullPointerEx.Throw(env, "name cannot be null");
+    return;
+  }
+  nt::SetNetworkIdentity(inst, JStringRef{env, name}.str());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getNetworkMode
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getNetworkMode
+  (JNIEnv*, jclass, jint inst)
+{
+  return nt::GetNetworkMode(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startLocal
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startLocal
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::StartLocal(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    stopLocal
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_stopLocal
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::StopLocal(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startServer
+ * Signature: (ILjava/lang/String;Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startServer
+  (JNIEnv* env, jclass, jint inst, jstring persistFilename,
+   jstring listenAddress, jint port)
+{
+  if (!persistFilename) {
+    nullPointerEx.Throw(env, "persistFilename cannot be null");
+    return;
+  }
+  if (!listenAddress) {
+    nullPointerEx.Throw(env, "listenAddress cannot be null");
+    return;
+  }
+  nt::StartServer(inst, JStringRef{env, persistFilename}.str(),
+                  JStringRef{env, listenAddress}.c_str(), port);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    stopServer
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_stopServer
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::StopServer(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startClient
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient__I
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::StartClient(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startClient
+ * Signature: (ILjava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient__ILjava_lang_String_2I
+  (JNIEnv* env, jclass, jint inst, jstring serverName, jint port)
+{
+  if (!serverName) {
+    nullPointerEx.Throw(env, "serverName cannot be null");
+    return;
+  }
+  nt::StartClient(inst, JStringRef{env, serverName}.c_str(), port);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startClient
+ * Signature: (I[Ljava/lang/Object;[I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient__I_3Ljava_lang_String_2_3I
+  (JNIEnv* env, jclass, jint inst, jobjectArray serverNames, jintArray ports)
+{
+  if (!serverNames) {
+    nullPointerEx.Throw(env, "serverNames cannot be null");
+    return;
+  }
+  if (!ports) {
+    nullPointerEx.Throw(env, "ports cannot be null");
+    return;
+  }
+  int len = env->GetArrayLength(serverNames);
+  if (len != env->GetArrayLength(ports)) {
+    illegalArgEx.Throw(env,
+                       "serverNames and ports arrays must be the same size");
+    return;
+  }
+  jint* portInts = env->GetIntArrayElements(ports, nullptr);
+  if (!portInts) return;
+
+  std::vector<std::string> names;
+  std::vector<std::pair<nt::StringRef, unsigned int>> servers;
+  names.reserve(len);
+  servers.reserve(len);
+  for (int i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(serverNames, i))};
+    if (!elem) {
+      nullPointerEx.Throw(env, "null string in serverNames");
+      return;
+    }
+    names.emplace_back(JStringRef{env, elem}.str());
+    servers.emplace_back(
+        std::make_pair(nt::StringRef(names.back()), portInts[i]));
+  }
+  env->ReleaseIntArrayElements(ports, portInts, JNI_ABORT);
+  nt::StartClient(inst, servers);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startClientTeam
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startClientTeam
+  (JNIEnv* env, jclass cls, jint inst, jint team, jint port)
+{
+  nt::StartClientTeam(inst, team, port);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    stopClient
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_stopClient
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::StopClient(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setServer
+ * Signature: (ILjava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setServer__ILjava_lang_String_2I
+  (JNIEnv* env, jclass, jint inst, jstring serverName, jint port)
+{
+  if (!serverName) {
+    nullPointerEx.Throw(env, "serverName cannot be null");
+    return;
+  }
+  nt::SetServer(inst, JStringRef{env, serverName}.c_str(), port);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setServer
+ * Signature: (I[Ljava/lang/Object;[I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setServer__I_3Ljava_lang_String_2_3I
+  (JNIEnv* env, jclass, jint inst, jobjectArray serverNames, jintArray ports)
+{
+  if (!serverNames) {
+    nullPointerEx.Throw(env, "serverNames cannot be null");
+    return;
+  }
+  if (!ports) {
+    nullPointerEx.Throw(env, "ports cannot be null");
+    return;
+  }
+  int len = env->GetArrayLength(serverNames);
+  if (len != env->GetArrayLength(ports)) {
+    illegalArgEx.Throw(env,
+                       "serverNames and ports arrays must be the same size");
+    return;
+  }
+  jint* portInts = env->GetIntArrayElements(ports, nullptr);
+  if (!portInts) return;
+
+  std::vector<std::string> names;
+  std::vector<std::pair<nt::StringRef, unsigned int>> servers;
+  names.reserve(len);
+  servers.reserve(len);
+  for (int i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(serverNames, i))};
+    if (!elem) {
+      nullPointerEx.Throw(env, "null string in serverNames");
+      return;
+    }
+    names.emplace_back(JStringRef{env, elem}.str());
+    servers.emplace_back(
+        std::make_pair(nt::StringRef(names.back()), portInts[i]));
+  }
+  env->ReleaseIntArrayElements(ports, portInts, JNI_ABORT);
+  nt::SetServer(inst, servers);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setServerTeam
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setServerTeam
+  (JNIEnv* env, jclass, jint inst, jint team, jint port)
+{
+  nt::SetServerTeam(inst, team, port);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    startDSClient
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startDSClient
+  (JNIEnv*, jclass, jint inst, jint port)
+{
+  nt::StartDSClient(inst, port);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    stopDSClient
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_stopDSClient
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::StopDSClient(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setUpdateRate
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setUpdateRate
+  (JNIEnv*, jclass, jint inst, jdouble interval)
+{
+  nt::SetUpdateRate(inst, interval);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    flush
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_flush
+  (JNIEnv*, jclass, jint inst)
+{
+  nt::Flush(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getConnections
+ * Signature: (I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getConnections
+  (JNIEnv* env, jclass, jint inst)
+{
+  auto arr = nt::GetConnections(inst);
+  jobjectArray jarr =
+      env->NewObjectArray(arr.size(), connectionInfoCls, nullptr);
+  if (!jarr) return nullptr;
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> jelem{env, MakeJObject(env, arr[i])};
+    env->SetObjectArrayElement(jarr, i, jelem);
+  }
+  return jarr;
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    isConnected
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_isConnected
+  (JNIEnv*, jclass, jint inst)
+{
+  return nt::IsConnected(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    savePersistent
+ * Signature: (ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_savePersistent
+  (JNIEnv* env, jclass, jint inst, jstring filename)
+{
+  if (!filename) {
+    nullPointerEx.Throw(env, "filename cannot be null");
+    return;
+  }
+  const char* err = nt::SavePersistent(inst, JStringRef{env, filename}.str());
+  if (err) persistentEx.Throw(env, err);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    loadPersistent
+ * Signature: (ILjava/lang/String;)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_loadPersistent
+  (JNIEnv* env, jclass, jint inst, jstring filename)
+{
+  if (!filename) {
+    nullPointerEx.Throw(env, "filename cannot be null");
+    return nullptr;
+  }
+  std::vector<std::string> warns;
+  const char* err = nt::LoadPersistent(inst, JStringRef{env, filename}.str(),
+                                       [&](size_t line, const char* msg) {
+                                         wpi::SmallString<128> warn;
+                                         wpi::raw_svector_ostream oss(warn);
+                                         oss << line << ": " << msg;
+                                         warns.emplace_back(oss.str());
+                                       });
+  if (err) {
+    persistentEx.Throw(env, err);
+    return nullptr;
+  }
+  return MakeJStringArray(env, warns);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    saveEntries
+ * Signature: (ILjava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_saveEntries
+  (JNIEnv* env, jclass, jint inst, jstring filename, jstring prefix)
+{
+  if (!filename) {
+    nullPointerEx.Throw(env, "filename cannot be null");
+    return;
+  }
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return;
+  }
+  const char* err = nt::SaveEntries(inst, JStringRef{env, filename}.str(),
+                                    JStringRef{env, prefix}.str());
+  if (err) persistentEx.Throw(env, err);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    loadEntries
+ * Signature: (ILjava/lang/String;Ljava/lang/String;)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_loadEntries
+  (JNIEnv* env, jclass, jint inst, jstring filename, jstring prefix)
+{
+  if (!filename) {
+    nullPointerEx.Throw(env, "filename cannot be null");
+    return nullptr;
+  }
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
+  }
+  std::vector<std::string> warns;
+  const char* err = nt::LoadEntries(inst, JStringRef{env, filename}.str(),
+                                    JStringRef{env, prefix}.str(),
+                                    [&](size_t line, const char* msg) {
+                                      wpi::SmallString<128> warn;
+                                      wpi::raw_svector_ostream oss(warn);
+                                      oss << line << ": " << msg;
+                                      warns.emplace_back(oss.str());
+                                    });
+  if (err) {
+    persistentEx.Throw(env, err);
+    return nullptr;
+  }
+  return MakeJStringArray(env, warns);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    now
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_now
+  (JNIEnv*, jclass)
+{
+  return nt::Now();
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    createLoggerPoller
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createLoggerPoller
+  (JNIEnv*, jclass, jint inst)
+{
+  return nt::CreateLoggerPoller(inst);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    destroyLoggerPoller
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyLoggerPoller
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::DestroyLoggerPoller(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    addPolledLogger
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addPolledLogger
+  (JNIEnv*, jclass, jint poller, jint minLevel, jint maxLevel)
+{
+  return nt::AddPolledLogger(poller, minLevel, maxLevel);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollLogger
+ * Signature: (Ljava/lang/Object;I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollLogger
+  (JNIEnv* env, jclass, jobject inst, jint poller)
+{
+  auto events = nt::PollLogger(poller);
+  if (events.empty()) {
+    interruptedEx.Throw(env, "PollLogger interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, events);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    pollLoggerTimeout
+ * Signature: (Ljava/lang/Object;ID)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_pollLoggerTimeout
+  (JNIEnv* env, jclass, jobject inst, jint poller, jdouble timeout)
+{
+  bool timed_out = false;
+  auto events = nt::PollLogger(poller, timeout, &timed_out);
+  if (events.empty() && !timed_out) {
+    interruptedEx.Throw(env, "PollLogger interrupted");
+    return nullptr;
+  }
+  return MakeJObject(env, inst, events);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    cancelPollLogger
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_cancelPollLogger
+  (JNIEnv*, jclass, jint poller)
+{
+  nt::CancelPollLogger(poller);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    removeLogger
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_removeLogger
+  (JNIEnv*, jclass, jint logger)
+{
+  nt::RemoveLogger(logger);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    waitForLoggerQueue
+ * Signature: (ID)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_waitForLoggerQueue
+  (JNIEnv*, jclass, jint inst, jdouble timeout)
+{
+  return nt::WaitForLoggerQueue(inst, timeout);
+}
+
+}  // extern "C"
diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp
new file mode 100644
index 0000000..6d41976
--- /dev/null
+++ b/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp
@@ -0,0 +1,564 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "networktables/NetworkTable.h"
+
+#include <algorithm>
+
+#include <wpi/SmallString.h>
+#include <wpi/StringMap.h>
+#include <wpi/raw_ostream.h>
+
+#include "networktables/NetworkTableInstance.h"
+#include "ntcore.h"
+#include "tables/ITableListener.h"
+
+using namespace nt;
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif _WIN32
+#pragma warning(disable : 4996)
+#endif
+
+const char NetworkTable::PATH_SEPARATOR_CHAR = '/';
+std::string NetworkTable::s_persistent_filename = "networktables.ini";
+bool NetworkTable::s_client = false;
+bool NetworkTable::s_enable_ds = true;
+bool NetworkTable::s_running = false;
+unsigned int NetworkTable::s_port = NT_DEFAULT_PORT;
+
+StringRef NetworkTable::BasenameKey(StringRef key) {
+  size_t slash = key.rfind(PATH_SEPARATOR_CHAR);
+  if (slash == StringRef::npos) return key;
+  return key.substr(slash + 1);
+}
+
+std::string NetworkTable::NormalizeKey(const Twine& key,
+                                       bool withLeadingSlash) {
+  wpi::SmallString<128> buf;
+  return NormalizeKey(key, buf, withLeadingSlash);
+}
+
+StringRef NetworkTable::NormalizeKey(const Twine& key,
+                                     wpi::SmallVectorImpl<char>& buf,
+                                     bool withLeadingSlash) {
+  buf.clear();
+  if (withLeadingSlash) buf.push_back(PATH_SEPARATOR_CHAR);
+  // for each path element, add it with a slash following
+  wpi::SmallString<128> keyBuf;
+  StringRef keyStr = key.toStringRef(keyBuf);
+  wpi::SmallVector<StringRef, 16> parts;
+  keyStr.split(parts, PATH_SEPARATOR_CHAR, -1, false);
+  for (auto i = parts.begin(); i != parts.end(); ++i) {
+    buf.append(i->begin(), i->end());
+    buf.push_back(PATH_SEPARATOR_CHAR);
+  }
+  // remove trailing slash if the input key didn't have one
+  if (!keyStr.empty() && keyStr.back() != PATH_SEPARATOR_CHAR) buf.pop_back();
+  return StringRef(buf.data(), buf.size());
+}
+
+std::vector<std::string> NetworkTable::GetHierarchy(const Twine& key) {
+  std::vector<std::string> hierarchy;
+  hierarchy.emplace_back(1, PATH_SEPARATOR_CHAR);
+  // for each path element, add it to the end of what we built previously
+  wpi::SmallString<128> keyBuf;
+  StringRef keyStr = key.toStringRef(keyBuf);
+  wpi::SmallString<128> path;
+  wpi::SmallVector<StringRef, 16> parts;
+  keyStr.split(parts, PATH_SEPARATOR_CHAR, -1, false);
+  if (!parts.empty()) {
+    for (auto i = parts.begin(); i != parts.end(); ++i) {
+      path += PATH_SEPARATOR_CHAR;
+      path += *i;
+      hierarchy.emplace_back(path.str());
+    }
+    // handle trailing slash
+    if (keyStr.back() == PATH_SEPARATOR_CHAR) {
+      path += PATH_SEPARATOR_CHAR;
+      hierarchy.emplace_back(path.str());
+    }
+  }
+  return hierarchy;
+}
+
+void NetworkTable::Initialize() {
+  if (s_running) Shutdown();
+  auto inst = NetworkTableInstance::GetDefault();
+  if (s_client) {
+    inst.StartClient();
+    if (s_enable_ds) inst.StartDSClient(s_port);
+  } else {
+    inst.StartServer(s_persistent_filename, "", s_port);
+  }
+  s_running = true;
+}
+
+void NetworkTable::Shutdown() {
+  if (!s_running) return;
+  auto inst = NetworkTableInstance::GetDefault();
+  if (s_client) {
+    inst.StopDSClient();
+    inst.StopClient();
+  } else {
+    inst.StopServer();
+  }
+  s_running = false;
+}
+
+void NetworkTable::SetClientMode() { s_client = true; }
+
+void NetworkTable::SetServerMode() { s_client = false; }
+
+void NetworkTable::SetTeam(int team) {
+  auto inst = NetworkTableInstance::GetDefault();
+  inst.SetServerTeam(team, s_port);
+  if (s_enable_ds) inst.StartDSClient(s_port);
+}
+
+void NetworkTable::SetIPAddress(StringRef address) {
+  auto inst = NetworkTableInstance::GetDefault();
+  wpi::SmallString<32> addr_copy{address};
+  inst.SetServer(addr_copy.c_str(), s_port);
+
+  // Stop the DS client if we're explicitly connecting to localhost
+  if (address == "localhost" || address == "127.0.0.1")
+    inst.StopDSClient();
+  else if (s_enable_ds)
+    inst.StartDSClient(s_port);
+}
+
+void NetworkTable::SetIPAddress(ArrayRef<std::string> addresses) {
+  auto inst = NetworkTableInstance::GetDefault();
+  wpi::SmallVector<StringRef, 8> servers;
+  for (const auto& ip_address : addresses) servers.emplace_back(ip_address);
+  inst.SetServer(servers, s_port);
+
+  // Stop the DS client if we're explicitly connecting to localhost
+  if (!addresses.empty() &&
+      (addresses[0] == "localhost" || addresses[0] == "127.0.0.1"))
+    inst.StopDSClient();
+  else if (s_enable_ds)
+    inst.StartDSClient(s_port);
+}
+
+void NetworkTable::SetPort(unsigned int port) { s_port = port; }
+
+void NetworkTable::SetDSClientEnabled(bool enabled) {
+  auto inst = NetworkTableInstance::GetDefault();
+  s_enable_ds = enabled;
+  if (s_enable_ds)
+    inst.StartDSClient(s_port);
+  else
+    inst.StopDSClient();
+}
+
+void NetworkTable::SetPersistentFilename(StringRef filename) {
+  s_persistent_filename = filename;
+}
+
+void NetworkTable::SetNetworkIdentity(StringRef name) {
+  NetworkTableInstance::GetDefault().SetNetworkIdentity(name);
+}
+
+void NetworkTable::GlobalDeleteAll() {
+  NetworkTableInstance::GetDefault().DeleteAllEntries();
+}
+
+void NetworkTable::Flush() { NetworkTableInstance::GetDefault().Flush(); }
+
+void NetworkTable::SetUpdateRate(double interval) {
+  NetworkTableInstance::GetDefault().SetUpdateRate(interval);
+}
+
+const char* NetworkTable::SavePersistent(StringRef filename) {
+  return NetworkTableInstance::GetDefault().SavePersistent(filename);
+}
+
+const char* NetworkTable::LoadPersistent(
+    StringRef filename,
+    std::function<void(size_t line, const char* msg)> warn) {
+  return NetworkTableInstance::GetDefault().LoadPersistent(filename, warn);
+}
+
+std::shared_ptr<NetworkTable> NetworkTable::GetTable(StringRef key) {
+  if (!s_running) Initialize();
+  return NetworkTableInstance::GetDefault().GetTable(key);
+}
+
+NetworkTable::NetworkTable(NT_Inst inst, const Twine& path, const private_init&)
+    : m_inst(inst), m_path(path.str()) {}
+
+NetworkTable::~NetworkTable() {
+  for (auto& i : m_listeners) RemoveEntryListener(i.second);
+  for (auto i : m_lambdaListeners) RemoveEntryListener(i);
+}
+
+NetworkTableInstance NetworkTable::GetInstance() const {
+  return NetworkTableInstance{m_inst};
+}
+
+NetworkTableEntry NetworkTable::GetEntry(const Twine& key) const {
+  wpi::SmallString<128> keyBuf;
+  StringRef keyStr = key.toStringRef(keyBuf);
+  std::scoped_lock lock(m_mutex);
+  NT_Entry& entry = m_entries[keyStr];
+  if (entry == 0) {
+    entry = nt::GetEntry(m_inst, m_path + Twine(PATH_SEPARATOR_CHAR) + keyStr);
+  }
+  return NetworkTableEntry{entry};
+}
+
+NT_EntryListener NetworkTable::AddEntryListener(TableEntryListener listener,
+                                                unsigned int flags) const {
+  size_t prefix_len = m_path.size() + 1;
+  return nt::AddEntryListener(
+      m_inst, m_path + Twine(PATH_SEPARATOR_CHAR),
+      [=](const EntryNotification& event) {
+        StringRef relative_key = event.name.substr(prefix_len);
+        if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) return;
+        listener(const_cast<NetworkTable*>(this), relative_key,
+                 NetworkTableEntry{event.entry}, event.value, event.flags);
+      },
+      flags);
+}
+
+NT_EntryListener NetworkTable::AddEntryListener(const Twine& key,
+                                                TableEntryListener listener,
+                                                unsigned int flags) const {
+  size_t prefix_len = m_path.size() + 1;
+  auto entry = GetEntry(key);
+  return nt::AddEntryListener(entry.GetHandle(),
+                              [=](const EntryNotification& event) {
+                                listener(const_cast<NetworkTable*>(this),
+                                         event.name.substr(prefix_len), entry,
+                                         event.value, event.flags);
+                              },
+                              flags);
+}
+
+void NetworkTable::RemoveEntryListener(NT_EntryListener listener) const {
+  nt::RemoveEntryListener(listener);
+}
+
+void NetworkTable::AddTableListener(ITableListener* listener) {
+  AddTableListenerEx(listener, NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
+}
+
+void NetworkTable::AddTableListener(ITableListener* listener,
+                                    bool immediateNotify) {
+  unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_UPDATE;
+  if (immediateNotify) flags |= NT_NOTIFY_IMMEDIATE;
+  AddTableListenerEx(listener, flags);
+}
+
+void NetworkTable::AddTableListenerEx(ITableListener* listener,
+                                      unsigned int flags) {
+  std::scoped_lock lock(m_mutex);
+  wpi::SmallString<128> path(m_path);
+  path += PATH_SEPARATOR_CHAR;
+  size_t prefix_len = path.size();
+  NT_EntryListener id = nt::AddEntryListener(
+      m_inst, path,
+      [=](const EntryNotification& event) {
+        StringRef relative_key = event.name.substr(prefix_len);
+        if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) return;
+        listener->ValueChangedEx(this, relative_key, event.value, event.flags);
+      },
+      flags);
+  m_listeners.emplace_back(listener, id);
+}
+
+void NetworkTable::AddTableListener(StringRef key, ITableListener* listener,
+                                    bool immediateNotify) {
+  unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_UPDATE;
+  if (immediateNotify) flags |= NT_NOTIFY_IMMEDIATE;
+  AddTableListenerEx(key, listener, flags);
+}
+
+void NetworkTable::AddTableListenerEx(StringRef key, ITableListener* listener,
+                                      unsigned int flags) {
+  std::scoped_lock lock(m_mutex);
+  size_t prefix_len = m_path.size() + 1;
+  auto entry = GetEntry(key);
+  NT_EntryListener id = nt::AddEntryListener(
+      entry.GetHandle(),
+      [=](const EntryNotification& event) {
+        listener->ValueChangedEx(this, event.name.substr(prefix_len),
+                                 event.value, event.flags);
+      },
+      flags);
+  m_listeners.emplace_back(listener, id);
+}
+
+void NetworkTable::AddSubTableListener(ITableListener* listener) {
+  AddSubTableListener(listener, false);
+}
+
+NT_EntryListener NetworkTable::AddSubTableListener(TableListener listener,
+                                                   bool localNotify) {
+  size_t prefix_len = m_path.size() + 1;
+
+  // The lambda needs to be copyable, but StringMap is not, so use
+  // a shared_ptr to it.
+  auto notified_tables = std::make_shared<wpi::StringMap<char>>();
+
+  unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_IMMEDIATE;
+  if (localNotify) flags |= NT_NOTIFY_LOCAL;
+  NT_EntryListener id = nt::AddEntryListener(
+      m_inst, m_path + Twine(PATH_SEPARATOR_CHAR),
+      [=](const EntryNotification& event) {
+        StringRef relative_key = event.name.substr(prefix_len);
+        auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
+        if (end_sub_table == StringRef::npos) return;
+        StringRef sub_table_key = relative_key.substr(0, end_sub_table);
+        if (notified_tables->find(sub_table_key) == notified_tables->end())
+          return;
+        notified_tables->insert(std::make_pair(sub_table_key, '\0'));
+        listener(this, sub_table_key, this->GetSubTable(sub_table_key));
+      },
+      flags);
+  m_lambdaListeners.emplace_back(id);
+  return id;
+}
+
+void NetworkTable::RemoveTableListener(NT_EntryListener listener) {
+  nt::RemoveEntryListener(listener);
+  auto matches_begin =
+      std::remove(m_lambdaListeners.begin(), m_lambdaListeners.end(), listener);
+  m_lambdaListeners.erase(matches_begin, m_lambdaListeners.end());
+}
+
+void NetworkTable::AddSubTableListener(ITableListener* listener,
+                                       bool localNotify) {
+  std::scoped_lock lock(m_mutex);
+  size_t prefix_len = m_path.size() + 1;
+
+  // The lambda needs to be copyable, but StringMap is not, so use
+  // a shared_ptr to it.
+  auto notified_tables = std::make_shared<wpi::StringMap<char>>();
+
+  unsigned int flags = NT_NOTIFY_NEW | NT_NOTIFY_IMMEDIATE;
+  if (localNotify) flags |= NT_NOTIFY_LOCAL;
+  NT_EntryListener id = nt::AddEntryListener(
+      m_inst, m_path + Twine(PATH_SEPARATOR_CHAR),
+      [=](const EntryNotification& event) {
+        StringRef relative_key = event.name.substr(prefix_len);
+        auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
+        if (end_sub_table == StringRef::npos) return;
+        StringRef sub_table_key = relative_key.substr(0, end_sub_table);
+        if (notified_tables->find(sub_table_key) == notified_tables->end())
+          return;
+        notified_tables->insert(std::make_pair(sub_table_key, '\0'));
+        listener->ValueChangedEx(this, sub_table_key, nullptr, event.flags);
+      },
+      flags);
+  m_listeners.emplace_back(listener, id);
+}
+
+void NetworkTable::RemoveTableListener(ITableListener* listener) {
+  std::scoped_lock lock(m_mutex);
+  auto matches_begin =
+      std::remove_if(m_listeners.begin(), m_listeners.end(),
+                     [=](const Listener& x) { return x.first == listener; });
+
+  for (auto i = matches_begin; i != m_listeners.end(); ++i)
+    RemoveEntryListener(i->second);
+  m_listeners.erase(matches_begin, m_listeners.end());
+}
+
+std::shared_ptr<NetworkTable> NetworkTable::GetSubTable(
+    const Twine& key) const {
+  return std::make_shared<NetworkTable>(
+      m_inst, m_path + Twine(PATH_SEPARATOR_CHAR) + key, private_init{});
+}
+
+bool NetworkTable::ContainsKey(const Twine& key) const {
+  if (key.isTriviallyEmpty() ||
+      (key.isSingleStringRef() && key.getSingleStringRef().empty()))
+    return false;
+  return GetEntry(key).Exists();
+}
+
+bool NetworkTable::ContainsSubTable(const Twine& key) const {
+  return !GetEntryInfo(m_inst,
+                       m_path + Twine(PATH_SEPARATOR_CHAR) + key +
+                           Twine(PATH_SEPARATOR_CHAR),
+                       0)
+              .empty();
+}
+
+std::vector<std::string> NetworkTable::GetKeys(int types) const {
+  std::vector<std::string> keys;
+  size_t prefix_len = m_path.size() + 1;
+  auto infos = GetEntryInfo(m_inst, m_path + Twine(PATH_SEPARATOR_CHAR), types);
+  std::scoped_lock lock(m_mutex);
+  for (auto& info : infos) {
+    auto relative_key = StringRef(info.name).substr(prefix_len);
+    if (relative_key.find(PATH_SEPARATOR_CHAR) != StringRef::npos) continue;
+    keys.push_back(relative_key);
+    m_entries[relative_key] = info.entry;
+  }
+  return keys;
+}
+
+std::vector<std::string> NetworkTable::GetSubTables() const {
+  std::vector<std::string> keys;
+  size_t prefix_len = m_path.size() + 1;
+  for (auto& entry :
+       GetEntryInfo(m_inst, m_path + Twine(PATH_SEPARATOR_CHAR), 0)) {
+    auto relative_key = StringRef(entry.name).substr(prefix_len);
+    size_t end_subtable = relative_key.find(PATH_SEPARATOR_CHAR);
+    if (end_subtable == StringRef::npos) continue;
+    keys.push_back(relative_key.substr(0, end_subtable));
+  }
+  return keys;
+}
+
+void NetworkTable::SetPersistent(StringRef key) {
+  GetEntry(key).SetPersistent();
+}
+
+void NetworkTable::ClearPersistent(StringRef key) {
+  GetEntry(key).ClearPersistent();
+}
+
+bool NetworkTable::IsPersistent(StringRef key) const {
+  return GetEntry(key).IsPersistent();
+}
+
+void NetworkTable::SetFlags(StringRef key, unsigned int flags) {
+  GetEntry(key).SetFlags(flags);
+}
+
+void NetworkTable::ClearFlags(StringRef key, unsigned int flags) {
+  GetEntry(key).ClearFlags(flags);
+}
+
+unsigned int NetworkTable::GetFlags(StringRef key) const {
+  return GetEntry(key).GetFlags();
+}
+
+void NetworkTable::Delete(const Twine& key) { GetEntry(key).Delete(); }
+
+bool NetworkTable::PutNumber(StringRef key, double value) {
+  return GetEntry(key).SetDouble(value);
+}
+
+bool NetworkTable::SetDefaultNumber(StringRef key, double defaultValue) {
+  return GetEntry(key).SetDefaultDouble(defaultValue);
+}
+
+double NetworkTable::GetNumber(StringRef key, double defaultValue) const {
+  return GetEntry(key).GetDouble(defaultValue);
+}
+
+bool NetworkTable::PutString(StringRef key, StringRef value) {
+  return GetEntry(key).SetString(value);
+}
+
+bool NetworkTable::SetDefaultString(StringRef key, StringRef defaultValue) {
+  return GetEntry(key).SetDefaultString(defaultValue);
+}
+
+std::string NetworkTable::GetString(StringRef key,
+                                    StringRef defaultValue) const {
+  return GetEntry(key).GetString(defaultValue);
+}
+
+bool NetworkTable::PutBoolean(StringRef key, bool value) {
+  return GetEntry(key).SetBoolean(value);
+}
+
+bool NetworkTable::SetDefaultBoolean(StringRef key, bool defaultValue) {
+  return GetEntry(key).SetDefaultBoolean(defaultValue);
+}
+
+bool NetworkTable::GetBoolean(StringRef key, bool defaultValue) const {
+  return GetEntry(key).GetBoolean(defaultValue);
+}
+
+bool NetworkTable::PutBooleanArray(StringRef key, ArrayRef<int> value) {
+  return GetEntry(key).SetBooleanArray(value);
+}
+
+bool NetworkTable::SetDefaultBooleanArray(StringRef key,
+                                          ArrayRef<int> defaultValue) {
+  return GetEntry(key).SetDefaultBooleanArray(defaultValue);
+}
+
+std::vector<int> NetworkTable::GetBooleanArray(
+    StringRef key, ArrayRef<int> defaultValue) const {
+  return GetEntry(key).GetBooleanArray(defaultValue);
+}
+
+bool NetworkTable::PutNumberArray(StringRef key, ArrayRef<double> value) {
+  return GetEntry(key).SetDoubleArray(value);
+}
+
+bool NetworkTable::SetDefaultNumberArray(StringRef key,
+                                         ArrayRef<double> defaultValue) {
+  return GetEntry(key).SetDefaultDoubleArray(defaultValue);
+}
+
+std::vector<double> NetworkTable::GetNumberArray(
+    StringRef key, ArrayRef<double> defaultValue) const {
+  return GetEntry(key).GetDoubleArray(defaultValue);
+}
+
+bool NetworkTable::PutStringArray(StringRef key, ArrayRef<std::string> value) {
+  return GetEntry(key).SetStringArray(value);
+}
+
+bool NetworkTable::SetDefaultStringArray(StringRef key,
+                                         ArrayRef<std::string> defaultValue) {
+  return GetEntry(key).SetDefaultStringArray(defaultValue);
+}
+
+std::vector<std::string> NetworkTable::GetStringArray(
+    StringRef key, ArrayRef<std::string> defaultValue) const {
+  return GetEntry(key).GetStringArray(defaultValue);
+}
+
+bool NetworkTable::PutRaw(StringRef key, StringRef value) {
+  return GetEntry(key).SetRaw(value);
+}
+
+bool NetworkTable::SetDefaultRaw(StringRef key, StringRef defaultValue) {
+  return GetEntry(key).SetDefaultRaw(defaultValue);
+}
+
+std::string NetworkTable::GetRaw(StringRef key, StringRef defaultValue) const {
+  return GetEntry(key).GetRaw(defaultValue);
+}
+
+bool NetworkTable::PutValue(const Twine& key, std::shared_ptr<Value> value) {
+  return GetEntry(key).SetValue(value);
+}
+
+bool NetworkTable::SetDefaultValue(const Twine& key,
+                                   std::shared_ptr<Value> defaultValue) {
+  return GetEntry(key).SetDefaultValue(defaultValue);
+}
+
+std::shared_ptr<Value> NetworkTable::GetValue(const Twine& key) const {
+  return GetEntry(key).GetValue();
+}
+
+StringRef NetworkTable::GetPath() const { return m_path; }
+
+const char* NetworkTable::SaveEntries(const Twine& filename) const {
+  return nt::SaveEntries(m_inst, filename, m_path + Twine(PATH_SEPARATOR_CHAR));
+}
+
+const char* NetworkTable::LoadEntries(
+    const Twine& filename,
+    std::function<void(size_t line, const char* msg)> warn) {
+  return nt::LoadEntries(m_inst, filename, m_path + Twine(PATH_SEPARATOR_CHAR),
+                         warn);
+}
diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp
new file mode 100644
index 0000000..5507ac0
--- /dev/null
+++ b/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "networktables/NetworkTableEntry.h"
+
+#include "networktables/NetworkTableInstance.h"
+
+using namespace nt;
+
+NetworkTableInstance NetworkTableEntry::GetInstance() const {
+  return NetworkTableInstance{GetInstanceFromHandle(m_handle)};
+}
diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp
new file mode 100644
index 0000000..018572e
--- /dev/null
+++ b/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp
@@ -0,0 +1,59 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "networktables/NetworkTableInstance.h"
+
+#include <wpi/SmallString.h>
+
+using namespace nt;
+
+std::shared_ptr<NetworkTable> NetworkTableInstance::GetTable(
+    const Twine& key) const {
+  StringRef simple;
+  bool isSimple = key.isSingleStringRef();
+  if (isSimple) simple = key.getSingleStringRef();
+  if (isSimple && (simple.empty() || simple == "/")) {
+    return std::make_shared<NetworkTable>(m_handle, "",
+                                          NetworkTable::private_init{});
+  } else if (isSimple && simple[0] == NetworkTable::PATH_SEPARATOR_CHAR) {
+    return std::make_shared<NetworkTable>(m_handle, key,
+                                          NetworkTable::private_init{});
+  } else {
+    return std::make_shared<NetworkTable>(
+        m_handle, Twine(NetworkTable::PATH_SEPARATOR_CHAR) + key,
+        NetworkTable::private_init{});
+  }
+}
+
+void NetworkTableInstance::StartClient(ArrayRef<StringRef> servers,
+                                       unsigned int port) {
+  wpi::SmallVector<std::pair<StringRef, unsigned int>, 8> server_ports;
+  for (const auto& server : servers)
+    server_ports.emplace_back(std::make_pair(server, port));
+  StartClient(server_ports);
+}
+
+void NetworkTableInstance::SetServer(ArrayRef<StringRef> servers,
+                                     unsigned int port) {
+  wpi::SmallVector<std::pair<StringRef, unsigned int>, 8> server_ports;
+  for (const auto& server : servers)
+    server_ports.emplace_back(std::make_pair(server, port));
+  SetServer(server_ports);
+}
+
+NT_EntryListener NetworkTableInstance::AddEntryListener(
+    const Twine& prefix,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags) const {
+  return ::nt::AddEntryListener(m_handle, prefix, callback, flags);
+}
+
+NT_ConnectionListener NetworkTableInstance::AddConnectionListener(
+    std::function<void(const ConnectionNotification& event)> callback,
+    bool immediate_notify) const {
+  return ::nt::AddConnectionListener(m_handle, callback, immediate_notify);
+}
diff --git a/ntcore/src/main/native/cpp/networktables/RpcCall.cpp b/ntcore/src/main/native/cpp/networktables/RpcCall.cpp
new file mode 100644
index 0000000..1149681
--- /dev/null
+++ b/ntcore/src/main/native/cpp/networktables/RpcCall.cpp
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "networktables/RpcCall.h"
+
+#include "networktables/NetworkTableEntry.h"
+
+using namespace nt;
+
+NetworkTableEntry RpcCall::GetEntry() const {
+  return NetworkTableEntry{m_entry};
+}
diff --git a/ntcore/src/main/native/cpp/ntcore_c.cpp b/ntcore/src/main/native/cpp/ntcore_c.cpp
new file mode 100644
index 0000000..60745fe
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ntcore_c.cpp
@@ -0,0 +1,1140 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <stdint.h>
+
+#include <cassert>
+#include <cstdlib>
+
+#include <wpi/MemAlloc.h>
+#include <wpi/timestamp.h>
+
+#include "Value_internal.h"
+#include "ntcore.h"
+
+using namespace nt;
+
+// Conversion helpers
+
+static void ConvertToC(wpi::StringRef in, char** out) {
+  *out = static_cast<char*>(wpi::safe_malloc(in.size() + 1));
+  std::memmove(*out, in.data(), in.size());
+  (*out)[in.size()] = '\0';
+}
+
+static void ConvertToC(const EntryInfo& in, NT_EntryInfo* out) {
+  out->entry = in.entry;
+  ConvertToC(in.name, &out->name);
+  out->type = in.type;
+  out->flags = in.flags;
+  out->last_change = in.last_change;
+}
+
+static void ConvertToC(const ConnectionInfo& in, NT_ConnectionInfo* out) {
+  ConvertToC(in.remote_id, &out->remote_id);
+  ConvertToC(in.remote_ip, &out->remote_ip);
+  out->remote_port = in.remote_port;
+  out->last_update = in.last_update;
+  out->protocol_version = in.protocol_version;
+}
+
+static void ConvertToC(const RpcParamDef& in, NT_RpcParamDef* out) {
+  ConvertToC(in.name, &out->name);
+  ConvertToC(*in.def_value, &out->def_value);
+}
+
+static void ConvertToC(const RpcResultDef& in, NT_RpcResultDef* out) {
+  ConvertToC(in.name, &out->name);
+  out->type = in.type;
+}
+
+static void ConvertToC(const RpcDefinition& in, NT_RpcDefinition* out) {
+  out->version = in.version;
+  ConvertToC(in.name, &out->name);
+
+  out->num_params = in.params.size();
+  out->params = static_cast<NT_RpcParamDef*>(
+      wpi::safe_malloc(in.params.size() * sizeof(NT_RpcParamDef)));
+  for (size_t i = 0; i < in.params.size(); ++i)
+    ConvertToC(in.params[i], &out->params[i]);
+
+  out->num_results = in.results.size();
+  out->results = static_cast<NT_RpcResultDef*>(
+      wpi::safe_malloc(in.results.size() * sizeof(NT_RpcResultDef)));
+  for (size_t i = 0; i < in.results.size(); ++i)
+    ConvertToC(in.results[i], &out->results[i]);
+}
+
+static void ConvertToC(const RpcAnswer& in, NT_RpcAnswer* out) {
+  out->entry = in.entry;
+  out->call = in.call;
+  ConvertToC(in.name, &out->name);
+  ConvertToC(in.params, &out->params);
+  ConvertToC(in.conn, &out->conn);
+}
+
+static void ConvertToC(const EntryNotification& in, NT_EntryNotification* out) {
+  out->listener = in.listener;
+  out->entry = in.entry;
+  ConvertToC(in.name, &out->name);
+  ConvertToC(*in.value, &out->value);
+  out->flags = in.flags;
+}
+
+static void ConvertToC(const ConnectionNotification& in,
+                       NT_ConnectionNotification* out) {
+  out->listener = in.listener;
+  out->connected = in.connected;
+  ConvertToC(in.conn, &out->conn);
+}
+
+static void ConvertToC(const LogMessage& in, NT_LogMessage* out) {
+  out->logger = in.logger;
+  out->level = in.level;
+  out->filename = in.filename;
+  out->line = in.line;
+  ConvertToC(in.message, &out->message);
+}
+
+template <typename O, typename I>
+static O* ConvertToC(const std::vector<I>& in, size_t* out_len) {
+  if (!out_len) return nullptr;
+  *out_len = in.size();
+  if (in.empty()) return nullptr;
+  O* out = static_cast<O*>(wpi::safe_malloc(sizeof(O) * in.size()));
+  for (size_t i = 0; i < in.size(); ++i) ConvertToC(in[i], &out[i]);
+  return out;
+}
+
+static void DisposeConnectionInfo(NT_ConnectionInfo* info) {
+  std::free(info->remote_id.str);
+  std::free(info->remote_ip.str);
+}
+
+static void DisposeEntryInfo(NT_EntryInfo* info) { std::free(info->name.str); }
+
+static void DisposeEntryNotification(NT_EntryNotification* info) {
+  std::free(info->name.str);
+  NT_DisposeValue(&info->value);
+}
+
+static void DisposeConnectionNotification(NT_ConnectionNotification* info) {
+  DisposeConnectionInfo(&info->conn);
+}
+
+static RpcParamDef ConvertFromC(const NT_RpcParamDef& in) {
+  RpcParamDef out;
+  out.name = ConvertFromC(in.name);
+  out.def_value = ConvertFromC(in.def_value);
+  return out;
+}
+
+static RpcResultDef ConvertFromC(const NT_RpcResultDef& in) {
+  RpcResultDef out;
+  out.name = ConvertFromC(in.name);
+  out.type = in.type;
+  return out;
+}
+
+static RpcDefinition ConvertFromC(const NT_RpcDefinition& in) {
+  RpcDefinition out;
+  out.version = in.version;
+  out.name = ConvertFromC(in.name);
+
+  out.params.reserve(in.num_params);
+  for (size_t i = 0; i < in.num_params; ++i)
+    out.params.push_back(ConvertFromC(in.params[i]));
+
+  out.results.reserve(in.num_results);
+  for (size_t i = 0; i < in.num_results; ++i)
+    out.results.push_back(ConvertFromC(in.results[i]));
+
+  return out;
+}
+
+extern "C" {
+
+/*
+ * Instance Functions
+ */
+
+NT_Inst NT_GetDefaultInstance(void) { return nt::GetDefaultInstance(); }
+
+NT_Inst NT_CreateInstance(void) { return nt::CreateInstance(); }
+
+void NT_DestroyInstance(NT_Inst inst) { return nt::DestroyInstance(inst); }
+
+NT_Inst NT_GetInstanceFromHandle(NT_Handle handle) {
+  return nt::GetInstanceFromHandle(handle);
+}
+
+/*
+ * Table Functions
+ */
+
+NT_Entry NT_GetEntry(NT_Inst inst, const char* name, size_t name_len) {
+  return nt::GetEntry(inst, StringRef(name, name_len));
+}
+
+NT_Entry* NT_GetEntries(NT_Inst inst, const char* prefix, size_t prefix_len,
+                        unsigned int types, size_t* count) {
+  auto info_v = nt::GetEntries(inst, StringRef(prefix, prefix_len), types);
+  *count = info_v.size();
+  if (info_v.size() == 0) return nullptr;
+
+  // create array and copy into it
+  NT_Entry* info = static_cast<NT_Entry*>(
+      wpi::safe_malloc(info_v.size() * sizeof(NT_Entry)));
+  std::memcpy(info, info_v.data(), info_v.size() * sizeof(NT_Entry));
+  return info;
+}
+
+char* NT_GetEntryName(NT_Entry entry, size_t* name_len) {
+  struct NT_String v_name;
+  nt::ConvertToC(nt::GetEntryName(entry), &v_name);
+  *name_len = v_name.len;
+  return v_name.str;
+}
+
+enum NT_Type NT_GetEntryType(NT_Entry entry) { return nt::GetEntryType(entry); }
+
+uint64_t NT_GetEntryLastChange(NT_Entry entry) {
+  return nt::GetEntryLastChange(entry);
+}
+
+void NT_GetEntryValue(NT_Entry entry, struct NT_Value* value) {
+  NT_InitValue(value);
+  auto v = nt::GetEntryValue(entry);
+  if (!v) return;
+  ConvertToC(*v, value);
+}
+
+int NT_SetDefaultEntryValue(NT_Entry entry,
+                            const struct NT_Value* default_value) {
+  return nt::SetDefaultEntryValue(entry, ConvertFromC(*default_value));
+}
+
+int NT_SetEntryValue(NT_Entry entry, const struct NT_Value* value) {
+  return nt::SetEntryValue(entry, ConvertFromC(*value));
+}
+
+void NT_SetEntryTypeValue(NT_Entry entry, const struct NT_Value* value) {
+  nt::SetEntryTypeValue(entry, ConvertFromC(*value));
+}
+
+void NT_SetEntryFlags(NT_Entry entry, unsigned int flags) {
+  nt::SetEntryFlags(entry, flags);
+}
+
+unsigned int NT_GetEntryFlags(NT_Entry entry) {
+  return nt::GetEntryFlags(entry);
+}
+
+void NT_DeleteEntry(NT_Entry entry) { nt::DeleteEntry(entry); }
+
+void NT_DeleteAllEntries(NT_Inst inst) { nt::DeleteAllEntries(inst); }
+
+struct NT_EntryInfo* NT_GetEntryInfo(NT_Inst inst, const char* prefix,
+                                     size_t prefix_len, unsigned int types,
+                                     size_t* count) {
+  auto info_v = nt::GetEntryInfo(inst, StringRef(prefix, prefix_len), types);
+  return ConvertToC<NT_EntryInfo>(info_v, count);
+}
+
+NT_Bool NT_GetEntryInfoHandle(NT_Entry entry, struct NT_EntryInfo* info) {
+  auto info_v = nt::GetEntryInfo(entry);
+  if (info_v.name.empty()) return false;
+  ConvertToC(info_v, info);
+  return true;
+}
+
+/*
+ * Callback Creation Functions
+ */
+
+NT_EntryListener NT_AddEntryListener(NT_Inst inst, const char* prefix,
+                                     size_t prefix_len, void* data,
+                                     NT_EntryListenerCallback callback,
+                                     unsigned int flags) {
+  return nt::AddEntryListener(inst, StringRef(prefix, prefix_len),
+                              [=](const EntryNotification& event) {
+                                NT_EntryNotification c_event;
+                                ConvertToC(event, &c_event);
+                                callback(data, &c_event);
+                                DisposeEntryNotification(&c_event);
+                              },
+                              flags);
+}
+
+NT_EntryListener NT_AddEntryListenerSingle(NT_Entry entry, void* data,
+                                           NT_EntryListenerCallback callback,
+                                           unsigned int flags) {
+  return nt::AddEntryListener(entry,
+                              [=](const EntryNotification& event) {
+                                NT_EntryNotification c_event;
+                                ConvertToC(event, &c_event);
+                                callback(data, &c_event);
+                                DisposeEntryNotification(&c_event);
+                              },
+                              flags);
+}
+
+NT_EntryListenerPoller NT_CreateEntryListenerPoller(NT_Inst inst) {
+  return nt::CreateEntryListenerPoller(inst);
+}
+
+void NT_DestroyEntryListenerPoller(NT_EntryListenerPoller poller) {
+  nt::DestroyEntryListenerPoller(poller);
+}
+
+NT_EntryListener NT_AddPolledEntryListener(NT_EntryListenerPoller poller,
+                                           const char* prefix,
+                                           size_t prefix_len,
+                                           unsigned int flags) {
+  return nt::AddPolledEntryListener(poller, StringRef(prefix, prefix_len),
+                                    flags);
+}
+
+NT_EntryListener NT_AddPolledEntryListenerSingle(NT_EntryListenerPoller poller,
+                                                 NT_Entry entry,
+                                                 unsigned int flags) {
+  return nt::AddPolledEntryListener(poller, entry, flags);
+}
+
+struct NT_EntryNotification* NT_PollEntryListener(NT_EntryListenerPoller poller,
+                                                  size_t* len) {
+  auto arr_cpp = nt::PollEntryListener(poller);
+  return ConvertToC<NT_EntryNotification>(arr_cpp, len);
+}
+
+struct NT_EntryNotification* NT_PollEntryListenerTimeout(
+    NT_EntryListenerPoller poller, size_t* len, double timeout,
+    NT_Bool* timed_out) {
+  bool cpp_timed_out = false;
+  auto arr_cpp = nt::PollEntryListener(poller, timeout, &cpp_timed_out);
+  *timed_out = cpp_timed_out;
+  return ConvertToC<NT_EntryNotification>(arr_cpp, len);
+}
+
+void NT_CancelPollEntryListener(NT_EntryListenerPoller poller) {
+  nt::CancelPollEntryListener(poller);
+}
+
+void NT_RemoveEntryListener(NT_EntryListener entry_listener) {
+  nt::RemoveEntryListener(entry_listener);
+}
+
+NT_Bool NT_WaitForEntryListenerQueue(NT_Inst inst, double timeout) {
+  return nt::WaitForEntryListenerQueue(inst, timeout);
+}
+
+NT_ConnectionListener NT_AddConnectionListener(
+    NT_Inst inst, void* data, NT_ConnectionListenerCallback callback,
+    NT_Bool immediate_notify) {
+  return nt::AddConnectionListener(inst,
+                                   [=](const ConnectionNotification& event) {
+                                     NT_ConnectionNotification event_c;
+                                     ConvertToC(event, &event_c);
+                                     callback(data, &event_c);
+                                     DisposeConnectionNotification(&event_c);
+                                   },
+                                   immediate_notify != 0);
+}
+
+NT_ConnectionListenerPoller NT_CreateConnectionListenerPoller(NT_Inst inst) {
+  return nt::CreateConnectionListenerPoller(inst);
+}
+
+void NT_DestroyConnectionListenerPoller(NT_ConnectionListenerPoller poller) {
+  nt::DestroyConnectionListenerPoller(poller);
+}
+
+NT_ConnectionListener NT_AddPolledConnectionListener(
+    NT_ConnectionListenerPoller poller, NT_Bool immediate_notify) {
+  return nt::AddPolledConnectionListener(poller, immediate_notify);
+}
+
+struct NT_ConnectionNotification* NT_PollConnectionListener(
+    NT_ConnectionListenerPoller poller, size_t* len) {
+  auto arr_cpp = nt::PollConnectionListener(poller);
+  return ConvertToC<NT_ConnectionNotification>(arr_cpp, len);
+}
+
+struct NT_ConnectionNotification* NT_PollConnectionListenerTimeout(
+    NT_ConnectionListenerPoller poller, size_t* len, double timeout,
+    NT_Bool* timed_out) {
+  bool cpp_timed_out = false;
+  auto arr_cpp = nt::PollConnectionListener(poller, timeout, &cpp_timed_out);
+  *timed_out = cpp_timed_out;
+  return ConvertToC<NT_ConnectionNotification>(arr_cpp, len);
+}
+
+void NT_CancelPollConnectionListener(NT_ConnectionListenerPoller poller) {
+  nt::CancelPollConnectionListener(poller);
+}
+
+void NT_RemoveConnectionListener(NT_ConnectionListener conn_listener) {
+  nt::RemoveConnectionListener(conn_listener);
+}
+
+NT_Bool NT_WaitForConnectionListenerQueue(NT_Inst inst, double timeout) {
+  return nt::WaitForConnectionListenerQueue(inst, timeout);
+}
+
+/*
+ * Remote Procedure Call Functions
+ */
+
+void NT_CreateRpc(NT_Entry entry, const char* def, size_t def_len, void* data,
+                  NT_RpcCallback callback) {
+  nt::CreateRpc(entry, StringRef(def, def_len), [=](const RpcAnswer& answer) {
+    NT_RpcAnswer answer_c;
+    ConvertToC(answer, &answer_c);
+    callback(data, &answer_c);
+    NT_DisposeRpcAnswer(&answer_c);
+  });
+}
+
+NT_RpcCallPoller NT_CreateRpcCallPoller(NT_Inst inst) {
+  return nt::CreateRpcCallPoller(inst);
+}
+
+void NT_DestroyRpcCallPoller(NT_RpcCallPoller poller) {
+  nt::DestroyRpcCallPoller(poller);
+}
+
+void NT_CreatePolledRpc(NT_Entry entry, const char* def, size_t def_len,
+                        NT_RpcCallPoller poller) {
+  nt::CreatePolledRpc(entry, StringRef(def, def_len), poller);
+}
+
+NT_RpcAnswer* NT_PollRpc(NT_RpcCallPoller poller, size_t* len) {
+  auto arr_cpp = nt::PollRpc(poller);
+  return ConvertToC<NT_RpcAnswer>(arr_cpp, len);
+}
+
+NT_RpcAnswer* NT_PollRpcTimeout(NT_RpcCallPoller poller, size_t* len,
+                                double timeout, NT_Bool* timed_out) {
+  bool cpp_timed_out = false;
+  auto arr_cpp = nt::PollRpc(poller, timeout, &cpp_timed_out);
+  *timed_out = cpp_timed_out;
+  return ConvertToC<NT_RpcAnswer>(arr_cpp, len);
+}
+
+void NT_CancelPollRpc(NT_RpcCallPoller poller) { nt::CancelPollRpc(poller); }
+
+NT_Bool NT_WaitForRpcCallQueue(NT_Inst inst, double timeout) {
+  return nt::WaitForRpcCallQueue(inst, timeout);
+}
+
+NT_Bool NT_PostRpcResponse(NT_Entry entry, NT_RpcCall call, const char* result,
+                           size_t result_len) {
+  return nt::PostRpcResponse(entry, call, StringRef(result, result_len));
+}
+
+NT_RpcCall NT_CallRpc(NT_Entry entry, const char* params, size_t params_len) {
+  return nt::CallRpc(entry, StringRef(params, params_len));
+}
+
+char* NT_GetRpcResult(NT_Entry entry, NT_RpcCall call, size_t* result_len) {
+  std::string result;
+  if (!nt::GetRpcResult(entry, call, &result)) return nullptr;
+
+  // convert result
+  *result_len = result.size();
+  char* result_cstr;
+  ConvertToC(result, &result_cstr);
+  return result_cstr;
+}
+
+char* NT_GetRpcResultTimeout(NT_Entry entry, NT_RpcCall call,
+                             size_t* result_len, double timeout,
+                             NT_Bool* timed_out) {
+  std::string result;
+  bool cpp_timed_out = false;
+  if (!nt::GetRpcResult(entry, call, &result, timeout, &cpp_timed_out)) {
+    *timed_out = cpp_timed_out;
+    return nullptr;
+  }
+
+  *timed_out = cpp_timed_out;
+  // convert result
+  *result_len = result.size();
+  char* result_cstr;
+  ConvertToC(result, &result_cstr);
+  return result_cstr;
+}
+
+void NT_CancelRpcResult(NT_Entry entry, NT_RpcCall call) {
+  nt::CancelRpcResult(entry, call);
+}
+
+char* NT_PackRpcDefinition(const NT_RpcDefinition* def, size_t* packed_len) {
+  auto packed = nt::PackRpcDefinition(ConvertFromC(*def));
+
+  // convert result
+  *packed_len = packed.size();
+  char* packed_cstr;
+  ConvertToC(packed, &packed_cstr);
+  return packed_cstr;
+}
+
+NT_Bool NT_UnpackRpcDefinition(const char* packed, size_t packed_len,
+                               NT_RpcDefinition* def) {
+  nt::RpcDefinition def_v;
+  if (!nt::UnpackRpcDefinition(StringRef(packed, packed_len), &def_v)) return 0;
+
+  // convert result
+  ConvertToC(def_v, def);
+  return 1;
+}
+
+char* NT_PackRpcValues(const NT_Value** values, size_t values_len,
+                       size_t* packed_len) {
+  // create input vector
+  std::vector<std::shared_ptr<Value>> values_v;
+  values_v.reserve(values_len);
+  for (size_t i = 0; i < values_len; ++i)
+    values_v.push_back(ConvertFromC(*values[i]));
+
+  // make the call
+  auto packed = nt::PackRpcValues(values_v);
+
+  // convert result
+  *packed_len = packed.size();
+  char* packed_cstr;
+  ConvertToC(packed, &packed_cstr);
+  return packed_cstr;
+}
+
+NT_Value** NT_UnpackRpcValues(const char* packed, size_t packed_len,
+                              const NT_Type* types, size_t types_len) {
+  auto values_v = nt::UnpackRpcValues(StringRef(packed, packed_len),
+                                      ArrayRef<NT_Type>(types, types_len));
+  if (values_v.size() == 0) return nullptr;
+
+  // create array and copy into it
+  NT_Value** values = static_cast<NT_Value**>(
+      wpi::safe_malloc(values_v.size() * sizeof(NT_Value*)));
+  for (size_t i = 0; i < values_v.size(); ++i) {
+    values[i] = static_cast<NT_Value*>(wpi::safe_malloc(sizeof(NT_Value)));
+    ConvertToC(*values_v[i], values[i]);
+  }
+  return values;
+}
+
+/*
+ * Client/Server Functions
+ */
+
+void NT_SetNetworkIdentity(NT_Inst inst, const char* name, size_t name_len) {
+  nt::SetNetworkIdentity(inst, StringRef(name, name_len));
+}
+
+unsigned int NT_GetNetworkMode(NT_Inst inst) {
+  return nt::GetNetworkMode(inst);
+}
+
+void NT_StartLocal(NT_Inst inst) { nt::StartLocal(inst); }
+
+void NT_StopLocal(NT_Inst inst) { nt::StopLocal(inst); }
+
+void NT_StartServer(NT_Inst inst, const char* persist_filename,
+                    const char* listen_address, unsigned int port) {
+  nt::StartServer(inst, persist_filename, listen_address, port);
+}
+
+void NT_StopServer(NT_Inst inst) { nt::StopServer(inst); }
+
+void NT_StartClientNone(NT_Inst inst) { nt::StartClient(inst); }
+
+void NT_StartClient(NT_Inst inst, const char* server_name, unsigned int port) {
+  nt::StartClient(inst, server_name, port);
+}
+
+void NT_StartClientMulti(NT_Inst inst, size_t count, const char** server_names,
+                         const unsigned int* ports) {
+  std::vector<std::pair<StringRef, unsigned int>> servers;
+  servers.reserve(count);
+  for (size_t i = 0; i < count; ++i)
+    servers.emplace_back(std::make_pair(server_names[i], ports[i]));
+  nt::StartClient(inst, servers);
+}
+
+void NT_StartClientTeam(NT_Inst inst, unsigned int team, unsigned int port) {
+  nt::StartClientTeam(inst, team, port);
+}
+
+void NT_StopClient(NT_Inst inst) { nt::StopClient(inst); }
+
+void NT_SetServer(NT_Inst inst, const char* server_name, unsigned int port) {
+  nt::SetServer(inst, server_name, port);
+}
+
+void NT_SetServerMulti(NT_Inst inst, size_t count, const char** server_names,
+                       const unsigned int* ports) {
+  std::vector<std::pair<StringRef, unsigned int>> servers;
+  servers.reserve(count);
+  for (size_t i = 0; i < count; ++i)
+    servers.emplace_back(std::make_pair(server_names[i], ports[i]));
+  nt::SetServer(inst, servers);
+}
+
+void NT_SetServerTeam(NT_Inst inst, unsigned int team, unsigned int port) {
+  nt::SetServerTeam(inst, team, port);
+}
+
+void NT_StartDSClient(NT_Inst inst, unsigned int port) {
+  nt::StartDSClient(inst, port);
+}
+
+void NT_StopDSClient(NT_Inst inst) { nt::StopDSClient(inst); }
+
+void NT_SetUpdateRate(NT_Inst inst, double interval) {
+  nt::SetUpdateRate(inst, interval);
+}
+
+void NT_Flush(NT_Inst inst) { nt::Flush(inst); }
+
+NT_Bool NT_IsConnected(NT_Inst inst) { return nt::IsConnected(inst); }
+
+struct NT_ConnectionInfo* NT_GetConnections(NT_Inst inst, size_t* count) {
+  auto conn_v = nt::GetConnections(inst);
+  return ConvertToC<NT_ConnectionInfo>(conn_v, count);
+}
+
+/*
+ * File Save/Load Functions
+ */
+
+const char* NT_SavePersistent(NT_Inst inst, const char* filename) {
+  return nt::SavePersistent(inst, filename);
+}
+
+const char* NT_LoadPersistent(NT_Inst inst, const char* filename,
+                              void (*warn)(size_t line, const char* msg)) {
+  return nt::LoadPersistent(inst, filename, warn);
+}
+
+const char* NT_SaveEntries(NT_Inst inst, const char* filename,
+                           const char* prefix, size_t prefix_len) {
+  return nt::SaveEntries(inst, filename, StringRef(prefix, prefix_len));
+}
+
+const char* NT_LoadEntries(NT_Inst inst, const char* filename,
+                           const char* prefix, size_t prefix_len,
+                           void (*warn)(size_t line, const char* msg)) {
+  return nt::LoadEntries(inst, filename, StringRef(prefix, prefix_len), warn);
+}
+
+/*
+ * Utility Functions
+ */
+
+uint64_t NT_Now(void) { return wpi::Now(); }
+
+NT_Logger NT_AddLogger(NT_Inst inst, void* data, NT_LogFunc func,
+                       unsigned int min_level, unsigned int max_level) {
+  return nt::AddLogger(inst,
+                       [=](const LogMessage& msg) {
+                         NT_LogMessage msg_c;
+                         ConvertToC(msg, &msg_c);
+                         func(data, &msg_c);
+                         NT_DisposeLogMessage(&msg_c);
+                       },
+                       min_level, max_level);
+}
+
+NT_LoggerPoller NT_CreateLoggerPoller(NT_Inst inst) {
+  return nt::CreateLoggerPoller(inst);
+}
+
+void NT_DestroyLoggerPoller(NT_LoggerPoller poller) {
+  nt::DestroyLoggerPoller(poller);
+}
+
+NT_Logger NT_AddPolledLogger(NT_LoggerPoller poller, unsigned int min_level,
+                             unsigned int max_level) {
+  return nt::AddPolledLogger(poller, min_level, max_level);
+}
+
+struct NT_LogMessage* NT_PollLogger(NT_LoggerPoller poller, size_t* len) {
+  auto arr_cpp = nt::PollLogger(poller);
+  return ConvertToC<NT_LogMessage>(arr_cpp, len);
+}
+
+struct NT_LogMessage* NT_PollLoggerTimeout(NT_LoggerPoller poller, size_t* len,
+                                           double timeout, NT_Bool* timed_out) {
+  bool cpp_timed_out = false;
+  auto arr_cpp = nt::PollLogger(poller, timeout, &cpp_timed_out);
+  *timed_out = cpp_timed_out;
+  return ConvertToC<NT_LogMessage>(arr_cpp, len);
+}
+
+void NT_CancelPollLogger(NT_LoggerPoller poller) {
+  nt::CancelPollLogger(poller);
+}
+
+void NT_RemoveLogger(NT_Logger logger) { nt::RemoveLogger(logger); }
+
+NT_Bool NT_WaitForLoggerQueue(NT_Inst inst, double timeout) {
+  return nt::WaitForLoggerQueue(inst, timeout);
+}
+
+void NT_DisposeValue(NT_Value* value) {
+  switch (value->type) {
+    case NT_UNASSIGNED:
+    case NT_BOOLEAN:
+    case NT_DOUBLE:
+      break;
+    case NT_STRING:
+    case NT_RAW:
+    case NT_RPC:
+      std::free(value->data.v_string.str);
+      break;
+    case NT_BOOLEAN_ARRAY:
+      std::free(value->data.arr_boolean.arr);
+      break;
+    case NT_DOUBLE_ARRAY:
+      std::free(value->data.arr_double.arr);
+      break;
+    case NT_STRING_ARRAY: {
+      for (size_t i = 0; i < value->data.arr_string.size; i++)
+        std::free(value->data.arr_string.arr[i].str);
+      std::free(value->data.arr_string.arr);
+      break;
+    }
+    default:
+      assert(false && "unknown value type");
+  }
+  value->type = NT_UNASSIGNED;
+  value->last_change = 0;
+}
+
+void NT_InitValue(NT_Value* value) {
+  value->type = NT_UNASSIGNED;
+  value->last_change = 0;
+}
+
+void NT_DisposeString(NT_String* str) {
+  std::free(str->str);
+  str->str = nullptr;
+  str->len = 0;
+}
+
+void NT_InitString(NT_String* str) {
+  str->str = nullptr;
+  str->len = 0;
+}
+
+void NT_DisposeEntryArray(NT_Entry* arr, size_t /*count*/) { std::free(arr); }
+
+void NT_DisposeConnectionInfoArray(NT_ConnectionInfo* arr, size_t count) {
+  for (size_t i = 0; i < count; i++) DisposeConnectionInfo(&arr[i]);
+  std::free(arr);
+}
+
+void NT_DisposeEntryInfoArray(NT_EntryInfo* arr, size_t count) {
+  for (size_t i = 0; i < count; i++) DisposeEntryInfo(&arr[i]);
+  std::free(arr);
+}
+
+void NT_DisposeEntryInfo(NT_EntryInfo* info) { DisposeEntryInfo(info); }
+
+void NT_DisposeEntryNotificationArray(NT_EntryNotification* arr, size_t count) {
+  for (size_t i = 0; i < count; i++) DisposeEntryNotification(&arr[i]);
+  std::free(arr);
+}
+
+void NT_DisposeEntryNotification(NT_EntryNotification* info) {
+  DisposeEntryNotification(info);
+}
+
+void NT_DisposeConnectionNotificationArray(NT_ConnectionNotification* arr,
+                                           size_t count) {
+  for (size_t i = 0; i < count; i++) DisposeConnectionNotification(&arr[i]);
+  std::free(arr);
+}
+
+void NT_DisposeConnectionNotification(NT_ConnectionNotification* info) {
+  DisposeConnectionNotification(info);
+}
+
+void NT_DisposeLogMessageArray(NT_LogMessage* arr, size_t count) {
+  for (size_t i = 0; i < count; i++) NT_DisposeLogMessage(&arr[i]);
+  std::free(arr);
+}
+
+void NT_DisposeLogMessage(NT_LogMessage* info) { std::free(info->message); }
+
+void NT_DisposeRpcDefinition(NT_RpcDefinition* def) {
+  NT_DisposeString(&def->name);
+
+  for (size_t i = 0; i < def->num_params; ++i) {
+    NT_DisposeString(&def->params[i].name);
+    NT_DisposeValue(&def->params[i].def_value);
+  }
+  std::free(def->params);
+  def->params = nullptr;
+  def->num_params = 0;
+
+  for (size_t i = 0; i < def->num_results; ++i)
+    NT_DisposeString(&def->results[i].name);
+  std::free(def->results);
+  def->results = nullptr;
+  def->num_results = 0;
+}
+
+void NT_DisposeRpcAnswerArray(NT_RpcAnswer* arr, size_t count) {
+  for (size_t i = 0; i < count; i++) NT_DisposeRpcAnswer(&arr[i]);
+  std::free(arr);
+}
+
+void NT_DisposeRpcAnswer(NT_RpcAnswer* call_info) {
+  NT_DisposeString(&call_info->name);
+  NT_DisposeString(&call_info->params);
+  DisposeConnectionInfo(&call_info->conn);
+}
+
+/* Interop Utility Functions */
+
+/* Array and Struct Allocations */
+
+/* Allocates a char array of the specified size.*/
+char* NT_AllocateCharArray(size_t size) {
+  char* retVal = static_cast<char*>(wpi::safe_malloc(size * sizeof(char)));
+  return retVal;
+}
+
+/* Allocates an integer or boolean array of the specified size. */
+int* NT_AllocateBooleanArray(size_t size) {
+  int* retVal = static_cast<int*>(wpi::safe_malloc(size * sizeof(int)));
+  return retVal;
+}
+
+/* Allocates a double array of the specified size. */
+double* NT_AllocateDoubleArray(size_t size) {
+  double* retVal =
+      static_cast<double*>(wpi::safe_malloc(size * sizeof(double)));
+  return retVal;
+}
+
+/* Allocates an NT_String array of the specified size. */
+struct NT_String* NT_AllocateStringArray(size_t size) {
+  NT_String* retVal =
+      static_cast<NT_String*>(wpi::safe_malloc(size * sizeof(NT_String)));
+  return retVal;
+}
+
+void NT_FreeCharArray(char* v_char) { std::free(v_char); }
+void NT_FreeDoubleArray(double* v_double) { std::free(v_double); }
+void NT_FreeBooleanArray(int* v_boolean) { std::free(v_boolean); }
+void NT_FreeStringArray(struct NT_String* v_string, size_t arr_size) {
+  for (size_t i = 0; i < arr_size; i++) std::free(v_string[i].str);
+  std::free(v_string);
+}
+
+NT_Bool NT_SetEntryDouble(NT_Entry entry, uint64_t time, double v_double,
+                          NT_Bool force) {
+  if (force != 0) {
+    nt::SetEntryTypeValue(entry, Value::MakeDouble(v_double, time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(entry, Value::MakeDouble(v_double, time));
+  }
+}
+
+NT_Bool NT_SetEntryBoolean(NT_Entry entry, uint64_t time, NT_Bool v_boolean,
+                           NT_Bool force) {
+  if (force != 0) {
+    nt::SetEntryTypeValue(entry, Value::MakeBoolean(v_boolean != 0, time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(entry, Value::MakeBoolean(v_boolean != 0, time));
+  }
+}
+
+NT_Bool NT_SetEntryString(NT_Entry entry, uint64_t time, const char* str,
+                          size_t str_len, NT_Bool force) {
+  if (force != 0) {
+    nt::SetEntryTypeValue(entry,
+                          Value::MakeString(StringRef(str, str_len), time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(entry,
+                             Value::MakeString(StringRef(str, str_len), time));
+  }
+}
+
+NT_Bool NT_SetEntryRaw(NT_Entry entry, uint64_t time, const char* raw,
+                       size_t raw_len, NT_Bool force) {
+  if (force != 0) {
+    nt::SetEntryTypeValue(entry, Value::MakeRaw(StringRef(raw, raw_len), time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(entry,
+                             Value::MakeRaw(StringRef(raw, raw_len), time));
+  }
+}
+
+NT_Bool NT_SetEntryBooleanArray(NT_Entry entry, uint64_t time,
+                                const NT_Bool* arr, size_t size,
+                                NT_Bool force) {
+  if (force != 0) {
+    nt::SetEntryTypeValue(
+        entry, Value::MakeBooleanArray(wpi::makeArrayRef(arr, size), time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(
+        entry, Value::MakeBooleanArray(wpi::makeArrayRef(arr, size), time));
+  }
+}
+
+NT_Bool NT_SetEntryDoubleArray(NT_Entry entry, uint64_t time, const double* arr,
+                               size_t size, NT_Bool force) {
+  if (force != 0) {
+    nt::SetEntryTypeValue(
+        entry, Value::MakeDoubleArray(wpi::makeArrayRef(arr, size), time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(
+        entry, Value::MakeDoubleArray(wpi::makeArrayRef(arr, size), time));
+  }
+}
+
+NT_Bool NT_SetEntryStringArray(NT_Entry entry, uint64_t time,
+                               const struct NT_String* arr, size_t size,
+                               NT_Bool force) {
+  std::vector<std::string> v;
+  v.reserve(size);
+  for (size_t i = 0; i < size; ++i) v.push_back(ConvertFromC(arr[i]));
+
+  if (force != 0) {
+    nt::SetEntryTypeValue(entry, Value::MakeStringArray(std::move(v), time));
+    return 1;
+  } else {
+    return nt::SetEntryValue(entry, Value::MakeStringArray(std::move(v), time));
+  }
+}
+
+enum NT_Type NT_GetValueType(const struct NT_Value* value) {
+  if (!value) return NT_Type::NT_UNASSIGNED;
+  return value->type;
+}
+
+NT_Bool NT_GetValueBoolean(const struct NT_Value* value, uint64_t* last_change,
+                           NT_Bool* v_boolean) {
+  if (!value || value->type != NT_Type::NT_BOOLEAN) return 0;
+  *v_boolean = value->data.v_boolean;
+  *last_change = value->last_change;
+  return 1;
+}
+
+NT_Bool NT_GetValueDouble(const struct NT_Value* value, uint64_t* last_change,
+                          double* v_double) {
+  if (!value || value->type != NT_Type::NT_DOUBLE) return 0;
+  *last_change = value->last_change;
+  *v_double = value->data.v_double;
+  return 1;
+}
+
+char* NT_GetValueString(const struct NT_Value* value, uint64_t* last_change,
+                        size_t* str_len) {
+  if (!value || value->type != NT_Type::NT_STRING) return nullptr;
+  *last_change = value->last_change;
+  *str_len = value->data.v_string.len;
+  char* str =
+      static_cast<char*>(wpi::safe_malloc(value->data.v_string.len + 1));
+  std::memcpy(str, value->data.v_string.str, value->data.v_string.len + 1);
+  return str;
+}
+
+char* NT_GetValueRaw(const struct NT_Value* value, uint64_t* last_change,
+                     size_t* raw_len) {
+  if (!value || value->type != NT_Type::NT_RAW) return nullptr;
+  *last_change = value->last_change;
+  *raw_len = value->data.v_string.len;
+  char* raw =
+      static_cast<char*>(wpi::safe_malloc(value->data.v_string.len + 1));
+  std::memcpy(raw, value->data.v_string.str, value->data.v_string.len + 1);
+  return raw;
+}
+
+NT_Bool* NT_GetValueBooleanArray(const struct NT_Value* value,
+                                 uint64_t* last_change, size_t* arr_size) {
+  if (!value || value->type != NT_Type::NT_BOOLEAN_ARRAY) return nullptr;
+  *last_change = value->last_change;
+  *arr_size = value->data.arr_boolean.size;
+  NT_Bool* arr = static_cast<int*>(
+      wpi::safe_malloc(value->data.arr_boolean.size * sizeof(NT_Bool)));
+  std::memcpy(arr, value->data.arr_boolean.arr,
+              value->data.arr_boolean.size * sizeof(NT_Bool));
+  return arr;
+}
+
+double* NT_GetValueDoubleArray(const struct NT_Value* value,
+                               uint64_t* last_change, size_t* arr_size) {
+  if (!value || value->type != NT_Type::NT_DOUBLE_ARRAY) return nullptr;
+  *last_change = value->last_change;
+  *arr_size = value->data.arr_double.size;
+  double* arr = static_cast<double*>(
+      wpi::safe_malloc(value->data.arr_double.size * sizeof(double)));
+  std::memcpy(arr, value->data.arr_double.arr,
+              value->data.arr_double.size * sizeof(double));
+  return arr;
+}
+
+NT_String* NT_GetValueStringArray(const struct NT_Value* value,
+                                  uint64_t* last_change, size_t* arr_size) {
+  if (!value || value->type != NT_Type::NT_STRING_ARRAY) return nullptr;
+  *last_change = value->last_change;
+  *arr_size = value->data.arr_string.size;
+  NT_String* arr = static_cast<NT_String*>(
+      wpi::safe_malloc(value->data.arr_string.size * sizeof(NT_String)));
+  for (size_t i = 0; i < value->data.arr_string.size; ++i) {
+    size_t len = value->data.arr_string.arr[i].len;
+    arr[i].len = len;
+    arr[i].str = static_cast<char*>(wpi::safe_malloc(len + 1));
+    std::memcpy(arr[i].str, value->data.arr_string.arr[i].str, len + 1);
+  }
+  return arr;
+}
+
+NT_Bool NT_SetDefaultEntryBoolean(NT_Entry entry, uint64_t time,
+                                  NT_Bool default_boolean) {
+  return nt::SetDefaultEntryValue(
+      entry, Value::MakeBoolean(default_boolean != 0, time));
+}
+
+NT_Bool NT_SetDefaultEntryDouble(NT_Entry entry, uint64_t time,
+                                 double default_double) {
+  return nt::SetDefaultEntryValue(entry,
+                                  Value::MakeDouble(default_double, time));
+}
+
+NT_Bool NT_SetDefaultEntryString(NT_Entry entry, uint64_t time,
+                                 const char* default_value,
+                                 size_t default_len) {
+  return nt::SetDefaultEntryValue(
+      entry, Value::MakeString(StringRef(default_value, default_len), time));
+}
+
+NT_Bool NT_SetDefaultEntryRaw(NT_Entry entry, uint64_t time,
+                              const char* default_value, size_t default_len) {
+  return nt::SetDefaultEntryValue(
+      entry, Value::MakeRaw(StringRef(default_value, default_len), time));
+}
+
+NT_Bool NT_SetDefaultEntryBooleanArray(NT_Entry entry, uint64_t time,
+                                       const NT_Bool* default_value,
+                                       size_t default_size) {
+  return nt::SetDefaultEntryValue(
+      entry, Value::MakeBooleanArray(
+                 wpi::makeArrayRef(default_value, default_size), time));
+}
+
+NT_Bool NT_SetDefaultEntryDoubleArray(NT_Entry entry, uint64_t time,
+                                      const double* default_value,
+                                      size_t default_size) {
+  return nt::SetDefaultEntryValue(
+      entry, Value::MakeDoubleArray(
+                 wpi::makeArrayRef(default_value, default_size), time));
+}
+
+NT_Bool NT_SetDefaultEntryStringArray(NT_Entry entry, uint64_t time,
+                                      const struct NT_String* default_value,
+                                      size_t default_size) {
+  std::vector<std::string> vec;
+  vec.reserve(default_size);
+  for (size_t i = 0; i < default_size; ++i)
+    vec.push_back(ConvertFromC(default_value[i]));
+
+  return nt::SetDefaultEntryValue(entry,
+                                  Value::MakeStringArray(std::move(vec), time));
+}
+
+NT_Bool NT_GetEntryBoolean(NT_Entry entry, uint64_t* last_change,
+                           NT_Bool* v_boolean) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsBoolean()) return 0;
+  *v_boolean = v->GetBoolean();
+  *last_change = v->last_change();
+  return 1;
+}
+
+NT_Bool NT_GetEntryDouble(NT_Entry entry, uint64_t* last_change,
+                          double* v_double) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsDouble()) return 0;
+  *last_change = v->last_change();
+  *v_double = v->GetDouble();
+  return 1;
+}
+
+char* NT_GetEntryString(NT_Entry entry, uint64_t* last_change,
+                        size_t* str_len) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsString()) return nullptr;
+  *last_change = v->last_change();
+  struct NT_String v_string;
+  nt::ConvertToC(v->GetString(), &v_string);
+  *str_len = v_string.len;
+  return v_string.str;
+}
+
+char* NT_GetEntryRaw(NT_Entry entry, uint64_t* last_change, size_t* raw_len) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsRaw()) return nullptr;
+  *last_change = v->last_change();
+  struct NT_String v_raw;
+  nt::ConvertToC(v->GetRaw(), &v_raw);
+  *raw_len = v_raw.len;
+  return v_raw.str;
+}
+
+NT_Bool* NT_GetEntryBooleanArray(NT_Entry entry, uint64_t* last_change,
+                                 size_t* arr_size) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsBooleanArray()) return nullptr;
+  *last_change = v->last_change();
+  auto vArr = v->GetBooleanArray();
+  NT_Bool* arr =
+      static_cast<int*>(wpi::safe_malloc(vArr.size() * sizeof(NT_Bool)));
+  *arr_size = vArr.size();
+  std::copy(vArr.begin(), vArr.end(), arr);
+  return arr;
+}
+
+double* NT_GetEntryDoubleArray(NT_Entry entry, uint64_t* last_change,
+                               size_t* arr_size) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsDoubleArray()) return nullptr;
+  *last_change = v->last_change();
+  auto vArr = v->GetDoubleArray();
+  double* arr =
+      static_cast<double*>(wpi::safe_malloc(vArr.size() * sizeof(double)));
+  *arr_size = vArr.size();
+  std::copy(vArr.begin(), vArr.end(), arr);
+  return arr;
+}
+
+NT_String* NT_GetEntryStringArray(NT_Entry entry, uint64_t* last_change,
+                                  size_t* arr_size) {
+  auto v = nt::GetEntryValue(entry);
+  if (!v || !v->IsStringArray()) return nullptr;
+  *last_change = v->last_change();
+  auto vArr = v->GetStringArray();
+  NT_String* arr = static_cast<NT_String*>(
+      wpi::safe_malloc(vArr.size() * sizeof(NT_String)));
+  for (size_t i = 0; i < vArr.size(); ++i) {
+    ConvertToC(vArr[i], &arr[i]);
+  }
+  *arr_size = vArr.size();
+  return arr;
+}
+
+}  // extern "C"
diff --git a/ntcore/src/main/native/cpp/ntcore_cpp.cpp b/ntcore/src/main/native/cpp/ntcore_cpp.cpp
new file mode 100644
index 0000000..ad8f68b
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ntcore_cpp.cpp
@@ -0,0 +1,1076 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <stdint.h>
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+
+#include <wpi/timestamp.h>
+
+#include "Handle.h"
+#include "InstanceImpl.h"
+#include "Log.h"
+#include "WireDecoder.h"
+#include "WireEncoder.h"
+#include "ntcore.h"
+
+namespace nt {
+
+/*
+ * Instance Functions
+ */
+
+NT_Inst GetDefaultInstance() {
+  return Handle{InstanceImpl::GetDefaultIndex(), 0, Handle::kInstance};
+}
+
+NT_Inst CreateInstance() {
+  return Handle{InstanceImpl::Alloc(), 0, Handle::kInstance};
+}
+
+void DestroyInstance(NT_Inst inst) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  if (i < 0) return;
+  InstanceImpl::Destroy(i);
+}
+
+NT_Inst GetInstanceFromHandle(NT_Handle handle) {
+  Handle h{handle};
+  auto type = h.GetType();
+  if (type >= Handle::kConnectionListener && type <= Handle::kRpcCallPoller)
+    return Handle(h.GetInst(), 0, Handle::kInstance);
+
+  return 0;
+}
+
+/*
+ * Table Functions
+ */
+
+NT_Entry GetEntry(NT_Inst inst, const Twine& name) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  unsigned int id = ii->storage.GetEntry(name);
+  if (id == UINT_MAX) return 0;
+  return Handle(i, id, Handle::kEntry);
+}
+
+std::vector<NT_Entry> GetEntries(NT_Inst inst, const Twine& prefix,
+                                 unsigned int types) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return std::vector<NT_Entry>{};
+
+  auto arr = ii->storage.GetEntries(prefix, types);
+  // convert indices to handles
+  for (auto& val : arr) val = Handle(i, val, Handle::kEntry);
+  return arr;
+}
+
+std::string GetEntryName(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::string{};
+
+  return ii->storage.GetEntryName(id);
+}
+
+NT_Type GetEntryType(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return NT_UNASSIGNED;
+
+  return ii->storage.GetEntryType(id);
+}
+
+uint64_t GetEntryLastChange(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return 0;
+
+  return ii->storage.GetEntryLastChange(id);
+}
+
+std::shared_ptr<Value> GetEntryValue(StringRef name) {
+  return InstanceImpl::GetDefault()->storage.GetEntryValue(name);
+}
+
+std::shared_ptr<Value> GetEntryValue(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return nullptr;
+
+  return ii->storage.GetEntryValue(id);
+}
+
+bool SetDefaultEntryValue(StringRef name, std::shared_ptr<Value> value) {
+  return InstanceImpl::GetDefault()->storage.SetDefaultEntryValue(name, value);
+}
+
+bool SetDefaultEntryValue(NT_Entry entry, std::shared_ptr<Value> value) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return false;
+
+  return ii->storage.SetDefaultEntryValue(id, value);
+}
+
+bool SetEntryValue(StringRef name, std::shared_ptr<Value> value) {
+  return InstanceImpl::GetDefault()->storage.SetEntryValue(name, value);
+}
+
+bool SetEntryValue(NT_Entry entry, std::shared_ptr<Value> value) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return false;
+
+  return ii->storage.SetEntryValue(id, value);
+}
+
+void SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value) {
+  InstanceImpl::GetDefault()->storage.SetEntryTypeValue(name, value);
+}
+
+void SetEntryTypeValue(NT_Entry entry, std::shared_ptr<Value> value) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->storage.SetEntryTypeValue(id, value);
+}
+
+void SetEntryFlags(StringRef name, unsigned int flags) {
+  InstanceImpl::GetDefault()->storage.SetEntryFlags(name, flags);
+}
+
+void SetEntryFlags(NT_Entry entry, unsigned int flags) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->storage.SetEntryFlags(id, flags);
+}
+
+unsigned int GetEntryFlags(StringRef name) {
+  return InstanceImpl::GetDefault()->storage.GetEntryFlags(name);
+}
+
+unsigned int GetEntryFlags(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return 0;
+
+  return ii->storage.GetEntryFlags(id);
+}
+
+void DeleteEntry(StringRef name) {
+  InstanceImpl::GetDefault()->storage.DeleteEntry(name);
+}
+
+void DeleteEntry(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->storage.DeleteEntry(id);
+}
+
+void DeleteAllEntries() {
+  InstanceImpl::GetDefault()->storage.DeleteAllEntries();
+}
+
+void DeleteAllEntries(NT_Inst inst) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (i < 0 || !ii) return;
+
+  ii->storage.DeleteAllEntries();
+}
+
+std::vector<EntryInfo> GetEntryInfo(StringRef prefix, unsigned int types) {
+  return InstanceImpl::GetDefault()->storage.GetEntryInfo(0, prefix, types);
+}
+
+std::vector<EntryInfo> GetEntryInfo(NT_Inst inst, const Twine& prefix,
+                                    unsigned int types) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return std::vector<EntryInfo>{};
+
+  return ii->storage.GetEntryInfo(i, prefix, types);
+}
+
+EntryInfo GetEntryInfo(NT_Entry entry) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) {
+    EntryInfo info;
+    info.entry = 0;
+    info.type = NT_UNASSIGNED;
+    info.flags = 0;
+    info.last_change = 0;
+    return info;
+  }
+
+  return ii->storage.GetEntryInfo(i, id);
+}
+
+/*
+ * Callback Creation Functions
+ */
+
+NT_EntryListener AddEntryListener(StringRef prefix,
+                                  EntryListenerCallback callback,
+                                  unsigned int flags) {
+  return AddEntryListener(
+      Handle(InstanceImpl::GetDefaultIndex(), 0, Handle::kInstance), prefix,
+      [=](const EntryNotification& event) {
+        callback(event.listener, event.name, event.value, event.flags);
+      },
+      flags);
+}
+
+NT_EntryListener AddEntryListener(
+    NT_Inst inst, const Twine& prefix,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (i < 0 || !ii) return 0;
+
+  unsigned int uid = ii->storage.AddListener(prefix, callback, flags);
+  return Handle(i, uid, Handle::kEntryListener);
+}
+
+NT_EntryListener AddEntryListener(
+    NT_Entry entry,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) return 0;
+
+  unsigned int uid = ii->storage.AddListener(id, callback, flags);
+  return Handle(i, uid, Handle::kEntryListener);
+}
+
+NT_EntryListenerPoller CreateEntryListenerPoller(NT_Inst inst) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  return Handle(i, ii->entry_notifier.CreatePoller(),
+                Handle::kEntryListenerPoller);
+}
+
+void DestroyEntryListenerPoller(NT_EntryListenerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kEntryListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->entry_notifier.RemovePoller(id);
+}
+
+NT_EntryListener AddPolledEntryListener(NT_EntryListenerPoller poller,
+                                        const Twine& prefix,
+                                        unsigned int flags) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kEntryListenerPoller);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) return 0;
+
+  unsigned int uid = ii->storage.AddPolledListener(id, prefix, flags);
+  return Handle(i, uid, Handle::kEntryListener);
+}
+
+NT_EntryListener AddPolledEntryListener(NT_EntryListenerPoller poller,
+                                        NT_Entry entry, unsigned int flags) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) return 0;
+
+  Handle phandle{poller};
+  int p_id = phandle.GetTypedIndex(Handle::kEntryListenerPoller);
+  if (p_id < 0) return 0;
+  if (handle.GetInst() != phandle.GetInst()) return 0;
+
+  unsigned int uid = ii->storage.AddPolledListener(p_id, id, flags);
+  return Handle(i, uid, Handle::kEntryListener);
+}
+
+std::vector<EntryNotification> PollEntryListener(
+    NT_EntryListenerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kEntryListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<EntryNotification>{};
+
+  return ii->entry_notifier.Poll(static_cast<unsigned int>(id));
+}
+
+std::vector<EntryNotification> PollEntryListener(NT_EntryListenerPoller poller,
+                                                 double timeout,
+                                                 bool* timed_out) {
+  *timed_out = false;
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kEntryListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<EntryNotification>{};
+
+  return ii->entry_notifier.Poll(static_cast<unsigned int>(id), timeout,
+                                 timed_out);
+}
+
+void CancelPollEntryListener(NT_EntryListenerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kEntryListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->entry_notifier.CancelPoll(id);
+}
+
+void RemoveEntryListener(NT_EntryListener entry_listener) {
+  Handle handle{entry_listener};
+  int uid = handle.GetTypedIndex(Handle::kEntryListener);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (uid < 0 || !ii) return;
+
+  ii->entry_notifier.Remove(uid);
+}
+
+bool WaitForEntryListenerQueue(NT_Inst inst, double timeout) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return true;
+  return ii->entry_notifier.WaitForQueue(timeout);
+}
+
+NT_ConnectionListener AddConnectionListener(ConnectionListenerCallback callback,
+                                            bool immediate_notify) {
+  return AddConnectionListener(
+      Handle(InstanceImpl::GetDefaultIndex(), 0, Handle::kInstance),
+      [=](const ConnectionNotification& event) {
+        callback(event.listener, event.connected, event.conn);
+      },
+      immediate_notify);
+}
+
+NT_ConnectionListener AddConnectionListener(
+    NT_Inst inst,
+    std::function<void(const ConnectionNotification& event)> callback,
+    bool immediate_notify) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  unsigned int uid = ii->dispatcher.AddListener(callback, immediate_notify);
+  return Handle(i, uid, Handle::kConnectionListener);
+}
+
+NT_ConnectionListenerPoller CreateConnectionListenerPoller(NT_Inst inst) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  return Handle(i, ii->connection_notifier.CreatePoller(),
+                Handle::kConnectionListenerPoller);
+}
+
+void DestroyConnectionListenerPoller(NT_ConnectionListenerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kConnectionListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->connection_notifier.RemovePoller(id);
+}
+
+NT_ConnectionListener AddPolledConnectionListener(
+    NT_ConnectionListenerPoller poller, bool immediate_notify) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kConnectionListenerPoller);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) return 0;
+
+  unsigned int uid = ii->dispatcher.AddPolledListener(id, immediate_notify);
+  return Handle(i, uid, Handle::kConnectionListener);
+}
+
+std::vector<ConnectionNotification> PollConnectionListener(
+    NT_ConnectionListenerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kConnectionListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<ConnectionNotification>{};
+
+  return ii->connection_notifier.Poll(static_cast<unsigned int>(id));
+}
+
+std::vector<ConnectionNotification> PollConnectionListener(
+    NT_ConnectionListenerPoller poller, double timeout, bool* timed_out) {
+  *timed_out = false;
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kConnectionListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<ConnectionNotification>{};
+
+  return ii->connection_notifier.Poll(static_cast<unsigned int>(id), timeout,
+                                      timed_out);
+}
+
+void CancelPollConnectionListener(NT_ConnectionListenerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kConnectionListenerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->connection_notifier.CancelPoll(id);
+}
+
+void RemoveConnectionListener(NT_ConnectionListener conn_listener) {
+  Handle handle{conn_listener};
+  int uid = handle.GetTypedIndex(Handle::kConnectionListener);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (uid < 0 || !ii) return;
+
+  ii->connection_notifier.Remove(uid);
+}
+
+bool WaitForConnectionListenerQueue(NT_Inst inst, double timeout) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return true;
+  return ii->connection_notifier.WaitForQueue(timeout);
+}
+
+/*
+ * Remote Procedure Call Functions
+ */
+
+void CreateRpc(NT_Entry entry, StringRef def,
+               std::function<void(const RpcAnswer& answer)> callback) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  // only server can create RPCs
+  if ((ii->dispatcher.GetNetworkMode() & NT_NET_MODE_SERVER) == 0) return;
+  if (def.empty() || !callback) return;
+
+  ii->storage.CreateRpc(id, def, ii->rpc_server.Add(callback));
+}
+
+NT_RpcCallPoller CreateRpcCallPoller(NT_Inst inst) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  return Handle(i, ii->rpc_server.CreatePoller(), Handle::kRpcCallPoller);
+}
+
+void DestroyRpcCallPoller(NT_RpcCallPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kRpcCallPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->rpc_server.RemovePoller(id);
+}
+
+void CreatePolledRpc(NT_Entry entry, StringRef def, NT_RpcCallPoller poller) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  Handle phandle{poller};
+  int p_id = phandle.GetTypedIndex(Handle::kRpcCallPoller);
+  if (p_id < 0) return;
+  if (handle.GetInst() != phandle.GetInst()) return;
+
+  // only server can create RPCs
+  if ((ii->dispatcher.GetNetworkMode() & NT_NET_MODE_SERVER) == 0) return;
+  if (def.empty()) return;
+
+  ii->storage.CreateRpc(id, def, ii->rpc_server.AddPolled(p_id));
+}
+
+std::vector<RpcAnswer> PollRpc(NT_RpcCallPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kRpcCallPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<RpcAnswer>{};
+
+  return ii->rpc_server.Poll(static_cast<unsigned int>(id));
+}
+
+std::vector<RpcAnswer> PollRpc(NT_RpcCallPoller poller, double timeout,
+                               bool* timed_out) {
+  *timed_out = false;
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kRpcCallPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<RpcAnswer>{};
+
+  return ii->rpc_server.Poll(static_cast<unsigned int>(id), timeout, timed_out);
+}
+
+void CancelPollRpc(NT_RpcCallPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kRpcCallPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->rpc_server.CancelPoll(id);
+}
+
+bool WaitForRpcCallQueue(NT_Inst inst, double timeout) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return true;
+  return ii->rpc_server.WaitForQueue(timeout);
+}
+
+bool PostRpcResponse(NT_Entry entry, NT_RpcCall call, StringRef result) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return false;
+
+  Handle chandle{call};
+  int call_uid = chandle.GetTypedIndex(Handle::kRpcCall);
+  if (call_uid < 0) return false;
+  if (handle.GetInst() != chandle.GetInst()) return false;
+
+  return ii->rpc_server.PostRpcResponse(id, call_uid, result);
+}
+
+NT_RpcCall CallRpc(NT_Entry entry, StringRef params) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) return 0;
+
+  unsigned int call_uid = ii->storage.CallRpc(id, params);
+  if (call_uid == 0) return 0;
+  return Handle(i, call_uid, Handle::kRpcCall);
+}
+
+bool GetRpcResult(NT_Entry entry, NT_RpcCall call, std::string* result) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return false;
+
+  Handle chandle{call};
+  int call_uid = chandle.GetTypedIndex(Handle::kRpcCall);
+  if (call_uid < 0) return false;
+  if (handle.GetInst() != chandle.GetInst()) return false;
+
+  return ii->storage.GetRpcResult(id, call_uid, result);
+}
+
+bool GetRpcResult(NT_Entry entry, NT_RpcCall call, std::string* result,
+                  double timeout, bool* timed_out) {
+  *timed_out = false;
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return false;
+
+  Handle chandle{call};
+  int call_uid = chandle.GetTypedIndex(Handle::kRpcCall);
+  if (call_uid < 0) return false;
+  if (handle.GetInst() != chandle.GetInst()) return false;
+
+  return ii->storage.GetRpcResult(id, call_uid, result, timeout, timed_out);
+}
+
+void CancelRpcResult(NT_Entry entry, NT_RpcCall call) {
+  Handle handle{entry};
+  int id = handle.GetTypedIndex(Handle::kEntry);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  Handle chandle{call};
+  int call_uid = chandle.GetTypedIndex(Handle::kRpcCall);
+  if (call_uid < 0) return;
+  if (handle.GetInst() != chandle.GetInst()) return;
+
+  ii->storage.CancelRpcResult(id, call_uid);
+}
+
+std::string PackRpcDefinition(const RpcDefinition& def) {
+  WireEncoder enc(0x0300);
+  enc.Write8(def.version);
+  enc.WriteString(def.name);
+
+  // parameters
+  unsigned int params_size = def.params.size();
+  if (params_size > 0xff) params_size = 0xff;
+  enc.Write8(params_size);
+  for (size_t i = 0; i < params_size; ++i) {
+    enc.WriteType(def.params[i].def_value->type());
+    enc.WriteString(def.params[i].name);
+    enc.WriteValue(*def.params[i].def_value);
+  }
+
+  // results
+  unsigned int results_size = def.results.size();
+  if (results_size > 0xff) results_size = 0xff;
+  enc.Write8(results_size);
+  for (size_t i = 0; i < results_size; ++i) {
+    enc.WriteType(def.results[i].type);
+    enc.WriteString(def.results[i].name);
+  }
+
+  return enc.ToStringRef();
+}
+
+bool UnpackRpcDefinition(StringRef packed, RpcDefinition* def) {
+  wpi::raw_mem_istream is(packed.data(), packed.size());
+  wpi::Logger logger;
+  WireDecoder dec(is, 0x0300, logger);
+  if (!dec.Read8(&def->version)) return false;
+  if (!dec.ReadString(&def->name)) return false;
+
+  // parameters
+  unsigned int params_size;
+  if (!dec.Read8(&params_size)) return false;
+  def->params.resize(0);
+  def->params.reserve(params_size);
+  for (size_t i = 0; i < params_size; ++i) {
+    RpcParamDef pdef;
+    NT_Type type;
+    if (!dec.ReadType(&type)) return false;
+    if (!dec.ReadString(&pdef.name)) return false;
+    pdef.def_value = dec.ReadValue(type);
+    if (!pdef.def_value) return false;
+    def->params.emplace_back(std::move(pdef));
+  }
+
+  // results
+  unsigned int results_size;
+  if (!dec.Read8(&results_size)) return false;
+  def->results.resize(0);
+  def->results.reserve(results_size);
+  for (size_t i = 0; i < results_size; ++i) {
+    RpcResultDef rdef;
+    if (!dec.ReadType(&rdef.type)) return false;
+    if (!dec.ReadString(&rdef.name)) return false;
+    def->results.emplace_back(std::move(rdef));
+  }
+
+  return true;
+}
+
+std::string PackRpcValues(ArrayRef<std::shared_ptr<Value>> values) {
+  WireEncoder enc(0x0300);
+  for (auto& value : values) enc.WriteValue(*value);
+  return enc.ToStringRef();
+}
+
+std::vector<std::shared_ptr<Value>> UnpackRpcValues(StringRef packed,
+                                                    ArrayRef<NT_Type> types) {
+  wpi::raw_mem_istream is(packed.data(), packed.size());
+  wpi::Logger logger;
+  WireDecoder dec(is, 0x0300, logger);
+  std::vector<std::shared_ptr<Value>> vec;
+  for (auto type : types) {
+    auto item = dec.ReadValue(type);
+    if (!item) return std::vector<std::shared_ptr<Value>>();
+    vec.emplace_back(std::move(item));
+  }
+  return vec;
+}
+
+uint64_t Now() { return wpi::Now(); }
+
+/*
+ * Client/Server Functions
+ */
+
+void SetNetworkIdentity(StringRef name) {
+  InstanceImpl::GetDefault()->dispatcher.SetIdentity(name);
+}
+
+void SetNetworkIdentity(NT_Inst inst, const Twine& name) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetIdentity(name);
+}
+
+unsigned int GetNetworkMode() {
+  return InstanceImpl::GetDefault()->dispatcher.GetNetworkMode();
+}
+
+unsigned int GetNetworkMode(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return 0;
+
+  return ii->dispatcher.GetNetworkMode();
+}
+
+void StartLocal(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.StartLocal();
+}
+
+void StopLocal(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.Stop();
+}
+
+void StartServer(StringRef persist_filename, const char* listen_address,
+                 unsigned int port) {
+  auto ii = InstanceImpl::GetDefault();
+  ii->dispatcher.StartServer(persist_filename, listen_address, port);
+}
+
+void StartServer(NT_Inst inst, const Twine& persist_filename,
+                 const char* listen_address, unsigned int port) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.StartServer(persist_filename, listen_address, port);
+}
+
+void StopServer() { InstanceImpl::GetDefault()->dispatcher.Stop(); }
+
+void StopServer(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.Stop();
+}
+
+void StartClient() { InstanceImpl::GetDefault()->dispatcher.StartClient(); }
+
+void StartClient(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.StartClient();
+}
+
+void StartClient(const char* server_name, unsigned int port) {
+  auto ii = InstanceImpl::GetDefault();
+  ii->dispatcher.SetServer(server_name, port);
+  ii->dispatcher.StartClient();
+}
+
+void StartClient(NT_Inst inst, const char* server_name, unsigned int port) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetServer(server_name, port);
+  ii->dispatcher.StartClient();
+}
+
+void StartClient(ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  auto ii = InstanceImpl::GetDefault();
+  ii->dispatcher.SetServer(servers);
+  ii->dispatcher.StartClient();
+}
+
+void StartClient(NT_Inst inst,
+                 ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetServer(servers);
+  ii->dispatcher.StartClient();
+}
+
+void StartClientTeam(NT_Inst inst, unsigned int team, unsigned int port) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetServerTeam(team, port);
+  ii->dispatcher.StartClient();
+}
+
+void StopClient() { InstanceImpl::GetDefault()->dispatcher.Stop(); }
+
+void StopClient(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.Stop();
+}
+
+void SetServer(const char* server_name, unsigned int port) {
+  InstanceImpl::GetDefault()->dispatcher.SetServer(server_name, port);
+}
+
+void SetServer(NT_Inst inst, const char* server_name, unsigned int port) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetServer(server_name, port);
+}
+
+void SetServer(ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  InstanceImpl::GetDefault()->dispatcher.SetServer(servers);
+}
+
+void SetServer(NT_Inst inst,
+               ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetServer(servers);
+}
+
+void SetServerTeam(NT_Inst inst, unsigned int team, unsigned int port) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetServerTeam(team, port);
+}
+
+void StartDSClient(unsigned int port) {
+  InstanceImpl::GetDefault()->ds_client.Start(port);
+}
+
+void StartDSClient(NT_Inst inst, unsigned int port) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->ds_client.Start(port);
+}
+
+void StopDSClient() { InstanceImpl::GetDefault()->ds_client.Stop(); }
+
+void StopDSClient(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->ds_client.Stop();
+}
+
+void SetUpdateRate(double interval) {
+  InstanceImpl::GetDefault()->dispatcher.SetUpdateRate(interval);
+}
+
+void SetUpdateRate(NT_Inst inst, double interval) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.SetUpdateRate(interval);
+}
+
+void Flush() { InstanceImpl::GetDefault()->dispatcher.Flush(); }
+
+void Flush(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return;
+
+  ii->dispatcher.Flush();
+}
+
+std::vector<ConnectionInfo> GetConnections() {
+  return InstanceImpl::GetDefault()->dispatcher.GetConnections();
+}
+
+std::vector<ConnectionInfo> GetConnections(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return std::vector<ConnectionInfo>{};
+
+  return ii->dispatcher.GetConnections();
+}
+
+bool IsConnected(NT_Inst inst) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return false;
+
+  return ii->dispatcher.IsConnected();
+}
+
+/*
+ * Persistent Functions
+ */
+
+const char* SavePersistent(StringRef filename) {
+  return InstanceImpl::GetDefault()->storage.SavePersistent(filename, false);
+}
+
+const char* SavePersistent(NT_Inst inst, const Twine& filename) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return "invalid instance handle";
+
+  return ii->storage.SavePersistent(filename, false);
+}
+
+const char* LoadPersistent(
+    StringRef filename,
+    std::function<void(size_t line, const char* msg)> warn) {
+  return InstanceImpl::GetDefault()->storage.LoadPersistent(filename, warn);
+}
+
+const char* LoadPersistent(
+    NT_Inst inst, const Twine& filename,
+    std::function<void(size_t line, const char* msg)> warn) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return "invalid instance handle";
+
+  return ii->storage.LoadPersistent(filename, warn);
+}
+
+const char* SaveEntries(NT_Inst inst, const Twine& filename,
+                        const Twine& prefix) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return "invalid instance handle";
+
+  return ii->storage.SaveEntries(filename, prefix);
+}
+
+const char* LoadEntries(
+    NT_Inst inst, const Twine& filename, const Twine& prefix,
+    std::function<void(size_t line, const char* msg)> warn) {
+  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
+  if (!ii) return "invalid instance handle";
+
+  return ii->storage.LoadEntries(filename, prefix, warn);
+}
+
+void SetLogger(LogFunc func, unsigned int min_level) {
+  auto ii = InstanceImpl::GetDefault();
+  static wpi::mutex mutex;
+  static unsigned int logger = 0;
+  std::scoped_lock lock(mutex);
+  if (logger != 0) ii->logger_impl.Remove(logger);
+  logger = ii->logger_impl.Add(
+      [=](const LogMessage& msg) {
+        func(msg.level, msg.filename, msg.line, msg.message.c_str());
+      },
+      min_level, UINT_MAX);
+}
+
+NT_Logger AddLogger(NT_Inst inst,
+                    std::function<void(const LogMessage& msg)> func,
+                    unsigned int min_level, unsigned int max_level) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  if (min_level < ii->logger.min_level()) ii->logger.set_min_level(min_level);
+
+  return Handle(i, ii->logger_impl.Add(func, min_level, max_level),
+                Handle::kLogger);
+}
+
+NT_LoggerPoller CreateLoggerPoller(NT_Inst inst) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return 0;
+
+  return Handle(i, ii->logger_impl.CreatePoller(), Handle::kLoggerPoller);
+}
+
+void DestroyLoggerPoller(NT_LoggerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kLoggerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->logger_impl.RemovePoller(id);
+}
+
+NT_Logger AddPolledLogger(NT_LoggerPoller poller, unsigned int min_level,
+                          unsigned int max_level) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kLoggerPoller);
+  int i = handle.GetInst();
+  auto ii = InstanceImpl::Get(i);
+  if (id < 0 || !ii) return 0;
+
+  if (min_level < ii->logger.min_level()) ii->logger.set_min_level(min_level);
+
+  return Handle(i, ii->logger_impl.AddPolled(id, min_level, max_level),
+                Handle::kLogger);
+}
+
+std::vector<LogMessage> PollLogger(NT_LoggerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kLoggerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<LogMessage>{};
+
+  return ii->logger_impl.Poll(static_cast<unsigned int>(id));
+}
+
+std::vector<LogMessage> PollLogger(NT_LoggerPoller poller, double timeout,
+                                   bool* timed_out) {
+  *timed_out = false;
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kLoggerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return std::vector<LogMessage>{};
+
+  return ii->logger_impl.Poll(static_cast<unsigned int>(id), timeout,
+                              timed_out);
+}
+
+void CancelPollLogger(NT_LoggerPoller poller) {
+  Handle handle{poller};
+  int id = handle.GetTypedIndex(Handle::kLoggerPoller);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (id < 0 || !ii) return;
+
+  ii->logger_impl.CancelPoll(id);
+}
+
+void RemoveLogger(NT_Logger logger) {
+  Handle handle{logger};
+  int uid = handle.GetTypedIndex(Handle::kLogger);
+  auto ii = InstanceImpl::Get(handle.GetInst());
+  if (uid < 0 || !ii) return;
+
+  ii->logger_impl.Remove(uid);
+  ii->logger.set_min_level(ii->logger_impl.GetMinLevel());
+}
+
+bool WaitForLoggerQueue(NT_Inst inst, double timeout) {
+  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
+  auto ii = InstanceImpl::Get(i);
+  if (!ii) return true;
+  return ii->logger_impl.WaitForQueue(timeout);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/ntcore_test.cpp b/ntcore/src/main/native/cpp/ntcore_test.cpp
new file mode 100644
index 0000000..d633fc5
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ntcore_test.cpp
@@ -0,0 +1,246 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "ntcore_test.h"
+
+#include <wpi/MemAlloc.h>
+
+#include "Value_internal.h"
+
+extern "C" {
+struct NT_String* NT_GetStringForTesting(const char* string, int* struct_size) {
+  struct NT_String* str =
+      static_cast<NT_String*>(wpi::safe_calloc(1, sizeof(NT_String)));
+  nt::ConvertToC(wpi::StringRef(string), str);
+  *struct_size = sizeof(NT_String);
+  return str;
+}
+
+struct NT_EntryInfo* NT_GetEntryInfoForTesting(const char* name,
+                                               enum NT_Type type,
+                                               unsigned int flags,
+                                               uint64_t last_change,
+                                               int* struct_size) {
+  struct NT_EntryInfo* entry_info =
+      static_cast<NT_EntryInfo*>(wpi::safe_calloc(1, sizeof(NT_EntryInfo)));
+  nt::ConvertToC(wpi::StringRef(name), &entry_info->name);
+  entry_info->type = type;
+  entry_info->flags = flags;
+  entry_info->last_change = last_change;
+  *struct_size = sizeof(NT_EntryInfo);
+  return entry_info;
+}
+
+void NT_FreeEntryInfoForTesting(struct NT_EntryInfo* info) {
+  std::free(info->name.str);
+  std::free(info);
+}
+
+struct NT_ConnectionInfo* NT_GetConnectionInfoForTesting(
+    const char* remote_id, const char* remote_ip, unsigned int remote_port,
+    uint64_t last_update, unsigned int protocol_version, int* struct_size) {
+  struct NT_ConnectionInfo* conn_info = static_cast<NT_ConnectionInfo*>(
+      wpi::safe_calloc(1, sizeof(NT_ConnectionInfo)));
+  nt::ConvertToC(wpi::StringRef(remote_id), &conn_info->remote_id);
+  nt::ConvertToC(wpi::StringRef(remote_ip), &conn_info->remote_ip);
+  conn_info->remote_port = remote_port;
+  conn_info->last_update = last_update;
+  conn_info->protocol_version = protocol_version;
+  *struct_size = sizeof(NT_ConnectionInfo);
+  return conn_info;
+}
+
+void NT_FreeConnectionInfoForTesting(struct NT_ConnectionInfo* info) {
+  std::free(info->remote_id.str);
+  std::free(info->remote_ip.str);
+  std::free(info);
+}
+
+struct NT_Value* NT_GetValueBooleanForTesting(uint64_t last_change, int val,
+                                              int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_BOOLEAN;
+  value->last_change = last_change;
+  value->data.v_boolean = val;
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+
+struct NT_Value* NT_GetValueDoubleForTesting(uint64_t last_change, double val,
+                                             int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_DOUBLE;
+  value->last_change = last_change;
+  value->data.v_double = val;
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+
+struct NT_Value* NT_GetValueStringForTesting(uint64_t last_change,
+                                             const char* str,
+                                             int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_STRING;
+  value->last_change = last_change;
+  nt::ConvertToC(wpi::StringRef(str), &value->data.v_string);
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+
+struct NT_Value* NT_GetValueRawForTesting(uint64_t last_change, const char* raw,
+                                          int raw_len, int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_RAW;
+  value->last_change = last_change;
+  nt::ConvertToC(wpi::StringRef(raw, raw_len), &value->data.v_string);
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+
+struct NT_Value* NT_GetValueBooleanArrayForTesting(uint64_t last_change,
+                                                   const int* arr,
+                                                   size_t array_len,
+                                                   int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_BOOLEAN_ARRAY;
+  value->last_change = last_change;
+  value->data.arr_boolean.arr = NT_AllocateBooleanArray(array_len);
+  value->data.arr_boolean.size = array_len;
+  std::memcpy(value->data.arr_boolean.arr, arr,
+              value->data.arr_boolean.size * sizeof(int));
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+
+struct NT_Value* NT_GetValueDoubleArrayForTesting(uint64_t last_change,
+                                                  const double* arr,
+                                                  size_t array_len,
+                                                  int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_BOOLEAN;
+  value->last_change = last_change;
+  value->data.arr_double.arr = NT_AllocateDoubleArray(array_len);
+  value->data.arr_double.size = array_len;
+  std::memcpy(value->data.arr_double.arr, arr,
+              value->data.arr_double.size * sizeof(int));
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+
+struct NT_Value* NT_GetValueStringArrayForTesting(uint64_t last_change,
+                                                  const struct NT_String* arr,
+                                                  size_t array_len,
+                                                  int* struct_size) {
+  struct NT_Value* value =
+      static_cast<NT_Value*>(wpi::safe_calloc(1, sizeof(NT_Value)));
+  value->type = NT_BOOLEAN;
+  value->last_change = last_change;
+  value->data.arr_string.arr = NT_AllocateStringArray(array_len);
+  value->data.arr_string.size = array_len;
+  for (size_t i = 0; i < value->data.arr_string.size; ++i) {
+    size_t len = arr[i].len;
+    value->data.arr_string.arr[i].len = len;
+    value->data.arr_string.arr[i].str =
+        static_cast<char*>(wpi::safe_malloc(len + 1));
+    std::memcpy(value->data.arr_string.arr[i].str, arr[i].str, len + 1);
+  }
+  *struct_size = sizeof(NT_Value);
+  return value;
+}
+// No need for free as one already exists in the main library
+
+static void CopyNtValue(const struct NT_Value* copy_from,
+                        struct NT_Value* copy_to) {
+  auto cpp_value = nt::ConvertFromC(*copy_from);
+  nt::ConvertToC(*cpp_value, copy_to);
+}
+
+static void CopyNtString(const struct NT_String* copy_from,
+                         struct NT_String* copy_to) {
+  nt::ConvertToC(wpi::StringRef(copy_from->str, copy_from->len), copy_to);
+}
+
+struct NT_RpcParamDef* NT_GetRpcParamDefForTesting(const char* name,
+                                                   const struct NT_Value* val,
+                                                   int* struct_size) {
+  struct NT_RpcParamDef* def =
+      static_cast<NT_RpcParamDef*>(wpi::safe_calloc(1, sizeof(NT_RpcParamDef)));
+  nt::ConvertToC(wpi::StringRef(name), &def->name);
+  CopyNtValue(val, &def->def_value);
+  *struct_size = sizeof(NT_RpcParamDef);
+  return def;
+}
+
+void NT_FreeRpcParamDefForTesting(struct NT_RpcParamDef* def) {
+  NT_DisposeValue(&def->def_value);
+  NT_DisposeString(&def->name);
+  std::free(def);
+}
+
+struct NT_RpcResultDef* NT_GetRpcResultsDefForTesting(const char* name,
+                                                      enum NT_Type type,
+                                                      int* struct_size) {
+  struct NT_RpcResultDef* def = static_cast<NT_RpcResultDef*>(
+      wpi::safe_calloc(1, sizeof(NT_RpcResultDef)));
+  nt::ConvertToC(wpi::StringRef(name), &def->name);
+  def->type = type;
+  *struct_size = sizeof(NT_RpcResultDef);
+  return def;
+}
+
+void NT_FreeRpcResultsDefForTesting(struct NT_RpcResultDef* def) {
+  NT_DisposeString(&def->name);
+  std::free(def);
+}
+
+struct NT_RpcDefinition* NT_GetRpcDefinitionForTesting(
+    unsigned int version, const char* name, size_t num_params,
+    const struct NT_RpcParamDef* params, size_t num_results,
+    const struct NT_RpcResultDef* results, int* struct_size) {
+  struct NT_RpcDefinition* def = static_cast<NT_RpcDefinition*>(
+      wpi::safe_calloc(1, sizeof(NT_RpcDefinition)));
+  def->version = version;
+  nt::ConvertToC(wpi::StringRef(name), &def->name);
+  def->num_params = num_params;
+  def->params = static_cast<NT_RpcParamDef*>(
+      wpi::safe_malloc(num_params * sizeof(NT_RpcParamDef)));
+  for (size_t i = 0; i < num_params; ++i) {
+    CopyNtString(&params[i].name, &def->params[i].name);
+    CopyNtValue(&params[i].def_value, &def->params[i].def_value);
+  }
+  def->num_results = num_results;
+  def->results = static_cast<NT_RpcResultDef*>(
+      wpi::safe_malloc(num_results * sizeof(NT_RpcResultDef)));
+  for (size_t i = 0; i < num_results; ++i) {
+    CopyNtString(&results[i].name, &def->results[i].name);
+    def->results[i].type = results[i].type;
+  }
+  *struct_size = sizeof(NT_RpcDefinition);
+  return def;
+}
+// No need for free as one already exists in the main library
+
+struct NT_RpcAnswer* NT_GetRpcAnswerForTesting(
+    unsigned int rpc_id, unsigned int call_uid, const char* name,
+    const char* params, size_t params_len, int* struct_size) {
+  struct NT_RpcAnswer* info =
+      static_cast<NT_RpcAnswer*>(wpi::safe_calloc(1, sizeof(NT_RpcAnswer)));
+  info->entry = rpc_id;
+  info->call = call_uid;
+  nt::ConvertToC(wpi::StringRef(name), &info->name);
+  nt::ConvertToC(wpi::StringRef(params, params_len), &info->params);
+  *struct_size = sizeof(NT_RpcAnswer);
+  return info;
+}
+// No need for free as one already exists in the main library
+}  // extern "C"
diff --git a/ntcore/src/main/native/cpp/tables/ITableListener.cpp b/ntcore/src/main/native/cpp/tables/ITableListener.cpp
new file mode 100644
index 0000000..6abd3bb
--- /dev/null
+++ b/ntcore/src/main/native/cpp/tables/ITableListener.cpp
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "tables/ITableListener.h"
+
+#include "ntcore_c.h"
+
+void ITableListener::ValueChangedEx(ITable* source, wpi::StringRef key,
+                                    std::shared_ptr<nt::Value> value,
+                                    unsigned int flags) {
+  ValueChanged(source, key, value, (flags & NT_NOTIFY_NEW) != 0);
+}
diff --git a/ntcore/src/main/native/include/networktables/EntryListenerFlags.h b/ntcore/src/main/native/include/networktables/EntryListenerFlags.h
new file mode 100644
index 0000000..c5cc620
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/EntryListenerFlags.h
@@ -0,0 +1,82 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_ENTRYLISTENERFLAGS_H_
+#define NTCORE_NETWORKTABLES_ENTRYLISTENERFLAGS_H_
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+/** Entry listener flags */
+namespace EntryListenerFlags {
+
+/**
+ * Flag values for use with entry listeners.
+ *
+ * The flags are a bitmask and must be OR'ed together to indicate the
+ * combination of events desired to be received.
+ *
+ * The constants kNew, kDelete, kUpdate, and kFlags represent different events
+ * that can occur to entries.
+ *
+ * By default, notifications are only generated for remote changes occurring
+ * after the listener is created.  The constants kImmediate and kLocal are
+ * modifiers that cause notifications to be generated at other times.
+ *
+ * @ingroup ntcore_cpp_api
+ */
+enum {
+  /**
+   * Initial listener addition.
+   * Set this flag to receive immediate notification of entries matching the
+   * flag criteria (generally only useful when combined with kNew).
+   */
+  kImmediate = NT_NOTIFY_IMMEDIATE,
+
+  /**
+   * Changed locally.
+   * Set this flag to receive notification of both local changes and changes
+   * coming from remote nodes.  By default, notifications are only generated
+   * for remote changes.  Must be combined with some combination of kNew,
+   * kDelete, kUpdate, and kFlags to receive notifications of those respective
+   * events.
+   */
+  kLocal = NT_NOTIFY_LOCAL,
+
+  /**
+   * Newly created entry.
+   * Set this flag to receive a notification when an entry is created.
+   */
+  kNew = NT_NOTIFY_NEW,
+
+  /**
+   * Entry was deleted.
+   * Set this flag to receive a notification when an entry is deleted.
+   */
+  kDelete = NT_NOTIFY_DELETE,
+
+  /**
+   * Entry's value changed.
+   * Set this flag to receive a notification when an entry's value (or type)
+   * changes.
+   */
+  kUpdate = NT_NOTIFY_UPDATE,
+
+  /**
+   * Entry's flags changed.
+   * Set this flag to receive a notification when an entry's flags value
+   * changes.
+   */
+  kFlags = NT_NOTIFY_FLAGS
+};
+
+}  // namespace EntryListenerFlags
+
+}  // namespace nt
+
+#endif  // NTCORE_NETWORKTABLES_ENTRYLISTENERFLAGS_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTable.h b/ntcore/src/main/native/include/networktables/NetworkTable.h
new file mode 100644
index 0000000..6504e09
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTable.h
@@ -0,0 +1,782 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_NETWORKTABLE_H_
+#define NTCORE_NETWORKTABLES_NETWORKTABLE_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <wpi/ArrayRef.h>
+#include <wpi/StringMap.h>
+#include <wpi/Twine.h>
+#include <wpi/mutex.h>
+
+#include "networktables/NetworkTableEntry.h"
+#include "networktables/TableEntryListener.h"
+#include "networktables/TableListener.h"
+#include "ntcore_c.h"
+#include "tables/ITable.h"
+
+namespace nt {
+
+using wpi::ArrayRef;
+using wpi::StringRef;
+using wpi::Twine;
+
+class NetworkTableInstance;
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif _WIN32
+#pragma warning(push)
+#pragma warning(disable : 4996)
+#endif
+
+/**
+ * @defgroup ntcore_cpp_api ntcore C++ object-oriented API
+ *
+ * Recommended interface for C++, identical to Java API.
+ */
+
+/**
+ * A network table that knows its subtable path.
+ * @ingroup ntcore_cpp_api
+ */
+class NetworkTable final : public ITable {
+ private:
+  NT_Inst m_inst;
+  std::string m_path;
+  mutable wpi::mutex m_mutex;
+  mutable wpi::StringMap<NT_Entry> m_entries;
+  typedef std::pair<ITableListener*, NT_EntryListener> Listener;
+  std::vector<Listener> m_listeners;
+  std::vector<NT_EntryListener> m_lambdaListeners;
+
+  static std::vector<std::string> s_ip_addresses;
+  static std::string s_persistent_filename;
+  static bool s_client;
+  static bool s_enable_ds;
+  static bool s_running;
+  static unsigned int s_port;
+
+  struct private_init {};
+  friend class NetworkTableInstance;
+
+ public:
+  /**
+   * Gets the "base name" of a key. For example, "/foo/bar" becomes "bar".
+   * If the key has a trailing slash, returns an empty string.
+   *
+   * @param key key
+   * @return base name
+   */
+  static StringRef BasenameKey(StringRef key);
+
+  /**
+   * Normalizes an network table key to contain no consecutive slashes and
+   * optionally start with a leading slash. For example:
+   *
+   * <pre><code>
+   * normalizeKey("/foo/bar", true)  == "/foo/bar"
+   * normalizeKey("foo/bar", true)   == "/foo/bar"
+   * normalizeKey("/foo/bar", false) == "foo/bar"
+   * normalizeKey("foo//bar", false) == "foo/bar"
+   * </code></pre>
+   *
+   * @param key              the key to normalize
+   * @param withLeadingSlash whether or not the normalized key should begin
+   *                         with a leading slash
+   * @return normalized key
+   */
+  static std::string NormalizeKey(const Twine& key,
+                                  bool withLeadingSlash = true);
+
+  static StringRef NormalizeKey(const Twine& key,
+                                wpi::SmallVectorImpl<char>& buf,
+                                bool withLeadingSlash = true);
+
+  /**
+   * Gets a list of the names of all the super tables of a given key. For
+   * example, the key "/foo/bar/baz" has a hierarchy of "/", "/foo",
+   * "/foo/bar", and "/foo/bar/baz".
+   *
+   * @param key the key
+   * @return List of super tables
+   */
+  static std::vector<std::string> GetHierarchy(const Twine& key);
+
+  /**
+   * Constructor.  Use NetworkTableInstance::GetTable() or GetSubTable()
+   * instead.
+   */
+  NetworkTable(NT_Inst inst, const Twine& path, const private_init&);
+  virtual ~NetworkTable();
+
+  /**
+   * Gets the instance for the table.
+   *
+   * @return Instance
+   */
+  NetworkTableInstance GetInstance() const;
+
+  /**
+   * The path separator for sub-tables and keys
+   */
+  static const char PATH_SEPARATOR_CHAR;
+
+  /**
+   * Initializes network tables
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::StartServer() or "
+      "NetworkTableInstance::StartClient() instead")
+  static void Initialize();
+
+  /**
+   * Shuts down network tables
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::StopServer() or "
+      "NetworkTableInstance::StopClient() instead")
+  static void Shutdown();
+
+  /**
+   * set that network tables should be a client
+   * This must be called before initialize or GetTable
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::StartClient() instead")
+  static void SetClientMode();
+
+  /**
+   * set that network tables should be a server
+   * This must be called before initialize or GetTable
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::StartServer() instead")
+  static void SetServerMode();
+
+  /**
+   * 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
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::SetServerTeam() or "
+      "NetworkTableInstance::StartClientTeam() instead")
+  static void SetTeam(int team);
+
+  /**
+   * @param address the adress that network tables will connect to in client
+   * mode
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::SetServer() or "
+      "NetworkTableInstance::StartClient() instead")
+  static void SetIPAddress(StringRef address);
+
+  /**
+   * @param addresses the addresses that network tables will connect to in
+   * client mode (in round robin order)
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::SetServer() or "
+      "NetworkTableInstance::StartClient() instead")
+  static void SetIPAddress(ArrayRef<std::string> addresses);
+
+  /**
+   * Set the port number that network tables will connect to in client
+   * mode or listen to in server mode.
+   *
+   * @param port the port number
+   */
+  WPI_DEPRECATED(
+      "use the appropriate parameters to NetworkTableInstance::SetServer(), "
+      "NetworkTableInstance::StartClient(), "
+      "NetworkTableInstance::StartServer(), and "
+      "NetworkTableInstance::StartDSClient() instead")
+  static void SetPort(unsigned int port);
+
+  /**
+   * Enable requesting the server address from the Driver Station.
+   *
+   * @param enabled whether to enable the connection to the local DS
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::StartDSClient() and "
+      "NetworkTableInstance::StopDSClient() instead")
+  static void SetDSClientEnabled(bool enabled);
+
+  /**
+   * Sets the persistent filename.
+   *
+   * @param filename the filename that the network tables server uses for
+   * automatic loading and saving of persistent values
+   */
+  WPI_DEPRECATED(
+      "use the appropriate parameter to NetworkTableInstance::StartServer() "
+      "instead")
+  static void SetPersistentFilename(StringRef filename);
+
+  /**
+   * Sets the network identity.
+   * This is provided in the connection info on the remote end.
+   *
+   * @param name identity
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::SetNetworkIdentity() instead")
+  static void SetNetworkIdentity(StringRef name);
+
+  /**
+   * Deletes ALL keys in ALL subtables.  Use with caution!
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::DeleteAllEntries() instead")
+  static void GlobalDeleteAll();
+
+  /**
+   * 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.
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::Flush() instead")
+  static void Flush();
+
+  /**
+   * Set the periodic update rate.
+   * Sets how frequently updates are sent to other nodes over the network.
+   *
+   * @param interval update interval in seconds (range 0.01 to 1.0)
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::SetUpdateRate() instead")
+  static void SetUpdateRate(double interval);
+
+  /**
+   * Saves persistent keys to a file.  The server does this automatically.
+   *
+   * @param filename file name
+   * @return Error (or nullptr).
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::SavePersistent() instead")
+  static const char* SavePersistent(StringRef filename);
+
+  /**
+   * Loads persistent keys from a file.  The server does this automatically.
+   *
+   * @param filename file name
+   * @param warn callback function called for warnings
+   * @return Error (or nullptr).
+   */
+  WPI_DEPRECATED("use NetworkTableInstance::LoadPersistent() instead")
+  static const char* LoadPersistent(
+      StringRef filename,
+      std::function<void(size_t line, const char* msg)> warn);
+
+  /**
+   * 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
+   */
+  WPI_DEPRECATED(
+      "use NetworkTableInstance::GetTable() or "
+      "NetworkTableInstance::GetEntry() instead")
+  static std::shared_ptr<NetworkTable> GetTable(StringRef key);
+
+  /**
+   * Gets the entry for a subkey.
+   *
+   * @param key the key name
+   * @return Network table entry.
+   */
+  NetworkTableEntry GetEntry(const Twine& key) const;
+
+  /**
+   * Listen to keys only within this table.
+   *
+   * @param listener    listener to add
+   * @param flags       EntryListenerFlags bitmask
+   * @return Listener handle
+   */
+  NT_EntryListener AddEntryListener(TableEntryListener listener,
+                                    unsigned int flags) const;
+
+  /**
+   * Listen to a single key.
+   *
+   * @param key         the key name
+   * @param listener    listener to add
+   * @param flags       EntryListenerFlags bitmask
+   * @return Listener handle
+   */
+  NT_EntryListener AddEntryListener(const Twine& key,
+                                    TableEntryListener listener,
+                                    unsigned int flags) const;
+
+  /**
+   * Remove an entry listener.
+   *
+   * @param listener    listener handle
+   */
+  void RemoveEntryListener(NT_EntryListener listener) const;
+
+  /**
+   * Listen for sub-table creation.
+   * This calls the listener once for each newly created sub-table.
+   * It immediately calls the listener for any existing sub-tables.
+   *
+   * @param listener        listener to add
+   * @param localNotify     notify local changes as well as remote
+   * @return Listener handle
+   */
+  NT_EntryListener AddSubTableListener(TableListener listener,
+                                       bool localNotify = false);
+
+  /**
+   * Remove a sub-table listener.
+   *
+   * @param listener    listener handle
+   */
+  void RemoveTableListener(NT_EntryListener listener);
+
+  WPI_DEPRECATED(
+      "use AddEntryListener() instead with flags value of NT_NOTIFY_NEW | "
+      "NT_NOTIFY_UPDATE")
+  void AddTableListener(ITableListener* listener) override;
+
+  WPI_DEPRECATED(
+      "use AddEntryListener() instead with flags value of NT_NOTIFY_NEW | "
+      "NT_NOTIFY_UPDATE | NT_NOTIFY_IMMEDIATE")
+  void AddTableListener(ITableListener* listener,
+                        bool immediateNotify) override;
+
+  WPI_DEPRECATED("use AddEntryListener() instead")
+  void AddTableListenerEx(ITableListener* listener,
+                          unsigned int flags) override;
+
+  WPI_DEPRECATED("use AddEntryListener() instead")
+  void AddTableListener(StringRef key, ITableListener* listener,
+                        bool immediateNotify) override;
+
+  WPI_DEPRECATED("use AddEntryListener() instead")
+  void AddTableListenerEx(StringRef key, ITableListener* listener,
+                          unsigned int flags) override;
+
+  WPI_DEPRECATED("use AddSubTableListener(TableListener, bool) instead")
+  void AddSubTableListener(ITableListener* listener) override;
+
+  WPI_DEPRECATED("use AddSubTableListener(TableListener, bool) instead")
+  void AddSubTableListener(ITableListener* listener, bool localNotify) override;
+
+  WPI_DEPRECATED("use RemoveTableListener(NT_EntryListener) instead")
+  void RemoveTableListener(ITableListener* listener) override;
+
+  /**
+   * 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 key name
+   * @return the networktable to be returned
+   */
+  std::shared_ptr<NetworkTable> GetSubTable(const Twine& key) const override;
+
+  /**
+   * Determines whether the given key is in this table.
+   *
+   * @param key the key to search for
+   * @return true if the table as a value assigned to the given key
+   */
+  bool ContainsKey(const Twine& key) const override;
+
+  /**
+   * Determines whether there exists a non-empty subtable for this key
+   * in this table.
+   *
+   * @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
+   */
+  bool ContainsSubTable(const Twine& key) const override;
+
+  /**
+   * Gets all keys in the table (not including sub-tables).
+   *
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return keys currently in the table
+   */
+  std::vector<std::string> GetKeys(int types = 0) const override;
+
+  /**
+   * Gets the names of all subtables in the table.
+   *
+   * @return subtables currently in the table
+   */
+  std::vector<std::string> GetSubTables() const override;
+
+  /**
+   * Makes a key's value persistent through program restarts.
+   *
+   * @param key the key to make persistent
+   */
+  void SetPersistent(StringRef key) override;
+
+  /**
+   * Stop making a key's value persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   */
+  void ClearPersistent(StringRef key) override;
+
+  /**
+   * Returns whether the value is persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   */
+  bool IsPersistent(StringRef key) const override;
+
+  /**
+   * 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)
+   */
+  void SetFlags(StringRef key, unsigned int flags) override;
+
+  /**
+   * 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)
+   */
+  void ClearFlags(StringRef key, unsigned int flags) override;
+
+  /**
+   * Returns the flags for the specified key.
+   *
+   * @param key the key name
+   * @return the flags, or 0 if the key is not defined
+   */
+  unsigned int GetFlags(StringRef key) const override;
+
+  /**
+   * Deletes the specified key in this table.
+   *
+   * @param key the key name
+   */
+  void Delete(const Twine& key) override;
+
+  /**
+   * 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
+   */
+  bool PutNumber(StringRef key, double value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  bool SetDefaultNumber(StringRef key, double defaultValue) override;
+
+  /**
+   * Gets the number associated with the given name.
+   *
+   * @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
+   */
+  double GetNumber(StringRef key, double defaultValue) const override;
+
+  /**
+   * 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
+   */
+  bool PutString(StringRef key, StringRef value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  bool SetDefaultString(StringRef key, StringRef defaultValue) override;
+
+  /**
+   * Gets the string associated with the given name. 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
+   */
+  std::string GetString(StringRef key, StringRef defaultValue) const override;
+
+  /**
+   * 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
+   */
+  bool PutBoolean(StringRef key, bool value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  bool SetDefaultBoolean(StringRef key, bool defaultValue) override;
+
+  /**
+   * Gets the boolean associated with the given name. 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
+   */
+  bool GetBoolean(StringRef key, bool defaultValue) const override;
+
+  /**
+   * 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
+   *
+   * @note The array must be of int's rather than of bool's because
+   *       std::vector<bool> is special-cased in C++.  0 is false, any
+   *       non-zero value is true.
+   */
+  bool PutBooleanArray(StringRef key, ArrayRef<int> value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @return False if the table key exists with a different type
+   */
+  bool SetDefaultBooleanArray(StringRef key,
+                              ArrayRef<int> defaultValue) override;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   *
+   * @note The returned array is std::vector<int> instead of std::vector<bool>
+   *       because std::vector<bool> is special-cased in C++.  0 is false, any
+   *       non-zero value is true.
+   */
+  std::vector<int> GetBooleanArray(StringRef key,
+                                   ArrayRef<int> defaultValue) const override;
+
+  /**
+   * 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
+   */
+  bool PutNumberArray(StringRef key, ArrayRef<double> value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  bool SetDefaultNumberArray(StringRef key,
+                             ArrayRef<double> defaultValue) override;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::vector<double> GetNumberArray(
+      StringRef key, ArrayRef<double> defaultValue) const override;
+
+  /**
+   * 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
+   */
+  bool PutStringArray(StringRef key, ArrayRef<std::string> value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  bool SetDefaultStringArray(StringRef key,
+                             ArrayRef<std::string> defaultValue) override;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::vector<std::string> GetStringArray(
+      StringRef key, ArrayRef<std::string> defaultValue) const override;
+
+  /**
+   * 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
+   */
+  bool PutRaw(StringRef key, StringRef value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @return False if the table key exists with a different type
+   */
+  bool SetDefaultRaw(StringRef key, StringRef defaultValue) override;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the raw contents.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::string GetRaw(StringRef key, StringRef defaultValue) const override;
+
+  /**
+   * 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
+   */
+  bool PutValue(const Twine& key, std::shared_ptr<Value> value) override;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   *
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @return False if the table key exists with a different type
+   */
+  bool SetDefaultValue(const Twine& key,
+                       std::shared_ptr<Value> defaultValue) override;
+
+  /**
+   * Gets the value associated with a key as an object
+   *
+   * @param key the key of the value to look up
+   * @return the value associated with the given key, or nullptr if the key
+   * does not exist
+   */
+  std::shared_ptr<Value> GetValue(const Twine& key) const override;
+
+  /**
+   * Gets the full path of this table.  Does not include the trailing "/".
+   *
+   * @return The path (e.g "", "/foo").
+   */
+  StringRef GetPath() const override;
+
+  /**
+   * Save table values to a file.  The file format used is identical to
+   * that used for SavePersistent.
+   *
+   * @param filename  filename
+   * @return error string, or nullptr if successful
+   */
+  const char* SaveEntries(const Twine& filename) const;
+
+  /**
+   * Load table values from a file.  The file format used is identical to
+   * that used for SavePersistent / LoadPersistent.
+   *
+   * @param filename  filename
+   * @param warn      callback function for warnings
+   * @return error string, or nullptr if successful
+   */
+  const char* LoadEntries(
+      const Twine& filename,
+      std::function<void(size_t line, const char* msg)> warn);
+};
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#elif _WIN32
+#pragma warning(pop)
+#endif
+
+}  // namespace nt
+
+// For backwards compatability
+#ifndef NAMESPACED_NT
+using nt::NetworkTable;  // NOLINT
+#endif
+
+#endif  // NTCORE_NETWORKTABLES_NETWORKTABLE_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableEntry.h b/ntcore/src/main/native/include/networktables/NetworkTableEntry.h
new file mode 100644
index 0000000..8fdedc6
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableEntry.h
@@ -0,0 +1,648 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_H_
+#define NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_H_
+
+#include <stdint.h>
+
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <wpi/StringRef.h>
+#include <wpi/Twine.h>
+
+#include "networktables/NetworkTableType.h"
+#include "networktables/NetworkTableValue.h"
+#include "networktables/RpcCall.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+using wpi::ArrayRef;
+using wpi::StringRef;
+using wpi::Twine;
+
+class NetworkTableInstance;
+
+/**
+ * NetworkTables Entry
+ * @ingroup ntcore_cpp_api
+ */
+class NetworkTableEntry final {
+ public:
+  /**
+   * Flag values (as returned by GetFlags()).
+   */
+  enum Flags { kPersistent = NT_PERSISTENT };
+
+  /**
+   * Construct invalid instance.
+   */
+  NetworkTableEntry();
+
+  /**
+   * Construct from native handle.
+   *
+   * @param handle Native handle
+   */
+  explicit NetworkTableEntry(NT_Entry handle);
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return m_handle != 0; }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  NT_Entry GetHandle() const;
+
+  /**
+   * Gets the instance for the entry.
+   *
+   * @return Instance
+   */
+  NetworkTableInstance GetInstance() const;
+
+  /**
+   * Determines if the entry currently exists.
+   *
+   * @return True if the entry exists, false otherwise.
+   */
+  bool Exists() const;
+
+  /**
+   * Gets the name of the entry (the key).
+   *
+   * @return the entry's name
+   */
+  std::string GetName() const;
+
+  /**
+   * Gets the type of the entry.
+   *
+   * @return the entry's type
+   */
+  NetworkTableType GetType() const;
+
+  /**
+   * Returns the flags.
+   *
+   * @return the flags (bitmask)
+   */
+  unsigned int GetFlags() const;
+
+  /**
+   * Gets the last time the entry's value was changed.
+   *
+   * @return Entry last change time
+   */
+  uint64_t GetLastChange() const;
+
+  /**
+   * Gets combined information about the entry.
+   *
+   * @return Entry information
+   */
+  EntryInfo GetInfo() const;
+
+  /**
+   * Gets the entry's value. If the entry does not exist, returns nullptr.
+   *
+   * @return the entry's value or nullptr if it does not exist.
+   */
+  std::shared_ptr<Value> GetValue() const;
+
+  /**
+   * Gets the entry's value as a boolean. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  bool GetBoolean(bool defaultValue) const;
+
+  /**
+   * Gets the entry's value as a double. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  double GetDouble(double defaultValue) const;
+
+  /**
+   * Gets the entry's value as a string. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  std::string GetString(StringRef defaultValue) const;
+
+  /**
+   * Gets the entry's value as a raw. If the entry does not exist or is of
+   * different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   */
+  std::string GetRaw(StringRef defaultValue) const;
+
+  /**
+   * Gets the entry's value as a boolean array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   *
+   * @note The returned array is std::vector<int> instead of std::vector<bool>
+   *       because std::vector<bool> is special-cased in C++.  0 is false, any
+   *       non-zero value is true.
+   */
+  std::vector<int> GetBooleanArray(ArrayRef<int> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a boolean array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   *
+   * @note The returned array is std::vector<int> instead of std::vector<bool>
+   *       because std::vector<bool> is special-cased in C++.  0 is false, any
+   *       non-zero value is true.
+   */
+  std::vector<int> GetBooleanArray(
+      std::initializer_list<int> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a double array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::vector<double> GetDoubleArray(ArrayRef<double> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a double array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::vector<double> GetDoubleArray(
+      std::initializer_list<double> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a string array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::vector<std::string> GetStringArray(
+      ArrayRef<std::string> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a string array. If the entry does not exist
+   * or is of different type, it will return the default value.
+   *
+   * @param defaultValue the value to be returned if no value is found
+   * @return the entry's value or the given default value
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  std::vector<std::string> GetStringArray(
+      std::initializer_list<std::string> defaultValue) const;
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultValue(std::shared_ptr<Value> value);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultBoolean(bool defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultDouble(double defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultString(const Twine& defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultRaw(StringRef defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultBooleanArray(ArrayRef<int> defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultBooleanArray(std::initializer_list<int> defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultDoubleArray(ArrayRef<double> defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultDoubleArray(std::initializer_list<double> defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultStringArray(ArrayRef<std::string> defaultValue);
+
+  /**
+   * Sets the entry's value if it does not exist.
+   *
+   * @param defaultValue the default value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDefaultStringArray(std::initializer_list<std::string> defaultValue);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetValue(std::shared_ptr<Value> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetBoolean(bool value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDouble(double value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetString(const Twine& value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetRaw(StringRef value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetBooleanArray(ArrayRef<bool> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetBooleanArray(std::initializer_list<bool> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetBooleanArray(ArrayRef<int> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetBooleanArray(std::initializer_list<int> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDoubleArray(ArrayRef<double> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetDoubleArray(std::initializer_list<double> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetStringArray(ArrayRef<std::string> value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  bool SetStringArray(std::initializer_list<std::string> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetValue(std::shared_ptr<Value> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetBoolean(bool value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetDouble(double value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetString(const Twine& value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetRaw(StringRef value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetBooleanArray(ArrayRef<bool> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetBooleanArray(std::initializer_list<bool> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetBooleanArray(ArrayRef<int> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetBooleanArray(std::initializer_list<int> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetDoubleArray(ArrayRef<double> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetDoubleArray(std::initializer_list<double> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetStringArray(ArrayRef<std::string> value);
+
+  /**
+   * Sets the entry's value.  If the value is of different type, the type is
+   * changed to match the new value.
+   *
+   * @param value the value to set
+   */
+  void ForceSetStringArray(std::initializer_list<std::string> value);
+
+  /**
+   * Sets flags.
+   *
+   * @param flags the flags to set (bitmask)
+   */
+  void SetFlags(unsigned int flags);
+
+  /**
+   * Clears flags.
+   *
+   * @param flags the flags to clear (bitmask)
+   */
+  void ClearFlags(unsigned int flags);
+
+  /**
+   * Make value persistent through program restarts.
+   */
+  void SetPersistent();
+
+  /**
+   * Stop making value persistent through program restarts.
+   */
+  void ClearPersistent();
+
+  /**
+   * Returns whether the value is persistent through program restarts.
+   *
+   * @return True if the value is persistent.
+   */
+  bool IsPersistent() const;
+
+  /**
+   * Deletes the entry.
+   */
+  void Delete();
+
+  /**
+   * Create a callback-based RPC entry point.  Only valid to use on the server.
+   * The callback function will be called when the RPC is called.
+   * This function creates RPC version 0 definitions (raw data in and out).
+   *
+   * @param callback  callback function
+   */
+  void CreateRpc(std::function<void(const RpcAnswer& answer)> callback);
+
+  /**
+   * Create a polled RPC entry point.  Only valid to use on the server.
+   * The caller is responsible for calling NetworkTableInstance::PollRpc()
+   * to poll for servicing incoming RPC calls.
+   * This function creates RPC version 0 definitions (raw data in and out).
+   */
+  void CreatePolledRpc();
+
+  /**
+   * Call a RPC function.  May be used on either the client or server.
+   * This function is non-blocking.  Either RpcCall::GetResult() or
+   * RpcCall::CancelResult() must be called on the return value to either
+   * get or ignore the result of the call.
+   *
+   * @param params      parameter
+   * @return RPC call object.
+   */
+  RpcCall CallRpc(StringRef params);
+
+  /**
+   * Add a listener for changes to this entry.
+   *
+   * @param callback          listener to add
+   * @param flags             NotifyKind bitmask
+   * @return Listener handle
+   */
+  NT_EntryListener AddListener(
+      std::function<void(const EntryNotification& event)> callback,
+      unsigned int flags) const;
+
+  /**
+   * Remove an entry listener.
+   *
+   * @param entry_listener Listener handle to remove
+   */
+  void RemoveListener(NT_EntryListener entry_listener);
+
+  /**
+   * Equality operator.  Returns true if both instances refer to the same
+   * native handle.
+   */
+  bool operator==(const NetworkTableEntry& oth) const {
+    return m_handle == oth.m_handle;
+  }
+
+  /** Inequality operator. */
+  bool operator!=(const NetworkTableEntry& oth) const {
+    return !(*this == oth);
+  }
+
+ protected:
+  /* Native handle */
+  NT_Entry m_handle;
+};
+
+}  // namespace nt
+
+#include "networktables/NetworkTableEntry.inl"
+
+#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableEntry.inl b/ntcore/src/main/native/include/networktables/NetworkTableEntry.inl
new file mode 100644
index 0000000..4a46b96
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableEntry.inl
@@ -0,0 +1,298 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2017-2019. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NT_ENTRY_INL_
+#define NT_ENTRY_INL_
+
+namespace nt {
+
+inline NetworkTableEntry::NetworkTableEntry() : m_handle{0} {}
+
+inline NetworkTableEntry::NetworkTableEntry(NT_Entry handle)
+    : m_handle{handle} {}
+
+inline NT_Entry NetworkTableEntry::GetHandle() const { return m_handle; }
+
+inline bool NetworkTableEntry::Exists() const {
+  return GetEntryType(m_handle) != NT_UNASSIGNED;
+}
+
+inline std::string NetworkTableEntry::GetName() const {
+  return GetEntryName(m_handle);
+}
+
+inline NetworkTableType NetworkTableEntry::GetType() const {
+  return static_cast<NetworkTableType>(GetEntryType(m_handle));
+}
+
+inline unsigned int NetworkTableEntry::GetFlags() const {
+  return GetEntryFlags(m_handle);
+}
+
+inline uint64_t NetworkTableEntry::GetLastChange() const {
+  return GetEntryLastChange(m_handle);
+}
+
+inline EntryInfo NetworkTableEntry::GetInfo() const {
+  return GetEntryInfo(m_handle);
+}
+
+inline std::shared_ptr<Value> NetworkTableEntry::GetValue() const {
+  return GetEntryValue(m_handle);
+}
+
+inline bool NetworkTableEntry::GetBoolean(bool defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_BOOLEAN) return defaultValue;
+  return value->GetBoolean();
+}
+
+inline double NetworkTableEntry::GetDouble(double defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_DOUBLE) return defaultValue;
+  return value->GetDouble();
+}
+
+inline std::string NetworkTableEntry::GetString(StringRef defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_STRING) return defaultValue;
+  return value->GetString();
+}
+
+inline std::string NetworkTableEntry::GetRaw(StringRef defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_RAW) return defaultValue;
+  return value->GetString();
+}
+
+inline std::vector<int> NetworkTableEntry::GetBooleanArray(
+    ArrayRef<int> defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_BOOLEAN_ARRAY) return defaultValue;
+  return value->GetBooleanArray();
+}
+
+inline std::vector<int> NetworkTableEntry::GetBooleanArray(
+    std::initializer_list<int> defaultValue) const {
+  return GetBooleanArray(
+      wpi::makeArrayRef(defaultValue.begin(), defaultValue.end()));
+}
+
+inline std::vector<double> NetworkTableEntry::GetDoubleArray(
+    ArrayRef<double> defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_DOUBLE_ARRAY) return defaultValue;
+  return value->GetDoubleArray();
+}
+
+inline std::vector<double> NetworkTableEntry::GetDoubleArray(
+    std::initializer_list<double> defaultValue) const {
+  return GetDoubleArray(
+      wpi::makeArrayRef(defaultValue.begin(), defaultValue.end()));
+}
+
+inline std::vector<std::string> NetworkTableEntry::GetStringArray(
+    ArrayRef<std::string> defaultValue) const {
+  auto value = GetEntryValue(m_handle);
+  if (!value || value->type() != NT_STRING_ARRAY) return defaultValue;
+  return value->GetStringArray();
+}
+
+inline std::vector<std::string> NetworkTableEntry::GetStringArray(
+    std::initializer_list<std::string> defaultValue) const {
+  return GetStringArray(
+      wpi::makeArrayRef(defaultValue.begin(), defaultValue.end()));
+}
+
+inline bool NetworkTableEntry::SetDefaultValue(std::shared_ptr<Value> value) {
+  return SetDefaultEntryValue(m_handle, value);
+}
+
+inline bool NetworkTableEntry::SetDefaultBoolean(bool defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeBoolean(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetDefaultDouble(double defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeDouble(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetDefaultString(const Twine& defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeString(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetDefaultRaw(StringRef defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeRaw(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetDefaultBooleanArray(
+    ArrayRef<int> defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeBooleanArray(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetDefaultDoubleArray(
+    ArrayRef<double> defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeDoubleArray(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetDefaultStringArray(
+    ArrayRef<std::string> defaultValue) {
+  return SetDefaultEntryValue(m_handle, Value::MakeStringArray(defaultValue));
+}
+
+inline bool NetworkTableEntry::SetValue(std::shared_ptr<Value> value) {
+  return SetEntryValue(m_handle, value);
+}
+
+inline bool NetworkTableEntry::SetBoolean(bool value) {
+  return SetEntryValue(m_handle, Value::MakeBoolean(value));
+}
+
+inline bool NetworkTableEntry::SetDouble(double value) {
+  return SetEntryValue(m_handle, Value::MakeDouble(value));
+}
+
+inline bool NetworkTableEntry::SetString(const Twine& value) {
+  return SetEntryValue(m_handle, Value::MakeString(value));
+}
+
+inline bool NetworkTableEntry::SetRaw(StringRef value) {
+  return SetEntryValue(m_handle, Value::MakeRaw(value));
+}
+
+inline bool NetworkTableEntry::SetBooleanArray(ArrayRef<bool> value) {
+  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline bool NetworkTableEntry::SetBooleanArray(
+    std::initializer_list<bool> value) {
+  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline bool NetworkTableEntry::SetBooleanArray(ArrayRef<int> value) {
+  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline bool NetworkTableEntry::SetBooleanArray(
+    std::initializer_list<int> value) {
+  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline bool NetworkTableEntry::SetDoubleArray(ArrayRef<double> value) {
+  return SetEntryValue(m_handle, Value::MakeDoubleArray(value));
+}
+
+inline bool NetworkTableEntry::SetDoubleArray(
+    std::initializer_list<double> value) {
+  return SetEntryValue(m_handle, Value::MakeDoubleArray(value));
+}
+
+inline bool NetworkTableEntry::SetStringArray(ArrayRef<std::string> value) {
+  return SetEntryValue(m_handle, Value::MakeStringArray(value));
+}
+
+inline bool NetworkTableEntry::SetStringArray(
+    std::initializer_list<std::string> value) {
+  return SetEntryValue(m_handle, Value::MakeStringArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetValue(std::shared_ptr<Value> value) {
+  SetEntryTypeValue(m_handle, value);
+}
+
+inline void NetworkTableEntry::ForceSetBoolean(bool value) {
+  SetEntryTypeValue(m_handle, Value::MakeBoolean(value));
+}
+
+inline void NetworkTableEntry::ForceSetDouble(double value) {
+  SetEntryTypeValue(m_handle, Value::MakeDouble(value));
+}
+
+inline void NetworkTableEntry::ForceSetString(const Twine& value) {
+  SetEntryTypeValue(m_handle, Value::MakeString(value));
+}
+
+inline void NetworkTableEntry::ForceSetRaw(StringRef value) {
+  SetEntryTypeValue(m_handle, Value::MakeRaw(value));
+}
+
+inline void NetworkTableEntry::ForceSetBooleanArray(ArrayRef<bool> value) {
+  SetEntryTypeValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetBooleanArray(
+    std::initializer_list<bool> value) {
+  SetEntryTypeValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetBooleanArray(ArrayRef<int> value) {
+  SetEntryTypeValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetBooleanArray(
+    std::initializer_list<int> value) {
+  SetEntryTypeValue(m_handle, Value::MakeBooleanArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetDoubleArray(ArrayRef<double> value) {
+  SetEntryTypeValue(m_handle, Value::MakeDoubleArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetDoubleArray(
+    std::initializer_list<double> value) {
+  SetEntryTypeValue(m_handle, Value::MakeDoubleArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetStringArray(
+    ArrayRef<std::string> value) {
+  SetEntryTypeValue(m_handle, Value::MakeStringArray(value));
+}
+
+inline void NetworkTableEntry::ForceSetStringArray(
+    std::initializer_list<std::string> value) {
+  SetEntryTypeValue(m_handle, Value::MakeStringArray(value));
+}
+
+inline void NetworkTableEntry::SetFlags(unsigned int flags) {
+  SetEntryFlags(m_handle, GetFlags() | flags);
+}
+
+inline void NetworkTableEntry::ClearFlags(unsigned int flags) {
+  SetEntryFlags(m_handle, GetFlags() & ~flags);
+}
+
+inline void NetworkTableEntry::SetPersistent() { SetFlags(kPersistent); }
+
+inline void NetworkTableEntry::ClearPersistent() { ClearFlags(kPersistent); }
+
+inline bool NetworkTableEntry::IsPersistent() const {
+  return (GetFlags() & kPersistent) != 0;
+}
+
+inline void NetworkTableEntry::Delete() { DeleteEntry(m_handle); }
+
+inline void NetworkTableEntry::CreateRpc(
+    std::function<void(const RpcAnswer& answer)> callback) {
+  ::nt::CreateRpc(m_handle, StringRef("\0", 1), callback);
+}
+
+inline RpcCall NetworkTableEntry::CallRpc(StringRef params) {
+  return RpcCall{m_handle, ::nt::CallRpc(m_handle, params)};
+}
+
+inline NT_EntryListener NetworkTableEntry::AddListener(
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags) const {
+  return AddEntryListener(m_handle, callback, flags);
+}
+
+inline void NetworkTableEntry::RemoveListener(NT_EntryListener entry_listener) {
+  RemoveEntryListener(entry_listener);
+}
+
+}  // namespace nt
+
+#endif  // NT_ENTRY_INL_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableInstance.h b/ntcore/src/main/native/include/networktables/NetworkTableInstance.h
new file mode 100644
index 0000000..16fc5b2
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableInstance.h
@@ -0,0 +1,575 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_H_
+#define NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <wpi/ArrayRef.h>
+#include <wpi/StringRef.h>
+#include <wpi/Twine.h>
+
+#include "networktables/NetworkTable.h"
+#include "networktables/NetworkTableEntry.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+using wpi::ArrayRef;
+using wpi::StringRef;
+using wpi::Twine;
+
+/**
+ * NetworkTables Instance.
+ *
+ * Instances are completely independent from each other.  Table operations on
+ * one instance will not be visible to other instances unless the instances are
+ * connected via the network.  The main limitation on instances is that you
+ * cannot have two servers on the same network port.  The main utility of
+ * instances is for unit testing, but they can also enable one program to
+ * connect to two different NetworkTables networks.
+ *
+ * The global "default" instance (as returned by GetDefault()) is
+ * always available, and is intended for the common case when there is only
+ * a single NetworkTables instance being used in the program.  The
+ * default instance cannot be destroyed.
+ *
+ * Additional instances can be created with the Create() function.
+ * Instances are not reference counted or RAII.  Instead, they must be
+ * explicitly destroyed (with Destroy()).
+ *
+ * @ingroup ntcore_cpp_api
+ */
+class NetworkTableInstance final {
+ public:
+  /**
+   * Client/server mode flag values (as returned by GetNetworkMode()).
+   * This is a bitmask.
+   */
+  enum NetworkMode {
+    kNetModeNone = NT_NET_MODE_NONE,
+    kNetModeServer = NT_NET_MODE_SERVER,
+    kNetModeClient = NT_NET_MODE_CLIENT,
+    kNetModeStarting = NT_NET_MODE_STARTING,
+    kNetModeFailure = NT_NET_MODE_FAILURE,
+    kNetModeLocal = NT_NET_MODE_LOCAL
+  };
+
+  /**
+   * Logging levels (as used by SetLogger()).
+   */
+  enum LogLevel {
+    kLogCritical = NT_LOG_CRITICAL,
+    kLogError = NT_LOG_ERROR,
+    kLogWarning = NT_LOG_WARNING,
+    kLogInfo = NT_LOG_INFO,
+    kLogDebug = NT_LOG_DEBUG,
+    kLogDebug1 = NT_LOG_DEBUG1,
+    kLogDebug2 = NT_LOG_DEBUG2,
+    kLogDebug3 = NT_LOG_DEBUG3,
+    kLogDebug4 = NT_LOG_DEBUG4
+  };
+
+  /**
+   * The default port that network tables operates on.
+   */
+  enum { kDefaultPort = NT_DEFAULT_PORT };
+
+  /**
+   * Construct invalid instance.
+   */
+  NetworkTableInstance() noexcept;
+
+  /**
+   * Construct from native handle.
+   *
+   * @param handle Native handle
+   */
+  explicit NetworkTableInstance(NT_Inst inst) noexcept;
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return m_handle != 0; }
+
+  /**
+   * Get global default instance.
+   *
+   * @return Global default instance
+   */
+  static NetworkTableInstance GetDefault();
+
+  /**
+   * Create an instance.
+   *
+   * @return Newly created instance
+   */
+  static NetworkTableInstance Create();
+
+  /**
+   * Destroys an instance (note: this has global effect).
+   *
+   * @param inst Instance
+   */
+  static void Destroy(NetworkTableInstance inst);
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  NT_Inst GetHandle() const;
+
+  /**
+   * Gets the entry for a key.
+   *
+   * @param name Key
+   * @return Network table entry.
+   */
+  NetworkTableEntry GetEntry(const Twine& name);
+
+  /**
+   * Get entries starting with the given prefix.
+   *
+   * The results are optionally filtered by string prefix and entry type to
+   * only return a subset of all entries.
+   *
+   * @param prefix entry name required prefix; only entries whose name
+   * starts with this string are returned
+   * @param types bitmask of types; 0 is treated as a "don't care"
+   * @return Array of entries.
+   */
+  std::vector<NetworkTableEntry> GetEntries(const Twine& prefix,
+                                            unsigned int types);
+
+  /**
+   * Get information about entries starting with the given prefix.
+   *
+   * The results are optionally filtered by string prefix and entry type to
+   * only return a subset of all entries.
+   *
+   * @param prefix entry name required prefix; only entries whose name
+   * starts with this string are returned
+   * @param types bitmask of types; 0 is treated as a "don't care"
+   * @return Array of entry information.
+   */
+  std::vector<EntryInfo> GetEntryInfo(const Twine& prefix,
+                                      unsigned int types) const;
+
+  /**
+   * Gets the table with the specified key.
+   *
+   * @param key the key name
+   * @return The network table
+   */
+  std::shared_ptr<NetworkTable> GetTable(const Twine& key) const;
+
+  /**
+   * Deletes ALL keys in ALL subtables (except persistent values).
+   * Use with caution!
+   */
+  void DeleteAllEntries();
+
+  /**
+   * @{
+   * @name Entry Listener Functions
+   */
+
+  /**
+   * Add a listener for all entries starting with a certain prefix.
+   *
+   * @param prefix            UTF-8 string prefix
+   * @param callback          listener to add
+   * @param flags             EntryListenerFlags bitmask
+   * @return Listener handle
+   */
+  NT_EntryListener AddEntryListener(
+      const Twine& prefix,
+      std::function<void(const EntryNotification& event)> callback,
+      unsigned int flags) const;
+
+  /**
+   * Remove an entry listener.
+   *
+   * @param entry_listener Listener handle to remove
+   */
+  static void RemoveEntryListener(NT_EntryListener entry_listener);
+
+  /**
+   * Wait for the entry listener queue to be empty.  This is primarily useful
+   * for deterministic testing.  This blocks until either the entry listener
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  bool WaitForEntryListenerQueue(double timeout);
+
+  /** @} */
+
+  /**
+   * @{
+   * @name Connection Listener Functions
+   */
+
+  /**
+   * Add a connection listener.
+   *
+   * @param callback          listener to add
+   * @param immediate_notify  notify listener of all existing connections
+   * @return Listener handle
+   */
+  NT_ConnectionListener AddConnectionListener(
+      std::function<void(const ConnectionNotification& event)> callback,
+      bool immediate_notify) const;
+
+  /**
+   * Remove a connection listener.
+   *
+   * @param conn_listener Listener handle to remove
+   */
+  static void RemoveConnectionListener(NT_ConnectionListener conn_listener);
+
+  /**
+   * Wait for the connection listener queue to be empty.  This is primarily
+   * useful for deterministic testing.  This blocks until either the connection
+   * listener queue is empty (e.g. there are no more events that need to be
+   * passed along to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  bool WaitForConnectionListenerQueue(double timeout);
+
+  /** @} */
+
+  /**
+   * @{
+   * @name Remote Procedure Call Functions
+   */
+
+  /**
+   * Wait for the incoming RPC call queue to be empty.  This is primarily useful
+   * for deterministic testing.  This blocks until either the RPC call
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  bool WaitForRpcCallQueue(double timeout);
+
+  /** @} */
+
+  /**
+   * @{
+   * @name Client/Server Functions
+   */
+
+  /**
+   * Set the network identity of this node.
+   *
+   * This is the name used during the initial connection handshake, and is
+   * visible through ConnectionInfo on the remote node.
+   *
+   * @param name      identity to advertise
+   */
+  void SetNetworkIdentity(const Twine& name);
+
+  /**
+   * Get the current network mode.
+   *
+   * @return Bitmask of NetworkMode.
+   */
+  unsigned int GetNetworkMode() const;
+
+  /**
+   * Starts local-only operation.  Prevents calls to StartServer or StartClient
+   * from taking effect.  Has no effect if StartServer or StartClient
+   * has already been called.
+   */
+  void StartLocal();
+
+  /**
+   * Stops local-only operation.  StartServer or StartClient can be called after
+   * this call to start a server or client.
+   */
+  void StopLocal();
+
+  /**
+   * Starts a server using the specified filename, listening address, and port.
+   *
+   * @param persist_filename  the name of the persist file to use (UTF-8 string,
+   *                          null terminated)
+   * @param listen_address    the address to listen on, or null to listen on any
+   *                          address (UTF-8 string, null terminated)
+   * @param port              port to communicate over
+   */
+  void StartServer(const Twine& persist_filename = "networktables.ini",
+                   const char* listen_address = "",
+                   unsigned int port = kDefaultPort);
+
+  /**
+   * Stops the server if it is running.
+   */
+  void StopServer();
+
+  /**
+   * Starts a client.  Use SetServer to set the server name and port.
+   */
+  void StartClient();
+
+  /**
+   * Starts a client using the specified server and port
+   *
+   * @param server_name server name (UTF-8 string, null terminated)
+   * @param port        port to communicate over
+   */
+  void StartClient(const char* server_name, unsigned int port = kDefaultPort);
+
+  /**
+   * Starts a client using the specified (server, port) combinations.  The
+   * client will attempt to connect to each server in round robin fashion.
+   *
+   * @param servers   array of server name and port pairs
+   */
+  void StartClient(ArrayRef<std::pair<StringRef, unsigned int>> servers);
+
+  /**
+   * Starts a client using the specified servers and port.  The
+   * client will attempt to connect to each server in round robin fashion.
+   *
+   * @param servers   array of server names
+   * @param port      port to communicate over
+   */
+  void StartClient(ArrayRef<StringRef> servers,
+                   unsigned int port = kDefaultPort);
+
+  /**
+   * Starts a client using commonly known robot addresses for the specified
+   * team.
+   *
+   * @param team        team number
+   * @param port        port to communicate over
+   */
+  void StartClientTeam(unsigned int team, unsigned int port = kDefaultPort);
+
+  /**
+   * Stops the client if it is running.
+   */
+  void StopClient();
+
+  /**
+   * Sets server address and port for client (without restarting client).
+   *
+   * @param server_name server name (UTF-8 string, null terminated)
+   * @param port        port to communicate over
+   */
+  void SetServer(const char* server_name, unsigned int port = kDefaultPort);
+
+  /**
+   * Sets server addresses and ports for client (without restarting client).
+   * The client will attempt to connect to each server in round robin fashion.
+   *
+   * @param servers   array of server name and port pairs
+   */
+  void SetServer(ArrayRef<std::pair<StringRef, unsigned int>> servers);
+
+  /**
+   * Sets server addresses and port for client (without restarting client).
+   * The client will attempt to connect to each server in round robin fashion.
+   *
+   * @param servers   array of server names
+   * @param port      port to communicate over
+   */
+  void SetServer(ArrayRef<StringRef> servers, unsigned int port = kDefaultPort);
+
+  /**
+   * Sets server addresses and port for client (without restarting client).
+   * Connects using commonly known robot addresses for the specified team.
+   *
+   * @param team        team number
+   * @param port        port to communicate over
+   */
+  void SetServerTeam(unsigned int team, unsigned int port = kDefaultPort);
+
+  /**
+   * Starts requesting server address from Driver Station.
+   * This connects to the Driver Station running on localhost to obtain the
+   * server IP address.
+   *
+   * @param port server port to use in combination with IP from DS
+   */
+  void StartDSClient(unsigned int port = kDefaultPort);
+
+  /**
+   * Stops requesting server address from Driver Station.
+   */
+  void StopDSClient();
+
+  /**
+   * Set the periodic update rate.
+   * Sets how frequently updates are sent to other nodes over the network.
+   *
+   * @param interval update interval in seconds (range 0.01 to 1.0)
+   */
+  void SetUpdateRate(double interval);
+
+  /**
+   * 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.
+   */
+  void Flush() const;
+
+  /**
+   * Get information on the currently established network connections.
+   * If operating as a client, this will return either zero or one values.
+   *
+   * @return array of connection information
+   */
+  std::vector<ConnectionInfo> GetConnections() const;
+
+  /**
+   * Return whether or not the instance is connected to another node.
+   *
+   * @return True if connected.
+   */
+  bool IsConnected() const;
+
+  /** @} */
+
+  /**
+   * @{
+   * @name File Save/Load Functions
+   */
+
+  /**
+   * Save persistent values to a file.  The server automatically does this,
+   * but this function provides a way to save persistent values in the same
+   * format to a file on either a client or a server.
+   *
+   * @param filename  filename
+   * @return error string, or nullptr if successful
+   */
+  const char* SavePersistent(const Twine& filename) const;
+
+  /**
+   * Load persistent values from a file.  The server automatically does this
+   * at startup, but this function provides a way to restore persistent values
+   * in the same format from a file at any time on either a client or a server.
+   *
+   * @param filename  filename
+   * @param warn      callback function for warnings
+   * @return error string, or nullptr if successful
+   */
+  const char* LoadPersistent(
+      const Twine& filename,
+      std::function<void(size_t line, const char* msg)> warn);
+
+  /**
+   * Save table values to a file.  The file format used is identical to
+   * that used for SavePersistent.
+   *
+   * @param filename  filename
+   * @param prefix    save only keys starting with this prefix
+   * @return error string, or nullptr if successful
+   */
+  const char* SaveEntries(const Twine& filename, const Twine& prefix) const;
+
+  /**
+   * Load table values from a file.  The file format used is identical to
+   * that used for SavePersistent / LoadPersistent.
+   *
+   * @param filename  filename
+   * @param prefix    load only keys starting with this prefix
+   * @param warn      callback function for warnings
+   * @return error string, or nullptr if successful
+   */
+  const char* LoadEntries(
+      const Twine& filename, const Twine& prefix,
+      std::function<void(size_t line, const char* msg)> warn);
+
+  /** @} */
+
+  /**
+   * @{
+   * @name Logger Functions
+   */
+
+  /**
+   * Add logger callback function.  By default, log messages are sent to stderr;
+   * this function sends log messages with the specified levels to the provided
+   * callback function instead.  The callback function will only be called for
+   * log messages with level greater than or equal to minLevel and less than or
+   * equal to maxLevel; messages outside this range will be silently ignored.
+   *
+   * @param func        log callback function
+   * @param minLevel    minimum log level
+   * @param maxLevel    maximum log level
+   * @return Logger handle
+   */
+  NT_Logger AddLogger(std::function<void(const LogMessage& msg)> func,
+                      unsigned int min_level, unsigned int max_level);
+
+  /**
+   * Remove a logger.
+   *
+   * @param logger Logger handle to remove
+   */
+  static void RemoveLogger(NT_Logger logger);
+
+  /**
+   * Wait for the incoming log event queue to be empty.  This is primarily
+   * useful for deterministic testing.  This blocks until either the log event
+   * queue is empty (e.g. there are no more events that need to be passed along
+   * to callbacks or poll queues) or the timeout expires.
+   *
+   * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+   *                  or a negative value to block indefinitely
+   * @return False if timed out, otherwise true.
+   */
+  bool WaitForLoggerQueue(double timeout);
+
+  /** @} */
+
+  /**
+   * Equality operator.  Returns true if both instances refer to the same
+   * native handle.
+   */
+  bool operator==(const NetworkTableInstance& other) const {
+    return m_handle == other.m_handle;
+  }
+
+  /** Inequality operator. */
+  bool operator!=(const NetworkTableInstance& other) const {
+    return !(*this == other);
+  }
+
+ private:
+  /* Native handle */
+  NT_Inst m_handle;
+};
+
+}  // namespace nt
+
+#include "networktables/NetworkTableInstance.inl"
+
+#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableInstance.inl b/ntcore/src/main/native/include/networktables/NetworkTableInstance.inl
new file mode 100644
index 0000000..2b6607f
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableInstance.inl
@@ -0,0 +1,191 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2017. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NT_INSTANCE_INL_
+#define NT_INSTANCE_INL_
+
+namespace nt {
+
+inline NetworkTableInstance::NetworkTableInstance() noexcept : m_handle{0} {}
+
+inline NetworkTableInstance::NetworkTableInstance(NT_Inst handle) noexcept
+    : m_handle{handle} {}
+
+inline NetworkTableInstance NetworkTableInstance::GetDefault() {
+  return NetworkTableInstance{GetDefaultInstance()};
+}
+
+inline NetworkTableInstance NetworkTableInstance::Create() {
+  return NetworkTableInstance{CreateInstance()};
+}
+
+inline void NetworkTableInstance::Destroy(NetworkTableInstance inst) {
+  if (inst.m_handle != 0) DestroyInstance(inst.m_handle);
+}
+
+inline NT_Inst NetworkTableInstance::GetHandle() const { return m_handle; }
+
+inline NetworkTableEntry NetworkTableInstance::GetEntry(const Twine& name) {
+  return NetworkTableEntry{::nt::GetEntry(m_handle, name)};
+}
+
+inline std::vector<NetworkTableEntry> NetworkTableInstance::GetEntries(
+    const Twine& prefix, unsigned int types) {
+  std::vector<NetworkTableEntry> entries;
+  for (auto entry : ::nt::GetEntries(m_handle, prefix, types))
+    entries.emplace_back(entry);
+  return entries;
+}
+
+inline std::vector<EntryInfo> NetworkTableInstance::GetEntryInfo(
+    const Twine& prefix, unsigned int types) const {
+  return ::nt::GetEntryInfo(m_handle, prefix, types);
+}
+
+inline void NetworkTableInstance::DeleteAllEntries() {
+  ::nt::DeleteAllEntries(m_handle);
+}
+
+inline void NetworkTableInstance::RemoveEntryListener(
+    NT_EntryListener entry_listener) {
+  ::nt::RemoveEntryListener(entry_listener);
+}
+
+inline bool NetworkTableInstance::WaitForEntryListenerQueue(double timeout) {
+  return ::nt::WaitForEntryListenerQueue(m_handle, timeout);
+}
+
+inline void NetworkTableInstance::RemoveConnectionListener(
+    NT_ConnectionListener conn_listener) {
+  ::nt::RemoveConnectionListener(conn_listener);
+}
+
+inline bool NetworkTableInstance::WaitForConnectionListenerQueue(
+    double timeout) {
+  return ::nt::WaitForConnectionListenerQueue(m_handle, timeout);
+}
+
+inline bool NetworkTableInstance::WaitForRpcCallQueue(double timeout) {
+  return ::nt::WaitForRpcCallQueue(m_handle, timeout);
+}
+
+inline void NetworkTableInstance::SetNetworkIdentity(const Twine& name) {
+  ::nt::SetNetworkIdentity(m_handle, name);
+}
+
+inline unsigned int NetworkTableInstance::GetNetworkMode() const {
+  return ::nt::GetNetworkMode(m_handle);
+}
+
+inline void NetworkTableInstance::StartLocal() { ::nt::StartLocal(m_handle); }
+
+inline void NetworkTableInstance::StopLocal() { ::nt::StopLocal(m_handle); }
+
+inline void NetworkTableInstance::StartServer(const Twine& persist_filename,
+                                              const char* listen_address,
+                                              unsigned int port) {
+  ::nt::StartServer(m_handle, persist_filename, listen_address, port);
+}
+
+inline void NetworkTableInstance::StopServer() { ::nt::StopServer(m_handle); }
+
+inline void NetworkTableInstance::StartClient() { ::nt::StartClient(m_handle); }
+
+inline void NetworkTableInstance::StartClient(const char* server_name,
+                                              unsigned int port) {
+  ::nt::StartClient(m_handle, server_name, port);
+}
+
+inline void NetworkTableInstance::StartClient(
+    ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  ::nt::StartClient(m_handle, servers);
+}
+
+inline void NetworkTableInstance::StartClientTeam(unsigned int team,
+                                                  unsigned int port) {
+  ::nt::StartClientTeam(m_handle, team, port);
+}
+
+inline void NetworkTableInstance::StopClient() { ::nt::StopClient(m_handle); }
+
+inline void NetworkTableInstance::SetServer(const char* server_name,
+                                            unsigned int port) {
+  ::nt::SetServer(m_handle, server_name, port);
+}
+
+inline void NetworkTableInstance::SetServer(
+    ArrayRef<std::pair<StringRef, unsigned int>> servers) {
+  ::nt::SetServer(m_handle, servers);
+}
+
+inline void NetworkTableInstance::SetServerTeam(unsigned int team,
+                                                unsigned int port) {
+  ::nt::SetServerTeam(m_handle, team, port);
+}
+
+inline void NetworkTableInstance::StartDSClient(unsigned int port) {
+  ::nt::StartDSClient(m_handle, port);
+}
+
+inline void NetworkTableInstance::StopDSClient() {
+  ::nt::StopDSClient(m_handle);
+}
+
+inline void NetworkTableInstance::SetUpdateRate(double interval) {
+  ::nt::SetUpdateRate(m_handle, interval);
+}
+
+inline void NetworkTableInstance::Flush() const { ::nt::Flush(m_handle); }
+
+inline std::vector<ConnectionInfo> NetworkTableInstance::GetConnections()
+    const {
+  return ::nt::GetConnections(m_handle);
+}
+
+inline bool NetworkTableInstance::IsConnected() const {
+  return ::nt::IsConnected(m_handle);
+}
+
+inline const char* NetworkTableInstance::SavePersistent(
+    const Twine& filename) const {
+  return ::nt::SavePersistent(m_handle, filename);
+}
+
+inline const char* NetworkTableInstance::LoadPersistent(
+    const Twine& filename,
+    std::function<void(size_t line, const char* msg)> warn) {
+  return ::nt::LoadPersistent(m_handle, filename, warn);
+}
+
+inline const char* NetworkTableInstance::SaveEntries(
+    const Twine& filename, const Twine& prefix) const {
+  return ::nt::SaveEntries(m_handle, filename, prefix);
+}
+
+inline const char* NetworkTableInstance::LoadEntries(
+    const Twine& filename, const Twine& prefix,
+    std::function<void(size_t line, const char* msg)> warn) {
+  return ::nt::LoadEntries(m_handle, filename, prefix, warn);
+}
+
+inline NT_Logger NetworkTableInstance::AddLogger(
+    std::function<void(const LogMessage& msg)> func, unsigned int min_level,
+    unsigned int max_level) {
+  return ::nt::AddLogger(m_handle, func, min_level, max_level);
+}
+
+inline void NetworkTableInstance::RemoveLogger(NT_Logger logger) {
+  ::nt::RemoveLogger(logger);
+}
+
+inline bool NetworkTableInstance::WaitForLoggerQueue(double timeout) {
+  return ::nt::WaitForLoggerQueue(m_handle, timeout);
+}
+
+}  // namespace nt
+
+#endif  // NT_INSTANCE_INL_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableType.h b/ntcore/src/main/native/include/networktables/NetworkTableType.h
new file mode 100644
index 0000000..7ac3d9a
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableType.h
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_NETWORKTABLETYPE_H_
+#define NTCORE_NETWORKTABLES_NETWORKTABLETYPE_H_
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+/**
+ * NetworkTable entry type.
+ * @ingroup ntcore_cpp_api
+ */
+enum class NetworkTableType {
+  kUnassigned = NT_UNASSIGNED,
+  kBoolean = NT_BOOLEAN,
+  kDouble = NT_DOUBLE,
+  kString = NT_STRING,
+  kRaw = NT_RAW,
+  kBooleanArray = NT_BOOLEAN_ARRAY,
+  kDoubleArray = NT_DOUBLE_ARRAY,
+  kStringArray = NT_STRING_ARRAY,
+  kRpc = NT_RPC
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_NETWORKTABLES_NETWORKTABLETYPE_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableValue.h b/ntcore/src/main/native/include/networktables/NetworkTableValue.h
new file mode 100644
index 0000000..1b8aabe
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableValue.h
@@ -0,0 +1,503 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEVALUE_H_
+#define NTCORE_NETWORKTABLES_NETWORKTABLEVALUE_H_
+
+#include <stdint.h>
+
+#include <cassert>
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <wpi/ArrayRef.h>
+#include <wpi/StringRef.h>
+#include <wpi/Twine.h>
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+using wpi::ArrayRef;
+using wpi::StringRef;
+using wpi::Twine;
+
+/**
+ * A network table entry value.
+ * @ingroup ntcore_cpp_api
+ */
+class Value final {
+  struct private_init {};
+
+ public:
+  Value();
+  Value(NT_Type type, uint64_t time, const private_init&);
+  ~Value();
+
+  /**
+   * Get the data type.
+   *
+   * @return The type.
+   */
+  NT_Type type() const { return m_val.type; }
+
+  /**
+   * Get the data value stored.
+   *
+   * @return The type.
+   */
+  const NT_Value& value() const { return m_val; }
+
+  /**
+   * Get the creation time of the value.
+   *
+   * @return The time, in the units returned by nt::Now().
+   */
+  uint64_t last_change() const { return m_val.last_change; }
+
+  /**
+   * Get the creation time of the value.
+   *
+   * @return The time, in the units returned by nt::Now().
+   */
+  uint64_t time() const { return m_val.last_change; }
+
+  /**
+   * @{
+   * @name Type Checkers
+   */
+
+  /**
+   * Determine if entry value contains a value or is unassigned.
+   *
+   * @return True if the entry value contains a value.
+   */
+  bool IsValid() const { return m_val.type != NT_UNASSIGNED; }
+
+  /**
+   * Determine if entry value contains a boolean.
+   *
+   * @return True if the entry value is of boolean type.
+   */
+  bool IsBoolean() const { return m_val.type == NT_BOOLEAN; }
+
+  /**
+   * Determine if entry value contains a double.
+   *
+   * @return True if the entry value is of double type.
+   */
+  bool IsDouble() const { return m_val.type == NT_DOUBLE; }
+
+  /**
+   * Determine if entry value contains a string.
+   *
+   * @return True if the entry value is of string type.
+   */
+  bool IsString() const { return m_val.type == NT_STRING; }
+
+  /**
+   * Determine if entry value contains a raw.
+   *
+   * @return True if the entry value is of raw type.
+   */
+  bool IsRaw() const { return m_val.type == NT_RAW; }
+
+  /**
+   * Determine if entry value contains a rpc definition.
+   *
+   * @return True if the entry value is of rpc definition type.
+   */
+  bool IsRpc() const { return m_val.type == NT_RPC; }
+
+  /**
+   * Determine if entry value contains a boolean array.
+   *
+   * @return True if the entry value is of boolean array type.
+   */
+  bool IsBooleanArray() const { return m_val.type == NT_BOOLEAN_ARRAY; }
+
+  /**
+   * Determine if entry value contains a double array.
+   *
+   * @return True if the entry value is of double array type.
+   */
+  bool IsDoubleArray() const { return m_val.type == NT_DOUBLE_ARRAY; }
+
+  /**
+   * Determine if entry value contains a string array.
+   *
+   * @return True if the entry value is of string array type.
+   */
+  bool IsStringArray() const { return m_val.type == NT_STRING_ARRAY; }
+
+  /** @} */
+
+  /**
+   * @{
+   * @name Type-Safe Getters
+   */
+
+  /**
+   * Get the entry's boolean value.
+   *
+   * @return The boolean value.
+   */
+  bool GetBoolean() const {
+    assert(m_val.type == NT_BOOLEAN);
+    return m_val.data.v_boolean != 0;
+  }
+
+  /**
+   * Get the entry's double value.
+   *
+   * @return The double value.
+   */
+  double GetDouble() const {
+    assert(m_val.type == NT_DOUBLE);
+    return m_val.data.v_double;
+  }
+
+  /**
+   * Get the entry's string value.
+   *
+   * @return The string value.
+   */
+  StringRef GetString() const {
+    assert(m_val.type == NT_STRING);
+    return m_string;
+  }
+
+  /**
+   * Get the entry's raw value.
+   *
+   * @return The raw value.
+   */
+  StringRef GetRaw() const {
+    assert(m_val.type == NT_RAW);
+    return m_string;
+  }
+
+  /**
+   * Get the entry's rpc definition value.
+   *
+   * @return The rpc definition value.
+   */
+  StringRef GetRpc() const {
+    assert(m_val.type == NT_RPC);
+    return m_string;
+  }
+
+  /**
+   * Get the entry's boolean array value.
+   *
+   * @return The boolean array value.
+   */
+  ArrayRef<int> GetBooleanArray() const {
+    assert(m_val.type == NT_BOOLEAN_ARRAY);
+    return ArrayRef<int>(m_val.data.arr_boolean.arr,
+                         m_val.data.arr_boolean.size);
+  }
+
+  /**
+   * Get the entry's double array value.
+   *
+   * @return The double array value.
+   */
+  ArrayRef<double> GetDoubleArray() const {
+    assert(m_val.type == NT_DOUBLE_ARRAY);
+    return ArrayRef<double>(m_val.data.arr_double.arr,
+                            m_val.data.arr_double.size);
+  }
+
+  /**
+   * Get the entry's string array value.
+   *
+   * @return The string array value.
+   */
+  ArrayRef<std::string> GetStringArray() const {
+    assert(m_val.type == NT_STRING_ARRAY);
+    return m_string_array;
+  }
+
+  /** @} */
+
+  /**
+   * @{
+   * @name Factory functions
+   */
+
+  /**
+   * Creates a boolean entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeBoolean(bool value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_BOOLEAN, time, private_init());
+    val->m_val.data.v_boolean = value;
+    return val;
+  }
+
+  /**
+   * Creates a double entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeDouble(double value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_DOUBLE, time, private_init());
+    val->m_val.data.v_double = value;
+    return val;
+  }
+
+  /**
+   * Creates a string entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeString(const Twine& value,
+                                           uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_STRING, time, private_init());
+    val->m_string = value.str();
+    val->m_val.data.v_string.str = const_cast<char*>(val->m_string.c_str());
+    val->m_val.data.v_string.len = val->m_string.size();
+    return val;
+  }
+
+  /**
+   * Creates a string entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  template <typename T,
+            typename std::enable_if<std::is_same<T, std::string>::value>::type>
+  static std::shared_ptr<Value> MakeString(T&& value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_STRING, time, private_init());
+    val->m_string = std::move(value);
+    val->m_val.data.v_string.str = const_cast<char*>(val->m_string.c_str());
+    val->m_val.data.v_string.len = val->m_string.size();
+    return val;
+  }
+
+  /**
+   * Creates a raw entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeRaw(StringRef value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_RAW, time, private_init());
+    val->m_string = value;
+    val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+    val->m_val.data.v_raw.len = val->m_string.size();
+    return val;
+  }
+
+  /**
+   * Creates a raw entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  template <typename T,
+            typename std::enable_if<std::is_same<T, std::string>::value>::type>
+  static std::shared_ptr<Value> MakeRaw(T&& value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_RAW, time, private_init());
+    val->m_string = std::move(value);
+    val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+    val->m_val.data.v_raw.len = val->m_string.size();
+    return val;
+  }
+
+  /**
+   * Creates a rpc entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeRpc(StringRef value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_RPC, time, private_init());
+    val->m_string = value;
+    val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+    val->m_val.data.v_raw.len = val->m_string.size();
+    return val;
+  }
+
+  /**
+   * Creates a rpc entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  template <typename T>
+  static std::shared_ptr<Value> MakeRpc(T&& value, uint64_t time = 0) {
+    auto val = std::make_shared<Value>(NT_RPC, time, private_init());
+    val->m_string = std::move(value);
+    val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+    val->m_val.data.v_raw.len = val->m_string.size();
+    return val;
+  }
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeBooleanArray(ArrayRef<bool> value,
+                                                 uint64_t time = 0);
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeBooleanArray(
+      std::initializer_list<bool> value, uint64_t time = 0) {
+    return MakeBooleanArray(wpi::makeArrayRef(value.begin(), value.end()),
+                            time);
+  }
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeBooleanArray(ArrayRef<int> value,
+                                                 uint64_t time = 0);
+
+  /**
+   * Creates a boolean array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeBooleanArray(
+      std::initializer_list<int> value, uint64_t time = 0) {
+    return MakeBooleanArray(wpi::makeArrayRef(value.begin(), value.end()),
+                            time);
+  }
+
+  /**
+   * Creates a double array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeDoubleArray(ArrayRef<double> value,
+                                                uint64_t time = 0);
+
+  /**
+   * Creates a double array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeDoubleArray(
+      std::initializer_list<double> value, uint64_t time = 0) {
+    return MakeDoubleArray(wpi::makeArrayRef(value.begin(), value.end()), time);
+  }
+
+  /**
+   * Creates a string array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeStringArray(ArrayRef<std::string> value,
+                                                uint64_t time = 0);
+
+  /**
+   * Creates a string array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   */
+  static std::shared_ptr<Value> MakeStringArray(
+      std::initializer_list<std::string> value, uint64_t time = 0) {
+    return MakeStringArray(wpi::makeArrayRef(value.begin(), value.end()), time);
+  }
+
+  /**
+   * Creates a string array entry value.
+   *
+   * @param value the value
+   * @param time if nonzero, the creation time to use (instead of the current
+   *             time)
+   * @return The entry value
+   *
+   * @note This function moves the values out of the vector.
+   */
+  static std::shared_ptr<Value> MakeStringArray(
+      std::vector<std::string>&& value, uint64_t time = 0);
+
+  /** @} */
+
+  Value(const Value&) = delete;
+  Value& operator=(const Value&) = delete;
+  friend bool operator==(const Value& lhs, const Value& rhs);
+
+ private:
+  NT_Value m_val;
+  std::string m_string;
+  std::vector<std::string> m_string_array;
+};
+
+bool operator==(const Value& lhs, const Value& rhs);
+inline bool operator!=(const Value& lhs, const Value& rhs) {
+  return !(lhs == rhs);
+}
+
+/**
+ * NetworkTable Value alias for similarity with Java.
+ * @ingroup ntcore_cpp_api
+ */
+typedef Value NetworkTableValue;
+
+}  // namespace nt
+
+#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEVALUE_H_
diff --git a/ntcore/src/main/native/include/networktables/RpcCall.h b/ntcore/src/main/native/include/networktables/RpcCall.h
new file mode 100644
index 0000000..fc2e0bf
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/RpcCall.h
@@ -0,0 +1,109 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_RPCCALL_H_
+#define NTCORE_NETWORKTABLES_RPCCALL_H_
+
+#include <string>
+#include <utility>
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+class NetworkTableEntry;
+
+/**
+ * NetworkTables Remote Procedure Call
+ * @ingroup ntcore_cpp_api
+ */
+class RpcCall final {
+ public:
+  /**
+   * Construct invalid instance.
+   */
+  RpcCall() : m_entry(0), m_call(0) {}
+
+  /**
+   * Construct from native handles.
+   *
+   * @param entry Entry handle
+   * @param call  Call handle
+   */
+  RpcCall(NT_Entry entry, NT_RpcCall call) : m_entry(entry), m_call(call) {}
+
+  RpcCall(RpcCall&& other) noexcept;
+  RpcCall(const RpcCall&) = delete;
+  RpcCall& operator=(const RpcCall&) = delete;
+
+  /**
+   * Destructor.  Cancels the result if no other action taken.
+   */
+  ~RpcCall();
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return m_call != 0; }
+
+  /**
+   * Get the RPC entry.
+   *
+   * @return NetworkTableEntry for the RPC.
+   */
+  NetworkTableEntry GetEntry() const;
+
+  /**
+   * Get the call native handle.
+   *
+   * @return Native handle.
+   */
+  NT_RpcCall GetCall() const { return m_call; }
+
+  /**
+   * Get the result (return value).  This function blocks until
+   * the result is received.
+   *
+   * @param result      received result (output)
+   * @return False on error, true otherwise.
+   */
+  bool GetResult(std::string* result);
+
+  /**
+   * Get the result (return value).  This function blocks until
+   * the result is received or it times out.
+   *
+   * @param result      received result (output)
+   * @param timeout     timeout, in seconds
+   * @param timed_out   true if the timeout period elapsed (output)
+   * @return False on error or timeout, true otherwise.
+   */
+  bool GetResult(std::string* result, double timeout, bool* timed_out);
+
+  /**
+   * Ignore the result.  This function is non-blocking.
+   */
+  void CancelResult();
+
+  friend void swap(RpcCall& first, RpcCall& second) {
+    using std::swap;
+    swap(first.m_entry, second.m_entry);
+    swap(first.m_call, second.m_call);
+  }
+
+ private:
+  NT_Entry m_entry;
+  NT_RpcCall m_call;
+};
+
+}  // namespace nt
+
+#include "networktables/RpcCall.inl"
+
+#endif  // NTCORE_NETWORKTABLES_RPCCALL_H_
diff --git a/ntcore/src/main/native/include/networktables/RpcCall.inl b/ntcore/src/main/native/include/networktables/RpcCall.inl
new file mode 100644
index 0000000..0e9b522
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/RpcCall.inl
@@ -0,0 +1,48 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2017. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NT_RPCCALL_INL_
+#define NT_RPCCALL_INL_
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+inline RpcCall::RpcCall(RpcCall&& other) noexcept : RpcCall() {
+  swap(*this, other);
+}
+
+inline RpcCall::~RpcCall() {
+  // automatically cancel result if user didn't request it
+  if (m_call != 0) CancelResult();
+}
+
+inline bool RpcCall::GetResult(std::string* result) {
+  if (GetRpcResult(m_entry, m_call, result)) {
+    m_call = 0;
+    return true;
+  }
+  return false;
+}
+
+inline bool RpcCall::GetResult(std::string* result, double timeout,
+                               bool* timed_out) {
+  if (GetRpcResult(m_entry, m_call, result, timeout, timed_out)) {
+    m_call = 0;
+    return true;
+  }
+  return false;
+}
+
+inline void RpcCall::CancelResult() {
+  CancelRpcResult(m_entry, m_call);
+  m_call = 0;
+}
+
+}  // namespace nt
+
+#endif  // NT_RPCCALL_INL_
diff --git a/ntcore/src/main/native/include/networktables/TableEntryListener.h b/ntcore/src/main/native/include/networktables/TableEntryListener.h
new file mode 100644
index 0000000..c4552678
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/TableEntryListener.h
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_TABLEENTRYLISTENER_H_
+#define NTCORE_NETWORKTABLES_TABLEENTRYLISTENER_H_
+
+#include <functional>
+#include <memory>
+
+#include <wpi/StringRef.h>
+
+namespace nt {
+
+class NetworkTable;
+class NetworkTableEntry;
+class Value;
+
+using wpi::StringRef;
+
+/**
+ * A listener that listens to changes in values in a NetworkTable.
+ *
+ * Called when a key-value pair is changed in a NetworkTable.
+ *
+ * @param table the table the key-value pair exists in
+ * @param key the key associated with the value that changed
+ * @param entry the entry associated with the value that changed
+ * @param value the new value
+ * @param flags update flags; for example, EntryListenerFlags.kNew if the key
+ * did not previously exist
+ *
+ * @ingroup ntcore_cpp_api
+ */
+typedef std::function<void(NetworkTable* table, StringRef name,
+                           NetworkTableEntry entry,
+                           std::shared_ptr<Value> value, int flags)>
+    TableEntryListener;
+
+}  // namespace nt
+
+#endif  // NTCORE_NETWORKTABLES_TABLEENTRYLISTENER_H_
diff --git a/ntcore/src/main/native/include/networktables/TableListener.h b/ntcore/src/main/native/include/networktables/TableListener.h
new file mode 100644
index 0000000..9940bad
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/TableListener.h
@@ -0,0 +1,39 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NETWORKTABLES_TABLELISTENER_H_
+#define NTCORE_NETWORKTABLES_TABLELISTENER_H_
+
+#include <functional>
+#include <memory>
+
+#include <wpi/StringRef.h>
+
+namespace nt {
+
+class NetworkTable;
+
+using wpi::StringRef;
+
+/**
+ * A listener that listens to new sub-tables in a NetworkTable.
+ *
+ * Called when a new table is created.
+ *
+ * @param parent the parent of the table
+ * @param name the name of the new table
+ * @param table the new table
+ *
+ * @ingroup ntcore_cpp_api
+ */
+typedef std::function<void(NetworkTable* parent, StringRef name,
+                           std::shared_ptr<NetworkTable> table)>
+    TableListener;
+
+}  // namespace nt
+
+#endif  // NTCORE_NETWORKTABLES_TABLELISTENER_H_
diff --git a/ntcore/src/main/native/include/ntcore.h b/ntcore/src/main/native/include/ntcore.h
new file mode 100644
index 0000000..ff0511a
--- /dev/null
+++ b/ntcore/src/main/native/include/ntcore.h
@@ -0,0 +1,19 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NTCORE_H_
+#define NTCORE_NTCORE_H_
+
+/* C API */
+#include "ntcore_c.h"
+
+#ifdef __cplusplus
+/* C++ API */
+#include "ntcore_cpp.h"
+#endif /* __cplusplus */
+
+#endif  // NTCORE_NTCORE_H_
diff --git a/ntcore/src/main/native/include/ntcore_c.h b/ntcore/src/main/native/include/ntcore_c.h
new file mode 100644
index 0000000..1ed4025
--- /dev/null
+++ b/ntcore/src/main/native/include/ntcore_c.h
@@ -0,0 +1,2085 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NTCORE_C_H_
+#define NTCORE_NTCORE_C_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#include <wpi/deprecated.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ntcore_c_api ntcore C API
+ *
+ * Handle-based interface for C.
+ *
+ * @{
+ */
+
+/** Typedefs */
+typedef int NT_Bool;
+
+typedef unsigned int NT_Handle;
+typedef NT_Handle NT_ConnectionListener;
+typedef NT_Handle NT_ConnectionListenerPoller;
+typedef NT_Handle NT_Entry;
+typedef NT_Handle NT_EntryListener;
+typedef NT_Handle NT_EntryListenerPoller;
+typedef NT_Handle NT_Inst;
+typedef NT_Handle NT_Logger;
+typedef NT_Handle NT_LoggerPoller;
+typedef NT_Handle NT_RpcCall;
+typedef NT_Handle NT_RpcCallPoller;
+
+/** Default network tables port number */
+#define NT_DEFAULT_PORT 1735
+
+/** NetworkTables data types. */
+enum NT_Type {
+  NT_UNASSIGNED = 0,
+  NT_BOOLEAN = 0x01,
+  NT_DOUBLE = 0x02,
+  NT_STRING = 0x04,
+  NT_RAW = 0x08,
+  NT_BOOLEAN_ARRAY = 0x10,
+  NT_DOUBLE_ARRAY = 0x20,
+  NT_STRING_ARRAY = 0x40,
+  NT_RPC = 0x80
+};
+
+/** NetworkTables entry flags. */
+enum NT_EntryFlags { NT_PERSISTENT = 0x01 };
+
+/** NetworkTables logging levels. */
+enum NT_LogLevel {
+  NT_LOG_CRITICAL = 50,
+  NT_LOG_ERROR = 40,
+  NT_LOG_WARNING = 30,
+  NT_LOG_INFO = 20,
+  NT_LOG_DEBUG = 10,
+  NT_LOG_DEBUG1 = 9,
+  NT_LOG_DEBUG2 = 8,
+  NT_LOG_DEBUG3 = 7,
+  NT_LOG_DEBUG4 = 6
+};
+
+/** NetworkTables notifier kinds. */
+enum NT_NotifyKind {
+  NT_NOTIFY_NONE = 0,
+  NT_NOTIFY_IMMEDIATE = 0x01, /* initial listener addition */
+  NT_NOTIFY_LOCAL = 0x02,     /* changed locally */
+  NT_NOTIFY_NEW = 0x04,       /* newly created entry */
+  NT_NOTIFY_DELETE = 0x08,    /* deleted */
+  NT_NOTIFY_UPDATE = 0x10,    /* value changed */
+  NT_NOTIFY_FLAGS = 0x20      /* flags changed */
+};
+
+/** Client/server modes */
+enum NT_NetworkMode {
+  NT_NET_MODE_NONE = 0x00,     /* not running */
+  NT_NET_MODE_SERVER = 0x01,   /* running in server mode */
+  NT_NET_MODE_CLIENT = 0x02,   /* running in client mode */
+  NT_NET_MODE_STARTING = 0x04, /* flag for starting (either client or server) */
+  NT_NET_MODE_FAILURE = 0x08,  /* flag for failure (either client or server) */
+  NT_NET_MODE_LOCAL = 0x10,    /* running in local-only mode */
+};
+
+/*
+ * Structures
+ */
+
+/** A NetworkTables string. */
+struct NT_String {
+  /**
+   * String contents (UTF-8).
+   * The string is NOT required to be zero-terminated.
+   * When returned by the library, this is zero-terminated and allocated with
+   * std::malloc().
+   */
+  char* str;
+
+  /**
+   * Length of the string in bytes.  If the string happens to be zero
+   * terminated, this does not include the zero-termination.
+   */
+  size_t len;
+};
+
+/** NetworkTables Entry Value.  Note this is a typed union. */
+struct NT_Value {
+  enum NT_Type type;
+  uint64_t last_change;
+  union {
+    NT_Bool v_boolean;
+    double v_double;
+    struct NT_String v_string;
+    struct NT_String v_raw;
+    struct {
+      NT_Bool* arr;
+      size_t size;
+    } arr_boolean;
+    struct {
+      double* arr;
+      size_t size;
+    } arr_double;
+    struct {
+      struct NT_String* arr;
+      size_t size;
+    } arr_string;
+  } data;
+};
+
+/** NetworkTables Entry Information */
+struct NT_EntryInfo {
+  /** Entry handle */
+  NT_Entry entry;
+
+  /** Entry name */
+  struct NT_String name;
+
+  /** Entry type */
+  enum NT_Type type;
+
+  /** Entry flags */
+  unsigned int flags;
+
+  /** Timestamp of last change to entry (type or value). */
+  uint64_t last_change;
+};
+
+/** NetworkTables Connection Information */
+struct NT_ConnectionInfo {
+  /**
+   * The remote identifier (as set on the remote node by
+   * NetworkTableInstance::SetNetworkIdentity() or nt::SetNetworkIdentity()).
+   */
+  struct NT_String remote_id;
+
+  /** The IP address of the remote node. */
+  struct NT_String remote_ip;
+
+  /** The port number of the remote node. */
+  unsigned int remote_port;
+
+  /**
+   * The last time any update was received from the remote node (same scale as
+   * returned by nt::Now()).
+   */
+  uint64_t last_update;
+
+  /**
+   * The protocol version being used for this connection.  This in protocol
+   * layer format, so 0x0200 = 2.0, 0x0300 = 3.0).
+   */
+  unsigned int protocol_version;
+};
+
+/** NetworkTables RPC Version 1 Definition Parameter */
+struct NT_RpcParamDef {
+  struct NT_String name;
+  struct NT_Value def_value;
+};
+
+/** NetworkTables RPC Version 1 Definition Result */
+struct NT_RpcResultDef {
+  struct NT_String name;
+  enum NT_Type type;
+};
+
+/** NetworkTables RPC Version 1 Definition */
+struct NT_RpcDefinition {
+  unsigned int version;
+  struct NT_String name;
+  size_t num_params;
+  struct NT_RpcParamDef* params;
+  size_t num_results;
+  struct NT_RpcResultDef* results;
+};
+
+/** NetworkTables RPC Call Data */
+struct NT_RpcAnswer {
+  NT_Entry entry;
+  NT_RpcCall call;
+  struct NT_String name;
+  struct NT_String params;
+  struct NT_ConnectionInfo conn;
+};
+
+/** NetworkTables Entry Notification */
+struct NT_EntryNotification {
+  /** Listener that was triggered. */
+  NT_EntryListener listener;
+
+  /** Entry handle. */
+  NT_Entry entry;
+
+  /** Entry name. */
+  struct NT_String name;
+
+  /** The new value. */
+  struct NT_Value value;
+
+  /**
+   * Update flags.  For example, NT_NOTIFY_NEW if the key did not previously
+   * exist.
+   */
+  unsigned int flags;
+};
+
+/** NetworkTables Connection Notification */
+struct NT_ConnectionNotification {
+  /** Listener that was triggered. */
+  NT_ConnectionListener listener;
+
+  /** True if event is due to connection being established. */
+  NT_Bool connected;
+
+  /** Connection info. */
+  struct NT_ConnectionInfo conn;
+};
+
+/** NetworkTables log message. */
+struct NT_LogMessage {
+  /** The logger that generated the message. */
+  NT_Logger logger;
+
+  /** Log level of the message.  See NT_LogLevel. */
+  unsigned int level;
+
+  /** The filename of the source file that generated the message. */
+  const char* filename;
+
+  /** The line number in the source file that generated the message. */
+  unsigned int line;
+
+  /** The message. */
+  char* message;
+};
+
+/**
+ * @defgroup ntcore_instance_cfunc Instance Functions
+ * @{
+ */
+
+/**
+ * Get default instance.
+ * This is the instance used by non-handle-taking functions.
+ *
+ * @return Instance handle
+ */
+NT_Inst NT_GetDefaultInstance(void);
+
+/**
+ * Create an instance.
+ *
+ * @return Instance handle
+ */
+NT_Inst NT_CreateInstance(void);
+
+/**
+ * Destroy an instance.
+ * The default instance cannot be destroyed.
+ *
+ * @param inst Instance handle
+ */
+void NT_DestroyInstance(NT_Inst inst);
+
+/**
+ * Get instance handle from another handle.
+ *
+ * @param handle    handle
+ * @return Instance handle
+ */
+NT_Inst NT_GetInstanceFromHandle(NT_Handle handle);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_table_cfunc Table Functions
+ * @{
+ */
+
+/**
+ * Get Entry Handle.
+ *
+ * @param inst      instance handle
+ * @param name      entry name (UTF-8 string)
+ * @param name_len  length of name in bytes
+ * @return entry handle
+ */
+NT_Entry NT_GetEntry(NT_Inst inst, const char* name, size_t name_len);
+
+/**
+ * Get Entry Handles.
+ *
+ * Returns an array of entry handles.  The results are optionally
+ * filtered by string prefix and entry type to only return a subset of all
+ * entries.
+ *
+ * @param prefix        entry name required prefix; only entries whose name
+ *                      starts with this string are returned
+ * @param prefix_len    length of prefix in bytes
+ * @param types         bitmask of NT_Type values; 0 is treated specially
+ *                      as a "don't care"
+ * @return Array of entry handles.
+ */
+NT_Entry* NT_GetEntries(NT_Inst inst, const char* prefix, size_t prefix_len,
+                        unsigned int types, size_t* count);
+
+/**
+ * Gets the name of the specified entry.
+ * Returns an empty string if the handle is invalid.
+ *
+ * @param entry     entry handle
+ * @param name_len  length of the returned string (output parameter)
+ * @return Entry name
+ */
+char* NT_GetEntryName(NT_Entry entry, size_t* name_len);
+
+/**
+ * Gets the type for the specified key, or unassigned if non existent.
+ *
+ * @param entry   entry handle
+ * @return Entry type
+ */
+enum NT_Type NT_GetEntryType(NT_Entry entry);
+
+/**
+ * Gets the last time the entry was changed.
+ * Returns 0 if the handle is invalid.
+ *
+ * @param entry   entry handle
+ * @return Entry last change time
+ */
+uint64_t NT_GetEntryLastChange(NT_Entry entry);
+
+/**
+ * Get Entry Value.
+ *
+ * Returns copy of current entry value.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param entry     entry handle
+ * @param value     storage for returned entry value
+ *
+ * It is the caller's responsibility to free value once it's no longer
+ * needed (the utility function NT_DisposeValue() is useful for this
+ * purpose).
+ */
+void NT_GetEntryValue(NT_Entry entry, struct NT_Value* value);
+
+/**
+ * Set Default Entry Value.
+ *
+ * Returns copy of current entry value if it exists.
+ * Otherwise, sets passed in value, and returns set value.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param entry     entry handle
+ * @param default_value     value to be set if name does not exist
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryValue(NT_Entry entry,
+                                const struct NT_Value* default_value);
+
+/**
+ * Set Entry Value.
+ *
+ * Sets new entry value.  If type of new value differs from the type of the
+ * currently stored entry, returns error and does not update value.
+ *
+ * @param entry     entry handle
+ * @param value     new entry value
+ * @return 0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryValue(NT_Entry entry, const struct NT_Value* value);
+
+/**
+ * Set Entry Type and Value.
+ *
+ * Sets new entry value.  If type of new value differs from the type of the
+ * currently stored entry, the currently stored entry type is overridden
+ * (generally this will generate an Entry Assignment message).
+ *
+ * This is NOT the preferred method to update a value; generally
+ * NT_SetEntryValue() should be used instead, with appropriate error handling.
+ *
+ * @param entry     entry handle
+ * @param value     new entry value
+ */
+void NT_SetEntryTypeValue(NT_Entry entry, const struct NT_Value* value);
+
+/**
+ * Set Entry Flags.
+ *
+ * @param entry     entry handle
+ * @param flags     flags value (bitmask of NT_EntryFlags)
+ */
+void NT_SetEntryFlags(NT_Entry entry, unsigned int flags);
+
+/**
+ * Get Entry Flags.
+ *
+ * @param entry     entry handle
+ * @return Flags value (bitmask of NT_EntryFlags)
+ */
+unsigned int NT_GetEntryFlags(NT_Entry entry);
+
+/**
+ * Delete Entry.
+ *
+ * Deletes an entry.  This is a new feature in version 3.0 of the protocol,
+ * so this may not have an effect if any other node in the network is not
+ * version 3.0 or newer.
+ *
+ * Note: NT_GetConnections() can be used to determine the protocol version
+ * of direct remote connection(s), but this is not sufficient to determine
+ * if all nodes in the network are version 3.0 or newer.
+ *
+ * @param entry     entry handle
+ */
+void NT_DeleteEntry(NT_Entry entry);
+
+/**
+ * Delete All Entries.
+ *
+ * Deletes ALL table entries.  This is a new feature in version 3.0 of the
+ * so this may not have an effect if any other node in the network is not
+ * version 3.0 or newer.
+ *
+ * Note: NT_GetConnections() can be used to determine the protocol version
+ * of direct remote connection(s), but this is not sufficient to determine
+ * if all nodes in the network are version 3.0 or newer.
+ *
+ * @param inst      instance handle
+ */
+void NT_DeleteAllEntries(NT_Inst inst);
+
+/**
+ * Get Entry Information.
+ *
+ * Returns an array of entry information (entry handle, name, entry type,
+ * and timestamp of last change to type/value).  The results are optionally
+ * filtered by string prefix and entry type to only return a subset of all
+ * entries.
+ *
+ * @param inst          instance handle
+ * @param prefix        entry name required prefix; only entries whose name
+ *                      starts with this string are returned
+ * @param prefix_len    length of prefix in bytes
+ * @param types         bitmask of NT_Type values; 0 is treated specially
+ *                      as a "don't care"
+ * @param count         output parameter; set to length of returned array
+ * @return Array of entry information.
+ */
+struct NT_EntryInfo* NT_GetEntryInfo(NT_Inst inst, const char* prefix,
+                                     size_t prefix_len, unsigned int types,
+                                     size_t* count);
+
+/**
+ * Get Entry Information.
+ *
+ * Returns information about an entry (name, entry type,
+ * and timestamp of last change to type/value).
+ *
+ * @param entry         entry handle
+ * @param info          entry information (output)
+ * @return True if successful, false on error.
+ */
+NT_Bool NT_GetEntryInfoHandle(NT_Entry entry, struct NT_EntryInfo* info);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_entrylistener_cfunc Entry Listener Functions
+ * @{
+ */
+
+/**
+ * Entry listener callback function.
+ * Called when a key-value pair is changed.
+ *
+ * @param data            data pointer provided to callback creation function
+ * @param event           event information
+ */
+typedef void (*NT_EntryListenerCallback)(
+    void* data, const struct NT_EntryNotification* event);
+
+/**
+ * Add a listener for all entries starting with a certain prefix.
+ *
+ * @param inst              instance handle
+ * @param prefix            UTF-8 string prefix
+ * @param prefix_len        length of prefix in bytes
+ * @param data              data pointer to pass to callback
+ * @param callback          listener to add
+ * @param flags             NT_NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener NT_AddEntryListener(NT_Inst inst, const char* prefix,
+                                     size_t prefix_len, void* data,
+                                     NT_EntryListenerCallback callback,
+                                     unsigned int flags);
+
+/**
+ * Add a listener for a single entry.
+ *
+ * @param entry             entry handle
+ * @param data              data pointer to pass to callback
+ * @param callback          listener to add
+ * @param flags             NT_NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener NT_AddEntryListenerSingle(NT_Entry entry, void* data,
+                                           NT_EntryListenerCallback callback,
+                                           unsigned int flags);
+
+/**
+ * Create a entry listener poller.
+ *
+ * A poller provides a single queue of poll events.  Events linked to this
+ * poller (using NT_AddPolledEntryListener()) will be stored in the queue and
+ * must be collected by calling NT_PollEntryListener().
+ * The returned handle must be destroyed with NT_DestroyEntryListenerPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_EntryListenerPoller NT_CreateEntryListenerPoller(NT_Inst inst);
+
+/**
+ * Destroy a entry listener poller.  This will abort any blocked polling
+ * call and prevent additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void NT_DestroyEntryListenerPoller(NT_EntryListenerPoller poller);
+
+/**
+ * Create a polled entry listener.
+ * The caller is responsible for calling NT_PollEntryListener() to poll.
+ *
+ * @param poller            poller handle
+ * @param prefix            UTF-8 string prefix
+ * @param flags             NT_NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener NT_AddPolledEntryListener(NT_EntryListenerPoller poller,
+                                           const char* prefix,
+                                           size_t prefix_len,
+                                           unsigned int flags);
+
+/**
+ * Create a polled entry listener.
+ * The caller is responsible for calling NT_PollEntryListener() to poll.
+ *
+ * @param poller            poller handle
+ * @param prefix            UTF-8 string prefix
+ * @param flags             NT_NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener NT_AddPolledEntryListenerSingle(NT_EntryListenerPoller poller,
+                                                 NT_Entry entry,
+                                                 unsigned int flags);
+
+/**
+ * Get the next entry listener event.  This blocks until the next event occurs.
+ *
+ * This is intended to be used with NT_AddPolledEntryListener(void); entry
+ * listeners created using NT_AddEntryListener() will not be serviced through
+ * this function.
+ *
+ * @param poller    poller handle
+ * @param len       length of returned array (output)
+ * @return Array of information on the entry listener events.  Returns NULL if
+ *         an erroroccurred (e.g. the instance was invalid or is shutting down).
+ */
+struct NT_EntryNotification* NT_PollEntryListener(NT_EntryListenerPoller poller,
+                                                  size_t* len);
+
+/**
+ * Get the next entry listener event.  This blocks until the next event occurs
+ * or it times out.  This is intended to be used with
+ * NT_AddPolledEntryListener(); entry listeners created using
+ * NT_AddEntryListener() will not be serviced through this function.
+ *
+ * @param poller      poller handle
+ * @param len         length of returned array (output)
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Array of information on the entry listener events.  If NULL is
+ *         returned and timed_out is also false, an error occurred (e.g. the
+ *         instance was invalid or is shutting down).
+ */
+struct NT_EntryNotification* NT_PollEntryListenerTimeout(
+    NT_EntryListenerPoller poller, size_t* len, double timeout,
+    NT_Bool* timed_out);
+
+/**
+ * Cancel a PollEntryListener call.  This wakes up a call to
+ * PollEntryListener for this poller and causes it to immediately return
+ * an empty array.
+ *
+ * @param poller  poller handle
+ */
+void NT_CancelPollEntryListener(NT_EntryListenerPoller poller);
+
+/**
+ * Remove an entry listener.
+ *
+ * @param entry_listener Listener handle to remove
+ */
+void NT_RemoveEntryListener(NT_EntryListener entry_listener);
+
+/**
+ * Wait for the entry listener queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the entry listener
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+NT_Bool NT_WaitForEntryListenerQueue(NT_Inst inst, double timeout);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_connectionlistener_cfunc Connection Listener Functions
+ * @{
+ */
+
+/**
+ * Connection listener callback function.
+ * Called when a network connection is made or lost.
+ *
+ * @param data            data pointer provided to callback creation function
+ * @param event           event info
+ */
+typedef void (*NT_ConnectionListenerCallback)(
+    void* data, const struct NT_ConnectionNotification* event);
+
+/**
+ * Add a connection listener.
+ *
+ * @param inst              instance handle
+ * @param data              data pointer to pass to callback
+ * @param callback          listener to add
+ * @param immediate_notify  notify listener of all existing connections
+ * @return Listener handle
+ */
+NT_ConnectionListener NT_AddConnectionListener(
+    NT_Inst inst, void* data, NT_ConnectionListenerCallback callback,
+    NT_Bool immediate_notify);
+
+/**
+ * Create a connection listener poller.
+ * A poller provides a single queue of poll events.  Events linked to this
+ * poller (using NT_AddPolledConnectionListener()) will be stored in the queue
+ * and must be collected by calling NT_PollConnectionListener().
+ * The returned handle must be destroyed with
+ * NT_DestroyConnectionListenerPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_ConnectionListenerPoller NT_CreateConnectionListenerPoller(NT_Inst inst);
+
+/**
+ * Destroy a connection listener poller.  This will abort any blocked polling
+ * call and prevent additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void NT_DestroyConnectionListenerPoller(NT_ConnectionListenerPoller poller);
+
+/**
+ * Create a polled connection listener.
+ * The caller is responsible for calling NT_PollConnectionListener() to poll.
+ *
+ * @param poller            poller handle
+ * @param immediate_notify  notify listener of all existing connections
+ */
+NT_ConnectionListener NT_AddPolledConnectionListener(
+    NT_ConnectionListenerPoller poller, NT_Bool immediate_notify);
+
+/**
+ * Get the next connection event.  This blocks until the next connect or
+ * disconnect occurs.  This is intended to be used with
+ * NT_AddPolledConnectionListener(); connection listeners created using
+ * NT_AddConnectionListener() will not be serviced through this function.
+ *
+ * @param poller    poller handle
+ * @param len       length of returned array (output)
+ * @return Array of information on the connection events.  Only returns NULL
+ *         if an error occurred (e.g. the instance was invalid or is shutting
+ *         down).
+ */
+struct NT_ConnectionNotification* NT_PollConnectionListener(
+    NT_ConnectionListenerPoller poller, size_t* len);
+
+/**
+ * Get the next connection event.  This blocks until the next connect or
+ * disconnect occurs or it times out.  This is intended to be used with
+ * NT_AddPolledConnectionListener(); connection listeners created using
+ * NT_AddConnectionListener() will not be serviced through this function.
+ *
+ * @param poller      poller handle
+ * @param len         length of returned array (output)
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Array of information on the connection events.  If NULL is returned
+ *         and timed_out is also false, an error occurred (e.g. the instance
+ *         was invalid or is shutting down).
+ */
+struct NT_ConnectionNotification* NT_PollConnectionListenerTimeout(
+    NT_ConnectionListenerPoller poller, size_t* len, double timeout,
+    NT_Bool* timed_out);
+
+/**
+ * Cancel a PollConnectionListener call.  This wakes up a call to
+ * PollConnectionListener for this poller and causes it to immediately return
+ * an empty array.
+ *
+ * @param poller  poller handle
+ */
+void NT_CancelPollConnectionListener(NT_ConnectionListenerPoller poller);
+
+/**
+ * Remove a connection listener.
+ *
+ * @param conn_listener Listener handle to remove
+ */
+void NT_RemoveConnectionListener(NT_ConnectionListener conn_listener);
+
+/**
+ * Wait for the connection listener queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the connection listener
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+NT_Bool NT_WaitForConnectionListenerQueue(NT_Inst inst, double timeout);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_rpc_cfunc Remote Procedure Call Functions
+ * @{
+ */
+
+/**
+ * Remote Procedure Call (RPC) callback function.
+ *
+ * @param data        data pointer provided to NT_CreateRpc()
+ * @param call        call information
+ *
+ * Note: NT_PostRpcResponse() must be called by the callback to provide a
+ * response to the call.
+ */
+typedef void (*NT_RpcCallback)(void* data, const struct NT_RpcAnswer* call);
+
+/**
+ * Create a callback-based RPC entry point.  Only valid to use on the server.
+ * The callback function will be called when the RPC is called.
+ *
+ * @param entry     entry handle of RPC entry
+ * @param def       RPC definition
+ * @param def_len   length of def in bytes
+ * @param data      data pointer to pass to callback function
+ * @param callback  callback function
+ */
+void NT_CreateRpc(NT_Entry entry, const char* def, size_t def_len, void* data,
+                  NT_RpcCallback callback);
+
+/**
+ * Create a RPC call poller.  Only valid to use on the server.
+ *
+ * A poller provides a single queue of poll events.  Events linked to this
+ * poller (using NT_CreatePolledRpc()) will be stored in the queue and must be
+ * collected by calling NT_PollRpc() or NT_PollRpcTimeout().
+ * The returned handle must be destroyed with NT_DestroyRpcCallPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_RpcCallPoller NT_CreateRpcCallPoller(NT_Inst inst);
+
+/**
+ * Destroy a RPC call poller.  This will abort any blocked polling call and
+ * prevent additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void NT_DestroyRpcCallPoller(NT_RpcCallPoller poller);
+
+/**
+ * Create a polled RPC entry point.  Only valid to use on the server.
+ *
+ * The caller is responsible for calling NT_PollRpc() or NT_PollRpcTimeout()
+ * to poll for servicing incoming RPC calls.
+ *
+ * @param entry     entry handle of RPC entry
+ * @param def       RPC definition
+ * @param def_len   length of def in bytes
+ * @param poller    poller handle
+ */
+void NT_CreatePolledRpc(NT_Entry entry, const char* def, size_t def_len,
+                        NT_RpcCallPoller poller);
+
+/**
+ * Get the next incoming RPC call.  This blocks until the next incoming RPC
+ * call is received.  This is intended to be used with NT_CreatePolledRpc(void);
+ * RPC calls created using NT_CreateRpc() will not be serviced through this
+ * function.  Upon successful return, NT_PostRpcResponse() must be called to
+ * send the return value to the caller.  The returned array must be freed
+ * using NT_DisposeRpcAnswerArray().
+ *
+ * @param poller      poller handle
+ * @param len         length of returned array (output)
+ * @return Array of RPC call information.  Only returns NULL if an error
+ *         occurred (e.g. the instance was invalid or is shutting down).
+ */
+struct NT_RpcAnswer* NT_PollRpc(NT_RpcCallPoller poller, size_t* len);
+
+/**
+ * Get the next incoming RPC call.  This blocks until the next incoming RPC
+ * call is received or it times out.  This is intended to be used with
+ * NT_CreatePolledRpc(); RPC calls created using NT_CreateRpc() will not be
+ * serviced through this function.  Upon successful return,
+ * NT_PostRpcResponse() must be called to send the return value to the caller.
+ * The returned array must be freed using NT_DisposeRpcAnswerArray().
+ *
+ * @param poller      poller handle
+ * @param len         length of returned array (output)
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Array of RPC call information.  If NULL is returned and timed_out
+ *         is also false, an error occurred (e.g. the instance was invalid or
+ *         is shutting down).
+ */
+struct NT_RpcAnswer* NT_PollRpcTimeout(NT_RpcCallPoller poller, size_t* len,
+                                       double timeout, NT_Bool* timed_out);
+
+/**
+ * Cancel a PollRpc call.  This wakes up a call to PollRpc for this poller
+ * and causes it to immediately return an empty array.
+ *
+ * @param poller  poller handle
+ */
+void NT_CancelPollRpc(NT_RpcCallPoller poller);
+
+/**
+ * Wait for the incoming RPC call queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the RPC call
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+NT_Bool NT_WaitForRpcCallQueue(NT_Inst inst, double timeout);
+
+/**
+ * Post RPC response (return value) for a polled RPC.
+ *
+ * The rpc and call parameters should come from the NT_RpcAnswer returned
+ * by NT_PollRpc().
+ *
+ * @param entry       entry handle of RPC entry (from NT_RpcAnswer)
+ * @param call        RPC call handle (from NT_RpcAnswer)
+ * @param result      result raw data that will be provided to remote caller
+ * @param result_len  length of result in bytes
+ * @return            true if the response was posted, otherwise false
+ */
+NT_Bool NT_PostRpcResponse(NT_Entry entry, NT_RpcCall call, const char* result,
+                           size_t result_len);
+
+/**
+ * Call a RPC function.  May be used on either the client or server.
+ *
+ * This function is non-blocking.  Either NT_GetRpcResult() or
+ * NT_CancelRpcResult() must be called to either get or ignore the result of
+ * the call.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param params      parameter
+ * @param params_len  length of param in bytes
+ * @return RPC call handle (for use with NT_GetRpcResult() or
+ *         NT_CancelRpcResult()).
+ */
+NT_RpcCall NT_CallRpc(NT_Entry entry, const char* params, size_t params_len);
+
+/**
+ * Get the result (return value) of a RPC call.  This function blocks until
+ * the result is received.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param call        RPC call handle returned by NT_CallRpc()
+ * @param result_len  length of returned result in bytes
+ * @return NULL on error, or result.
+ */
+char* NT_GetRpcResult(NT_Entry entry, NT_RpcCall call, size_t* result_len);
+
+/**
+ * Get the result (return value) of a RPC call.  This function blocks until
+ * the result is received or it times out.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param call        RPC call handle returned by NT_CallRpc()
+ * @param result_len  length of returned result in bytes
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return NULL on error or timeout, or result.
+ */
+char* NT_GetRpcResultTimeout(NT_Entry entry, NT_RpcCall call,
+                             size_t* result_len, double timeout,
+                             NT_Bool* timed_out);
+
+/**
+ * Ignore the result of a RPC call.  This function is non-blocking.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param call        RPC call handle returned by NT_CallRpc()
+ */
+void NT_CancelRpcResult(NT_Entry entry, NT_RpcCall call);
+
+/**
+ * Pack a RPC version 1 definition.
+ *
+ * @param def         RPC version 1 definition
+ * @param packed_len  length of return value in bytes
+ * @return Raw packed bytes.  Use C standard library std::free() to release.
+ */
+char* NT_PackRpcDefinition(const struct NT_RpcDefinition* def,
+                           size_t* packed_len);
+
+/**
+ * Unpack a RPC version 1 definition.  This can be used for introspection or
+ * validation.
+ *
+ * @param packed      raw packed bytes
+ * @param packed_len  length of packed in bytes
+ * @param def         RPC version 1 definition (output)
+ * @return True if successfully unpacked, false otherwise.
+ */
+NT_Bool NT_UnpackRpcDefinition(const char* packed, size_t packed_len,
+                               struct NT_RpcDefinition* def);
+
+/**
+ * Pack RPC values as required for RPC version 1 definition messages.
+ *
+ * @param values      array of values to pack
+ * @param values_len  length of values
+ * @param packed_len  length of return value in bytes
+ * @return Raw packed bytes.  Use C standard library std::free() to release.
+ */
+char* NT_PackRpcValues(const struct NT_Value** values, size_t values_len,
+                       size_t* packed_len);
+
+/**
+ * Unpack RPC values as required for RPC version 1 definition messages.
+ *
+ * @param packed      raw packed bytes
+ * @param packed_len  length of packed in bytes
+ * @param types       array of data types (as provided in the RPC definition)
+ * @param types_len   length of types
+ * @return Array of NT_Value's.
+ */
+struct NT_Value** NT_UnpackRpcValues(const char* packed, size_t packed_len,
+                                     const enum NT_Type* types,
+                                     size_t types_len);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_network_cfunc Client/Server Functions
+ * @{
+ */
+
+/**
+ * Set the network identity of this node.
+ * This is the name used during the initial connection handshake, and is
+ * visible through NT_ConnectionInfo on the remote node.
+ *
+ * @param inst      instance handle
+ * @param name      identity to advertise
+ * @param name_len  length of name in bytes
+ */
+void NT_SetNetworkIdentity(NT_Inst inst, const char* name, size_t name_len);
+
+/**
+ * Get the current network mode.
+ *
+ * @param inst  instance handle
+ * @return Bitmask of NT_NetworkMode.
+ */
+unsigned int NT_GetNetworkMode(NT_Inst inst);
+
+/**
+ * Starts local-only operation.  Prevents calls to NT_StartServer or
+ * NT_StartClient from taking effect.  Has no effect if NT_StartServer or
+ * NT_StartClient has already been called.
+ */
+void NT_StartLocal(NT_Inst inst);
+
+/**
+ * Stops local-only operation.  NT_StartServer or NT_StartClient can be called
+ * after this call to start a server or client.
+ */
+void NT_StopLocal(NT_Inst inst);
+
+/**
+ * Starts a server using the specified filename, listening address, and port.
+ *
+ * @param inst              instance handle
+ * @param persist_filename  the name of the persist file to use (UTF-8 string,
+ *                          null terminated)
+ * @param listen_address    the address to listen on, or null to listen on any
+ *                          address. (UTF-8 string, null terminated)
+ * @param port              port to communicate over.
+ */
+void NT_StartServer(NT_Inst inst, const char* persist_filename,
+                    const char* listen_address, unsigned int port);
+
+/**
+ * Stops the server if it is running.
+ *
+ * @param inst  instance handle
+ */
+void NT_StopServer(NT_Inst inst);
+
+/**
+ * Starts a client.  Use NT_SetServer to set the server name and port.
+ *
+ * @param inst  instance handle
+ */
+void NT_StartClientNone(NT_Inst inst);
+
+/**
+ * Starts a client using the specified server and port
+ *
+ * @param inst        instance handle
+ * @param server_name server name (UTF-8 string, null terminated)
+ * @param port        port to communicate over
+ */
+void NT_StartClient(NT_Inst inst, const char* server_name, unsigned int port);
+
+/**
+ * Starts a client using the specified (server, port) combinations.  The
+ * client will attempt to connect to each server in round robin fashion.
+ *
+ * @param inst         instance handle
+ * @param count        length of the server_names and ports arrays
+ * @param server_names array of server names (each a UTF-8 string, null
+ *                     terminated)
+ * @param ports        array of ports to communicate over (one for each server)
+ */
+void NT_StartClientMulti(NT_Inst inst, size_t count, const char** server_names,
+                         const unsigned int* ports);
+
+/**
+ * Starts a client using commonly known robot addresses for the specified team.
+ *
+ * @param inst        instance handle
+ * @param team        team number
+ * @param port        port to communicate over
+ */
+void NT_StartClientTeam(NT_Inst inst, unsigned int team, unsigned int port);
+
+/**
+ * Stops the client if it is running.
+ *
+ * @param inst  instance handle
+ */
+void NT_StopClient(NT_Inst inst);
+
+/**
+ * Sets server address and port for client (without restarting client).
+ *
+ * @param inst        instance handle
+ * @param server_name server name (UTF-8 string, null terminated)
+ * @param port        port to communicate over
+ */
+void NT_SetServer(NT_Inst inst, const char* server_name, unsigned int port);
+
+/**
+ * Sets server addresses for client (without restarting client).
+ * The client will attempt to connect to each server in round robin fashion.
+ *
+ * @param inst         instance handle
+ * @param count        length of the server_names and ports arrays
+ * @param server_names array of server names (each a UTF-8 string, null
+ *                     terminated)
+ * @param ports        array of ports to communicate over (one for each server)
+ */
+void NT_SetServerMulti(NT_Inst inst, size_t count, const char** server_names,
+                       const unsigned int* ports);
+
+/**
+ * Sets server addresses and port for client (without restarting client).
+ * Connects using commonly known robot addresses for the specified team.
+ *
+ * @param inst        instance handle
+ * @param team        team number
+ * @param port        port to communicate over
+ */
+void NT_SetServerTeam(NT_Inst inst, unsigned int team, unsigned int port);
+
+/**
+ * Starts requesting server address from Driver Station.
+ * This connects to the Driver Station running on localhost to obtain the
+ * server IP address.
+ *
+ * @param inst  instance handle
+ * @param port server port to use in combination with IP from DS
+ */
+void NT_StartDSClient(NT_Inst inst, unsigned int port);
+
+/**
+ * Stops requesting server address from Driver Station.
+ *
+ * @param inst  instance handle
+ */
+void NT_StopDSClient(NT_Inst inst);
+
+/**
+ * Set the periodic update rate.
+ * Sets how frequently updates are sent to other nodes over the network.
+ *
+ * @param inst      instance handle
+ * @param interval  update interval in seconds (range 0.01 to 1.0)
+ */
+void NT_SetUpdateRate(NT_Inst inst, double interval);
+
+/**
+ * Flush Entries.
+ *
+ * Forces an immediate flush of all local entry changes to network.
+ * Normally this is done on a regularly scheduled interval (see
+ * NT_SetUpdateRate()).
+ *
+ * Note: flushes are rate limited to avoid excessive network traffic.  If
+ * the time between calls is too short, the flush will occur after the minimum
+ * time elapses (rather than immediately).
+ *
+ * @param inst      instance handle
+ */
+void NT_Flush(NT_Inst inst);
+
+/**
+ * Get information on the currently established network connections.
+ * If operating as a client, this will return either zero or one values.
+ *
+ * @param inst  instance handle
+ * @param count returns the number of elements in the array
+ * @return      array of connection information
+ *
+ * It is the caller's responsibility to free the array. The
+ * NT_DisposeConnectionInfoArray function is useful for this purpose.
+ */
+struct NT_ConnectionInfo* NT_GetConnections(NT_Inst inst, size_t* count);
+
+/**
+ * Return whether or not the instance is connected to another node.
+ *
+ * @param inst  instance handle
+ * @return True if connected.
+ */
+NT_Bool NT_IsConnected(NT_Inst inst);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_file_cfunc File Save/Load Functions
+ * @{
+ */
+
+/**
+ * Save persistent values to a file.  The server automatically does this,
+ * but this function provides a way to save persistent values in the same
+ * format to a file on either a client or a server.
+ *
+ * @param inst      instance handle
+ * @param filename  filename
+ * @return error string, or NULL if successful
+ */
+const char* NT_SavePersistent(NT_Inst inst, const char* filename);
+
+/**
+ * Load persistent values from a file.  The server automatically does this
+ * at startup, but this function provides a way to restore persistent values
+ * in the same format from a file at any time on either a client or a server.
+ *
+ * @param inst      instance handle
+ * @param filename  filename
+ * @param warn      callback function for warnings
+ * @return error string, or NULL if successful
+ */
+const char* NT_LoadPersistent(NT_Inst inst, const char* filename,
+                              void (*warn)(size_t line, const char* msg));
+
+/**
+ * Save table values to a file.  The file format used is identical to
+ * that used for SavePersistent.
+ *
+ * @param inst        instance handle
+ * @param filename    filename
+ * @param prefix      save only keys starting with this prefix
+ * @param prefix_len  length of prefix in bytes
+ * @return error string, or nullptr if successful
+ */
+const char* NT_SaveEntries(NT_Inst inst, const char* filename,
+                           const char* prefix, size_t prefix_len);
+
+/**
+ * Load table values from a file.  The file format used is identical to
+ * that used for SavePersistent / LoadPersistent.
+ *
+ * @param inst        instance handle
+ * @param filename    filename
+ * @param prefix      load only keys starting with this prefix
+ * @param prefix_len  length of prefix in bytes
+ * @param warn        callback function for warnings
+ * @return error string, or nullptr if successful
+ */
+const char* NT_LoadEntries(NT_Inst inst, const char* filename,
+                           const char* prefix, size_t prefix_len,
+                           void (*warn)(size_t line, const char* msg));
+
+/** @} */
+
+/**
+ * @defgroup ntcore_utility_cfunc Utility Functions
+ * @{
+ */
+
+/**
+ * Frees value memory.
+ *
+ * @param value   value to free
+ */
+void NT_DisposeValue(struct NT_Value* value);
+
+/**
+ * Initializes a NT_Value.
+ * Sets type to NT_UNASSIGNED and clears rest of struct.
+ *
+ * @param value value to initialize
+ */
+void NT_InitValue(struct NT_Value* value);
+
+/**
+ * Frees string memory.
+ *
+ * @param str   string to free
+ */
+void NT_DisposeString(struct NT_String* str);
+
+/**
+ * Initializes a NT_String.
+ * Sets length to zero and pointer to null.
+ *
+ * @param str   string to initialize
+ */
+void NT_InitString(struct NT_String* str);
+
+/**
+ * Disposes an entry handle array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeEntryArray(NT_Entry* arr, size_t count);
+
+/**
+ * Disposes a connection info array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeConnectionInfoArray(struct NT_ConnectionInfo* arr, size_t count);
+
+/**
+ * Disposes an entry info array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeEntryInfoArray(struct NT_EntryInfo* arr, size_t count);
+
+/**
+ * Disposes a single entry info (as returned by NT_GetEntryInfoHandle).
+ *
+ * @param info  pointer to the info to dispose
+ */
+void NT_DisposeEntryInfo(struct NT_EntryInfo* info);
+
+/**
+ * Disposes a Rpc Definition structure.
+ *
+ * @param def  pointer to the struct to dispose
+ */
+void NT_DisposeRpcDefinition(struct NT_RpcDefinition* def);
+
+/**
+ * Disposes a Rpc Answer array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeRpcAnswerArray(struct NT_RpcAnswer* arr, size_t count);
+
+/**
+ * Disposes a Rpc Answer structure.
+ *
+ * @param answer     pointer to the struct to dispose
+ */
+void NT_DisposeRpcAnswer(struct NT_RpcAnswer* answer);
+
+/**
+ * Disposes an entry notification array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeEntryNotificationArray(struct NT_EntryNotification* arr,
+                                      size_t count);
+
+/**
+ * Disposes a single entry notification.
+ *
+ * @param info  pointer to the info to dispose
+ */
+void NT_DisposeEntryNotification(struct NT_EntryNotification* info);
+
+/**
+ * Disposes a connection notification array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeConnectionNotificationArray(
+    struct NT_ConnectionNotification* arr, size_t count);
+
+/**
+ * Disposes a single connection notification.
+ *
+ * @param info  pointer to the info to dispose
+ */
+void NT_DisposeConnectionNotification(struct NT_ConnectionNotification* info);
+
+/**
+ * Disposes a log message array.
+ *
+ * @param arr   pointer to the array to dispose
+ * @param count number of elements in the array
+ */
+void NT_DisposeLogMessageArray(struct NT_LogMessage* arr, size_t count);
+
+/**
+ * Disposes a single log message.
+ *
+ * @param info  pointer to the info to dispose
+ */
+void NT_DisposeLogMessage(struct NT_LogMessage* info);
+
+/**
+ * Returns monotonic current time in 1 us increments.
+ * This is the same time base used for entry and connection timestamps.
+ * This function is a compatibility wrapper around WPI_Now().
+ *
+ * @return Timestamp
+ */
+uint64_t NT_Now(void);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_logger_cfunc Logger Functions
+ * @{
+ */
+
+/**
+ * Log function.
+ *
+ * @param data    data pointer passed to NT_AddLogger()
+ * @param msg     message information
+ */
+typedef void (*NT_LogFunc)(void* data, const struct NT_LogMessage* msg);
+
+/**
+ * Add logger callback function.  By default, log messages are sent to stderr;
+ * this function sends log messages to the provided callback function instead.
+ * The callback function will only be called for log messages with level
+ * greater than or equal to min_level and less than or equal to max_level;
+ * messages outside this range will be silently ignored.
+ *
+ * @param inst        instance handle
+ * @param data        data pointer to pass to func
+ * @param func        log callback function
+ * @param min_level   minimum log level
+ * @param max_level   maximum log level
+ * @return Logger handle
+ */
+NT_Logger NT_AddLogger(NT_Inst inst, void* data, NT_LogFunc func,
+                       unsigned int min_level, unsigned int max_level);
+
+/**
+ * Create a log poller.  A poller provides a single queue of poll events.
+ * The returned handle must be destroyed with NT_DestroyLoggerPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_LoggerPoller NT_CreateLoggerPoller(NT_Inst inst);
+
+/**
+ * Destroy a log poller.  This will abort any blocked polling call and prevent
+ * additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void NT_DestroyLoggerPoller(NT_LoggerPoller poller);
+
+/**
+ * Set the log level for a log poller.  Events will only be generated for
+ * log messages with level greater than or equal to min_level and less than or
+ * equal to max_level; messages outside this range will be silently ignored.
+ *
+ * @param poller        poller handle
+ * @param min_level     minimum log level
+ * @param max_level     maximum log level
+ * @return Logger handle
+ */
+NT_Logger NT_AddPolledLogger(NT_LoggerPoller poller, unsigned int min_level,
+                             unsigned int max_level);
+
+/**
+ * Get the next log event.  This blocks until the next log occurs.
+ *
+ * @param poller    poller handle
+ * @param len       length of returned array (output)
+ * @return Array of information on the log events.  Only returns NULL if an
+ *         error occurred (e.g. the instance was invalid or is shutting down).
+ */
+struct NT_LogMessage* NT_PollLogger(NT_LoggerPoller poller, size_t* len);
+
+/**
+ * Get the next log event.  This blocks until the next log occurs or it times
+ * out.
+ *
+ * @param poller      poller handle
+ * @param len         length of returned array (output)
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Array of information on the log events.  If NULL is returned and
+ *         timed_out is also false, an error occurred (e.g. the instance was
+ *         invalid or is shutting down).
+ */
+struct NT_LogMessage* NT_PollLoggerTimeout(NT_LoggerPoller poller, size_t* len,
+                                           double timeout, NT_Bool* timed_out);
+
+/**
+ * Cancel a PollLogger call.  This wakes up a call to PollLogger for this
+ * poller and causes it to immediately return an empty array.
+ *
+ * @param poller  poller handle
+ */
+void NT_CancelPollLogger(NT_LoggerPoller poller);
+
+/**
+ * Remove a logger.
+ *
+ * @param logger Logger handle to remove
+ */
+void NT_RemoveLogger(NT_Logger logger);
+
+/**
+ * Wait for the incoming log event queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the log event
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+NT_Bool NT_WaitForLoggerQueue(NT_Inst inst, double timeout);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_interop_cfunc Interop Utility Functions
+ * @{
+ */
+
+/**
+ * @defgroup ntcore_memoryallocators_cfunc Memory Allocators
+ * @{
+ */
+
+/**
+ * Allocates an array of chars.
+ * Note that the size is the number of elements, and not the
+ * specific number of bytes to allocate. That is calculated internally.
+ *
+ * @param size  the number of elements the array will contain
+ * @return      the allocated char array
+ *
+ * After use, the array should be freed using the NT_FreeCharArray()
+ * function.
+ */
+char* NT_AllocateCharArray(size_t size);
+
+/**
+ * Allocates an array of booleans.
+ * Note that the size is the number of elements, and not the
+ * specific number of bytes to allocate. That is calculated internally.
+ *
+ * @param size  the number of elements the array will contain
+ * @return      the allocated boolean array
+ *
+ * After use, the array should be freed using the NT_FreeBooleanArray()
+ * function.
+ */
+NT_Bool* NT_AllocateBooleanArray(size_t size);
+
+/**
+ * Allocates an array of doubles.
+ * Note that the size is the number of elements, and not the
+ * specific number of bytes to allocate. That is calculated internally.
+ *
+ * @param size  the number of elements the array will contain
+ * @return      the allocated double array
+ *
+ * After use, the array should be freed using the NT_FreeDoubleArray()
+ * function.
+ */
+double* NT_AllocateDoubleArray(size_t size);
+
+/**
+ * Allocates an array of NT_Strings.
+ * Note that the size is the number of elements, and not the
+ * specific number of bytes to allocate. That is calculated internally.
+ *
+ * @param size  the number of elements the array will contain
+ * @return      the allocated NT_String array
+ *
+ * After use, the array should be freed using the NT_FreeStringArray()
+ * function.
+ */
+struct NT_String* NT_AllocateStringArray(size_t size);
+
+/**
+ * Frees an array of chars.
+ *
+ * @param v_boolean  pointer to the char array to free
+ */
+void NT_FreeCharArray(char* v_char);
+
+/**
+ * Frees an array of doubles.
+ *
+ * @param v_boolean  pointer to the double array to free
+ */
+void NT_FreeDoubleArray(double* v_double);
+
+/**
+ * Frees an array of booleans.
+ *
+ * @param v_boolean  pointer to the boolean array to free
+ */
+void NT_FreeBooleanArray(NT_Bool* v_boolean);
+
+/**
+ * Frees an array of NT_Strings.
+ *
+ * @param v_string  pointer to the string array to free
+ * @param arr_size  size of the string array to free
+ *
+ * Note that the individual NT_Strings in the array should NOT be
+ * freed before calling this. This function will free all the strings
+ * individually.
+ */
+void NT_FreeStringArray(struct NT_String* v_string, size_t arr_size);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_typedgetters_cfunc Typed Getters
+ * @{
+ */
+
+/**
+ * Returns the type of an NT_Value struct.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param value  The NT_Value struct to get the type from.
+ * @return       The type of the value, or unassigned if null.
+ */
+enum NT_Type NT_GetValueType(const struct NT_Value* value);
+
+/**
+ * Returns the boolean from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns 0.
+ *
+ * @param value       NT_Value struct to get the boolean from
+ * @param last_change returns time in ms since the last change in the value
+ * @param v_boolean   returns the boolean assigned to the name
+ * @return            1 if successful, or 0 if value is null or not a boolean
+ */
+NT_Bool NT_GetValueBoolean(const struct NT_Value* value, uint64_t* last_change,
+                           NT_Bool* v_boolean);
+
+/**
+ * Returns the double from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns 0.
+ *
+ * @param value       NT_Value struct to get the double from
+ * @param last_change returns time in ms since the last change in the value
+ * @param v_double    returns the boolean assigned to the name
+ * @return            1 if successful, or 0 if value is null or not a double
+ */
+NT_Bool NT_GetValueDouble(const struct NT_Value* value, uint64_t* last_change,
+                          double* v_double);
+
+/**
+ * Returns a copy of the string from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns 0.
+ *
+ * @param value       NT_Value struct to get the string from
+ * @param last_change returns time in ms since the last change in the value
+ * @param str_len     returns the length of the string
+ * @return            pointer to the string (UTF-8), or null if error
+ *
+ * It is the caller's responsibility to free the string once its no longer
+ * needed. The NT_FreeCharArray() function is useful for this purpose. The
+ * returned string is a copy of the string in the value, and must be freed
+ * separately.
+ */
+char* NT_GetValueString(const struct NT_Value* value, uint64_t* last_change,
+                        size_t* str_len);
+
+/**
+ * Returns a copy of the raw value from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns null.
+ *
+ * @param value       NT_Value struct to get the string from
+ * @param last_change returns time in ms since the last change in the value
+ * @param raw_len     returns the length of the string
+ * @return            pointer to the raw value (UTF-8), or null if error
+ *
+ * It is the caller's responsibility to free the raw value once its no longer
+ * needed. The NT_FreeCharArray() function is useful for this purpose. The
+ * returned string is a copy of the string in the value, and must be freed
+ * separately.
+ */
+char* NT_GetValueRaw(const struct NT_Value* value, uint64_t* last_change,
+                     size_t* raw_len);
+
+/**
+ * Returns a copy of the boolean array from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns null.
+ *
+ * @param value       NT_Value struct to get the boolean array from
+ * @param last_change returns time in ms since the last change in the value
+ * @param arr_size    returns the number of elements in the array
+ * @return            pointer to the boolean array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeBooleanArray() function is useful for this purpose.
+ * The returned array is a copy of the array in the value, and must be
+ * freed separately.
+ */
+NT_Bool* NT_GetValueBooleanArray(const struct NT_Value* value,
+                                 uint64_t* last_change, size_t* arr_size);
+
+/**
+ * Returns a copy of the double array from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns null.
+ *
+ * @param value       NT_Value struct to get the double array from
+ * @param last_change returns time in ms since the last change in the value
+ * @param arr_size    returns the number of elements in the array
+ * @return            pointer to the double array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeDoubleArray() function is useful for this purpose.
+ * The returned array is a copy of the array in the value, and must be
+ * freed separately.
+ */
+double* NT_GetValueDoubleArray(const struct NT_Value* value,
+                               uint64_t* last_change, size_t* arr_size);
+
+/**
+ * Returns a copy of the NT_String array from the NT_Value.
+ * If the NT_Value is null, or is assigned to a different type, returns null.
+ *
+ * @param value       NT_Value struct to get the NT_String array from
+ * @param last_change returns time in ms since the last change in the value
+ * @param arr_size    returns the number of elements in the array
+ * @return            pointer to the NT_String array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeStringArray() function is useful for this purpose.
+ * The returned array is a copy of the array in the value, and must be
+ * freed seperately. Note that the individual NT_Strings should not be freed,
+ * but the entire array should be freed at once. The NT_FreeStringArray()
+ * function will free all the NT_Strings.
+ */
+struct NT_String* NT_GetValueStringArray(const struct NT_Value* value,
+                                         uint64_t* last_change,
+                                         size_t* arr_size);
+
+/**
+ * Returns the boolean currently assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns 0.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param v_boolean   returns the boolean assigned to the name
+ * @return            1 if successful, or 0 if value is unassigned or not a
+ *                    boolean
+ */
+NT_Bool NT_GetEntryBoolean(NT_Entry entry, uint64_t* last_change,
+                           NT_Bool* v_boolean);
+
+/**
+ * Returns the double currently assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns 0.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param v_double    returns the double assigned to the name
+ * @return            1 if successful, or 0 if value is unassigned or not a
+ *                    double
+ */
+NT_Bool NT_GetEntryDouble(NT_Entry entry, uint64_t* last_change,
+                          double* v_double);
+
+/**
+ * Returns a copy of the string assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns null.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param str_len     returns the length of the string
+ * @return            pointer to the string (UTF-8), or null if error
+ *
+ * It is the caller's responsibility to free the string once its no longer
+ * needed. The NT_FreeCharArray() function is useful for this purpose.
+ */
+char* NT_GetEntryString(NT_Entry entry, uint64_t* last_change, size_t* str_len);
+
+/**
+ * Returns a copy of the raw value assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns null.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param raw_len     returns the length of the string
+ * @return            pointer to the raw value (UTF-8), or null if error
+ *
+ * It is the caller's responsibility to free the raw value once its no longer
+ * needed. The NT_FreeCharArray() function is useful for this purpose.
+ */
+char* NT_GetEntryRaw(NT_Entry entry, uint64_t* last_change, size_t* raw_len);
+
+/**
+ * Returns a copy of the boolean array assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns null.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param arr_size    returns the number of elements in the array
+ * @return            pointer to the boolean array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeBooleanArray() function is useful for this purpose.
+ */
+NT_Bool* NT_GetEntryBooleanArray(NT_Entry entry, uint64_t* last_change,
+                                 size_t* arr_size);
+
+/**
+ * Returns a copy of the double array assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns null.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param arr_size    returns the number of elements in the array
+ * @return            pointer to the double array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeDoubleArray() function is useful for this purpose.
+ */
+double* NT_GetEntryDoubleArray(NT_Entry entry, uint64_t* last_change,
+                               size_t* arr_size);
+
+/**
+ * Returns a copy of the NT_String array assigned to the entry name.
+ * If the entry name is not currently assigned, or is assigned to a
+ * different type, returns null.
+ *
+ * @param entry       entry handle
+ * @param last_change returns time in ms since the last change in the value
+ * @param arr_size    returns the number of elements in the array
+ * @return            pointer to the NT_String array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeStringArray() function is useful for this purpose. Note
+ * that the individual NT_Strings should not be freed, but the entire array
+ * should be freed at once. The NT_FreeStringArray() function will free all the
+ * NT_Strings.
+ */
+struct NT_String* NT_GetEntryStringArray(NT_Entry entry, uint64_t* last_change,
+                                         size_t* arr_size);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_setdefault_cfunc Set Default Values
+ * @{
+ */
+
+/** Set Default Entry Boolean.
+ * Sets the default for the specified key to be a boolean.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_boolean     value to be set if name does not exist
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryBoolean(NT_Entry entry, uint64_t time,
+                                  NT_Bool default_boolean);
+
+/** Set Default Entry Double.
+ * Sets the default for the specified key.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_double     value to be set if name does not exist
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryDouble(NT_Entry entry, uint64_t time,
+                                 double default_double);
+
+/** Set Default Entry String.
+ * Sets the default for the specified key.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_value     value to be set if name does not exist
+ * @param default_len       length of value
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryString(NT_Entry entry, uint64_t time,
+                                 const char* default_value, size_t default_len);
+
+/** Set Default Entry Raw.
+ * Sets the default for the specified key.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_value     value to be set if name does not exist
+ * @param default_len       length of value array
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryRaw(NT_Entry entry, uint64_t time,
+                              const char* default_value, size_t default_len);
+
+/** Set Default Entry Boolean Array.
+ * Sets the default for the specified key.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_value     value to be set if name does not exist
+ * @param default_size      size of value array
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryBooleanArray(NT_Entry entry, uint64_t time,
+                                       const int* default_value,
+                                       size_t default_size);
+
+/** Set Default Entry Double Array.
+ * Sets the default for the specified key.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_value     value to be set if name does not exist
+ * @param default_size      size of value array
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryDoubleArray(NT_Entry entry, uint64_t time,
+                                      const double* default_value,
+                                      size_t default_size);
+
+/** Set Default Entry String Array.
+ * Sets the default for the specified key.
+ * If key exists with same type, does not set value. Otherwise
+ * sets value to the default.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param default_value     value to be set if name does not exist
+ * @param default_size      size of value array
+ * @return 0 on error (value not set), 1 on success
+ */
+NT_Bool NT_SetDefaultEntryStringArray(NT_Entry entry, uint64_t time,
+                                      const struct NT_String* default_value,
+                                      size_t default_size);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_valuesetters_cfunc Entry Value Setters
+ * @{
+ */
+
+/** Set Entry Boolean
+ * Sets an entry boolean. If the entry name is not currently assigned to a
+ * boolean, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param v_boolean boolean value to set
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryBoolean(NT_Entry entry, uint64_t time, NT_Bool v_boolean,
+                           NT_Bool force);
+
+/** Set Entry Double
+ * Sets an entry double. If the entry name is not currently assigned to a
+ * double, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param v_double  double value to set
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryDouble(NT_Entry entry, uint64_t time, double v_double,
+                          NT_Bool force);
+
+/** Set Entry String
+ * Sets an entry string. If the entry name is not currently assigned to a
+ * string, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param str       string to set (UTF-8 string)
+ * @param str_len   length of string to write in bytes
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryString(NT_Entry entry, uint64_t time, const char* str,
+                          size_t str_len, NT_Bool force);
+
+/** Set Entry Raw
+ * Sets the raw value of an entry. If the entry name is not currently assigned
+ * to a raw value, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param raw       raw string to set (UTF-8 string)
+ * @param raw_len   length of raw string to write in bytes
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryRaw(NT_Entry entry, uint64_t time, const char* raw,
+                       size_t raw_len, NT_Bool force);
+
+/** Set Entry Boolean Array
+ * Sets an entry boolean array. If the entry name is not currently assigned to
+ * a boolean array, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param arr       boolean array to write
+ * @param size      number of elements in the array
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryBooleanArray(NT_Entry entry, uint64_t time, const int* arr,
+                                size_t size, NT_Bool force);
+
+/** Set Entry Double Array
+ * Sets an entry double array. If the entry name is not currently assigned to
+ * a double array, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param arr       double array to write
+ * @param size      number of elements in the array
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryDoubleArray(NT_Entry entry, uint64_t time, const double* arr,
+                               size_t size, NT_Bool force);
+
+/** Set Entry String Array
+ * Sets an entry string array. If the entry name is not currently assigned to
+ * a string array, returns error unless the force parameter is set.
+ *
+ * @param entry     entry handle
+ * @param time      timestamp
+ * @param arr       NT_String array to write
+ * @param size      number of elements in the array
+ * @param force     1 to force the entry to get overwritten, otherwise 0
+ * @return          0 on error (type mismatch), 1 on success
+ */
+NT_Bool NT_SetEntryStringArray(NT_Entry entry, uint64_t time,
+                               const struct NT_String* arr, size_t size,
+                               NT_Bool force);
+
+/** @} */
+/** @} */
+/** @} */
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // NTCORE_NTCORE_C_H_
diff --git a/ntcore/src/main/native/include/ntcore_cpp.h b/ntcore/src/main/native/include/ntcore_cpp.h
new file mode 100644
index 0000000..af1ea12
--- /dev/null
+++ b/ntcore/src/main/native/include/ntcore_cpp.h
@@ -0,0 +1,1613 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NTCORE_CPP_H_
+#define NTCORE_NTCORE_CPP_H_
+
+#include <stdint.h>
+
+#include <cassert>
+#include <functional>
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
+
+#include <wpi/ArrayRef.h>
+#include <wpi/StringRef.h>
+#include <wpi/Twine.h>
+#include <wpi/deprecated.h>
+
+#include "networktables/NetworkTableValue.h"
+
+/** NetworkTables (ntcore) namespace */
+namespace nt {
+
+/**
+ * @defgroup ntcore_cpp_handle_api ntcore C++ API
+ *
+ * Handle-based interface for C++.
+ *
+ * @{
+ */
+
+using wpi::ArrayRef;
+using wpi::StringRef;
+using wpi::Twine;
+
+/** NetworkTables Entry Information */
+struct EntryInfo {
+  /** Entry handle */
+  NT_Entry entry;
+
+  /** Entry name */
+  std::string name;
+
+  /** Entry type */
+  NT_Type type;
+
+  /** Entry flags */
+  unsigned int flags;
+
+  /** Timestamp of last change to entry (type or value). */
+  uint64_t last_change;
+
+  friend void swap(EntryInfo& first, EntryInfo& second) {
+    using std::swap;
+    swap(first.entry, second.entry);
+    swap(first.name, second.name);
+    swap(first.type, second.type);
+    swap(first.flags, second.flags);
+    swap(first.last_change, second.last_change);
+  }
+};
+
+/** NetworkTables Connection Information */
+struct ConnectionInfo {
+  /**
+   * The remote identifier (as set on the remote node by
+   * NetworkTableInstance::SetNetworkIdentity() or nt::SetNetworkIdentity()).
+   */
+  std::string remote_id;
+
+  /** The IP address of the remote node. */
+  std::string remote_ip;
+
+  /** The port number of the remote node. */
+  unsigned int remote_port{0};
+
+  /**
+   * The last time any update was received from the remote node (same scale as
+   * returned by nt::Now()).
+   */
+  uint64_t last_update{0};
+
+  /**
+   * The protocol version being used for this connection.  This in protocol
+   * layer format, so 0x0200 = 2.0, 0x0300 = 3.0).
+   */
+  unsigned int protocol_version{0};
+
+  friend void swap(ConnectionInfo& first, ConnectionInfo& second) {
+    using std::swap;
+    swap(first.remote_id, second.remote_id);
+    swap(first.remote_ip, second.remote_ip);
+    swap(first.remote_port, second.remote_port);
+    swap(first.last_update, second.last_update);
+    swap(first.protocol_version, second.protocol_version);
+  }
+};
+
+/** NetworkTables RPC Version 1 Definition Parameter */
+struct RpcParamDef {
+  RpcParamDef() = default;
+  RpcParamDef(StringRef name_, std::shared_ptr<Value> def_value_)
+      : name(name_), def_value(def_value_) {}
+
+  std::string name;
+  std::shared_ptr<Value> def_value;
+};
+
+/** NetworkTables RPC Version 1 Definition Result */
+struct RpcResultDef {
+  RpcResultDef() = default;
+  RpcResultDef(StringRef name_, NT_Type type_) : name(name_), type(type_) {}
+
+  std::string name;
+  NT_Type type;
+};
+
+/** NetworkTables RPC Version 1 Definition */
+struct RpcDefinition {
+  unsigned int version;
+  std::string name;
+  std::vector<RpcParamDef> params;
+  std::vector<RpcResultDef> results;
+};
+
+/** NetworkTables Remote Procedure Call (Server Side) */
+class RpcAnswer {
+ public:
+  RpcAnswer() : entry(0), call(0) {}
+  RpcAnswer(NT_Entry entry_, NT_RpcCall call_, StringRef name_,
+            StringRef params_, const ConnectionInfo& conn_)
+      : entry(entry_), call(call_), name(name_), params(params_), conn(conn_) {}
+
+  /** Entry handle. */
+  NT_Entry entry;
+
+  /** Call handle. */
+  mutable NT_RpcCall call;
+
+  /** Entry name. */
+  std::string name;
+
+  /** Call raw parameters. */
+  std::string params;
+
+  /** Connection that called the RPC. */
+  ConnectionInfo conn;
+
+  /**
+   * Determines if the native handle is valid.
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return call != 0; }
+
+  /**
+   * Post RPC response (return value) for a polled RPC.
+   * @param result  result raw data that will be provided to remote caller
+   * @return True if posting the response is valid, otherwise false
+   */
+  bool PostResponse(StringRef result) const;
+
+  friend void swap(RpcAnswer& first, RpcAnswer& second) {
+    using std::swap;
+    swap(first.entry, second.entry);
+    swap(first.call, second.call);
+    swap(first.name, second.name);
+    swap(first.params, second.params);
+    swap(first.conn, second.conn);
+  }
+};
+
+/** NetworkTables Entry Notification */
+class EntryNotification {
+ public:
+  EntryNotification() : listener(0), entry(0), flags(0) {}
+  EntryNotification(NT_EntryListener listener_, NT_Entry entry_,
+                    StringRef name_, std::shared_ptr<Value> value_,
+                    unsigned int flags_)
+      : listener(listener_),
+        entry(entry_),
+        name(name_),
+        value(value_),
+        flags(flags_) {}
+
+  /** Listener that was triggered. */
+  NT_EntryListener listener;
+
+  /** Entry handle. */
+  NT_Entry entry;
+
+  /** Entry name. */
+  std::string name;
+
+  /** The new value. */
+  std::shared_ptr<Value> value;
+
+  /**
+   * Update flags.  For example, NT_NOTIFY_NEW if the key did not previously
+   * exist.
+   */
+  unsigned int flags;
+
+  friend void swap(EntryNotification& first, EntryNotification& second) {
+    using std::swap;
+    swap(first.listener, second.listener);
+    swap(first.entry, second.entry);
+    swap(first.name, second.name);
+    swap(first.value, second.value);
+    swap(first.flags, second.flags);
+  }
+};
+
+/** NetworkTables Connection Notification */
+class ConnectionNotification {
+ public:
+  ConnectionNotification() : listener(0), connected(false) {}
+  ConnectionNotification(NT_ConnectionListener listener_, bool connected_,
+                         const ConnectionInfo& conn_)
+      : listener(listener_), connected(connected_), conn(conn_) {}
+
+  /** Listener that was triggered. */
+  NT_ConnectionListener listener;
+
+  /** True if event is due to connection being established. */
+  bool connected = false;
+
+  /** Connection info. */
+  ConnectionInfo conn;
+
+  friend void swap(ConnectionNotification& first,
+                   ConnectionNotification& second) {
+    using std::swap;
+    swap(first.listener, second.listener);
+    swap(first.connected, second.connected);
+    swap(first.conn, second.conn);
+  }
+};
+
+/** NetworkTables log message. */
+class LogMessage {
+ public:
+  LogMessage() : logger(0), level(0), filename(""), line(0) {}
+  LogMessage(NT_Logger logger_, unsigned int level_, const char* filename_,
+             unsigned int line_, StringRef message_)
+      : logger(logger_),
+        level(level_),
+        filename(filename_),
+        line(line_),
+        message(message_) {}
+
+  /** The logger that generated the message. */
+  NT_Logger logger;
+
+  /** Log level of the message.  See NT_LogLevel. */
+  unsigned int level;
+
+  /** The filename of the source file that generated the message. */
+  const char* filename;
+
+  /** The line number in the source file that generated the message. */
+  unsigned int line;
+
+  /** The message. */
+  std::string message;
+
+  friend void swap(LogMessage& first, LogMessage& second) {
+    using std::swap;
+    swap(first.logger, second.logger);
+    swap(first.level, second.level);
+    swap(first.filename, second.filename);
+    swap(first.line, second.line);
+    swap(first.message, second.message);
+  }
+};
+
+/**
+ * @defgroup ntcore_instance_func Instance Functions
+ * @{
+ */
+
+/**
+ * Get default instance.
+ * This is the instance used by non-handle-taking functions.
+ *
+ * @return Instance handle
+ */
+NT_Inst GetDefaultInstance();
+
+/**
+ * Create an instance.
+ *
+ * @return Instance handle
+ */
+NT_Inst CreateInstance();
+
+/**
+ * Destroy an instance.
+ * The default instance cannot be destroyed.
+ *
+ * @param inst Instance handle
+ */
+void DestroyInstance(NT_Inst inst);
+
+/**
+ * Get instance handle from another handle.
+ *
+ * @param handle    entry/instance/etc. handle
+ * @return Instance handle
+ */
+NT_Inst GetInstanceFromHandle(NT_Handle handle);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_table_func Table Functions
+ * @{
+ */
+
+/**
+ * Get Entry Handle.
+ *
+ * @param inst      instance handle
+ * @param name      entry name (UTF-8 string)
+ * @return entry handle
+ */
+NT_Entry GetEntry(NT_Inst inst, const Twine& name);
+
+/**
+ * Get Entry Handles.
+ *
+ * Returns an array of entry handles.  The results are optionally
+ * filtered by string prefix and entry type to only return a subset of all
+ * entries.
+ *
+ * @param inst          instance handle
+ * @param prefix        entry name required prefix; only entries whose name
+ *                      starts with this string are returned
+ * @param types         bitmask of NT_Type values; 0 is treated specially
+ *                      as a "don't care"
+ * @return Array of entry handles.
+ */
+std::vector<NT_Entry> GetEntries(NT_Inst inst, const Twine& prefix,
+                                 unsigned int types);
+
+/**
+ * Gets the name of the specified entry.
+ * Returns an empty string if the handle is invalid.
+ *
+ * @param entry   entry handle
+ * @return Entry name
+ */
+std::string GetEntryName(NT_Entry entry);
+
+/**
+ * Gets the type for the specified entry, or unassigned if non existent.
+ *
+ * @param entry   entry handle
+ * @return Entry type
+ */
+NT_Type GetEntryType(NT_Entry entry);
+
+/**
+ * Gets the last time the entry was changed.
+ * Returns 0 if the handle is invalid.
+ *
+ * @param entry   entry handle
+ * @return Entry last change time
+ */
+uint64_t GetEntryLastChange(NT_Entry entry);
+
+/**
+ * Get Entry Value.
+ *
+ * Returns copy of current entry value.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param name      entry name (UTF-8 string)
+ * @return entry value
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+std::shared_ptr<Value> GetEntryValue(StringRef name);
+
+/**
+ * Get Entry Value.
+ *
+ * Returns copy of current entry value.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param entry     entry handle
+ * @return entry value
+ */
+std::shared_ptr<Value> GetEntryValue(NT_Entry entry);
+
+/**
+ * Set Default Entry Value
+ *
+ * Returns copy of current entry value if it exists.
+ * Otherwise, sets passed in value, and returns set value.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param name      entry name (UTF-8 string)
+ * @param value     value to be set if name does not exist
+ * @return False on error (value not set), True on success
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+bool SetDefaultEntryValue(StringRef name, std::shared_ptr<Value> value);
+
+/**
+ * Set Default Entry Value
+ *
+ * Returns copy of current entry value if it exists.
+ * Otherwise, sets passed in value, and returns set value.
+ * Note that one of the type options is "unassigned".
+ *
+ * @param entry     entry handle
+ * @param value     value to be set if name does not exist
+ * @return False on error (value not set), True on success
+ */
+bool SetDefaultEntryValue(NT_Entry entry, std::shared_ptr<Value> value);
+
+/**
+ * Set Entry Value.
+ *
+ * Sets new entry value.  If type of new value differs from the type of the
+ * currently stored entry, returns error and does not update value.
+ *
+ * @param name      entry name (UTF-8 string)
+ * @param value     new entry value
+ * @return False on error (type mismatch), True on success
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+bool SetEntryValue(StringRef name, std::shared_ptr<Value> value);
+
+/**
+ * Set Entry Value.
+ *
+ * Sets new entry value.  If type of new value differs from the type of the
+ * currently stored entry, returns error and does not update value.
+ *
+ * @param entry     entry handle
+ * @param value     new entry value
+ * @return False on error (type mismatch), True on success
+ */
+bool SetEntryValue(NT_Entry entry, std::shared_ptr<Value> value);
+
+/**
+ * Set Entry Type and Value.
+ *
+ * Sets new entry value.  If type of new value differs from the type of the
+ * currently stored entry, the currently stored entry type is overridden
+ * (generally this will generate an Entry Assignment message).
+ *
+ * This is NOT the preferred method to update a value; generally
+ * SetEntryValue() should be used instead, with appropriate error handling.
+ *
+ * @param name      entry name (UTF-8 string)
+ * @param value     new entry value
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+void SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value);
+
+/**
+ * Set Entry Type and Value.
+ *
+ * Sets new entry value.  If type of new value differs from the type of the
+ * currently stored entry, the currently stored entry type is overridden
+ * (generally this will generate an Entry Assignment message).
+ *
+ * This is NOT the preferred method to update a value; generally
+ * SetEntryValue() should be used instead, with appropriate error handling.
+ *
+ * @param entry     entry handle
+ * @param value     new entry value
+ */
+void SetEntryTypeValue(NT_Entry entry, std::shared_ptr<Value> value);
+
+/**
+ * Set Entry Flags.
+ *
+ * @param name      entry name (UTF-8 string)
+ * @param flags     flags value (bitmask of NT_EntryFlags)
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+void SetEntryFlags(StringRef name, unsigned int flags);
+
+/**
+ * Set Entry Flags.
+ *
+ * @param entry     entry handle
+ * @param flags     flags value (bitmask of NT_EntryFlags)
+ */
+void SetEntryFlags(NT_Entry entry, unsigned int flags);
+
+/**
+ * Get Entry Flags.
+ *
+ * @param name      entry name (UTF-8 string)
+ * @return Flags value (bitmask of NT_EntryFlags)
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+unsigned int GetEntryFlags(StringRef name);
+
+/**
+ * Get Entry Flags.
+ *
+ * @param entry     entry handle
+ * @return Flags value (bitmask of NT_EntryFlags)
+ */
+unsigned int GetEntryFlags(NT_Entry entry);
+
+/**
+ * Delete Entry.
+ *
+ * Deletes an entry.  This is a new feature in version 3.0 of the protocol,
+ * so this may not have an effect if any other node in the network is not
+ * version 3.0 or newer.
+ *
+ * Note: GetConnections() can be used to determine the protocol version
+ * of direct remote connection(s), but this is not sufficient to determine
+ * if all nodes in the network are version 3.0 or newer.
+ *
+ * @param name      entry name (UTF-8 string)
+ */
+WPI_DEPRECATED("use NT_Entry function instead")
+void DeleteEntry(StringRef name);
+
+/**
+ * Delete Entry.
+ *
+ * Deletes an entry.  This is a new feature in version 3.0 of the protocol,
+ * so this may not have an effect if any other node in the network is not
+ * version 3.0 or newer.
+ *
+ * Note: GetConnections() can be used to determine the protocol version
+ * of direct remote connection(s), but this is not sufficient to determine
+ * if all nodes in the network are version 3.0 or newer.
+ *
+ * @param entry     entry handle
+ */
+void DeleteEntry(NT_Entry entry);
+
+/**
+ * Delete All Entries.
+ *
+ * Deletes ALL table entries.  This is a new feature in version 3.0 of the
+ * so this may not have an effect if any other node in the network is not
+ * version 3.0 or newer.
+ *
+ * Note: GetConnections() can be used to determine the protocol version
+ * of direct remote connection(s), but this is not sufficient to determine
+ * if all nodes in the network are version 3.0 or newer.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void DeleteAllEntries();
+
+/**
+ * @copydoc DeleteAllEntries()
+ *
+ * @param inst      instance handle
+ */
+void DeleteAllEntries(NT_Inst inst);
+
+/**
+ * Get Entry Information.
+ *
+ * Returns an array of entry information (name, entry type,
+ * and timestamp of last change to type/value).  The results are optionally
+ * filtered by string prefix and entry type to only return a subset of all
+ * entries.
+ *
+ * @param prefix        entry name required prefix; only entries whose name
+ *                      starts with this string are returned
+ * @param types         bitmask of NT_Type values; 0 is treated specially
+ *                      as a "don't care"
+ * @return Array of entry information.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+std::vector<EntryInfo> GetEntryInfo(StringRef prefix, unsigned int types);
+
+/**
+ * @copydoc GetEntryInfo(StringRef, unsigned int)
+ *
+ * @param inst    instance handle
+ */
+std::vector<EntryInfo> GetEntryInfo(NT_Inst inst, const Twine& prefix,
+                                    unsigned int types);
+
+/**
+ * Get Entry Information.
+ *
+ * Returns information about an entry (name, entry type,
+ * and timestamp of last change to type/value).
+ *
+ * @param entry         entry handle
+ * @return Entry information.
+ */
+EntryInfo GetEntryInfo(NT_Entry entry);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_entrylistener_func Entry Listener Functions
+ * @{
+ */
+
+/**
+ * Entry listener callback function.
+ * Called when a key-value pair is changed.
+ *
+ * @param entry_listener  entry listener handle returned by callback creation
+ *                        function
+ * @param name            entry name
+ * @param value           the new value
+ * @param flags           update flags; for example, NT_NOTIFY_NEW if the key
+ *                        did not previously exist
+ */
+typedef std::function<void(NT_EntryListener entry_listener, StringRef name,
+                           std::shared_ptr<Value> value, unsigned int flags)>
+    EntryListenerCallback;
+
+/**
+ * Add a listener for all entries starting with a certain prefix.
+ *
+ * @param prefix            UTF-8 string prefix
+ * @param callback          listener to add
+ * @param flags             NotifyKind bitmask
+ * @return Listener handle
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+NT_EntryListener AddEntryListener(StringRef prefix,
+                                  EntryListenerCallback callback,
+                                  unsigned int flags);
+
+/**
+ * @copydoc AddEntryListener(StringRef, EntryListenerCallback, unsigned int)
+ *
+ * @param inst              instance handle
+ */
+NT_EntryListener AddEntryListener(
+    NT_Inst inst, const Twine& prefix,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags);
+
+/**
+ * Add a listener for a single entry.
+ *
+ * @param entry             entry handle
+ * @param callback          listener to add
+ * @param flags             NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener AddEntryListener(
+    NT_Entry entry,
+    std::function<void(const EntryNotification& event)> callback,
+    unsigned int flags);
+
+/**
+ * Create a entry listener poller.
+ *
+ * A poller provides a single queue of poll events.  Events linked to this
+ * poller (using AddPolledEntryListener()) will be stored in the queue and
+ * must be collected by calling PollEntryListener().
+ * The returned handle must be destroyed with DestroyEntryListenerPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_EntryListenerPoller CreateEntryListenerPoller(NT_Inst inst);
+
+/**
+ * Destroy a entry listener poller.  This will abort any blocked polling
+ * call and prevent additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void DestroyEntryListenerPoller(NT_EntryListenerPoller poller);
+
+/**
+ * Create a polled entry listener.
+ * The caller is responsible for calling PollEntryListener() to poll.
+ *
+ * @param poller            poller handle
+ * @param prefix            UTF-8 string prefix
+ * @param flags             NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener AddPolledEntryListener(NT_EntryListenerPoller poller,
+                                        const Twine& prefix,
+                                        unsigned int flags);
+
+/**
+ * Create a polled entry listener.
+ * The caller is responsible for calling PollEntryListener() to poll.
+ *
+ * @param poller            poller handle
+ * @param prefix            UTF-8 string prefix
+ * @param flags             NotifyKind bitmask
+ * @return Listener handle
+ */
+NT_EntryListener AddPolledEntryListener(NT_EntryListenerPoller poller,
+                                        NT_Entry entry, unsigned int flags);
+
+/**
+ * Get the next entry listener event.  This blocks until the next event occurs.
+ * This is intended to be used with AddPolledEntryListener(); entry listeners
+ * created using AddEntryListener() will not be serviced through this function.
+ *
+ * @param poller    poller handle
+ * @return Information on the entry listener events.  Only returns empty if an
+ *         error occurred (e.g. the instance was invalid or is shutting down).
+ */
+std::vector<EntryNotification> PollEntryListener(NT_EntryListenerPoller poller);
+
+/**
+ * Get the next entry listener event.  This blocks until the next event occurs
+ * or it times out.  This is intended to be used with AddPolledEntryListener();
+ * entry listeners created using AddEntryListener() will not be serviced
+ * through this function.
+ *
+ * @param poller      poller handle
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Information on the entry listener events.  If empty is returned and
+ *         and timed_out is also false, an error occurred (e.g. the instance
+ *         was invalid or is shutting down).
+ */
+std::vector<EntryNotification> PollEntryListener(NT_EntryListenerPoller poller,
+                                                 double timeout,
+                                                 bool* timed_out);
+
+/**
+ * Cancel a PollEntryListener call.  This wakes up a call to
+ * PollEntryListener for this poller and causes it to immediately return
+ * an empty array.
+ *
+ * @param poller  poller handle
+ */
+void CancelPollEntryListener(NT_EntryListenerPoller poller);
+
+/**
+ * Remove an entry listener.
+ *
+ * @param entry_listener Listener handle to remove
+ */
+void RemoveEntryListener(NT_EntryListener entry_listener);
+
+/**
+ * Wait for the entry listener queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the entry listener
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+bool WaitForEntryListenerQueue(NT_Inst inst, double timeout);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_connectionlistener_func Connection Listener Functions
+ * @{
+ */
+
+/**
+ * Connection listener callback function.
+ * Called when a network connection is made or lost.
+ *
+ * @param conn_listener   connection listener handle returned by callback
+ *                        creation function
+ * @param connected       true if event is due to connection being established
+ * @param conn            connection info
+ */
+typedef std::function<void(NT_ConnectionListener conn_listener, bool connected,
+                           const ConnectionInfo& conn)>
+    ConnectionListenerCallback;
+
+/**
+ * Add a connection listener.
+ *
+ * @param callback          listener to add
+ * @param immediate_notify  notify listener of all existing connections
+ * @return Listener handle
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+NT_ConnectionListener AddConnectionListener(ConnectionListenerCallback callback,
+                                            bool immediate_notify);
+
+/**
+ * @copydoc AddConnectionListener(ConnectionListenerCallback, bool)
+ *
+ * @param inst              instance handle
+ */
+NT_ConnectionListener AddConnectionListener(
+    NT_Inst inst,
+    std::function<void(const ConnectionNotification& event)> callback,
+    bool immediate_notify);
+
+/**
+ * Create a connection listener poller.
+ *
+ * A poller provides a single queue of poll events.  Events linked to this
+ * poller (using AddPolledConnectionListener()) will be stored in the queue and
+ * must be collected by calling PollConnectionListener().
+ * The returned handle must be destroyed with DestroyConnectionListenerPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_ConnectionListenerPoller CreateConnectionListenerPoller(NT_Inst inst);
+
+/**
+ * Destroy a connection listener poller.  This will abort any blocked polling
+ * call and prevent additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void DestroyConnectionListenerPoller(NT_ConnectionListenerPoller poller);
+
+/**
+ * Create a polled connection listener.
+ * The caller is responsible for calling PollConnectionListener() to poll.
+ *
+ * @param poller            poller handle
+ * @param immediate_notify  notify listener of all existing connections
+ */
+NT_ConnectionListener AddPolledConnectionListener(
+    NT_ConnectionListenerPoller poller, bool immediate_notify);
+
+/**
+ * Get the next connection event.  This blocks until the next connect or
+ * disconnect occurs.  This is intended to be used with
+ * AddPolledConnectionListener(); connection listeners created using
+ * AddConnectionListener() will not be serviced through this function.
+ *
+ * @param poller    poller handle
+ * @return Information on the connection events.  Only returns empty if an
+ *         error occurred (e.g. the instance was invalid or is shutting down).
+ */
+std::vector<ConnectionNotification> PollConnectionListener(
+    NT_ConnectionListenerPoller poller);
+
+/**
+ * Get the next connection event.  This blocks until the next connect or
+ * disconnect occurs or it times out.  This is intended to be used with
+ * AddPolledConnectionListener(); connection listeners created using
+ * AddConnectionListener() will not be serviced through this function.
+ *
+ * @param poller      poller handle
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Information on the connection events.  If empty is returned and
+ *         timed_out is also false, an error occurred (e.g. the instance was
+ *         invalid or is shutting down).
+ */
+std::vector<ConnectionNotification> PollConnectionListener(
+    NT_ConnectionListenerPoller poller, double timeout, bool* timed_out);
+
+/**
+ * Cancel a PollConnectionListener call.  This wakes up a call to
+ * PollConnectionListener for this poller and causes it to immediately return
+ * an empty array.
+ *
+ * @param poller  poller handle
+ */
+void CancelPollConnectionListener(NT_ConnectionListenerPoller poller);
+
+/**
+ * Remove a connection listener.
+ *
+ * @param conn_listener Listener handle to remove
+ */
+void RemoveConnectionListener(NT_ConnectionListener conn_listener);
+
+/**
+ * Wait for the connection listener queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the connection listener
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+bool WaitForConnectionListenerQueue(NT_Inst inst, double timeout);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_rpc_func Remote Procedure Call Functions
+ * @{
+ */
+
+/**
+ * Create a callback-based RPC entry point.  Only valid to use on the server.
+ * The callback function will be called when the RPC is called.
+ *
+ * @param entry     entry handle of RPC entry
+ * @param def       RPC definition
+ * @param callback  callback function; note the callback function must call
+ *                  PostRpcResponse() to provide a response to the call
+ */
+void CreateRpc(NT_Entry entry, StringRef def,
+               std::function<void(const RpcAnswer& answer)> callback);
+
+/**
+ * Create a RPC call poller.  Only valid to use on the server.
+ *
+ * A poller provides a single queue of poll events.  Events linked to this
+ * poller (using CreatePolledRpc()) will be stored in the queue and must be
+ * collected by calling PollRpc().
+ * The returned handle must be destroyed with DestroyRpcCallPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_RpcCallPoller CreateRpcCallPoller(NT_Inst inst);
+
+/**
+ * Destroy a RPC call poller.  This will abort any blocked polling call and
+ * prevent additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void DestroyRpcCallPoller(NT_RpcCallPoller poller);
+
+/**
+ * Create a polled RPC entry point.  Only valid to use on the server.
+ * The caller is responsible for calling PollRpc() to poll for servicing
+ * incoming RPC calls.
+ *
+ * @param entry     entry handle of RPC entry
+ * @param def       RPC definition
+ * @param poller    poller handle
+ */
+void CreatePolledRpc(NT_Entry entry, StringRef def, NT_RpcCallPoller poller);
+
+/**
+ * Get the next incoming RPC call.  This blocks until the next incoming RPC
+ * call is received.  This is intended to be used with CreatePolledRpc();
+ * RPC calls created using CreateRpc() will not be serviced through this
+ * function.  Upon successful return, PostRpcResponse() must be called to
+ * send the return value to the caller.
+ *
+ * @param poller      poller handle
+ * @return Information on the next RPC calls.  Only returns empty if an error
+ *         occurred (e.g. the instance was invalid or is shutting down).
+ */
+std::vector<RpcAnswer> PollRpc(NT_RpcCallPoller poller);
+
+/**
+ * Get the next incoming RPC call.  This blocks until the next incoming RPC
+ * call is received or it times out.  This is intended to be used with
+ * CreatePolledRpc(); RPC calls created using CreateRpc() will not be
+ * serviced through this function.  Upon successful return,
+ * PostRpcResponse() must be called to send the return value to the caller.
+ *
+ * @param poller      poller handle
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Information on the next RPC calls.  If empty and timed_out is also
+ *         false, an error occurred (e.g. the instance was invalid or is
+ *         shutting down).
+ */
+std::vector<RpcAnswer> PollRpc(NT_RpcCallPoller poller, double timeout,
+                               bool* timed_out);
+
+/**
+ * Cancel a PollRpc call.  This wakes up a call to PollRpc for this poller
+ * and causes it to immediately return an empty array.
+ *
+ * @param poller  poller handle
+ */
+void CancelPollRpc(NT_RpcCallPoller poller);
+
+/**
+ * Wait for the incoming RPC call queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the RPC call
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+bool WaitForRpcCallQueue(NT_Inst inst, double timeout);
+
+/**
+ * Post RPC response (return value) for a polled RPC.
+ * The rpc and call parameters should come from the RpcAnswer returned
+ * by PollRpc().
+ *
+ * @param entry       entry handle of RPC entry (from RpcAnswer)
+ * @param call        RPC call handle (from RpcAnswer)
+ * @param result      result raw data that will be provided to remote caller
+ * @return            true if the response was posted, otherwise false
+ */
+bool PostRpcResponse(NT_Entry entry, NT_RpcCall call, StringRef result);
+
+/**
+ * Call a RPC function.  May be used on either the client or server.
+ * This function is non-blocking.  Either GetRpcResult() or
+ * CancelRpcResult() must be called to either get or ignore the result of
+ * the call.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param params      parameter
+ * @return RPC call handle (for use with GetRpcResult() or
+ *         CancelRpcResult()).
+ */
+NT_RpcCall CallRpc(NT_Entry entry, StringRef params);
+
+/**
+ * Get the result (return value) of a RPC call.  This function blocks until
+ * the result is received.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param call        RPC call handle returned by CallRpc()
+ * @param result      received result (output)
+ * @return False on error, true otherwise.
+ */
+bool GetRpcResult(NT_Entry entry, NT_RpcCall call, std::string* result);
+
+/**
+ * Get the result (return value) of a RPC call.  This function blocks until
+ * the result is received or it times out.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param call        RPC call handle returned by CallRpc()
+ * @param result      received result (output)
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return False on error or timeout, true otherwise.
+ */
+bool GetRpcResult(NT_Entry entry, NT_RpcCall call, std::string* result,
+                  double timeout, bool* timed_out);
+
+/**
+ * Ignore the result of a RPC call.  This function is non-blocking.
+ *
+ * @param entry       entry handle of RPC entry
+ * @param call        RPC call handle returned by CallRpc()
+ */
+void CancelRpcResult(NT_Entry entry, NT_RpcCall call);
+
+/**
+ * Pack a RPC version 1 definition.
+ *
+ * @param def         RPC version 1 definition
+ * @return Raw packed bytes.
+ */
+std::string PackRpcDefinition(const RpcDefinition& def);
+
+/**
+ * Unpack a RPC version 1 definition.  This can be used for introspection or
+ * validation.
+ *
+ * @param packed      raw packed bytes
+ * @param def         RPC version 1 definition (output)
+ * @return True if successfully unpacked, false otherwise.
+ */
+bool UnpackRpcDefinition(StringRef packed, RpcDefinition* def);
+
+/**
+ * Pack RPC values as required for RPC version 1 definition messages.
+ *
+ * @param values      array of values to pack
+ * @return Raw packed bytes.
+ */
+std::string PackRpcValues(ArrayRef<std::shared_ptr<Value>> values);
+
+/**
+ * Unpack RPC values as required for RPC version 1 definition messages.
+ *
+ * @param packed      raw packed bytes
+ * @param types       array of data types (as provided in the RPC definition)
+ * @return Array of values.
+ */
+std::vector<std::shared_ptr<Value>> UnpackRpcValues(StringRef packed,
+                                                    ArrayRef<NT_Type> types);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_network_func Client/Server Functions
+ * @{
+ */
+
+/**
+ * Set the network identity of this node.
+ * This is the name used during the initial connection handshake, and is
+ * visible through ConnectionInfo on the remote node.
+ *
+ * @param name      identity to advertise
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void SetNetworkIdentity(StringRef name);
+
+/**
+ * @copydoc SetNetworkIdentity(StringRef)
+ *
+ * @param inst      instance handle
+ */
+void SetNetworkIdentity(NT_Inst inst, const Twine& name);
+
+/**
+ * Get the current network mode.
+ *
+ * @return Bitmask of NT_NetworkMode.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+unsigned int GetNetworkMode();
+
+/**
+ * Get the current network mode.
+ *
+ * @param inst  instance handle
+ * @return Bitmask of NT_NetworkMode.
+ */
+unsigned int GetNetworkMode(NT_Inst inst);
+
+/**
+ * Starts local-only operation.  Prevents calls to StartServer or StartClient
+ * from taking effect.  Has no effect if StartServer or StartClient
+ * has already been called.
+ */
+void StartLocal(NT_Inst inst);
+
+/**
+ * Stops local-only operation.  StartServer or StartClient can be called after
+ * this call to start a server or client.
+ */
+void StopLocal(NT_Inst inst);
+
+/**
+ * Starts a server using the specified filename, listening address, and port.
+ *
+ * @param persist_filename  the name of the persist file to use (UTF-8 string,
+ *                          null terminated)
+ * @param listen_address    the address to listen on, or null to listen on any
+ *                          address. (UTF-8 string, null terminated)
+ * @param port              port to communicate over.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StartServer(StringRef persist_filename, const char* listen_address,
+                 unsigned int port);
+
+/**
+ * @copydoc StartServer(StringRef, const char*, unsigned int)
+ *
+ * @param inst              instance handle
+ */
+void StartServer(NT_Inst inst, const Twine& persist_filename,
+                 const char* listen_address, unsigned int port);
+
+/**
+ * Stops the server if it is running.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StopServer();
+
+/**
+ * @copydoc StopServer()
+ *
+ * @param inst  instance handle
+ */
+void StopServer(NT_Inst inst);
+
+/**
+ * Starts a client.  Use SetServer to set the server name and port.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StartClient();
+
+/**
+ * Starts a client using the specified server and port
+ *
+ * @param server_name server name (UTF-8 string, null terminated)
+ * @param port        port to communicate over
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StartClient(const char* server_name, unsigned int port);
+
+/**
+ * Starts a client using the specified (server, port) combinations.  The
+ * client will attempt to connect to each server in round robin fashion.
+ *
+ * @param servers   array of server name and port pairs
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StartClient(ArrayRef<std::pair<StringRef, unsigned int>> servers);
+
+/**
+ * @copydoc StartClient()
+ *
+ * @param inst  instance handle
+ */
+void StartClient(NT_Inst inst);
+
+/**
+ * @copydoc StartClient(const char*, unsigned int)
+ *
+ * @param inst        instance handle
+ */
+void StartClient(NT_Inst inst, const char* server_name, unsigned int port);
+
+/**
+ * @copydoc StartClient(ArrayRef<std::pair<StringRef, unsigned int>>)
+ *
+ * @param inst      instance handle
+ */
+void StartClient(NT_Inst inst,
+                 ArrayRef<std::pair<StringRef, unsigned int>> servers);
+
+/**
+ * Starts a client using commonly known robot addresses for the specified
+ * team.
+ *
+ * @param inst        instance handle
+ * @param team        team number
+ * @param port        port to communicate over
+ */
+void StartClientTeam(NT_Inst inst, unsigned int team, unsigned int port);
+
+/**
+ * Stops the client if it is running.
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StopClient();
+
+/**
+ * @copydoc StopClient()
+ * @param inst  instance handle
+ */
+void StopClient(NT_Inst inst);
+
+/**
+ * Sets server address and port for client (without restarting client).
+ *
+ * @param server_name server name (UTF-8 string, null terminated)
+ * @param port        port to communicate over
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void SetServer(const char* server_name, unsigned int port);
+
+/**
+ * Sets server addresses for client (without restarting client).
+ * The client will attempt to connect to each server in round robin fashion.
+ *
+ * @param servers   array of server name and port pairs
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void SetServer(ArrayRef<std::pair<StringRef, unsigned int>> servers);
+
+/**
+ * @copydoc SetServer(const char*, unsigned int)
+ *
+ * @param inst        instance handle
+ */
+void SetServer(NT_Inst inst, const char* server_name, unsigned int port);
+
+/**
+ * @copydoc SetServer(ArrayRef<std::pair<StringRef, unsigned int>>)
+ *
+ * @param inst      instance handle
+ */
+void SetServer(NT_Inst inst,
+               ArrayRef<std::pair<StringRef, unsigned int>> servers);
+
+/**
+ * Sets server addresses and port for client (without restarting client).
+ * Connects using commonly known robot addresses for the specified team.
+ *
+ * @param inst        instance handle
+ * @param team        team number
+ * @param port        port to communicate over
+ */
+void SetServerTeam(NT_Inst inst, unsigned int team, unsigned int port);
+
+/**
+ * Starts requesting server address from Driver Station.
+ * This connects to the Driver Station running on localhost to obtain the
+ * server IP address.
+ *
+ * @param port server port to use in combination with IP from DS
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StartDSClient(unsigned int port);
+
+/**
+ * @copydoc StartDSClient(unsigned int)
+ * @param inst  instance handle
+ */
+void StartDSClient(NT_Inst inst, unsigned int port);
+
+/** Stops requesting server address from Driver Station. */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StopDSClient();
+
+/**
+ * @copydoc StopDSClient()
+ *
+ * @param inst  instance handle
+ */
+void StopDSClient(NT_Inst inst);
+
+/** Stops the RPC server if it is running. */
+WPI_DEPRECATED("use NT_Inst function instead")
+void StopRpcServer();
+
+/**
+ * Set the periodic update rate.
+ * Sets how frequently updates are sent to other nodes over the network.
+ *
+ * @param interval  update interval in seconds (range 0.01 to 1.0)
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void SetUpdateRate(double interval);
+
+/**
+ * @copydoc SetUpdateRate(double)
+ *
+ * @param inst      instance handle
+ */
+void SetUpdateRate(NT_Inst inst, double interval);
+
+/**
+ * Flush Entries.
+ *
+ * Forces an immediate flush of all local entry changes to network.
+ * Normally this is done on a regularly scheduled interval (see
+ * SetUpdateRate()).
+ *
+ * Note: flushes are rate limited to avoid excessive network traffic.  If
+ * the time between calls is too short, the flush will occur after the minimum
+ * time elapses (rather than immediately).
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void Flush();
+
+/**
+ * @copydoc Flush()
+ *
+ * @param inst      instance handle
+ */
+void Flush(NT_Inst inst);
+
+/**
+ * Get information on the currently established network connections.
+ * If operating as a client, this will return either zero or one values.
+ *
+ * @return      array of connection information
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+std::vector<ConnectionInfo> GetConnections();
+
+/**
+ * @copydoc GetConnections()
+ *
+ * @param inst  instance handle
+ */
+std::vector<ConnectionInfo> GetConnections(NT_Inst inst);
+
+/**
+ * Return whether or not the instance is connected to another node.
+ *
+ * @param inst  instance handle
+ * @return True if connected.
+ */
+bool IsConnected(NT_Inst inst);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_file_func File Save/Load Functions
+ * @{
+ */
+
+/**
+ * Save persistent values to a file.  The server automatically does this,
+ * but this function provides a way to save persistent values in the same
+ * format to a file on either a client or a server.
+ *
+ * @param filename  filename
+ * @return error string, or nullptr if successful
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+const char* SavePersistent(StringRef filename);
+
+/**
+ * @copydoc SavePersistent(StringRef)
+ * @param inst      instance handle
+ */
+const char* SavePersistent(NT_Inst inst, const Twine& filename);
+
+/**
+ * Load persistent values from a file.  The server automatically does this
+ * at startup, but this function provides a way to restore persistent values
+ * in the same format from a file at any time on either a client or a server.
+ *
+ * @param filename  filename
+ * @param warn      callback function for warnings
+ * @return error string, or nullptr if successful
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+const char* LoadPersistent(
+    StringRef filename, std::function<void(size_t line, const char* msg)> warn);
+
+/**
+ * @copydoc LoadPersistent(StringRef, std::function<void(size_t, const
+ * char*)>)
+ *
+ * @param inst      instance handle
+ */
+const char* LoadPersistent(
+    NT_Inst inst, const Twine& filename,
+    std::function<void(size_t line, const char* msg)> warn);
+
+/**
+ * Save table values to a file.  The file format used is identical to
+ * that used for SavePersistent.
+ *
+ * @param inst      instance handle
+ * @param filename  filename
+ * @param prefix    save only keys starting with this prefix
+ * @return error string, or nullptr if successful
+ */
+const char* SaveEntries(NT_Inst inst, const Twine& filename,
+                        const Twine& prefix);
+
+/**
+ * Load table values from a file.  The file format used is identical to
+ * that used for SavePersistent / LoadPersistent.
+ *
+ * @param inst      instance handle
+ * @param filename  filename
+ * @param prefix    load only keys starting with this prefix
+ * @param warn      callback function for warnings
+ * @return error string, or nullptr if successful
+ */
+const char* LoadEntries(NT_Inst inst, const Twine& filename,
+                        const Twine& prefix,
+                        std::function<void(size_t line, const char* msg)> warn);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_utility_func Utility Functions
+ * @{
+ */
+
+/**
+ * Returns monotonic current time in 1 us increments.
+ * This is the same time base used for entry and connection timestamps.
+ * This function is a compatibility wrapper around wpi::Now().
+ *
+ * @return Timestamp
+ */
+uint64_t Now();
+
+/** @} */
+
+/**
+ * @defgroup ntcore_logger_func Logger Functions
+ * @{
+ */
+
+/**
+ * Log function.
+ *
+ * @param level   log level of the message (see NT_LogLevel)
+ * @param file    origin source filename
+ * @param line    origin source line number
+ * @param msg     message
+ */
+typedef std::function<void(unsigned int level, const char* file,
+                           unsigned int line, const char* msg)>
+    LogFunc;
+
+/**
+ * Set logger callback function.  By default, log messages are sent to stderr;
+ * this function changes the log level and sends log messages to the provided
+ * callback function instead.  The callback function will only be called for
+ * log messages with level greater than or equal to min_level; messages lower
+ * than this level will be silently ignored.
+ *
+ * @param func        log callback function
+ * @param min_level   minimum log level
+ */
+WPI_DEPRECATED("use NT_Inst function instead")
+void SetLogger(LogFunc func, unsigned int min_level);
+
+/**
+ * Add logger callback function.  By default, log messages are sent to stderr;
+ * this function sends log messages to the provided callback function instead.
+ * The callback function will only be called for log messages with level
+ * greater than or equal to min_level and less than or equal to max_level;
+ * messages outside this range will be silently ignored.
+ *
+ * @param inst        instance handle
+ * @param func        log callback function
+ * @param min_level   minimum log level
+ * @param max_level   maximum log level
+ * @return Logger handle
+ */
+NT_Logger AddLogger(NT_Inst inst,
+                    std::function<void(const LogMessage& msg)> func,
+                    unsigned int min_level, unsigned int max_level);
+
+/**
+ * Create a log poller.  A poller provides a single queue of poll events.
+ * The returned handle must be destroyed with DestroyLoggerPoller().
+ *
+ * @param inst      instance handle
+ * @return poller handle
+ */
+NT_LoggerPoller CreateLoggerPoller(NT_Inst inst);
+
+/**
+ * Destroy a log poller.  This will abort any blocked polling call and prevent
+ * additional events from being generated for this poller.
+ *
+ * @param poller    poller handle
+ */
+void DestroyLoggerPoller(NT_LoggerPoller poller);
+
+/**
+ * Set the log level for a log poller.  Events will only be generated for
+ * log messages with level greater than or equal to min_level and less than or
+ * equal to max_level; messages outside this range will be silently ignored.
+ *
+ * @param poller        poller handle
+ * @param min_level     minimum log level
+ * @param max_level     maximum log level
+ * @return Logger handle
+ */
+NT_Logger AddPolledLogger(NT_LoggerPoller poller, unsigned int min_level,
+                          unsigned int max_level);
+
+/**
+ * Get the next log event.  This blocks until the next log occurs.
+ *
+ * @param poller    poller handle
+ * @return Information on the log events.  Only returns empty if an error
+ *         occurred (e.g. the instance was invalid or is shutting down).
+ */
+std::vector<LogMessage> PollLogger(NT_LoggerPoller poller);
+
+/**
+ * Get the next log event.  This blocks until the next log occurs or it times
+ * out.
+ *
+ * @param poller      poller handle
+ * @param timeout     timeout, in seconds
+ * @param timed_out   true if the timeout period elapsed (output)
+ * @return Information on the log events.  If empty is returned and timed_out
+ *         is also false, an error occurred (e.g. the instance was invalid or
+ *         is shutting down).
+ */
+std::vector<LogMessage> PollLogger(NT_LoggerPoller poller, double timeout,
+                                   bool* timed_out);
+
+/**
+ * Cancel a PollLogger call.  This wakes up a call to PollLogger for this
+ * poller and causes it to immediately return an empty array.
+ *
+ * @param poller  poller handle
+ */
+void CancelPollLogger(NT_LoggerPoller poller);
+
+/**
+ * Remove a logger.
+ *
+ * @param logger Logger handle to remove
+ */
+void RemoveLogger(NT_Logger logger);
+
+/**
+ * Wait for the incoming log event queue to be empty.  This is primarily useful
+ * for deterministic testing.  This blocks until either the log event
+ * queue is empty (e.g. there are no more events that need to be passed along
+ * to callbacks or poll queues) or the timeout expires.
+ *
+ * @param inst      instance handle
+ * @param timeout   timeout, in seconds.  Set to 0 for non-blocking behavior,
+ *                  or a negative value to block indefinitely
+ * @return False if timed out, otherwise true.
+ */
+bool WaitForLoggerQueue(NT_Inst inst, double timeout);
+
+/** @} */
+/** @} */
+
+inline bool RpcAnswer::PostResponse(StringRef result) const {
+  auto ret = PostRpcResponse(entry, call, result);
+  call = 0;
+  return ret;
+}
+
+}  // namespace nt
+
+#endif  // NTCORE_NTCORE_CPP_H_
diff --git a/ntcore/src/main/native/include/ntcore_test.h b/ntcore/src/main/native/include/ntcore_test.h
new file mode 100644
index 0000000..920fd68
--- /dev/null
+++ b/ntcore/src/main/native/include/ntcore_test.h
@@ -0,0 +1,89 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_NTCORE_TEST_H_
+#define NTCORE_NTCORE_TEST_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "ntcore.h"
+
+// Functions in this header are to be used only for testing
+
+extern "C" {
+struct NT_String* NT_GetStringForTesting(const char* string, int* struct_size);
+// No need for free as one already exists in main library
+
+struct NT_EntryInfo* NT_GetEntryInfoForTesting(const char* name,
+                                               enum NT_Type type,
+                                               unsigned int flags,
+                                               uint64_t last_change,
+                                               int* struct_size);
+
+void NT_FreeEntryInfoForTesting(struct NT_EntryInfo* info);
+
+struct NT_ConnectionInfo* NT_GetConnectionInfoForTesting(
+    const char* remote_id, const char* remote_ip, unsigned int remote_port,
+    uint64_t last_update, unsigned int protocol_version, int* struct_size);
+
+void NT_FreeConnectionInfoForTesting(struct NT_ConnectionInfo* info);
+
+struct NT_Value* NT_GetValueBooleanForTesting(uint64_t last_change, int val,
+                                              int* struct_size);
+
+struct NT_Value* NT_GetValueDoubleForTesting(uint64_t last_change, double val,
+                                             int* struct_size);
+
+struct NT_Value* NT_GetValueStringForTesting(uint64_t last_change,
+                                             const char* str, int* struct_size);
+
+struct NT_Value* NT_GetValueRawForTesting(uint64_t last_change, const char* raw,
+                                          int raw_len, int* struct_size);
+
+struct NT_Value* NT_GetValueBooleanArrayForTesting(uint64_t last_change,
+                                                   const int* arr,
+                                                   size_t array_len,
+                                                   int* struct_size);
+
+struct NT_Value* NT_GetValueDoubleArrayForTesting(uint64_t last_change,
+                                                  const double* arr,
+                                                  size_t array_len,
+                                                  int* struct_size);
+
+struct NT_Value* NT_GetValueStringArrayForTesting(uint64_t last_change,
+                                                  const struct NT_String* arr,
+                                                  size_t array_len,
+                                                  int* struct_size);
+// No need for free as one already exists in the main library
+
+struct NT_RpcParamDef* NT_GetRpcParamDefForTesting(const char* name,
+                                                   const struct NT_Value* val,
+                                                   int* struct_size);
+
+void NT_FreeRpcParamDefForTesting(struct NT_RpcParamDef* def);
+
+struct NT_RpcResultDef* NT_GetRpcResultsDefForTesting(const char* name,
+                                                      enum NT_Type type,
+                                                      int* struct_size);
+
+void NT_FreeRpcResultsDefForTesting(struct NT_RpcResultDef* def);
+
+struct NT_RpcDefinition* NT_GetRpcDefinitionForTesting(
+    unsigned int version, const char* name, size_t num_params,
+    const struct NT_RpcParamDef* params, size_t num_results,
+    const struct NT_RpcResultDef* results, int* struct_size);
+// No need for free as one already exists in the main library
+
+struct NT_RpcCallInfo* NT_GetRpcCallInfoForTesting(
+    unsigned int rpc_id, unsigned int call_uid, const char* name,
+    const char* params, size_t params_len, int* struct_size);
+// No need for free as one already exists in the main library
+}  // extern "C"
+
+#endif  // NTCORE_NTCORE_TEST_H_
diff --git a/ntcore/src/main/native/include/tables/ITable.h b/ntcore/src/main/native/include/tables/ITable.h
new file mode 100644
index 0000000..d03aaa7
--- /dev/null
+++ b/ntcore/src/main/native/include/tables/ITable.h
@@ -0,0 +1,456 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_TABLES_ITABLE_H_
+#define NTCORE_TABLES_ITABLE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <wpi/StringRef.h>
+#include <wpi/Twine.h>
+#include <wpi/deprecated.h>
+
+#include "networktables/NetworkTableValue.h"
+
+namespace nt {
+class NetworkTable;
+}  // namespace nt
+
+class ITableListener;
+
+/**
+ * A table whose values can be read and written to
+ */
+class WPI_DEPRECATED("Use NetworkTable directly") ITable {
+ public:
+  /**
+   * Determines whether the given key is in this table.
+   *
+   * @param key the key to search for
+   * @return true if the table as a value assigned to the given key
+   */
+  virtual bool ContainsKey(const wpi::Twine& key) const = 0;
+
+  /**
+   * Determines whether there exists a non-empty subtable for this key
+   * in this table.
+   *
+   * @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
+   */
+  virtual bool ContainsSubTable(const wpi::Twine& key) const = 0;
+
+  /**
+   * Gets the subtable in this table for the given name.
+   *
+   * @param key the name of the table relative to this one
+   * @return a sub table relative to this one
+   */
+  virtual std::shared_ptr<nt::NetworkTable> GetSubTable(
+      const wpi::Twine& key) const = 0;
+
+  /**
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return keys currently in the table
+   */
+  virtual std::vector<std::string> GetKeys(int types = 0) const = 0;
+
+  /**
+   * @return subtables currently in the table
+   */
+  virtual std::vector<std::string> GetSubTables() const = 0;
+
+  /**
+   * Makes a key's value persistent through program restarts.
+   *
+   * @param key the key to make persistent
+   */
+  virtual void SetPersistent(wpi::StringRef key) = 0;
+
+  /**
+   * Stop making a key's value persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   */
+  virtual void ClearPersistent(wpi::StringRef key) = 0;
+
+  /**
+   * Returns whether the value is persistent through program restarts.
+   * The key cannot be null.
+   *
+   * @param key the key name
+   */
+  virtual bool IsPersistent(wpi::StringRef key) const = 0;
+
+  /**
+   * 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)
+   */
+  virtual void SetFlags(wpi::StringRef key, unsigned int flags) = 0;
+
+  /**
+   * 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)
+   */
+  virtual void ClearFlags(wpi::StringRef key, unsigned int flags) = 0;
+
+  /**
+   * Returns the flags for the specified key.
+   *
+   * @param key the key name
+   * @return the flags, or 0 if the key is not defined
+   */
+  virtual unsigned int GetFlags(wpi::StringRef key) const = 0;
+
+  /**
+   * Deletes the specified key in this table.
+   *
+   * @param key the key name
+   */
+  virtual void Delete(const wpi::Twine& key) = 0;
+
+  /**
+   * Gets the value associated with a key as an object
+   *
+   * @param key the key of the value to look up
+   * @return the value associated with the given key, or nullptr if the key
+   * does not exist
+   */
+  virtual std::shared_ptr<nt::Value> GetValue(const wpi::Twine& key) const = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultValue(const wpi::Twine& key,
+                               std::shared_ptr<nt::Value> defaultValue) = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutValue(const wpi::Twine& key,
+                        std::shared_ptr<nt::Value> value) = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutNumber(wpi::StringRef key, double value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultNumber(wpi::StringRef key, double defaultValue) = 0;
+
+  /**
+   * Gets the number associated with the given name.
+   *
+   * @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
+   */
+  virtual double GetNumber(wpi::StringRef key, double defaultValue) const = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutString(wpi::StringRef key, wpi::StringRef value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultString(wpi::StringRef key,
+                                wpi::StringRef defaultValue) = 0;
+
+  /**
+   * Gets the string associated with the given name. 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
+   *
+   * @note This makes a copy of the string.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  virtual std::string GetString(wpi::StringRef key,
+                                wpi::StringRef defaultValue) const = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutBoolean(wpi::StringRef key, bool value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultBoolean(wpi::StringRef key, bool defaultValue) = 0;
+
+  /**
+   * Gets the boolean associated with the given name. 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
+   */
+  virtual bool GetBoolean(wpi::StringRef key, bool defaultValue) const = 0;
+
+  /**
+   * 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
+   *
+   * @note The array must be of int's rather than of bool's because
+   *       std::vector<bool> is special-cased in C++.  0 is false, any
+   *       non-zero value is true.
+   */
+  virtual bool PutBooleanArray(wpi::StringRef key,
+                               wpi::ArrayRef<int> value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultBooleanArray(wpi::StringRef key,
+                                      wpi::ArrayRef<int> defaultValue) = 0;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   *
+   * @note The returned array is std::vector<int> instead of std::vector<bool>
+   *       because std::vector<bool> is special-cased in C++.  0 is false, any
+   *       non-zero value is true.
+   */
+  virtual std::vector<int> GetBooleanArray(
+      wpi::StringRef key, wpi::ArrayRef<int> defaultValue) const = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutNumberArray(wpi::StringRef key,
+                              wpi::ArrayRef<double> value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultNumberArray(wpi::StringRef key,
+                                     wpi::ArrayRef<double> defaultValue) = 0;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  virtual std::vector<double> GetNumberArray(
+      wpi::StringRef key, wpi::ArrayRef<double> defaultValue) const = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutStringArray(wpi::StringRef key,
+                              wpi::ArrayRef<std::string> value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultStringArray(
+      wpi::StringRef key, wpi::ArrayRef<std::string> defaultValue) = 0;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the array.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  virtual std::vector<std::string> GetStringArray(
+      wpi::StringRef key, wpi::ArrayRef<std::string> defaultValue) const = 0;
+
+  /**
+   * 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
+   */
+  virtual bool PutRaw(wpi::StringRef key, wpi::StringRef value) = 0;
+
+  /**
+   * Gets the current value in the table, setting it if it does not exist.
+   * @param key the key
+   * @param defaultValue the default value to set if key doesn't exist.
+   * @returns False if the table key exists with a different type
+   */
+  virtual bool SetDefaultRaw(wpi::StringRef key,
+                             wpi::StringRef defaultValue) = 0;
+
+  /**
+   * 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
+   *
+   * @note This makes a copy of the raw contents.  If the overhead of this is a
+   *       concern, use GetValue() instead.
+   */
+  virtual std::string GetRaw(wpi::StringRef key,
+                             wpi::StringRef defaultValue) const = 0;
+
+  /**
+   * Add a listener for changes to the table
+   *
+   * @param listener the listener to add
+   */
+  virtual void AddTableListener(ITableListener* listener) = 0;
+
+  /**
+   * 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)
+   */
+  virtual void AddTableListener(ITableListener* listener,
+                                bool immediateNotify) = 0;
+
+  /**
+   * 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)
+   * @param flags bitmask of NT_NotifyKind specifying desired notifications
+   */
+  virtual void AddTableListenerEx(ITableListener* listener,
+                                  unsigned int flags) = 0;
+
+  /**
+   * 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)
+   */
+  virtual void AddTableListener(wpi::StringRef key, ITableListener* listener,
+                                bool immediateNotify) = 0;
+
+  /**
+   * 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)
+   * @param flags bitmask of NT_NotifyKind specifying desired notifications
+   */
+  virtual void AddTableListenerEx(wpi::StringRef key, ITableListener* listener,
+                                  unsigned int flags) = 0;
+
+  /**
+   * This will immediately notify the listener of all current sub tables
+   * @param listener the listener to add
+   */
+  virtual void AddSubTableListener(ITableListener* listener) = 0;
+
+  /**
+   * This will immediately notify the listener of all current sub tables
+   * @param listener the listener to add
+   * @param localNotify if true then this listener will be notified of all
+   * local changes in addition to all remote changes
+   */
+  virtual void AddSubTableListener(ITableListener* listener,
+                                   bool localNotify) = 0;
+
+  /**
+   * Remove a listener from receiving table events
+   *
+   * @param listener the listener to be removed
+   */
+  virtual void RemoveTableListener(ITableListener* listener) = 0;
+
+  /**
+   * Gets the full path of this table.
+   */
+  virtual wpi::StringRef GetPath() const = 0;
+};
+
+#endif  // NTCORE_TABLES_ITABLE_H_
diff --git a/ntcore/src/main/native/include/tables/ITableListener.h b/ntcore/src/main/native/include/tables/ITableListener.h
new file mode 100644
index 0000000..dae6f85
--- /dev/null
+++ b/ntcore/src/main/native/include/tables/ITableListener.h
@@ -0,0 +1,68 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_TABLES_ITABLELISTENER_H_
+#define NTCORE_TABLES_ITABLELISTENER_H_
+
+#include <memory>
+
+#include <wpi/StringRef.h>
+#include <wpi/deprecated.h>
+
+#include "networktables/NetworkTableValue.h"
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif _WIN32
+#pragma warning(push)
+#pragma warning(disable : 4996)
+#endif
+
+class ITable;
+
+/**
+ * A listener that listens to changes in values in a {@link ITable}
+ */
+class WPI_DEPRECATED(
+    "Use EntryListener, TableEntryListener, or TableListener as appropriate")
+    ITableListener {
+ public:
+  virtual ~ITableListener() = default;
+  /**
+   * 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
+   */
+  virtual void ValueChanged(ITable* source, wpi::StringRef key,
+                            std::shared_ptr<nt::Value> value, bool isNew) = 0;
+
+  /**
+   * 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, NT_NOTIFY_NEW if the key did not
+   * previously exist in the table
+   */
+  virtual void ValueChangedEx(ITable* source, wpi::StringRef key,
+                              std::shared_ptr<nt::Value> value,
+                              unsigned int flags);
+};
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#elif _WIN32
+#pragma warning(pop)
+#endif
+
+#endif  // NTCORE_TABLES_ITABLELISTENER_H_
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java
new file mode 100644
index 0000000..9628a0e
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java
@@ -0,0 +1,160 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+class ConnectionListenerTest {
+  private NetworkTableInstance m_serverInst;
+  private NetworkTableInstance m_clientInst;
+
+  @BeforeEach
+  void setUp() {
+    m_serverInst = NetworkTableInstance.create();
+    m_serverInst.setNetworkIdentity("server");
+
+    m_clientInst = NetworkTableInstance.create();
+    m_clientInst.setNetworkIdentity("client");
+  }
+
+  @AfterEach
+  void tearDown() {
+    m_clientInst.close();
+    m_serverInst.close();
+  }
+
+  /**
+   * Connect to the server.
+   */
+  @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
+  private void connect() {
+    m_serverInst.startServer("connectionlistenertest.ini", "127.0.0.1", 10000);
+    m_clientInst.startClient("127.0.0.1", 10000);
+
+    // wait for client to report it's started, then wait another 0.1 sec
+    try {
+      while ((m_clientInst.getNetworkMode() & NetworkTableInstance.kNetModeStarting) != 0) {
+        Thread.sleep(100);
+      }
+      Thread.sleep(100);
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for client to start");
+    }
+  }
+
+  @Test
+  @DisabledOnOs(OS.WINDOWS)
+  void testJNI() {
+    // set up the poller
+    int poller = NetworkTablesJNI.createConnectionListenerPoller(m_serverInst.getHandle());
+    assertNotSame(poller, 0, "bad poller handle");
+    int handle = NetworkTablesJNI.addPolledConnectionListener(poller, false);
+    assertNotSame(handle, 0, "bad listener handle");
+
+    // trigger a connect event
+    connect();
+
+    // get the event
+    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
+    ConnectionNotification[] events = null;
+    try {
+      events = NetworkTablesJNI.pollConnectionListenerTimeout(m_serverInst, poller, 0.0);
+    } catch (InterruptedException ex) {
+      Thread.currentThread().interrupt();
+      fail("unexpected interrupted exception" + ex);
+    }
+
+    assertNotNull(events);
+    assertEquals(1, events.length);
+    assertEquals(handle, events[0].listener);
+    assertTrue(events[0].connected);
+
+    // trigger a disconnect event
+    m_clientInst.stopClient();
+    try {
+      Thread.sleep(100);
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for client to stop");
+    }
+
+    // get the event
+    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
+    try {
+      events = NetworkTablesJNI.pollConnectionListenerTimeout(m_serverInst, poller, 0.0);
+    } catch (InterruptedException ex) {
+      Thread.currentThread().interrupt();
+      fail("unexpected interrupted exception" + ex);
+    }
+
+    assertNotNull(events);
+    assertEquals(1, events.length);
+    assertEquals(handle, events[0].listener);
+    assertFalse(events[0].connected);
+
+  }
+
+  @ParameterizedTest
+  @DisabledOnOs(OS.WINDOWS)
+  @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
+  @ValueSource(strings = { "127.0.0.1", "127.0.0.1 ", " 127.0.0.1 " })
+  void testThreaded(String address) {
+    m_serverInst.startServer("connectionlistenertest.ini", address, 10000);
+    List<ConnectionNotification> events = new ArrayList<>();
+    final int handle = m_serverInst.addConnectionListener(events::add, false);
+
+    // trigger a connect event
+    m_clientInst.startClient(address, 10000);
+
+    // wait for client to report it's started, then wait another 0.1 sec
+    try {
+      while ((m_clientInst.getNetworkMode() & NetworkTableInstance.kNetModeStarting) != 0) {
+        Thread.sleep(100);
+      }
+      Thread.sleep(100);
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for client to start");
+    }
+    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
+
+    // get the event
+    assertEquals(1, events.size());
+    assertEquals(handle, events.get(0).listener);
+    assertTrue(events.get(0).connected);
+    events.clear();
+
+    // trigger a disconnect event
+    m_clientInst.stopClient();
+    try {
+      Thread.sleep(100);
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for client to stop");
+    }
+
+    // get the event
+    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
+    assertEquals(1, events.size());
+    assertEquals(handle, events.get(0).listener);
+    assertFalse(events.get(0).connected);
+  }
+}
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/EntryListenerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/EntryListenerTest.java
new file mode 100644
index 0000000..80627a4
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/EntryListenerTest.java
@@ -0,0 +1,91 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+class EntryListenerTest {
+  private NetworkTableInstance m_serverInst;
+  private NetworkTableInstance m_clientInst;
+
+  @BeforeEach
+  void setUp() {
+    m_serverInst = NetworkTableInstance.create();
+    m_serverInst.setNetworkIdentity("server");
+
+    m_clientInst = NetworkTableInstance.create();
+    m_clientInst.setNetworkIdentity("client");
+  }
+
+  @AfterEach
+  void tearDown() {
+    m_clientInst.close();
+    m_serverInst.close();
+  }
+
+  @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
+  private void connect() {
+    m_serverInst.startServer("connectionlistenertest.ini", "127.0.0.1", 10000);
+    m_clientInst.startClient("127.0.0.1", 10000);
+
+    // Use connection listener to ensure we've connected
+    int poller = NetworkTablesJNI.createConnectionListenerPoller(m_clientInst.getHandle());
+    NetworkTablesJNI.addPolledConnectionListener(poller, false);
+    try {
+      if (NetworkTablesJNI.pollConnectionListenerTimeout(m_clientInst, poller, 1.0).length == 0) {
+        fail("client didn't connect to server");
+      }
+    } catch (InterruptedException ex) {
+      Thread.currentThread().interrupt();
+      fail("interrupted while waiting for server connection");
+    }
+  }
+
+  /**
+   * Test prefix with a new remote.
+   */
+  @Test
+  void testPrefixNewRemote() {
+    connect();
+    List<EntryNotification> events = new ArrayList<>();
+    final int handle = m_serverInst.addEntryListener("/foo", events::add,
+        EntryListenerFlags.kNew);
+
+    // Trigger an event
+    m_clientInst.getEntry("/foo/bar").setDouble(1.0);
+    m_clientInst.getEntry("/baz").setDouble(1.0);
+    m_clientInst.flush();
+    try {
+      Thread.sleep(100);
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for entries to update");
+    }
+
+    assertTrue(m_serverInst.waitForEntryListenerQueue(1.0));
+
+    // Check the event
+    assertAll("Event",
+        () -> assertEquals(1, events.size()),
+        () -> assertEquals(handle, events.get(0).listener),
+        () -> assertEquals(m_serverInst.getEntry("/foo/bar"), events.get(0).getEntry()),
+        () -> assertEquals("/foo/bar", events.get(0).name),
+        () -> assertEquals(NetworkTableValue.makeDouble(1.0), events.get(0).value),
+        () -> assertEquals(EntryListenerFlags.kNew, events.get(0).flags)
+    );
+  }
+}
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/JNITest.java b/ntcore/src/test/java/edu/wpi/first/networktables/JNITest.java
new file mode 100644
index 0000000..ef2b42b
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/JNITest.java
@@ -0,0 +1,19 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import org.junit.jupiter.api.Test;
+
+class JNITest {
+  @Test
+  void jniLinkTest() {
+    // Test to verify that the JNI test link works correctly.
+    int inst = NetworkTablesJNI.getDefaultInstance();
+    NetworkTablesJNI.flush(inst);
+  }
+}
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/LoggerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/LoggerTest.java
new file mode 100644
index 0000000..420f9dc
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/LoggerTest.java
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.fail;
+
+class LoggerTest {
+  private NetworkTableInstance m_clientInst;
+
+  @BeforeEach
+  protected void setUp() {
+    m_clientInst = NetworkTableInstance.create();
+  }
+
+  @AfterEach
+  protected void tearDown() {
+    m_clientInst.close();
+  }
+
+  @Test
+  @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
+  void addMessageTest() {
+    List<LogMessage> msgs = new ArrayList<>();
+    m_clientInst.addLogger(msgs::add, LogMessage.kInfo, 100);
+
+    m_clientInst.startClient("127.0.0.1", 10000);
+
+    // wait for client to report it's started, then wait another 0.1 sec
+    try {
+      while ((m_clientInst.getNetworkMode() & NetworkTableInstance.kNetModeStarting) != 0) {
+        Thread.sleep(100);
+      }
+      Thread.sleep(100);
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for client to start");
+    }
+
+    assertFalse(msgs.isEmpty());
+  }
+}
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/NetworkTableTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/NetworkTableTest.java
new file mode 100644
index 0000000..71ce0ae
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/NetworkTableTest.java
@@ -0,0 +1,81 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.networktables;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class NetworkTableTest {
+  private static Stream<Arguments> basenameKeyArguments() {
+    return Stream.of(
+        Arguments.of("simple", "simple"),
+        Arguments.of("simple", "one/two/many/simple"),
+        Arguments.of("simple", "//////an/////awful/key////simple")
+    );
+  }
+
+  @ParameterizedTest
+  @MethodSource("basenameKeyArguments")
+  void basenameKeyTest(final String expected, final String testString) {
+    assertEquals(expected, NetworkTable.basenameKey(testString));
+  }
+
+  private static Stream<Arguments> normalizeKeySlashArguments() {
+    return Stream.of(
+        Arguments.of("/", "///"),
+        Arguments.of("/no/normal/req", "/no/normal/req"),
+        Arguments.of("/no/leading/slash", "no/leading/slash"),
+        Arguments.of("/what/an/awful/key/", "//////what////an/awful/////key///")
+    );
+  }
+
+  @ParameterizedTest
+  @MethodSource("normalizeKeySlashArguments")
+  void normalizeKeySlashTest(final String expected, final String testString) {
+    assertEquals(expected, NetworkTable.normalizeKey(testString));
+  }
+
+  private static Stream<Arguments> normalizeKeyNoSlashArguments() {
+    return Stream.of(
+        Arguments.of("a", "a"),
+        Arguments.of("a", "///a"),
+        Arguments.of("leading/slash", "/leading/slash"),
+        Arguments.of("no/leading/slash", "no/leading/slash"),
+        Arguments.of("what/an/awful/key/", "//////what////an/awful/////key///")
+    );
+  }
+
+  @ParameterizedTest
+  @MethodSource("normalizeKeyNoSlashArguments")
+  void normalizeKeyNoSlashTest(final String expected, final String testString) {
+    assertEquals(expected, NetworkTable.normalizeKey(testString, false));
+  }
+
+  private static Stream<Arguments> getHierarchyArguments() {
+    return Stream.of(
+        Arguments.of(Collections.singletonList("/"), ""),
+        Arguments.of(Collections.singletonList("/"), "/"),
+        Arguments.of(Arrays.asList("/", "/foo", "/foo/bar", "/foo/bar/baz"), "/foo/bar/baz"),
+        Arguments.of(Arrays.asList("/", "/foo", "/foo/bar", "/foo/bar/"), "/foo/bar/")
+    );
+  }
+
+  @ParameterizedTest
+  @MethodSource("getHierarchyArguments")
+  void getHierarchyTest(final List<String> expected, final String testString) {
+    assertEquals(expected, NetworkTable.getHierarchy(testString));
+  }
+}
diff --git a/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp b/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp
new file mode 100644
index 0000000..a56e45c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp
@@ -0,0 +1,108 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <chrono>
+#include <thread>
+
+#include "TestPrinters.h"
+#include "gtest/gtest.h"
+#include "ntcore_cpp.h"
+
+class ConnectionListenerTest : public ::testing::Test {
+ public:
+  ConnectionListenerTest()
+      : server_inst(nt::CreateInstance()), client_inst(nt::CreateInstance()) {
+    nt::SetNetworkIdentity(server_inst, "server");
+    nt::SetNetworkIdentity(client_inst, "client");
+  }
+
+  ~ConnectionListenerTest() override {
+    nt::DestroyInstance(server_inst);
+    nt::DestroyInstance(client_inst);
+  }
+
+  void Connect();
+
+ protected:
+  NT_Inst server_inst;
+  NT_Inst client_inst;
+};
+
+void ConnectionListenerTest::Connect() {
+  nt::StartServer(server_inst, "connectionlistenertest.ini", "127.0.0.1",
+                  10000);
+  nt::StartClient(client_inst, "127.0.0.1", 10000);
+
+  // wait for client to report it's started, then wait another 0.1 sec
+  while ((nt::GetNetworkMode(client_inst) & NT_NET_MODE_STARTING) != 0)
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+}
+
+TEST_F(ConnectionListenerTest, Polled) {
+  // set up the poller
+  NT_ConnectionListenerPoller poller =
+      nt::CreateConnectionListenerPoller(server_inst);
+  ASSERT_NE(poller, 0u);
+  NT_ConnectionListener handle = nt::AddPolledConnectionListener(poller, false);
+  ASSERT_NE(handle, 0u);
+
+  // trigger a connect event
+  Connect();
+
+  // get the event
+  ASSERT_TRUE(nt::WaitForConnectionListenerQueue(server_inst, 1.0));
+  bool timed_out = false;
+  auto result = nt::PollConnectionListener(poller, 0.1, &timed_out);
+  EXPECT_FALSE(timed_out);
+  ASSERT_EQ(result.size(), 1u);
+  EXPECT_EQ(handle, result[0].listener);
+  EXPECT_TRUE(result[0].connected);
+
+  // trigger a disconnect event
+  nt::StopClient(client_inst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  // get the event
+  ASSERT_TRUE(nt::WaitForConnectionListenerQueue(server_inst, 1.0));
+  timed_out = false;
+  result = nt::PollConnectionListener(poller, 0.1, &timed_out);
+  EXPECT_FALSE(timed_out);
+  ASSERT_EQ(result.size(), 1u);
+  EXPECT_EQ(handle, result[0].listener);
+  EXPECT_FALSE(result[0].connected);
+
+  // trigger a disconnect event
+}
+
+TEST_F(ConnectionListenerTest, Threaded) {
+  std::vector<nt::ConnectionNotification> result;
+  auto handle = nt::AddConnectionListener(
+      server_inst,
+      [&](const nt::ConnectionNotification& event) { result.push_back(event); },
+      false);
+
+  // trigger a connect event
+  Connect();
+
+  ASSERT_TRUE(nt::WaitForConnectionListenerQueue(server_inst, 1.0));
+
+  // get the event
+  ASSERT_EQ(result.size(), 1u);
+  EXPECT_EQ(handle, result[0].listener);
+  EXPECT_TRUE(result[0].connected);
+  result.clear();
+
+  // trigger a disconnect event
+  nt::StopClient(client_inst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  // get the event
+  ASSERT_EQ(result.size(), 1u);
+  EXPECT_EQ(handle, result[0].listener);
+  EXPECT_FALSE(result[0].connected);
+}
diff --git a/ntcore/src/test/native/cpp/EntryListenerTest.cpp b/ntcore/src/test/native/cpp/EntryListenerTest.cpp
new file mode 100644
index 0000000..b7bf2f6
--- /dev/null
+++ b/ntcore/src/test/native/cpp/EntryListenerTest.cpp
@@ -0,0 +1,164 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <chrono>
+#include <thread>
+
+#include "TestPrinters.h"
+#include "ValueMatcher.h"
+#include "gtest/gtest.h"
+#include "ntcore_cpp.h"
+
+class EntryListenerTest : public ::testing::Test {
+ public:
+  EntryListenerTest()
+      : server_inst(nt::CreateInstance()), client_inst(nt::CreateInstance()) {
+    nt::SetNetworkIdentity(server_inst, "server");
+    nt::SetNetworkIdentity(client_inst, "client");
+#if 0
+    nt::AddLogger(server_inst,
+                  [](const nt::LogMessage& msg) {
+                    std::fprintf(stderr, "SERVER: %s\n", msg.message.c_str());
+                  },
+                  0, UINT_MAX);
+    nt::AddLogger(client_inst,
+                  [](const nt::LogMessage& msg) {
+                    std::fprintf(stderr, "CLIENT: %s\n", msg.message.c_str());
+                  },
+                  0, UINT_MAX);
+#endif
+  }
+
+  ~EntryListenerTest() override {
+    nt::DestroyInstance(server_inst);
+    nt::DestroyInstance(client_inst);
+  }
+
+  void Connect();
+
+ protected:
+  NT_Inst server_inst;
+  NT_Inst client_inst;
+};
+
+void EntryListenerTest::Connect() {
+  nt::StartServer(server_inst, "entrylistenertest.ini", "127.0.0.1", 10000);
+  nt::StartClient(client_inst, "127.0.0.1", 10000);
+
+  // Use connection listener to ensure we've connected
+  NT_ConnectionListenerPoller poller =
+      nt::CreateConnectionListenerPoller(server_inst);
+  nt::AddPolledConnectionListener(poller, false);
+  bool timed_out = false;
+  if (nt::PollConnectionListener(poller, 1.0, &timed_out).empty()) {
+    FAIL() << "client didn't connect to server";
+  }
+}
+
+TEST_F(EntryListenerTest, EntryNewLocal) {
+  std::vector<nt::EntryNotification> events;
+  auto handle = nt::AddEntryListener(
+      nt::GetEntry(server_inst, "/foo"),
+      [&](const nt::EntryNotification& event) { events.push_back(event); },
+      NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
+
+  // Trigger an event
+  nt::SetEntryValue(nt::GetEntry(server_inst, "/foo/bar"),
+                    nt::Value::MakeDouble(2.0));
+  nt::SetEntryValue(nt::GetEntry(server_inst, "/foo"),
+                    nt::Value::MakeDouble(1.0));
+
+  ASSERT_TRUE(nt::WaitForEntryListenerQueue(server_inst, 1.0));
+
+  // Check the event
+  ASSERT_EQ(events.size(), 1u);
+  ASSERT_EQ(events[0].listener, handle);
+  ASSERT_EQ(events[0].entry, nt::GetEntry(server_inst, "/foo"));
+  ASSERT_EQ(events[0].name, "/foo");
+  ASSERT_THAT(events[0].value, nt::ValueEq(nt::Value::MakeDouble(1.0)));
+  ASSERT_EQ(events[0].flags, (unsigned int)(NT_NOTIFY_NEW | NT_NOTIFY_LOCAL));
+}
+
+TEST_F(EntryListenerTest, DISABLED_EntryNewRemote) {
+  Connect();
+  if (HasFatalFailure()) return;
+  std::vector<nt::EntryNotification> events;
+  auto handle = nt::AddEntryListener(
+      nt::GetEntry(server_inst, "/foo"),
+      [&](const nt::EntryNotification& event) { events.push_back(event); },
+      NT_NOTIFY_NEW);
+
+  // Trigger an event
+  nt::SetEntryValue(nt::GetEntry(client_inst, "/foo/bar"),
+                    nt::Value::MakeDouble(2.0));
+  nt::SetEntryValue(nt::GetEntry(client_inst, "/foo"),
+                    nt::Value::MakeDouble(1.0));
+  nt::Flush(client_inst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  ASSERT_TRUE(nt::WaitForEntryListenerQueue(server_inst, 1.0));
+
+  // Check the event
+  ASSERT_EQ(events.size(), 1u);
+  ASSERT_EQ(events[0].listener, handle);
+  ASSERT_EQ(events[0].entry, nt::GetEntry(server_inst, "/foo"));
+  ASSERT_EQ(events[0].name, "/foo");
+  ASSERT_THAT(events[0].value, nt::ValueEq(nt::Value::MakeDouble(1.0)));
+  ASSERT_EQ(events[0].flags, NT_NOTIFY_NEW);
+}
+
+TEST_F(EntryListenerTest, PrefixNewLocal) {
+  std::vector<nt::EntryNotification> events;
+  auto handle = nt::AddEntryListener(
+      server_inst, "/foo",
+      [&](const nt::EntryNotification& event) { events.push_back(event); },
+      NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
+
+  // Trigger an event
+  nt::SetEntryValue(nt::GetEntry(server_inst, "/foo/bar"),
+                    nt::Value::MakeDouble(1.0));
+  nt::SetEntryValue(nt::GetEntry(server_inst, "/baz"),
+                    nt::Value::MakeDouble(1.0));
+
+  ASSERT_TRUE(nt::WaitForEntryListenerQueue(server_inst, 1.0));
+
+  // Check the event
+  ASSERT_EQ(events.size(), 1u);
+  ASSERT_EQ(events[0].listener, handle);
+  ASSERT_EQ(events[0].entry, nt::GetEntry(server_inst, "/foo/bar"));
+  ASSERT_EQ(events[0].name, "/foo/bar");
+  ASSERT_THAT(events[0].value, nt::ValueEq(nt::Value::MakeDouble(1.0)));
+  ASSERT_EQ(events[0].flags, (unsigned int)(NT_NOTIFY_NEW | NT_NOTIFY_LOCAL));
+}
+
+TEST_F(EntryListenerTest, DISABLED_PrefixNewRemote) {
+  Connect();
+  if (HasFatalFailure()) return;
+  std::vector<nt::EntryNotification> events;
+  auto handle = nt::AddEntryListener(
+      server_inst, "/foo",
+      [&](const nt::EntryNotification& event) { events.push_back(event); },
+      NT_NOTIFY_NEW);
+
+  // Trigger an event
+  nt::SetEntryValue(nt::GetEntry(client_inst, "/foo/bar"),
+                    nt::Value::MakeDouble(1.0));
+  nt::SetEntryValue(nt::GetEntry(client_inst, "/baz"),
+                    nt::Value::MakeDouble(1.0));
+  nt::Flush(client_inst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  ASSERT_TRUE(nt::WaitForEntryListenerQueue(server_inst, 1.0));
+
+  // Check the event
+  ASSERT_EQ(events.size(), 1u);
+  ASSERT_EQ(events[0].listener, handle);
+  ASSERT_EQ(events[0].entry, nt::GetEntry(server_inst, "/foo/bar"));
+  ASSERT_EQ(events[0].name, "/foo/bar");
+  ASSERT_THAT(events[0].value, nt::ValueEq(nt::Value::MakeDouble(1.0)));
+  ASSERT_EQ(events[0].flags, NT_NOTIFY_NEW);
+}
diff --git a/ntcore/src/test/native/cpp/EntryNotifierTest.cpp b/ntcore/src/test/native/cpp/EntryNotifierTest.cpp
new file mode 100644
index 0000000..604db3d
--- /dev/null
+++ b/ntcore/src/test/native/cpp/EntryNotifierTest.cpp
@@ -0,0 +1,314 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <wpi/Logger.h>
+
+#include "EntryNotifier.h"
+#include "TestPrinters.h"
+#include "ValueMatcher.h"
+#include "gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::IsNull;
+using ::testing::Return;
+
+namespace nt {
+
+class EntryNotifierTest : public ::testing::Test {
+ public:
+  EntryNotifierTest() : notifier(1, logger) { notifier.Start(); }
+
+  void GenerateNotifications();
+
+ protected:
+  wpi::Logger logger;
+  EntryNotifier notifier;
+};
+
+void EntryNotifierTest::GenerateNotifications() {
+  // All flags combos that can be generated by Storage
+  static const unsigned int flags[] = {
+      // "normal" notifications
+      NT_NOTIFY_NEW, NT_NOTIFY_DELETE, NT_NOTIFY_UPDATE, NT_NOTIFY_FLAGS,
+      NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS,
+      // immediate notifications are always "new"
+      NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW,
+      // local notifications can be of any flag combo
+      NT_NOTIFY_LOCAL | NT_NOTIFY_NEW, NT_NOTIFY_LOCAL | NT_NOTIFY_DELETE,
+      NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE, NT_NOTIFY_LOCAL | NT_NOTIFY_FLAGS,
+      NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS};
+  // Generate across keys
+  static const char* keys[] = {"/foo/bar", "/baz", "/boo"};
+
+  auto val = Value::MakeDouble(1);
+
+  // Provide unique key indexes for each key
+  unsigned int keyindex = 5;
+  for (auto key : keys) {
+    for (auto flag : flags) {
+      notifier.NotifyEntry(keyindex, key, val, flag);
+    }
+    ++keyindex;
+  }
+}
+
+TEST_F(EntryNotifierTest, PollEntryMultiple) {
+  auto poller1 = notifier.CreatePoller();
+  auto poller2 = notifier.CreatePoller();
+  auto poller3 = notifier.CreatePoller();
+  auto h1 = notifier.AddPolled(poller1, 6, NT_NOTIFY_NEW);
+  auto h2 = notifier.AddPolled(poller2, 6, NT_NOTIFY_NEW);
+  auto h3 = notifier.AddPolled(poller3, 6, NT_NOTIFY_UPDATE);
+
+  ASSERT_FALSE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results1 = notifier.Poll(poller1, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  auto results2 = notifier.Poll(poller2, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  auto results3 = notifier.Poll(poller3, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+
+  ASSERT_EQ(results1.size(), 2u);
+  for (const auto& result : results1) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(Handle{result.listener}.GetIndex(), (int)h1);
+  }
+
+  ASSERT_EQ(results2.size(), 2u);
+  for (const auto& result : results2) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(Handle{result.listener}.GetIndex(), (int)h2);
+  }
+
+  ASSERT_EQ(results3.size(), 2u);
+  for (const auto& result : results3) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(Handle{result.listener}.GetIndex(), (int)h3);
+  }
+}
+
+TEST_F(EntryNotifierTest, PollEntryBasic) {
+  auto poller = notifier.CreatePoller();
+  auto g1 = notifier.AddPolled(poller, 6, NT_NOTIFY_NEW);
+  auto g2 = notifier.AddPolled(poller, 6, NT_NOTIFY_DELETE);
+  auto g3 = notifier.AddPolled(poller, 6, NT_NOTIFY_UPDATE);
+  auto g4 = notifier.AddPolled(poller, 6, NT_NOTIFY_FLAGS);
+
+  ASSERT_FALSE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results = notifier.Poll(poller, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+
+  int g1count = 0;
+  int g2count = 0;
+  int g3count = 0;
+  int g4count = 0;
+  for (const auto& result : results) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(result.name, "/baz");
+    EXPECT_THAT(result.value, ValueEq(Value::MakeDouble(1)));
+    EXPECT_EQ(Handle{result.entry}.GetType(), Handle::kEntry);
+    EXPECT_EQ(Handle{result.entry}.GetInst(), 1);
+    EXPECT_EQ(Handle{result.entry}.GetIndex(), 6);
+    EXPECT_EQ(Handle{result.listener}.GetType(), Handle::kEntryListener);
+    EXPECT_EQ(Handle{result.listener}.GetInst(), 1);
+    if (Handle{result.listener}.GetIndex() == static_cast<int>(g1)) {
+      ++g1count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_NEW) != 0);
+    } else if (Handle{result.listener}.GetIndex() == static_cast<int>(g2)) {
+      ++g2count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_DELETE) != 0);
+    } else if (Handle{result.listener}.GetIndex() == static_cast<int>(g3)) {
+      ++g3count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_UPDATE) != 0);
+    } else if (Handle{result.listener}.GetIndex() == static_cast<int>(g4)) {
+      ++g4count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_FLAGS) != 0);
+    } else {
+      ADD_FAILURE() << "unknown listener index";
+    }
+  }
+  EXPECT_EQ(g1count, 2);
+  EXPECT_EQ(g2count, 1);  // NT_NOTIFY_DELETE
+  EXPECT_EQ(g3count, 2);
+  EXPECT_EQ(g4count, 2);
+}
+
+TEST_F(EntryNotifierTest, PollEntryImmediate) {
+  auto poller = notifier.CreatePoller();
+  notifier.AddPolled(poller, 6, NT_NOTIFY_NEW | NT_NOTIFY_IMMEDIATE);
+  notifier.AddPolled(poller, 6, NT_NOTIFY_NEW);
+
+  ASSERT_FALSE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results = notifier.Poll(poller, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  SCOPED_TRACE(::testing::PrintToString(results));
+  ASSERT_EQ(results.size(), 4u);
+}
+
+TEST_F(EntryNotifierTest, PollEntryLocal) {
+  auto poller = notifier.CreatePoller();
+  notifier.AddPolled(poller, 6, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
+  notifier.AddPolled(poller, 6, NT_NOTIFY_NEW);
+
+  ASSERT_TRUE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results = notifier.Poll(poller, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  SCOPED_TRACE(::testing::PrintToString(results));
+  ASSERT_EQ(results.size(), 6u);
+}
+
+TEST_F(EntryNotifierTest, PollPrefixMultiple) {
+  auto poller1 = notifier.CreatePoller();
+  auto poller2 = notifier.CreatePoller();
+  auto poller3 = notifier.CreatePoller();
+  auto h1 = notifier.AddPolled(poller1, "/foo", NT_NOTIFY_NEW);
+  auto h2 = notifier.AddPolled(poller2, "/foo", NT_NOTIFY_NEW);
+  auto h3 = notifier.AddPolled(poller3, "/foo", NT_NOTIFY_UPDATE);
+
+  ASSERT_FALSE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results1 = notifier.Poll(poller1, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  auto results2 = notifier.Poll(poller2, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  auto results3 = notifier.Poll(poller3, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+
+  ASSERT_EQ(results1.size(), 2u);
+  for (const auto& result : results1) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(Handle{result.listener}.GetIndex(), (int)h1);
+  }
+
+  ASSERT_EQ(results2.size(), 2u);
+  for (const auto& result : results2) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(Handle{result.listener}.GetIndex(), (int)h2);
+  }
+
+  ASSERT_EQ(results3.size(), 2u);
+  for (const auto& result : results3) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_EQ(Handle{result.listener}.GetIndex(), (int)h3);
+  }
+}
+
+TEST_F(EntryNotifierTest, PollPrefixBasic) {
+  auto poller = notifier.CreatePoller();
+  auto g1 = notifier.AddPolled(poller, "/foo", NT_NOTIFY_NEW);
+  auto g2 = notifier.AddPolled(poller, "/foo", NT_NOTIFY_DELETE);
+  auto g3 = notifier.AddPolled(poller, "/foo", NT_NOTIFY_UPDATE);
+  auto g4 = notifier.AddPolled(poller, "/foo", NT_NOTIFY_FLAGS);
+  notifier.AddPolled(poller, "/bar", NT_NOTIFY_NEW);
+  notifier.AddPolled(poller, "/bar", NT_NOTIFY_DELETE);
+  notifier.AddPolled(poller, "/bar", NT_NOTIFY_UPDATE);
+  notifier.AddPolled(poller, "/bar", NT_NOTIFY_FLAGS);
+
+  ASSERT_FALSE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results = notifier.Poll(poller, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+
+  int g1count = 0;
+  int g2count = 0;
+  int g3count = 0;
+  int g4count = 0;
+  for (const auto& result : results) {
+    SCOPED_TRACE(::testing::PrintToString(result));
+    EXPECT_TRUE(StringRef(result.name).startswith("/foo"));
+    EXPECT_THAT(result.value, ValueEq(Value::MakeDouble(1)));
+    EXPECT_EQ(Handle{result.entry}.GetType(), Handle::kEntry);
+    EXPECT_EQ(Handle{result.entry}.GetInst(), 1);
+    EXPECT_EQ(Handle{result.entry}.GetIndex(), 5);
+    EXPECT_EQ(Handle{result.listener}.GetType(), Handle::kEntryListener);
+    EXPECT_EQ(Handle{result.listener}.GetInst(), 1);
+    if (Handle{result.listener}.GetIndex() == static_cast<int>(g1)) {
+      ++g1count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_NEW) != 0);
+    } else if (Handle{result.listener}.GetIndex() == static_cast<int>(g2)) {
+      ++g2count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_DELETE) != 0);
+    } else if (Handle{result.listener}.GetIndex() == static_cast<int>(g3)) {
+      ++g3count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_UPDATE) != 0);
+    } else if (Handle{result.listener}.GetIndex() == static_cast<int>(g4)) {
+      ++g4count;
+      EXPECT_TRUE((result.flags & NT_NOTIFY_FLAGS) != 0);
+    } else {
+      ADD_FAILURE() << "unknown listener index";
+    }
+  }
+  EXPECT_EQ(g1count, 2);
+  EXPECT_EQ(g2count, 1);  // NT_NOTIFY_DELETE
+  EXPECT_EQ(g3count, 2);
+  EXPECT_EQ(g4count, 2);
+}
+
+TEST_F(EntryNotifierTest, PollPrefixImmediate) {
+  auto poller = notifier.CreatePoller();
+  notifier.AddPolled(poller, "/foo", NT_NOTIFY_NEW | NT_NOTIFY_IMMEDIATE);
+  notifier.AddPolled(poller, "/foo", NT_NOTIFY_NEW);
+
+  ASSERT_FALSE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results = notifier.Poll(poller, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  SCOPED_TRACE(::testing::PrintToString(results));
+  ASSERT_EQ(results.size(), 4u);
+}
+
+TEST_F(EntryNotifierTest, PollPrefixLocal) {
+  auto poller = notifier.CreatePoller();
+  notifier.AddPolled(poller, "/foo", NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
+  notifier.AddPolled(poller, "/foo", NT_NOTIFY_NEW);
+
+  ASSERT_TRUE(notifier.local_notifiers());
+
+  GenerateNotifications();
+
+  ASSERT_TRUE(notifier.WaitForQueue(1.0));
+  bool timed_out = false;
+  auto results = notifier.Poll(poller, 0, &timed_out);
+  ASSERT_FALSE(timed_out);
+  SCOPED_TRACE(::testing::PrintToString(results));
+  ASSERT_EQ(results.size(), 6u);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/MessageMatcher.cpp b/ntcore/src/test/native/cpp/MessageMatcher.cpp
new file mode 100644
index 0000000..35d4f8b
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MessageMatcher.cpp
@@ -0,0 +1,52 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "MessageMatcher.h"
+
+namespace nt {
+
+bool MessageMatcher::MatchAndExplain(
+    std::shared_ptr<Message> msg,
+    ::testing::MatchResultListener* listener) const {
+  bool match = true;
+  if (!msg) return false;
+  if (msg->str() != goodmsg->str()) {
+    *listener << "str mismatch ";
+    match = false;
+  }
+  if ((!msg->value() && goodmsg->value()) ||
+      (msg->value() && !goodmsg->value()) ||
+      (msg->value() && goodmsg->value() &&
+       *msg->value() != *goodmsg->value())) {
+    *listener << "value mismatch ";
+    match = false;
+  }
+  if (msg->id() != goodmsg->id()) {
+    *listener << "id mismatch ";
+    match = false;
+  }
+  if (msg->flags() != goodmsg->flags()) {
+    *listener << "flags mismatch";
+    match = false;
+  }
+  if (msg->seq_num_uid() != goodmsg->seq_num_uid()) {
+    *listener << "seq_num_uid mismatch";
+    match = false;
+  }
+  return match;
+}
+
+void MessageMatcher::DescribeTo(::std::ostream* os) const {
+  PrintTo(goodmsg, os);
+}
+
+void MessageMatcher::DescribeNegationTo(::std::ostream* os) const {
+  *os << "is not equal to ";
+  PrintTo(goodmsg, os);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/MessageMatcher.h b/ntcore/src/test/native/cpp/MessageMatcher.h
new file mode 100644
index 0000000..5b14334
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MessageMatcher.h
@@ -0,0 +1,42 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MESSAGEMATCHER_H_
+#define NTCORE_MESSAGEMATCHER_H_
+
+#include <memory>
+#include <ostream>
+
+#include "Message.h"
+#include "TestPrinters.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MessageMatcher
+    : public ::testing::MatcherInterface<std::shared_ptr<Message>> {
+ public:
+  explicit MessageMatcher(std::shared_ptr<Message> goodmsg_)
+      : goodmsg(goodmsg_) {}
+
+  bool MatchAndExplain(std::shared_ptr<Message> msg,
+                       ::testing::MatchResultListener* listener) const override;
+  void DescribeTo(::std::ostream* os) const override;
+  void DescribeNegationTo(::std::ostream* os) const override;
+
+ private:
+  std::shared_ptr<Message> goodmsg;
+};
+
+inline ::testing::Matcher<std::shared_ptr<Message>> MessageEq(
+    std::shared_ptr<Message> goodmsg) {
+  return ::testing::MakeMatcher(new MessageMatcher(goodmsg));
+}
+
+}  // namespace nt
+
+#endif  // NTCORE_MESSAGEMATCHER_H_
diff --git a/ntcore/src/test/native/cpp/MockConnectionNotifier.h b/ntcore/src/test/native/cpp/MockConnectionNotifier.h
new file mode 100644
index 0000000..ddf8b2e
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockConnectionNotifier.h
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MOCKCONNECTIONNOTIFIER_H_
+#define NTCORE_MOCKCONNECTIONNOTIFIER_H_
+
+#include "IConnectionNotifier.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockConnectionNotifier : public IConnectionNotifier {
+ public:
+  MOCK_METHOD1(
+      Add,
+      unsigned int(
+          std::function<void(const ConnectionNotification& event)> callback));
+  MOCK_METHOD1(AddPolled, unsigned int(unsigned int poller_uid));
+  MOCK_METHOD3(NotifyConnection,
+               void(bool connected, const ConnectionInfo& conn_info,
+                    unsigned int only_listener));
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_MOCKCONNECTIONNOTIFIER_H_
diff --git a/ntcore/src/test/native/cpp/MockDispatcher.h b/ntcore/src/test/native/cpp/MockDispatcher.h
new file mode 100644
index 0000000..10af839
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockDispatcher.h
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MOCKDISPATCHER_H_
+#define NTCORE_MOCKDISPATCHER_H_
+
+#include <memory>
+
+#include "IDispatcher.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockDispatcher : public IDispatcher {
+ public:
+  MOCK_METHOD3(QueueOutgoing,
+               void(std::shared_ptr<Message> msg, INetworkConnection* only,
+                    INetworkConnection* except));
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_MOCKDISPATCHER_H_
diff --git a/ntcore/src/test/native/cpp/MockEntryNotifier.h b/ntcore/src/test/native/cpp/MockEntryNotifier.h
new file mode 100644
index 0000000..2f078cb
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockEntryNotifier.h
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MOCKENTRYNOTIFIER_H_
+#define NTCORE_MOCKENTRYNOTIFIER_H_
+
+#include <memory>
+
+#include "IEntryNotifier.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockEntryNotifier : public IEntryNotifier {
+ public:
+  MOCK_CONST_METHOD0(local_notifiers, bool());
+  MOCK_METHOD3(
+      Add,
+      unsigned int(std::function<void(const EntryNotification& event)> callback,
+                   wpi::StringRef prefix, unsigned int flags));
+  MOCK_METHOD3(
+      Add,
+      unsigned int(std::function<void(const EntryNotification& event)> callback,
+                   unsigned int local_id, unsigned int flags));
+  MOCK_METHOD3(AddPolled,
+               unsigned int(unsigned int poller_uid, wpi::StringRef prefix,
+                            unsigned int flags));
+  MOCK_METHOD3(AddPolled,
+               unsigned int(unsigned int poller_uid, unsigned int local_id,
+                            unsigned int flags));
+  MOCK_METHOD5(NotifyEntry,
+               void(unsigned int local_id, StringRef name,
+                    std::shared_ptr<Value> value, unsigned int flags,
+                    unsigned int only_listener));
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_MOCKENTRYNOTIFIER_H_
diff --git a/ntcore/src/test/native/cpp/MockNetworkConnection.h b/ntcore/src/test/native/cpp/MockNetworkConnection.h
new file mode 100644
index 0000000..52c917d
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockNetworkConnection.h
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MOCKNETWORKCONNECTION_H_
+#define NTCORE_MOCKNETWORKCONNECTION_H_
+
+#include <memory>
+
+#include "INetworkConnection.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockNetworkConnection : public INetworkConnection {
+ public:
+  MOCK_CONST_METHOD0(info, ConnectionInfo());
+
+  MOCK_METHOD1(QueueOutgoing, void(std::shared_ptr<Message> msg));
+  MOCK_METHOD1(PostOutgoing, void(bool keep_alive));
+
+  MOCK_CONST_METHOD0(proto_rev, unsigned int());
+  MOCK_METHOD1(set_proto_rev, void(unsigned int proto_rev));
+
+  MOCK_CONST_METHOD0(state, State());
+  MOCK_METHOD1(set_state, void(State state));
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_MOCKNETWORKCONNECTION_H_
diff --git a/ntcore/src/test/native/cpp/MockRpcServer.h b/ntcore/src/test/native/cpp/MockRpcServer.h
new file mode 100644
index 0000000..6e9d970
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockRpcServer.h
@@ -0,0 +1,29 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_MOCKRPCSERVER_H_
+#define NTCORE_MOCKRPCSERVER_H_
+
+#include "IRpcServer.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockRpcServer : public IRpcServer {
+ public:
+  MOCK_METHOD0(Start, void());
+  MOCK_METHOD1(RemoveRpc, void(unsigned int rpc_uid));
+  MOCK_METHOD7(ProcessRpc,
+               void(unsigned int local_id, unsigned int call_uid,
+                    StringRef name, StringRef params,
+                    const ConnectionInfo& conn, SendResponseFunc send_response,
+                    unsigned int rpc_uid));
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_MOCKRPCSERVER_H_
diff --git a/ntcore/src/test/native/cpp/NetworkTableTest.cpp b/ntcore/src/test/native/cpp/NetworkTableTest.cpp
new file mode 100644
index 0000000..d9a2743
--- /dev/null
+++ b/ntcore/src/test/native/cpp/NetworkTableTest.cpp
@@ -0,0 +1,91 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "TestPrinters.h"
+#include "gtest/gtest.h"
+#include "networktables/NetworkTable.h"
+#include "networktables/NetworkTableInstance.h"
+
+class NetworkTableTest : public ::testing::Test {};
+
+TEST_F(NetworkTableTest, BasenameKey) {
+  EXPECT_EQ("simple", NetworkTable::BasenameKey("simple"));
+  EXPECT_EQ("simple", NetworkTable::BasenameKey("one/two/many/simple"));
+  EXPECT_EQ("simple",
+            NetworkTable::BasenameKey("//////an/////awful/key////simple"));
+}
+
+TEST_F(NetworkTableTest, NormalizeKeySlash) {
+  EXPECT_EQ("/", NetworkTable::NormalizeKey("///"));
+  EXPECT_EQ("/no/normal/req", NetworkTable::NormalizeKey("/no/normal/req"));
+  EXPECT_EQ("/no/leading/slash",
+            NetworkTable::NormalizeKey("no/leading/slash"));
+  EXPECT_EQ("/what/an/awful/key/",
+            NetworkTable::NormalizeKey("//////what////an/awful/////key///"));
+}
+
+TEST_F(NetworkTableTest, NormalizeKeyNoSlash) {
+  EXPECT_EQ("a", NetworkTable::NormalizeKey("a", false));
+  EXPECT_EQ("a", NetworkTable::NormalizeKey("///a", false));
+  EXPECT_EQ("leading/slash",
+            NetworkTable::NormalizeKey("/leading/slash", false));
+  EXPECT_EQ("no/leading/slash",
+            NetworkTable::NormalizeKey("no/leading/slash", false));
+  EXPECT_EQ(
+      "what/an/awful/key/",
+      NetworkTable::NormalizeKey("//////what////an/awful/////key///", false));
+}
+
+TEST_F(NetworkTableTest, GetHierarchyEmpty) {
+  std::vector<std::string> expected{"/"};
+  ASSERT_EQ(expected, NetworkTable::GetHierarchy(""));
+}
+
+TEST_F(NetworkTableTest, GetHierarchyRoot) {
+  std::vector<std::string> expected{"/"};
+  ASSERT_EQ(expected, NetworkTable::GetHierarchy("/"));
+}
+
+TEST_F(NetworkTableTest, GetHierarchyNormal) {
+  std::vector<std::string> expected{"/", "/foo", "/foo/bar", "/foo/bar/baz"};
+  ASSERT_EQ(expected, NetworkTable::GetHierarchy("/foo/bar/baz"));
+}
+
+TEST_F(NetworkTableTest, GetHierarchyTrailingSlash) {
+  std::vector<std::string> expected{"/", "/foo", "/foo/bar", "/foo/bar/"};
+  ASSERT_EQ(expected, NetworkTable::GetHierarchy("/foo/bar/"));
+}
+
+TEST_F(NetworkTableTest, ContainsKey) {
+  auto inst = nt::NetworkTableInstance::Create();
+  auto nt = inst.GetTable("containskey");
+  ASSERT_FALSE(nt->ContainsKey("testkey"));
+  nt->PutNumber("testkey", 5);
+  ASSERT_TRUE(nt->ContainsKey("testkey"));
+  ASSERT_TRUE(inst.GetEntry("/containskey/testkey").Exists());
+  ASSERT_FALSE(inst.GetEntry("containskey/testkey").Exists());
+}
+
+TEST_F(NetworkTableTest, LeadingSlash) {
+  auto inst = nt::NetworkTableInstance::Create();
+  auto nt = inst.GetTable("leadingslash");
+  auto nt2 = inst.GetTable("/leadingslash");
+  ASSERT_FALSE(nt->ContainsKey("testkey"));
+  nt2->PutNumber("testkey", 5);
+  ASSERT_TRUE(nt->ContainsKey("testkey"));
+  ASSERT_TRUE(inst.GetEntry("/leadingslash/testkey").Exists());
+}
+
+TEST_F(NetworkTableTest, EmptyOrNoSlash) {
+  auto inst = nt::NetworkTableInstance::Create();
+  auto nt = inst.GetTable("/");
+  auto nt2 = inst.GetTable("");
+  ASSERT_FALSE(nt->ContainsKey("testkey"));
+  nt2->PutNumber("testkey", 5);
+  ASSERT_TRUE(nt->ContainsKey("testkey"));
+  ASSERT_TRUE(inst.GetEntry("/testkey").Exists());
+}
diff --git a/ntcore/src/test/native/cpp/StorageTest.cpp b/ntcore/src/test/native/cpp/StorageTest.cpp
new file mode 100644
index 0000000..f271123
--- /dev/null
+++ b/ntcore/src/test/native/cpp/StorageTest.cpp
@@ -0,0 +1,993 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "StorageTest.h"
+
+#include <wpi/raw_istream.h>
+#include <wpi/raw_ostream.h>
+
+#include "MessageMatcher.h"
+#include "MockNetworkConnection.h"
+#include "Storage.h"
+#include "TestPrinters.h"
+#include "ValueMatcher.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::IsNull;
+using ::testing::Return;
+
+namespace nt {
+
+class StorageTestEmpty : public StorageTest,
+                         public ::testing::TestWithParam<bool> {
+ public:
+  StorageTestEmpty() {
+    HookOutgoing(GetParam());
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(true));
+  }
+};
+
+class StorageTestPopulateOne : public StorageTestEmpty {
+ public:
+  StorageTestPopulateOne() {
+    EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+    EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(false));
+    storage.SetEntryTypeValue("foo", Value::MakeBoolean(true));
+    ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+    ::testing::Mock::VerifyAndClearExpectations(&notifier);
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(true));
+  }
+};
+
+class StorageTestPopulated : public StorageTestEmpty {
+ public:
+  StorageTestPopulated() {
+    EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+    EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(false));
+    storage.SetEntryTypeValue("foo", Value::MakeBoolean(true));
+    storage.SetEntryTypeValue("foo2", Value::MakeDouble(0.0));
+    storage.SetEntryTypeValue("bar", Value::MakeDouble(1.0));
+    storage.SetEntryTypeValue("bar2", Value::MakeBoolean(false));
+    ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+    ::testing::Mock::VerifyAndClearExpectations(&notifier);
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(true));
+  }
+};
+
+class StorageTestPersistent : public StorageTestEmpty {
+ public:
+  StorageTestPersistent() {
+    EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+    EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(false));
+    storage.SetEntryTypeValue("boolean/true", Value::MakeBoolean(true));
+    storage.SetEntryTypeValue("boolean/false", Value::MakeBoolean(false));
+    storage.SetEntryTypeValue("double/neg", Value::MakeDouble(-1.5));
+    storage.SetEntryTypeValue("double/zero", Value::MakeDouble(0.0));
+    storage.SetEntryTypeValue("double/big", Value::MakeDouble(1.3e8));
+    storage.SetEntryTypeValue("string/empty", Value::MakeString(""));
+    storage.SetEntryTypeValue("string/normal", Value::MakeString("hello"));
+    storage.SetEntryTypeValue("string/special",
+                              Value::MakeString(StringRef("\0\3\5\n", 4)));
+    storage.SetEntryTypeValue("string/quoted", Value::MakeString("\"a\""));
+    storage.SetEntryTypeValue("raw/empty", Value::MakeRaw(""));
+    storage.SetEntryTypeValue("raw/normal", Value::MakeRaw("hello"));
+    storage.SetEntryTypeValue("raw/special",
+                              Value::MakeRaw(StringRef("\0\3\5\n", 4)));
+    storage.SetEntryTypeValue("booleanarr/empty",
+                              Value::MakeBooleanArray(std::vector<int>{}));
+    storage.SetEntryTypeValue("booleanarr/one",
+                              Value::MakeBooleanArray(std::vector<int>{1}));
+    storage.SetEntryTypeValue("booleanarr/two",
+                              Value::MakeBooleanArray(std::vector<int>{1, 0}));
+    storage.SetEntryTypeValue("doublearr/empty",
+                              Value::MakeDoubleArray(std::vector<double>{}));
+    storage.SetEntryTypeValue("doublearr/one",
+                              Value::MakeDoubleArray(std::vector<double>{0.5}));
+    storage.SetEntryTypeValue(
+        "doublearr/two",
+        Value::MakeDoubleArray(std::vector<double>{0.5, -0.25}));
+    storage.SetEntryTypeValue(
+        "stringarr/empty", Value::MakeStringArray(std::vector<std::string>{}));
+    storage.SetEntryTypeValue(
+        "stringarr/one",
+        Value::MakeStringArray(std::vector<std::string>{"hello"}));
+    storage.SetEntryTypeValue(
+        "stringarr/two",
+        Value::MakeStringArray(std::vector<std::string>{"hello", "world\n"}));
+    storage.SetEntryTypeValue(StringRef("\0\3\5\n", 4),
+                              Value::MakeBoolean(true));
+    storage.SetEntryTypeValue("=", Value::MakeBoolean(true));
+    ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+    ::testing::Mock::VerifyAndClearExpectations(&notifier);
+    EXPECT_CALL(notifier, local_notifiers())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(true));
+  }
+};
+
+class MockLoadWarn {
+ public:
+  MOCK_METHOD2(Warn, void(size_t line, wpi::StringRef msg));
+};
+
+TEST_P(StorageTestEmpty, Construct) {
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, StorageEntryInit) {
+  auto entry = GetEntry("foo");
+  EXPECT_FALSE(entry->value);
+  EXPECT_EQ(0u, entry->flags);
+  EXPECT_EQ("foobar", entry->name);  // since GetEntry uses the tmp_entry.
+  EXPECT_EQ(0xffffu, entry->id);
+  EXPECT_EQ(SequenceNumber(), entry->seq_num);
+}
+
+TEST_P(StorageTestEmpty, GetEntryValueNotExist) {
+  EXPECT_FALSE(storage.GetEntryValue("foo"));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, GetEntryValueExist) {
+  auto value = Value::MakeBoolean(true);
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _));
+  storage.SetEntryTypeValue("foo", value);
+  EXPECT_EQ(value, storage.GetEntryValue("foo"));
+}
+
+TEST_P(StorageTestEmpty, SetEntryTypeValueAssignNew) {
+  // brand new entry
+  auto value = Value::MakeBoolean(true);
+  // id assigned if server
+  EXPECT_CALL(dispatcher,
+              QueueOutgoing(MessageEq(Message::EntryAssign(
+                                "foo", GetParam() ? 0 : 0xffff, 1, value, 0)),
+                            IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"), value,
+                                    NT_NOTIFY_NEW | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  storage.SetEntryTypeValue("foo", value);
+  EXPECT_EQ(value, GetEntry("foo")->value);
+  if (GetParam()) {
+    ASSERT_EQ(1u, idmap().size());
+    EXPECT_EQ(value, idmap()[0]->value);
+  } else {
+    EXPECT_TRUE(idmap().empty());
+  }
+}
+
+TEST_P(StorageTestPopulateOne, SetEntryTypeValueAssignTypeChange) {
+  // update with different type results in assignment message
+  auto value = Value::MakeDouble(0.0);
+
+  // id assigned if server; seq_num incremented
+  EXPECT_CALL(dispatcher,
+              QueueOutgoing(MessageEq(Message::EntryAssign(
+                                "foo", GetParam() ? 0 : 0xffff, 2, value, 0)),
+                            IsNull(), IsNull()));
+  EXPECT_CALL(notifier,
+              NotifyEntry(0, StringRef("foo"), value,
+                          NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  storage.SetEntryTypeValue("foo", value);
+  EXPECT_EQ(value, GetEntry("foo")->value);
+}
+
+TEST_P(StorageTestPopulateOne, SetEntryTypeValueEqualValue) {
+  // update with same type and same value: change value contents but no update
+  // message is issued (minimizing bandwidth usage)
+  auto value = Value::MakeBoolean(true);
+  storage.SetEntryTypeValue("foo", value);
+  EXPECT_EQ(value, GetEntry("foo")->value);
+}
+
+TEST_P(StorageTestPopulated, SetEntryTypeValueDifferentValue) {
+  // update with same type and different value results in value update message
+  auto value = Value::MakeDouble(1.0);
+
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned if server; seq_num incremented
+    EXPECT_CALL(dispatcher,
+                QueueOutgoing(MessageEq(Message::EntryUpdate(1, 2, value)),
+                              IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), value,
+                          NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL, UINT_MAX));
+  storage.SetEntryTypeValue("foo2", value);
+  EXPECT_EQ(value, GetEntry("foo2")->value);
+
+  if (!GetParam()) {
+    // seq_num should still be incremented
+    EXPECT_EQ(2u, GetEntry("foo2")->seq_num.value());
+  }
+}
+
+TEST_P(StorageTestEmpty, SetEntryTypeValueEmptyName) {
+  auto value = Value::MakeBoolean(true);
+  storage.SetEntryTypeValue("", value);
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, SetEntryTypeValueEmptyValue) {
+  storage.SetEntryTypeValue("foo", nullptr);
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, SetEntryValueAssignNew) {
+  // brand new entry
+  auto value = Value::MakeBoolean(true);
+
+  // id assigned if server
+  EXPECT_CALL(dispatcher,
+              QueueOutgoing(MessageEq(Message::EntryAssign(
+                                "foo", GetParam() ? 0 : 0xffff, 1, value, 0)),
+                            IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"), value,
+                                    NT_NOTIFY_NEW | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  EXPECT_TRUE(storage.SetEntryValue("foo", value));
+  EXPECT_EQ(value, GetEntry("foo")->value);
+}
+
+TEST_P(StorageTestPopulateOne, SetEntryValueAssignTypeChange) {
+  // update with different type results in error and no message or notification
+  auto value = Value::MakeDouble(0.0);
+  EXPECT_FALSE(storage.SetEntryValue("foo", value));
+  auto entry = GetEntry("foo");
+  EXPECT_NE(value, entry->value);
+}
+
+TEST_P(StorageTestPopulateOne, SetEntryValueEqualValue) {
+  // update with same type and same value: change value contents but no update
+  // message is issued (minimizing bandwidth usage)
+  auto value = Value::MakeBoolean(true);
+  EXPECT_TRUE(storage.SetEntryValue("foo", value));
+  auto entry = GetEntry("foo");
+  EXPECT_EQ(value, entry->value);
+}
+
+TEST_P(StorageTestPopulated, SetEntryValueDifferentValue) {
+  // update with same type and different value results in value update message
+  auto value = Value::MakeDouble(1.0);
+
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned if server; seq_num incremented
+    EXPECT_CALL(dispatcher,
+                QueueOutgoing(MessageEq(Message::EntryUpdate(1, 2, value)),
+                              IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), value,
+                          NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  EXPECT_TRUE(storage.SetEntryValue("foo2", value));
+  auto entry = GetEntry("foo2");
+  EXPECT_EQ(value, entry->value);
+
+  if (!GetParam()) {
+    // seq_num should still be incremented
+    EXPECT_EQ(2u, GetEntry("foo2")->seq_num.value());
+  }
+}
+
+TEST_P(StorageTestEmpty, SetEntryValueEmptyName) {
+  auto value = Value::MakeBoolean(true);
+  EXPECT_TRUE(storage.SetEntryValue("", value));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, SetEntryValueEmptyValue) {
+  EXPECT_TRUE(storage.SetEntryValue("foo", nullptr));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, SetDefaultEntryAssignNew) {
+  // brand new entry
+  auto value = Value::MakeBoolean(true);
+
+  // id assigned if server
+  EXPECT_CALL(dispatcher,
+              QueueOutgoing(MessageEq(Message::EntryAssign(
+                                "foo", GetParam() ? 0 : 0xffff, 1, value, 0)),
+                            IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"), value,
+                                    NT_NOTIFY_NEW | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  auto ret_val = storage.SetDefaultEntryValue("foo", value);
+  EXPECT_TRUE(ret_val);
+  EXPECT_EQ(value, GetEntry("foo")->value);
+}
+
+TEST_P(StorageTestPopulateOne, SetDefaultEntryExistsSameType) {
+  // existing entry
+  auto value = Value::MakeBoolean(true);
+  auto ret_val = storage.SetDefaultEntryValue("foo", value);
+  EXPECT_TRUE(ret_val);
+  EXPECT_NE(value, GetEntry("foo")->value);
+}
+
+TEST_P(StorageTestPopulateOne, SetDefaultEntryExistsDifferentType) {
+  // existing entry is boolean
+  auto value = Value::MakeDouble(2.0);
+  auto ret_val = storage.SetDefaultEntryValue("foo", value);
+  EXPECT_FALSE(ret_val);
+  // should not have updated value in table if it already existed.
+  EXPECT_NE(value, GetEntry("foo")->value);
+}
+
+TEST_P(StorageTestEmpty, SetDefaultEntryEmptyName) {
+  auto value = Value::MakeBoolean(true);
+  auto ret_val = storage.SetDefaultEntryValue("", value);
+  EXPECT_FALSE(ret_val);
+  auto entry = GetEntry("foo");
+  EXPECT_FALSE(entry->value);
+  EXPECT_EQ(0u, entry->flags);
+  EXPECT_EQ("foobar", entry->name);  // since GetEntry uses the tmp_entry.
+  EXPECT_EQ(0xffffu, entry->id);
+  EXPECT_EQ(SequenceNumber(), entry->seq_num);
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, SetDefaultEntryEmptyValue) {
+  auto value = Value::MakeBoolean(true);
+  auto ret_val = storage.SetDefaultEntryValue("", nullptr);
+  EXPECT_FALSE(ret_val);
+  auto entry = GetEntry("foo");
+  EXPECT_FALSE(entry->value);
+  EXPECT_EQ(0u, entry->flags);
+  EXPECT_EQ("foobar", entry->name);  // since GetEntry uses the tmp_entry.
+  EXPECT_EQ(0xffffu, entry->id);
+  EXPECT_EQ(SequenceNumber(), entry->seq_num);
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestPopulated, SetDefaultEntryEmptyName) {
+  auto value = Value::MakeBoolean(true);
+  auto ret_val = storage.SetDefaultEntryValue("", value);
+  EXPECT_FALSE(ret_val);
+  // assert that no entries get added
+  EXPECT_EQ(4u, entries().size());
+  if (GetParam())
+    EXPECT_EQ(4u, idmap().size());
+  else
+    EXPECT_EQ(0u, idmap().size());
+}
+
+TEST_P(StorageTestPopulated, SetDefaultEntryEmptyValue) {
+  auto value = Value::MakeBoolean(true);
+  auto ret_val = storage.SetDefaultEntryValue("", nullptr);
+  EXPECT_FALSE(ret_val);
+  // assert that no entries get added
+  EXPECT_EQ(4u, entries().size());
+  if (GetParam())
+    EXPECT_EQ(4u, idmap().size());
+  else
+    EXPECT_EQ(0u, idmap().size());
+}
+
+TEST_P(StorageTestEmpty, SetEntryFlagsNew) {
+  // flags setting doesn't create an entry
+  storage.SetEntryFlags("foo", 0u);
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestPopulateOne, SetEntryFlagsEqualValue) {
+  // update with same value: no update message is issued (minimizing bandwidth
+  // usage)
+  storage.SetEntryFlags("foo", 0u);
+  auto entry = GetEntry("foo");
+  EXPECT_EQ(0u, entry->flags);
+}
+
+TEST_P(StorageTestPopulated, SetEntryFlagsDifferentValue) {
+  // update with different value results in flags update message
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned as this is the server
+    EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::FlagsUpdate(1, 1)),
+                                          IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), _,
+                          NT_NOTIFY_FLAGS | NT_NOTIFY_LOCAL, UINT_MAX));
+  storage.SetEntryFlags("foo2", 1u);
+  EXPECT_EQ(1u, GetEntry("foo2")->flags);
+}
+
+TEST_P(StorageTestEmpty, SetEntryFlagsEmptyName) {
+  storage.SetEntryFlags("", 0u);
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, GetEntryFlagsNotExist) {
+  EXPECT_EQ(0u, storage.GetEntryFlags("foo"));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestPopulateOne, GetEntryFlagsExist) {
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _));
+  storage.SetEntryFlags("foo", 1u);
+  ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+  EXPECT_EQ(1u, storage.GetEntryFlags("foo"));
+}
+
+TEST_P(StorageTestEmpty, DeleteEntryNotExist) { storage.DeleteEntry("foo"); }
+
+TEST_P(StorageTestPopulated, DeleteEntryExist) {
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned as this is the server
+    EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::EntryDelete(1)),
+                                          IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), ValueEq(Value::MakeDouble(0)),
+                          NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  storage.DeleteEntry("foo2");
+  ASSERT_EQ(1u, entries().count("foo2"));
+  EXPECT_EQ(nullptr, entries()["foo2"]->value);
+  EXPECT_EQ(0xffffu, entries()["foo2"]->id);
+  EXPECT_FALSE(entries()["foo2"]->local_write);
+  if (GetParam()) {
+    ASSERT_TRUE(idmap().size() >= 2);
+    EXPECT_FALSE(idmap()[1]);
+  }
+}
+
+TEST_P(StorageTestEmpty, DeleteAllEntriesEmpty) {
+  storage.DeleteAllEntries();
+  ASSERT_TRUE(entries().empty());
+}
+
+TEST_P(StorageTestPopulated, DeleteAllEntries) {
+  EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::ClearEntries()),
+                                        IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL,
+                                    UINT_MAX))
+      .Times(4);
+
+  storage.DeleteAllEntries();
+  ASSERT_EQ(1u, entries().count("foo2"));
+  EXPECT_EQ(nullptr, entries()["foo2"]->value);
+}
+
+TEST_P(StorageTestPopulated, DeleteAllEntriesPersistent) {
+  GetEntry("foo2")->flags = NT_PERSISTENT;
+
+  EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::ClearEntries()),
+                                        IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL,
+                                    UINT_MAX))
+      .Times(3);
+
+  storage.DeleteAllEntries();
+  ASSERT_EQ(1u, entries().count("foo2"));
+  EXPECT_NE(nullptr, entries()["foo2"]->value);
+}
+
+TEST_P(StorageTestPopulated, GetEntryInfoAll) {
+  auto info = storage.GetEntryInfo(0, "", 0u);
+  ASSERT_EQ(4u, info.size());
+}
+
+TEST_P(StorageTestPopulated, GetEntryInfoPrefix) {
+  auto info = storage.GetEntryInfo(0, "foo", 0u);
+  ASSERT_EQ(2u, info.size());
+  if (info[0].name == "foo") {
+    EXPECT_EQ("foo", info[0].name);
+    EXPECT_EQ(NT_BOOLEAN, info[0].type);
+    EXPECT_EQ("foo2", info[1].name);
+    EXPECT_EQ(NT_DOUBLE, info[1].type);
+  } else {
+    EXPECT_EQ("foo2", info[0].name);
+    EXPECT_EQ(NT_DOUBLE, info[0].type);
+    EXPECT_EQ("foo", info[1].name);
+    EXPECT_EQ(NT_BOOLEAN, info[1].type);
+  }
+}
+
+TEST_P(StorageTestPopulated, GetEntryInfoTypes) {
+  auto info = storage.GetEntryInfo(0, "", NT_DOUBLE);
+  ASSERT_EQ(2u, info.size());
+  EXPECT_EQ(NT_DOUBLE, info[0].type);
+  EXPECT_EQ(NT_DOUBLE, info[1].type);
+  if (info[0].name == "foo2") {
+    EXPECT_EQ("foo2", info[0].name);
+    EXPECT_EQ("bar", info[1].name);
+  } else {
+    EXPECT_EQ("bar", info[0].name);
+    EXPECT_EQ("foo2", info[1].name);
+  }
+}
+
+TEST_P(StorageTestPopulated, GetEntryInfoPrefixTypes) {
+  auto info = storage.GetEntryInfo(0, "bar", NT_BOOLEAN);
+  ASSERT_EQ(1u, info.size());
+  EXPECT_EQ("bar2", info[0].name);
+  EXPECT_EQ(NT_BOOLEAN, info[0].type);
+}
+
+TEST_P(StorageTestPersistent, SavePersistentEmpty) {
+  wpi::SmallString<256> buf;
+  wpi::raw_svector_ostream oss(buf);
+  storage.SavePersistent(oss, false);
+  ASSERT_EQ("[NetworkTables Storage 3.0]\n", oss.str());
+}
+
+TEST_P(StorageTestPersistent, SavePersistent) {
+  for (auto& i : entries()) i.getValue()->flags = NT_PERSISTENT;
+  wpi::SmallString<256> buf;
+  wpi::raw_svector_ostream oss(buf);
+  storage.SavePersistent(oss, false);
+  wpi::StringRef out = oss.str();
+  // std::fputs(out.c_str(), stderr);
+  wpi::StringRef line, rem = out;
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("[NetworkTables Storage 3.0]", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("boolean \"\\x00\\x03\\x05\\n\"=true", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("boolean \"\\x3D\"=true", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("boolean \"boolean/false\"=false", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("boolean \"boolean/true\"=true", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array boolean \"booleanarr/empty\"=", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array boolean \"booleanarr/one\"=true", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array boolean \"booleanarr/two\"=true,false", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("double \"double/big\"=1.3e+08", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("double \"double/neg\"=-1.5", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("double \"double/zero\"=0", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array double \"doublearr/empty\"=", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array double \"doublearr/one\"=0.5", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array double \"doublearr/two\"=0.5,-0.25", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("raw \"raw/empty\"=", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("raw \"raw/normal\"=aGVsbG8=", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("raw \"raw/special\"=AAMFCg==", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("string \"string/empty\"=\"\"", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("string \"string/normal\"=\"hello\"", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("string \"string/quoted\"=\"\\\"a\\\"\"", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("string \"string/special\"=\"\\x00\\x03\\x05\\n\"", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array string \"stringarr/empty\"=", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array string \"stringarr/one\"=\"hello\"", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("array string \"stringarr/two\"=\"hello\",\"world\\n\"", line);
+  std::tie(line, rem) = rem.split('\n');
+  ASSERT_EQ("", line);
+}
+
+TEST_P(StorageTestEmpty, LoadPersistentBadHeader) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  wpi::raw_mem_istream iss("");
+  EXPECT_CALL(
+      warn,
+      Warn(1, wpi::StringRef("header line mismatch, ignoring rest of file")));
+  EXPECT_FALSE(storage.LoadEntries(iss, "", true, warn_func));
+
+  wpi::raw_mem_istream iss2("[NetworkTables");
+  EXPECT_CALL(
+      warn,
+      Warn(1, wpi::StringRef("header line mismatch, ignoring rest of file")));
+
+  EXPECT_FALSE(storage.LoadEntries(iss2, "", true, warn_func));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, LoadPersistentCommentHeader) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  wpi::raw_mem_istream iss(
+      "\n; comment\n# comment\n[NetworkTables Storage 3.0]\n");
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, LoadPersistentEmptyName) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  wpi::raw_mem_istream iss("[NetworkTables Storage 3.0]\nboolean \"\"=true\n");
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, LoadPersistentAssign) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  auto value = Value::MakeBoolean(true);
+
+  // id assigned if server
+  EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::EntryAssign(
+                                            "foo", GetParam() ? 0 : 0xffff, 1,
+                                            value, NT_PERSISTENT)),
+                                        IsNull(), IsNull()));
+  EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"),
+                                    ValueEq(Value::MakeBoolean(true)),
+                                    NT_NOTIFY_NEW | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  wpi::raw_mem_istream iss(
+      "[NetworkTables Storage 3.0]\nboolean \"foo\"=true\n");
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  auto entry = GetEntry("foo");
+  EXPECT_EQ(*value, *entry->value);
+  EXPECT_EQ(NT_PERSISTENT, entry->flags);
+}
+
+TEST_P(StorageTestPopulated, LoadPersistentUpdateFlags) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned as this is server
+    EXPECT_CALL(dispatcher,
+                QueueOutgoing(MessageEq(Message::FlagsUpdate(1, NT_PERSISTENT)),
+                              IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), ValueEq(Value::MakeDouble(0)),
+                          NT_NOTIFY_FLAGS | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  wpi::raw_mem_istream iss(
+      "[NetworkTables Storage 3.0]\ndouble \"foo2\"=0.0\n");
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  auto entry = GetEntry("foo2");
+  EXPECT_EQ(*Value::MakeDouble(0.0), *entry->value);
+  EXPECT_EQ(NT_PERSISTENT, entry->flags);
+}
+
+TEST_P(StorageTestPopulated, LoadPersistentUpdateValue) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  GetEntry("foo2")->flags = NT_PERSISTENT;
+
+  auto value = Value::MakeDouble(1.0);
+
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned as this is the server; seq_num incremented
+    EXPECT_CALL(dispatcher,
+                QueueOutgoing(MessageEq(Message::EntryUpdate(1, 2, value)),
+                              IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), ValueEq(Value::MakeDouble(1)),
+                          NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL, UINT_MAX));
+
+  wpi::raw_mem_istream iss(
+      "[NetworkTables Storage 3.0]\ndouble \"foo2\"=1.0\n");
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  auto entry = GetEntry("foo2");
+  EXPECT_EQ(*value, *entry->value);
+  EXPECT_EQ(NT_PERSISTENT, entry->flags);
+
+  if (!GetParam()) {
+    // seq_num should still be incremented
+    EXPECT_EQ(2u, GetEntry("foo2")->seq_num.value());
+  }
+}
+
+TEST_P(StorageTestPopulated, LoadPersistentUpdateValueFlags) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  auto value = Value::MakeDouble(1.0);
+
+  // client shouldn't send an update as id not assigned yet
+  if (GetParam()) {
+    // id assigned as this is the server; seq_num incremented
+    EXPECT_CALL(dispatcher,
+                QueueOutgoing(MessageEq(Message::EntryUpdate(1, 2, value)),
+                              IsNull(), IsNull()));
+    EXPECT_CALL(dispatcher,
+                QueueOutgoing(MessageEq(Message::FlagsUpdate(1, NT_PERSISTENT)),
+                              IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier,
+              NotifyEntry(1, StringRef("foo2"), ValueEq(Value::MakeDouble(1)),
+                          NT_NOTIFY_FLAGS | NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL,
+                          UINT_MAX));
+
+  wpi::raw_mem_istream iss(
+      "[NetworkTables Storage 3.0]\ndouble \"foo2\"=1.0\n");
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  auto entry = GetEntry("foo2");
+  EXPECT_EQ(*value, *entry->value);
+  EXPECT_EQ(NT_PERSISTENT, entry->flags);
+
+  if (!GetParam()) {
+    // seq_num should still be incremented
+    EXPECT_EQ(2u, GetEntry("foo2")->seq_num.value());
+  }
+}
+
+TEST_P(StorageTestEmpty, LoadPersistent) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  std::string in = "[NetworkTables Storage 3.0]\n";
+  in += "boolean \"\\x00\\x03\\x05\\n\"=true\n";
+  in += "boolean \"\\x3D\"=true\n";
+  in += "boolean \"boolean/false\"=false\n";
+  in += "boolean \"boolean/true\"=true\n";
+  in += "array boolean \"booleanarr/empty\"=\n";
+  in += "array boolean \"booleanarr/one\"=true\n";
+  in += "array boolean \"booleanarr/two\"=true,false\n";
+  in += "double \"double/big\"=1.3e+08\n";
+  in += "double \"double/neg\"=-1.5\n";
+  in += "double \"double/zero\"=0\n";
+  in += "array double \"doublearr/empty\"=\n";
+  in += "array double \"doublearr/one\"=0.5\n";
+  in += "array double \"doublearr/two\"=0.5,-0.25\n";
+  in += "raw \"raw/empty\"=\n";
+  in += "raw \"raw/normal\"=aGVsbG8=\n";
+  in += "raw \"raw/special\"=AAMFCg==\n";
+  in += "string \"string/empty\"=\"\"\n";
+  in += "string \"string/normal\"=\"hello\"\n";
+  in += "string \"string/special\"=\"\\x00\\x03\\x05\\n\"\n";
+  in += "string \"string/quoted\"=\"\\\"a\\\"\"\n";
+  in += "array string \"stringarr/empty\"=\n";
+  in += "array string \"stringarr/one\"=\"hello\"\n";
+  in += "array string \"stringarr/two\"=\"hello\",\"world\\n\"\n";
+
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(23);
+  EXPECT_CALL(notifier,
+              NotifyEntry(_, _, _, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL, UINT_MAX))
+      .Times(23);
+
+  wpi::raw_mem_istream iss(in);
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+  ASSERT_EQ(23u, entries().size());
+
+  EXPECT_EQ(*Value::MakeBoolean(true), *storage.GetEntryValue("boolean/true"));
+  EXPECT_EQ(*Value::MakeBoolean(false),
+            *storage.GetEntryValue("boolean/false"));
+  EXPECT_EQ(*Value::MakeDouble(-1.5), *storage.GetEntryValue("double/neg"));
+  EXPECT_EQ(*Value::MakeDouble(0.0), *storage.GetEntryValue("double/zero"));
+  EXPECT_EQ(*Value::MakeDouble(1.3e8), *storage.GetEntryValue("double/big"));
+  EXPECT_EQ(*Value::MakeString(""), *storage.GetEntryValue("string/empty"));
+  EXPECT_EQ(*Value::MakeString("hello"),
+            *storage.GetEntryValue("string/normal"));
+  EXPECT_EQ(*Value::MakeString(StringRef("\0\3\5\n", 4)),
+            *storage.GetEntryValue("string/special"));
+  EXPECT_EQ(*Value::MakeString("\"a\""),
+            *storage.GetEntryValue("string/quoted"));
+  EXPECT_EQ(*Value::MakeRaw(""), *storage.GetEntryValue("raw/empty"));
+  EXPECT_EQ(*Value::MakeRaw("hello"), *storage.GetEntryValue("raw/normal"));
+  EXPECT_EQ(*Value::MakeRaw(StringRef("\0\3\5\n", 4)),
+            *storage.GetEntryValue("raw/special"));
+  EXPECT_EQ(*Value::MakeBooleanArray(std::vector<int>{}),
+            *storage.GetEntryValue("booleanarr/empty"));
+  EXPECT_EQ(*Value::MakeBooleanArray(std::vector<int>{1}),
+            *storage.GetEntryValue("booleanarr/one"));
+  EXPECT_EQ(*Value::MakeBooleanArray(std::vector<int>{1, 0}),
+            *storage.GetEntryValue("booleanarr/two"));
+  EXPECT_EQ(*Value::MakeDoubleArray(std::vector<double>{}),
+            *storage.GetEntryValue("doublearr/empty"));
+  EXPECT_EQ(*Value::MakeDoubleArray(std::vector<double>{0.5}),
+            *storage.GetEntryValue("doublearr/one"));
+  EXPECT_EQ(*Value::MakeDoubleArray(std::vector<double>{0.5, -0.25}),
+            *storage.GetEntryValue("doublearr/two"));
+  EXPECT_EQ(*Value::MakeStringArray(std::vector<std::string>{}),
+            *storage.GetEntryValue("stringarr/empty"));
+  EXPECT_EQ(*Value::MakeStringArray(std::vector<std::string>{"hello"}),
+            *storage.GetEntryValue("stringarr/one"));
+  EXPECT_EQ(
+      *Value::MakeStringArray(std::vector<std::string>{"hello", "world\n"}),
+      *storage.GetEntryValue("stringarr/two"));
+  EXPECT_EQ(*Value::MakeBoolean(true),
+            *storage.GetEntryValue(StringRef("\0\3\5\n", 4)));
+  EXPECT_EQ(*Value::MakeBoolean(true), *storage.GetEntryValue("="));
+}
+
+TEST_P(StorageTestEmpty, LoadPersistentWarn) {
+  MockLoadWarn warn;
+  auto warn_func = [&](size_t line, const char* msg) { warn.Warn(line, msg); };
+
+  wpi::raw_mem_istream iss(
+      "[NetworkTables Storage 3.0]\nboolean \"foo\"=foo\n");
+  EXPECT_CALL(
+      warn, Warn(2, wpi::StringRef(
+                        "unrecognized boolean value, not 'true' or 'false'")));
+  EXPECT_TRUE(storage.LoadEntries(iss, "", true, warn_func));
+
+  EXPECT_TRUE(entries().empty());
+  EXPECT_TRUE(idmap().empty());
+}
+
+TEST_P(StorageTestEmpty, ProcessIncomingEntryAssign) {
+  auto conn = std::make_shared<MockNetworkConnection>();
+  auto value = Value::MakeDouble(1.0);
+  if (GetParam()) {
+    // id assign message reply generated on the server; sent to everyone
+    EXPECT_CALL(
+        dispatcher,
+        QueueOutgoing(MessageEq(Message::EntryAssign("foo", 0, 0, value, 0)),
+                      IsNull(), IsNull()));
+  }
+  EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"), ValueEq(value),
+                                    NT_NOTIFY_NEW, UINT_MAX));
+
+  storage.ProcessIncoming(
+      Message::EntryAssign("foo", GetParam() ? 0xffff : 0, 0, value, 0),
+      conn.get(), conn);
+}
+
+TEST_P(StorageTestPopulateOne, ProcessIncomingEntryAssign) {
+  auto conn = std::make_shared<MockNetworkConnection>();
+  auto value = Value::MakeDouble(1.0);
+  EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u));
+  if (GetParam()) {
+    // server broadcasts new value to all *other* connections
+    EXPECT_CALL(
+        dispatcher,
+        QueueOutgoing(MessageEq(Message::EntryAssign("foo", 0, 1, value, 0)),
+                      IsNull(), conn.get()));
+  }
+  EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"), ValueEq(value),
+                                    NT_NOTIFY_UPDATE, UINT_MAX));
+
+  storage.ProcessIncoming(Message::EntryAssign("foo", 0, 1, value, 0),
+                          conn.get(), conn);
+}
+
+TEST_P(StorageTestPopulateOne, ProcessIncomingEntryAssignIgnore) {
+  auto conn = std::make_shared<MockNetworkConnection>();
+  auto value = Value::MakeDouble(1.0);
+  storage.ProcessIncoming(Message::EntryAssign("foo", 0xffff, 1, value, 0),
+                          conn.get(), conn);
+}
+
+TEST_P(StorageTestPopulateOne, ProcessIncomingEntryAssignWithFlags) {
+  auto conn = std::make_shared<MockNetworkConnection>();
+  auto value = Value::MakeDouble(1.0);
+  EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u));
+  if (GetParam()) {
+    // server broadcasts new value/flags to all *other* connections
+    EXPECT_CALL(
+        dispatcher,
+        QueueOutgoing(MessageEq(Message::EntryAssign("foo", 0, 1, value, 0x2)),
+                      IsNull(), conn.get()));
+    EXPECT_CALL(notifier,
+                NotifyEntry(0, StringRef("foo"), ValueEq(value),
+                            NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS, UINT_MAX));
+  } else {
+    // client forces flags back when an assign message is received for an
+    // existing entry with different flags
+    EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::FlagsUpdate(0, 0)),
+                                          IsNull(), IsNull()));
+    EXPECT_CALL(notifier, NotifyEntry(0, StringRef("foo"), ValueEq(value),
+                                      NT_NOTIFY_UPDATE, UINT_MAX));
+  }
+
+  storage.ProcessIncoming(Message::EntryAssign("foo", 0, 1, value, 0x2),
+                          conn.get(), conn);
+}
+
+TEST_P(StorageTestPopulateOne, DeleteCheckHandle) {
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+  auto handle = storage.GetEntry("foo");
+  storage.DeleteEntry("foo");
+  storage.SetEntryTypeValue("foo", Value::MakeBoolean(true));
+  ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+  ::testing::Mock::VerifyAndClearExpectations(&notifier);
+
+  auto handle2 = storage.GetEntry("foo");
+  ASSERT_EQ(handle, handle2);
+}
+
+TEST_P(StorageTestPopulateOne, DeletedEntryFlags) {
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+  auto handle = storage.GetEntry("foo");
+  storage.SetEntryFlags("foo", 2);
+  storage.DeleteEntry("foo");
+  ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+  ::testing::Mock::VerifyAndClearExpectations(&notifier);
+
+  EXPECT_EQ(storage.GetEntryFlags("foo"), 0u);
+  EXPECT_EQ(storage.GetEntryFlags(handle), 0u);
+  storage.SetEntryFlags("foo", 4);
+  storage.SetEntryFlags(handle, 4);
+  EXPECT_EQ(storage.GetEntryFlags("foo"), 0u);
+  EXPECT_EQ(storage.GetEntryFlags(handle), 0u);
+}
+
+TEST_P(StorageTestPopulateOne, DeletedDeleteAllEntries) {
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+  storage.DeleteEntry("foo");
+  ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+  ::testing::Mock::VerifyAndClearExpectations(&notifier);
+
+  EXPECT_CALL(dispatcher, QueueOutgoing(MessageEq(Message::ClearEntries()),
+                                        IsNull(), IsNull()));
+  storage.DeleteAllEntries();
+}
+
+TEST_P(StorageTestPopulateOne, DeletedGetEntries) {
+  EXPECT_CALL(dispatcher, QueueOutgoing(_, _, _)).Times(AnyNumber());
+  EXPECT_CALL(notifier, NotifyEntry(_, _, _, _, _)).Times(AnyNumber());
+  storage.DeleteEntry("foo");
+  ::testing::Mock::VerifyAndClearExpectations(&dispatcher);
+  ::testing::Mock::VerifyAndClearExpectations(&notifier);
+
+  EXPECT_TRUE(storage.GetEntries("", 0).empty());
+}
+
+INSTANTIATE_TEST_SUITE_P(StorageTestsEmpty, StorageTestEmpty,
+                         ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(StorageTestsPopulateOne, StorageTestPopulateOne,
+                         ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(StorageTestsPopulated, StorageTestPopulated,
+                         ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(StorageTestsPersistent, StorageTestPersistent,
+                         ::testing::Bool());
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/StorageTest.h b/ntcore/src/test/native/cpp/StorageTest.h
new file mode 100644
index 0000000..1bb8a8c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/StorageTest.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_STORAGETEST_H_
+#define NTCORE_STORAGETEST_H_
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include "Log.h"
+#include "MockDispatcher.h"
+#include "MockEntryNotifier.h"
+#include "MockRpcServer.h"
+#include "Storage.h"
+
+namespace nt {
+
+class StorageTest {
+ public:
+  StorageTest() : storage(notifier, rpc_server, logger), tmp_entry("foobar") {}
+
+  Storage::EntriesMap& entries() { return storage.m_entries; }
+  Storage::IdMap& idmap() { return storage.m_idmap; }
+
+  Storage::Entry* GetEntry(StringRef name) {
+    auto i = storage.m_entries.find(name);
+    return i == storage.m_entries.end() ? &tmp_entry : i->getValue();
+  }
+
+  void HookOutgoing(bool server) { storage.SetDispatcher(&dispatcher, server); }
+
+  wpi::Logger logger;
+  ::testing::StrictMock<MockEntryNotifier> notifier;
+  ::testing::StrictMock<MockRpcServer> rpc_server;
+  ::testing::StrictMock<MockDispatcher> dispatcher;
+  Storage storage;
+  Storage::Entry tmp_entry;
+};
+
+}  // namespace nt
+
+#endif  // NTCORE_STORAGETEST_H_
diff --git a/ntcore/src/test/native/cpp/TestPrinters.cpp b/ntcore/src/test/native/cpp/TestPrinters.cpp
new file mode 100644
index 0000000..3368b8c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/TestPrinters.cpp
@@ -0,0 +1,156 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "TestPrinters.h"
+
+#include "Handle.h"
+#include "Message.h"
+#include "networktables/NetworkTableValue.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+void PrintTo(const EntryNotification& event, std::ostream* os) {
+  *os << "EntryNotification{listener=";
+  PrintTo(Handle{event.listener}, os);
+  *os << ", entry=";
+  PrintTo(Handle{event.entry}, os);
+  *os << ", name=\"" << event.name << "\", flags=" << event.flags << ", value=";
+  PrintTo(event.value, os);
+  *os << '}';
+}
+
+void PrintTo(const Handle& handle, std::ostream* os) {
+  *os << "Handle{";
+  switch (handle.GetType()) {
+    case Handle::kConnectionListener:
+      *os << "kConnectionListener";
+      break;
+    case Handle::kConnectionListenerPoller:
+      *os << "kConnectionListenerPoller";
+      break;
+    case Handle::kEntry:
+      *os << "kEntry";
+      break;
+    case Handle::kEntryListener:
+      *os << "kEntryListener";
+      break;
+    case Handle::kEntryListenerPoller:
+      *os << "kEntryListenerPoller";
+      break;
+    case Handle::kInstance:
+      *os << "kInstance";
+      break;
+    case Handle::kLogger:
+      *os << "kLogger";
+      break;
+    case Handle::kLoggerPoller:
+      *os << "kLoggerPoller";
+      break;
+    case Handle::kRpcCall:
+      *os << "kRpcCall";
+      break;
+    case Handle::kRpcCallPoller:
+      *os << "kRpcCallPoller";
+      break;
+    default:
+      *os << "UNKNOWN";
+      break;
+  }
+  *os << ", " << handle.GetInst() << ", " << handle.GetIndex() << '}';
+}
+
+void PrintTo(const Message& msg, std::ostream* os) {
+  *os << "Message{";
+  switch (msg.type()) {
+    case Message::kKeepAlive:
+      *os << "kKeepAlive";
+      break;
+    case Message::kClientHello:
+      *os << "kClientHello";
+      break;
+    case Message::kProtoUnsup:
+      *os << "kProtoUnsup";
+      break;
+    case Message::kServerHelloDone:
+      *os << "kServerHelloDone";
+      break;
+    case Message::kServerHello:
+      *os << "kServerHello";
+      break;
+    case Message::kClientHelloDone:
+      *os << "kClientHelloDone";
+      break;
+    case Message::kEntryAssign:
+      *os << "kEntryAssign";
+      break;
+    case Message::kEntryUpdate:
+      *os << "kEntryUpdate";
+      break;
+    case Message::kFlagsUpdate:
+      *os << "kFlagsUpdate";
+      break;
+    case Message::kEntryDelete:
+      *os << "kEntryDelete";
+      break;
+    case Message::kClearEntries:
+      *os << "kClearEntries";
+      break;
+    case Message::kExecuteRpc:
+      *os << "kExecuteRpc";
+      break;
+    case Message::kRpcResponse:
+      *os << "kRpcResponse";
+      break;
+    default:
+      *os << "UNKNOWN";
+      break;
+  }
+  *os << ": str=\"" << msg.str() << "\", id=" << msg.id()
+      << ", flags=" << msg.flags() << ", seq_num_uid=" << msg.seq_num_uid()
+      << ", value=";
+  PrintTo(msg.value(), os);
+  *os << '}';
+}
+
+void PrintTo(const Value& value, std::ostream* os) {
+  *os << "Value{";
+  switch (value.type()) {
+    case NT_UNASSIGNED:
+      break;
+    case NT_BOOLEAN:
+      *os << (value.GetBoolean() ? "true" : "false");
+      break;
+    case NT_DOUBLE:
+      *os << value.GetDouble();
+      break;
+    case NT_STRING:
+      *os << '"' << value.GetString().str() << '"';
+      break;
+    case NT_RAW:
+      *os << ::testing::PrintToString(value.GetRaw());
+      break;
+    case NT_BOOLEAN_ARRAY:
+      *os << ::testing::PrintToString(value.GetBooleanArray());
+      break;
+    case NT_DOUBLE_ARRAY:
+      *os << ::testing::PrintToString(value.GetDoubleArray());
+      break;
+    case NT_STRING_ARRAY:
+      *os << ::testing::PrintToString(value.GetStringArray());
+      break;
+    case NT_RPC:
+      *os << ::testing::PrintToString(value.GetRpc());
+      break;
+    default:
+      *os << "UNKNOWN TYPE " << value.type();
+      break;
+  }
+  *os << '}';
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/TestPrinters.h b/ntcore/src/test/native/cpp/TestPrinters.h
new file mode 100644
index 0000000..2976c1c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/TestPrinters.h
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_TESTPRINTERS_H_
+#define NTCORE_TESTPRINTERS_H_
+
+#include <memory>
+#include <ostream>
+
+#include <wpi/StringRef.h>
+
+#include "gtest/gtest.h"
+
+namespace wpi {
+
+inline void PrintTo(StringRef str, ::std::ostream* os) {
+  ::testing::internal::PrintStringTo(str.str(), os);
+}
+
+}  // namespace wpi
+
+namespace nt {
+
+class EntryNotification;
+class Handle;
+class Message;
+class Value;
+
+void PrintTo(const EntryNotification& event, std::ostream* os);
+void PrintTo(const Handle& handle, std::ostream* os);
+
+void PrintTo(const Message& msg, std::ostream* os);
+
+inline void PrintTo(std::shared_ptr<Message> msg, std::ostream* os) {
+  *os << "shared_ptr{";
+  if (msg) PrintTo(*msg, os);
+  *os << '}';
+}
+
+void PrintTo(const Value& value, std::ostream* os);
+
+inline void PrintTo(std::shared_ptr<Value> value, std::ostream* os) {
+  *os << "shared_ptr{";
+  if (value) PrintTo(*value, os);
+  *os << '}';
+}
+
+}  // namespace nt
+
+#endif  // NTCORE_TESTPRINTERS_H_
diff --git a/ntcore/src/test/native/cpp/ValueMatcher.cpp b/ntcore/src/test/native/cpp/ValueMatcher.cpp
new file mode 100644
index 0000000..45b09ed
--- /dev/null
+++ b/ntcore/src/test/native/cpp/ValueMatcher.cpp
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "ValueMatcher.h"
+
+#include "TestPrinters.h"
+
+namespace nt {
+
+bool ValueMatcher::MatchAndExplain(
+    std::shared_ptr<Value> val,
+    ::testing::MatchResultListener* listener) const {
+  if ((!val && goodval) || (val && !goodval) ||
+      (val && goodval && *val != *goodval)) {
+    return false;
+  }
+  return true;
+}
+
+void ValueMatcher::DescribeTo(::std::ostream* os) const {
+  PrintTo(goodval, os);
+}
+
+void ValueMatcher::DescribeNegationTo(::std::ostream* os) const {
+  *os << "is not equal to ";
+  PrintTo(goodval, os);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/ValueMatcher.h b/ntcore/src/test/native/cpp/ValueMatcher.h
new file mode 100644
index 0000000..5c417d7
--- /dev/null
+++ b/ntcore/src/test/native/cpp/ValueMatcher.h
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NTCORE_VALUEMATCHER_H_
+#define NTCORE_VALUEMATCHER_H_
+
+#include <memory>
+#include <ostream>
+
+#include "gmock/gmock.h"
+#include "networktables/NetworkTableValue.h"
+
+namespace nt {
+
+class ValueMatcher
+    : public ::testing::MatcherInterface<std::shared_ptr<Value>> {
+ public:
+  explicit ValueMatcher(std::shared_ptr<Value> goodval_) : goodval(goodval_) {}
+
+  bool MatchAndExplain(std::shared_ptr<Value> msg,
+                       ::testing::MatchResultListener* listener) const override;
+  void DescribeTo(::std::ostream* os) const override;
+  void DescribeNegationTo(::std::ostream* os) const override;
+
+ private:
+  std::shared_ptr<Value> goodval;
+};
+
+inline ::testing::Matcher<std::shared_ptr<Value>> ValueEq(
+    std::shared_ptr<Value> goodval) {
+  return ::testing::MakeMatcher(new ValueMatcher(goodval));
+}
+
+}  // namespace nt
+
+#endif  // NTCORE_VALUEMATCHER_H_
diff --git a/ntcore/src/test/native/cpp/ValueTest.cpp b/ntcore/src/test/native/cpp/ValueTest.cpp
new file mode 100644
index 0000000..818cdac
--- /dev/null
+++ b/ntcore/src/test/native/cpp/ValueTest.cpp
@@ -0,0 +1,365 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "TestPrinters.h"
+#include "Value_internal.h"
+#include "gtest/gtest.h"
+#include "networktables/NetworkTableValue.h"
+
+namespace nt {
+
+class ValueTest : public ::testing::Test {};
+
+typedef ValueTest ValueDeathTest;
+
+TEST_F(ValueTest, ConstructEmpty) {
+  Value v;
+  ASSERT_EQ(NT_UNASSIGNED, v.type());
+}
+
+TEST_F(ValueTest, Boolean) {
+  auto v = Value::MakeBoolean(false);
+  ASSERT_EQ(NT_BOOLEAN, v->type());
+  ASSERT_FALSE(v->GetBoolean());
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_BOOLEAN, cv.type);
+  ASSERT_EQ(0, cv.data.v_boolean);
+
+  v = Value::MakeBoolean(true);
+  ASSERT_EQ(NT_BOOLEAN, v->type());
+  ASSERT_TRUE(v->GetBoolean());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_BOOLEAN, cv.type);
+  ASSERT_EQ(1, cv.data.v_boolean);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueTest, Double) {
+  auto v = Value::MakeDouble(0.5);
+  ASSERT_EQ(NT_DOUBLE, v->type());
+  ASSERT_EQ(0.5, v->GetDouble());
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_DOUBLE, cv.type);
+  ASSERT_EQ(0.5, cv.data.v_double);
+
+  v = Value::MakeDouble(0.25);
+  ASSERT_EQ(NT_DOUBLE, v->type());
+  ASSERT_EQ(0.25, v->GetDouble());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_DOUBLE, cv.type);
+  ASSERT_EQ(0.25, cv.data.v_double);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueTest, String) {
+  auto v = Value::MakeString("hello");
+  ASSERT_EQ(NT_STRING, v->type());
+  ASSERT_EQ("hello", v->GetString());
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_STRING, cv.type);
+  ASSERT_EQ(wpi::StringRef("hello"), cv.data.v_string.str);
+  ASSERT_EQ(5u, cv.data.v_string.len);
+
+  v = Value::MakeString("goodbye");
+  ASSERT_EQ(NT_STRING, v->type());
+  ASSERT_EQ("goodbye", v->GetString());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_STRING, cv.type);
+  ASSERT_EQ(wpi::StringRef("goodbye"), cv.data.v_string.str);
+  ASSERT_EQ(7u, cv.data.v_string.len);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueTest, Raw) {
+  auto v = Value::MakeRaw("hello");
+  ASSERT_EQ(NT_RAW, v->type());
+  ASSERT_EQ("hello", v->GetRaw());
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_RAW, cv.type);
+  ASSERT_EQ(wpi::StringRef("hello"), cv.data.v_string.str);
+  ASSERT_EQ(5u, cv.data.v_string.len);
+
+  v = Value::MakeRaw("goodbye");
+  ASSERT_EQ(NT_RAW, v->type());
+  ASSERT_EQ("goodbye", v->GetRaw());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_RAW, cv.type);
+  ASSERT_EQ(wpi::StringRef("goodbye"), cv.data.v_string.str);
+  ASSERT_EQ(7u, cv.data.v_string.len);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueTest, BooleanArray) {
+  std::vector<int> vec{1, 0, 1};
+  auto v = Value::MakeBooleanArray(vec);
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, v->type());
+  ASSERT_EQ(wpi::ArrayRef<int>(vec), v->GetBooleanArray());
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, cv.type);
+  ASSERT_EQ(3u, cv.data.arr_boolean.size);
+  ASSERT_EQ(vec[0], cv.data.arr_boolean.arr[0]);
+  ASSERT_EQ(vec[1], cv.data.arr_boolean.arr[1]);
+  ASSERT_EQ(vec[2], cv.data.arr_boolean.arr[2]);
+
+  // assign with same size
+  vec = {0, 1, 0};
+  v = Value::MakeBooleanArray(vec);
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, v->type());
+  ASSERT_EQ(wpi::ArrayRef<int>(vec), v->GetBooleanArray());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, cv.type);
+  ASSERT_EQ(3u, cv.data.arr_boolean.size);
+  ASSERT_EQ(vec[0], cv.data.arr_boolean.arr[0]);
+  ASSERT_EQ(vec[1], cv.data.arr_boolean.arr[1]);
+  ASSERT_EQ(vec[2], cv.data.arr_boolean.arr[2]);
+
+  // assign with different size
+  vec = {1, 0};
+  v = Value::MakeBooleanArray(vec);
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, v->type());
+  ASSERT_EQ(wpi::ArrayRef<int>(vec), v->GetBooleanArray());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, cv.type);
+  ASSERT_EQ(2u, cv.data.arr_boolean.size);
+  ASSERT_EQ(vec[0], cv.data.arr_boolean.arr[0]);
+  ASSERT_EQ(vec[1], cv.data.arr_boolean.arr[1]);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueTest, DoubleArray) {
+  std::vector<double> vec{0.5, 0.25, 0.5};
+  auto v = Value::MakeDoubleArray(vec);
+  ASSERT_EQ(NT_DOUBLE_ARRAY, v->type());
+  ASSERT_EQ(wpi::ArrayRef<double>(vec), v->GetDoubleArray());
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_DOUBLE_ARRAY, cv.type);
+  ASSERT_EQ(3u, cv.data.arr_double.size);
+  ASSERT_EQ(vec[0], cv.data.arr_double.arr[0]);
+  ASSERT_EQ(vec[1], cv.data.arr_double.arr[1]);
+  ASSERT_EQ(vec[2], cv.data.arr_double.arr[2]);
+
+  // assign with same size
+  vec = {0.25, 0.5, 0.25};
+  v = Value::MakeDoubleArray(vec);
+  ASSERT_EQ(NT_DOUBLE_ARRAY, v->type());
+  ASSERT_EQ(wpi::ArrayRef<double>(vec), v->GetDoubleArray());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_DOUBLE_ARRAY, cv.type);
+  ASSERT_EQ(3u, cv.data.arr_double.size);
+  ASSERT_EQ(vec[0], cv.data.arr_double.arr[0]);
+  ASSERT_EQ(vec[1], cv.data.arr_double.arr[1]);
+  ASSERT_EQ(vec[2], cv.data.arr_double.arr[2]);
+
+  // assign with different size
+  vec = {0.5, 0.25};
+  v = Value::MakeDoubleArray(vec);
+  ASSERT_EQ(NT_DOUBLE_ARRAY, v->type());
+  ASSERT_EQ(wpi::ArrayRef<double>(vec), v->GetDoubleArray());
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_DOUBLE_ARRAY, cv.type);
+  ASSERT_EQ(2u, cv.data.arr_double.size);
+  ASSERT_EQ(vec[0], cv.data.arr_double.arr[0]);
+  ASSERT_EQ(vec[1], cv.data.arr_double.arr[1]);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueTest, StringArray) {
+  std::vector<std::string> vec;
+  vec.push_back("hello");
+  vec.push_back("goodbye");
+  vec.push_back("string");
+  auto v = Value::MakeStringArray(std::move(vec));
+  ASSERT_EQ(NT_STRING_ARRAY, v->type());
+  ASSERT_EQ(3u, v->GetStringArray().size());
+  ASSERT_EQ(wpi::StringRef("hello"), v->GetStringArray()[0]);
+  ASSERT_EQ(wpi::StringRef("goodbye"), v->GetStringArray()[1]);
+  ASSERT_EQ(wpi::StringRef("string"), v->GetStringArray()[2]);
+  NT_Value cv;
+  NT_InitValue(&cv);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_STRING_ARRAY, cv.type);
+  ASSERT_EQ(3u, cv.data.arr_string.size);
+  ASSERT_EQ(wpi::StringRef("hello"), cv.data.arr_string.arr[0].str);
+  ASSERT_EQ(wpi::StringRef("goodbye"), cv.data.arr_string.arr[1].str);
+  ASSERT_EQ(wpi::StringRef("string"), cv.data.arr_string.arr[2].str);
+
+  // assign with same size
+  vec.clear();
+  vec.push_back("s1");
+  vec.push_back("str2");
+  vec.push_back("string3");
+  v = Value::MakeStringArray(vec);
+  ASSERT_EQ(NT_STRING_ARRAY, v->type());
+  ASSERT_EQ(3u, v->GetStringArray().size());
+  ASSERT_EQ(wpi::StringRef("s1"), v->GetStringArray()[0]);
+  ASSERT_EQ(wpi::StringRef("str2"), v->GetStringArray()[1]);
+  ASSERT_EQ(wpi::StringRef("string3"), v->GetStringArray()[2]);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_STRING_ARRAY, cv.type);
+  ASSERT_EQ(3u, cv.data.arr_string.size);
+  ASSERT_EQ(wpi::StringRef("s1"), cv.data.arr_string.arr[0].str);
+  ASSERT_EQ(wpi::StringRef("str2"), cv.data.arr_string.arr[1].str);
+  ASSERT_EQ(wpi::StringRef("string3"), cv.data.arr_string.arr[2].str);
+
+  // assign with different size
+  vec.clear();
+  vec.push_back("short");
+  vec.push_back("er");
+  v = Value::MakeStringArray(std::move(vec));
+  ASSERT_EQ(NT_STRING_ARRAY, v->type());
+  ASSERT_EQ(2u, v->GetStringArray().size());
+  ASSERT_EQ(wpi::StringRef("short"), v->GetStringArray()[0]);
+  ASSERT_EQ(wpi::StringRef("er"), v->GetStringArray()[1]);
+  ConvertToC(*v, &cv);
+  ASSERT_EQ(NT_STRING_ARRAY, cv.type);
+  ASSERT_EQ(2u, cv.data.arr_string.size);
+  ASSERT_EQ(wpi::StringRef("short"), cv.data.arr_string.arr[0].str);
+  ASSERT_EQ(wpi::StringRef("er"), cv.data.arr_string.arr[1].str);
+
+  NT_DisposeValue(&cv);
+}
+
+TEST_F(ValueDeathTest, GetAssertions) {
+  Value v;
+  ASSERT_DEATH((void)v.GetBoolean(), "type == NT_BOOLEAN");
+  ASSERT_DEATH((void)v.GetDouble(), "type == NT_DOUBLE");
+  ASSERT_DEATH((void)v.GetString(), "type == NT_STRING");
+  ASSERT_DEATH((void)v.GetRaw(), "type == NT_RAW");
+  ASSERT_DEATH((void)v.GetBooleanArray(), "type == NT_BOOLEAN_ARRAY");
+  ASSERT_DEATH((void)v.GetDoubleArray(), "type == NT_DOUBLE_ARRAY");
+  ASSERT_DEATH((void)v.GetStringArray(), "type == NT_STRING_ARRAY");
+}
+
+TEST_F(ValueTest, UnassignedComparison) {
+  Value v1, v2;
+  ASSERT_EQ(v1, v2);
+}
+
+TEST_F(ValueTest, MixedComparison) {
+  Value v1;
+  auto v2 = Value::MakeBoolean(true);
+  ASSERT_NE(v1, *v2);  // unassigned vs boolean
+  auto v3 = Value::MakeDouble(0.5);
+  ASSERT_NE(*v2, *v3);  // boolean vs double
+}
+
+TEST_F(ValueTest, BooleanComparison) {
+  auto v1 = Value::MakeBoolean(true);
+  auto v2 = Value::MakeBoolean(true);
+  ASSERT_EQ(*v1, *v2);
+  v2 = Value::MakeBoolean(false);
+  ASSERT_NE(*v1, *v2);
+}
+
+TEST_F(ValueTest, DoubleComparison) {
+  auto v1 = Value::MakeDouble(0.25);
+  auto v2 = Value::MakeDouble(0.25);
+  ASSERT_EQ(*v1, *v2);
+  v2 = Value::MakeDouble(0.5);
+  ASSERT_NE(*v1, *v2);
+}
+
+TEST_F(ValueTest, StringComparison) {
+  auto v1 = Value::MakeString("hello");
+  auto v2 = Value::MakeString("hello");
+  ASSERT_EQ(*v1, *v2);
+  v2 = Value::MakeString("world");  // different contents
+  ASSERT_NE(*v1, *v2);
+  v2 = Value::MakeString("goodbye");  // different size
+  ASSERT_NE(*v1, *v2);
+}
+
+TEST_F(ValueTest, BooleanArrayComparison) {
+  std::vector<int> vec{1, 0, 1};
+  auto v1 = Value::MakeBooleanArray(vec);
+  auto v2 = Value::MakeBooleanArray(vec);
+  ASSERT_EQ(*v1, *v2);
+
+  // different contents
+  vec = {1, 1, 1};
+  v2 = Value::MakeBooleanArray(vec);
+  ASSERT_NE(*v1, *v2);
+
+  // different size
+  vec = {1, 0};
+  v2 = Value::MakeBooleanArray(vec);
+  ASSERT_NE(*v1, *v2);
+}
+
+TEST_F(ValueTest, DoubleArrayComparison) {
+  std::vector<double> vec{0.5, 0.25, 0.5};
+  auto v1 = Value::MakeDoubleArray(vec);
+  auto v2 = Value::MakeDoubleArray(vec);
+  ASSERT_EQ(*v1, *v2);
+
+  // different contents
+  vec = {0.5, 0.5, 0.5};
+  v2 = Value::MakeDoubleArray(vec);
+  ASSERT_NE(*v1, *v2);
+
+  // different size
+  vec = {0.5, 0.25};
+  v2 = Value::MakeDoubleArray(vec);
+  ASSERT_NE(*v1, *v2);
+}
+
+TEST_F(ValueTest, StringArrayComparison) {
+  std::vector<std::string> vec;
+  vec.push_back("hello");
+  vec.push_back("goodbye");
+  vec.push_back("string");
+  auto v1 = Value::MakeStringArray(vec);
+  vec.clear();
+  vec.push_back("hello");
+  vec.push_back("goodbye");
+  vec.push_back("string");
+  auto v2 = Value::MakeStringArray(std::move(vec));
+  ASSERT_EQ(*v1, *v2);
+
+  // different contents
+  vec.clear();
+  vec.push_back("hello");
+  vec.push_back("goodby2");
+  vec.push_back("string");
+  v2 = Value::MakeStringArray(std::move(vec));
+  ASSERT_NE(*v1, *v2);
+
+  // different sized contents
+  vec.clear();
+  vec.push_back("hello");
+  vec.push_back("goodbye2");
+  vec.push_back("string");
+  v2 = Value::MakeStringArray(vec);
+  ASSERT_NE(*v1, *v2);
+
+  // different size
+  vec.clear();
+  vec.push_back("hello");
+  vec.push_back("goodbye");
+  v2 = Value::MakeStringArray(std::move(vec));
+  ASSERT_NE(*v1, *v2);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/WireDecoderTest.cpp b/ntcore/src/test/native/cpp/WireDecoderTest.cpp
new file mode 100644
index 0000000..e32f909
--- /dev/null
+++ b/ntcore/src/test/native/cpp/WireDecoderTest.cpp
@@ -0,0 +1,643 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <stdint.h>
+
+#include <cfloat>
+#include <climits>
+#include <string>
+
+#include <wpi/StringRef.h>
+
+#include "TestPrinters.h"
+#include "WireDecoder.h"
+#include "gtest/gtest.h"
+
+namespace nt {
+
+class WireDecoderTest : public ::testing::Test {
+ protected:
+  WireDecoderTest() {
+    v_boolean = Value::MakeBoolean(true);
+    v_double = Value::MakeDouble(1.0);
+    v_string = Value::MakeString(wpi::StringRef("hello"));
+    v_raw = Value::MakeRaw(wpi::StringRef("hello"));
+    v_boolean_array = Value::MakeBooleanArray(std::vector<int>{0, 1, 0});
+    v_boolean_array_big = Value::MakeBooleanArray(std::vector<int>(255));
+    v_double_array = Value::MakeDoubleArray(std::vector<double>{0.5, 0.25});
+    v_double_array_big = Value::MakeDoubleArray(std::vector<double>(255));
+
+    std::vector<std::string> sa;
+    sa.push_back("hello");
+    sa.push_back("goodbye");
+    v_string_array = Value::MakeStringArray(std::move(sa));
+
+    sa.clear();
+    for (int i = 0; i < 255; ++i) sa.push_back("h");
+    v_string_array_big = Value::MakeStringArray(std::move(sa));
+
+    s_normal = std::string("hello");
+
+    s_long.clear();
+    s_long.append(127, '*');
+    s_long.push_back('x');
+
+    s_big2.clear();
+    s_big2.append(65534, '*');
+    s_big2.push_back('x');
+
+    s_big3.clear();
+    s_big3.append(65534, '*');
+    s_big3.append(3, 'x');
+  }
+
+  std::shared_ptr<Value> v_boolean, v_double, v_string, v_raw;
+  std::shared_ptr<Value> v_boolean_array, v_boolean_array_big;
+  std::shared_ptr<Value> v_double_array, v_double_array_big;
+  std::shared_ptr<Value> v_string_array, v_string_array_big;
+
+  std::string s_normal, s_long, s_big2, s_big3;
+};
+
+TEST_F(WireDecoderTest, Construct) {
+  wpi::raw_mem_istream is("", 0);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  EXPECT_EQ(nullptr, d.error());
+  EXPECT_EQ(0x0300u, d.proto_rev());
+}
+
+TEST_F(WireDecoderTest, SetProtoRev) {
+  wpi::raw_mem_istream is("", 0);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  d.set_proto_rev(0x0200u);
+  EXPECT_EQ(0x0200u, d.proto_rev());
+}
+
+TEST_F(WireDecoderTest, Read8) {
+  wpi::raw_mem_istream is("\x05\x01\x00", 3);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  unsigned int val;
+  ASSERT_TRUE(d.Read8(&val));
+  EXPECT_EQ(5u, val);
+  ASSERT_TRUE(d.Read8(&val));
+  EXPECT_EQ(1u, val);
+  ASSERT_TRUE(d.Read8(&val));
+  EXPECT_EQ(0u, val);
+  ASSERT_FALSE(d.Read8(&val));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, Read16) {
+  wpi::raw_mem_istream is("\x00\x05\x00\x01\x45\x67\x00\x00", 8);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  unsigned int val;
+  ASSERT_TRUE(d.Read16(&val));
+  EXPECT_EQ(5u, val);
+  ASSERT_TRUE(d.Read16(&val));
+  EXPECT_EQ(1u, val);
+  ASSERT_TRUE(d.Read16(&val));
+  EXPECT_EQ(0x4567u, val);
+  ASSERT_TRUE(d.Read16(&val));
+  EXPECT_EQ(0u, val);
+  ASSERT_FALSE(d.Read16(&val));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, Read32) {
+  wpi::raw_mem_istream is(
+      "\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\xab\xcd"
+      "\x12\x34\x56\x78\x00\x00\x00\x00",
+      20);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  uint32_t val;
+  ASSERT_TRUE(d.Read32(&val));
+  EXPECT_EQ(5ul, val);
+  ASSERT_TRUE(d.Read32(&val));
+  EXPECT_EQ(1ul, val);
+  ASSERT_TRUE(d.Read32(&val));
+  EXPECT_EQ(0xabcdul, val);
+  ASSERT_TRUE(d.Read32(&val));
+  EXPECT_EQ(0x12345678ul, val);
+  ASSERT_TRUE(d.Read32(&val));
+  EXPECT_EQ(0ul, val);
+  ASSERT_FALSE(d.Read32(&val));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDouble) {
+  // values except min and max from
+  // http://www.binaryconvert.com/result_double.html
+  wpi::raw_mem_istream is(
+      "\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x41\x0c\x13\x80\x00\x00\x00\x00"
+      "\x7f\xf0\x00\x00\x00\x00\x00\x00"
+      "\x00\x10\x00\x00\x00\x00\x00\x00"
+      "\x7f\xef\xff\xff\xff\xff\xff\xff",
+      40);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  double val;
+  ASSERT_TRUE(d.ReadDouble(&val));
+  EXPECT_EQ(0.0, val);
+  ASSERT_TRUE(d.ReadDouble(&val));
+  EXPECT_EQ(2.3e5, val);
+  ASSERT_TRUE(d.ReadDouble(&val));
+  EXPECT_EQ(std::numeric_limits<double>::infinity(), val);
+  ASSERT_TRUE(d.ReadDouble(&val));
+  EXPECT_EQ(DBL_MIN, val);
+  ASSERT_TRUE(d.ReadDouble(&val));
+  EXPECT_EQ(DBL_MAX, val);
+  ASSERT_FALSE(d.ReadDouble(&val));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadUleb128) {
+  wpi::raw_mem_istream is("\x00\x7f\x80\x01\x80", 5);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  uint64_t val;
+  ASSERT_TRUE(d.ReadUleb128(&val));
+  EXPECT_EQ(0ul, val);
+  ASSERT_TRUE(d.ReadUleb128(&val));
+  EXPECT_EQ(0x7ful, val);
+  ASSERT_TRUE(d.ReadUleb128(&val));
+  EXPECT_EQ(0x80ul, val);
+  ASSERT_FALSE(d.ReadUleb128(&val));  // partial
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadType) {
+  wpi::raw_mem_istream is("\x00\x01\x02\x03\x10\x11\x12\x20", 8);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  NT_Type val;
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_BOOLEAN, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_DOUBLE, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_STRING, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_RAW, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_BOOLEAN_ARRAY, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_DOUBLE_ARRAY, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_STRING_ARRAY, val);
+  ASSERT_TRUE(d.ReadType(&val));
+  EXPECT_EQ(NT_RPC, val);
+  ASSERT_FALSE(d.ReadType(&val));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadTypeError) {
+  wpi::raw_mem_istream is("\x30", 1);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  NT_Type val;
+  ASSERT_FALSE(d.ReadType(&val));
+  EXPECT_EQ(NT_UNASSIGNED, val);
+  ASSERT_NE(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, Reset) {
+  wpi::raw_mem_istream is("\x30", 1);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  NT_Type val;
+  ASSERT_FALSE(d.ReadType(&val));
+  EXPECT_EQ(NT_UNASSIGNED, val);
+  ASSERT_NE(nullptr, d.error());
+  d.Reset();
+  EXPECT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadBooleanValue2) {
+  wpi::raw_mem_istream is("\x01\x00", 2);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_BOOLEAN);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean, *val);
+
+  auto v_false = Value::MakeBoolean(false);
+  val = d.ReadValue(NT_BOOLEAN);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_false, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_BOOLEAN));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDoubleValue2) {
+  wpi::raw_mem_istream is(
+      "\x3f\xf0\x00\x00\x00\x00\x00\x00"
+      "\x3f\xf0\x00\x00\x00\x00\x00\x00",
+      16);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_DOUBLE);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double, *val);
+
+  val = d.ReadValue(NT_DOUBLE);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_DOUBLE));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadStringValue2) {
+  wpi::raw_mem_istream is(
+      "\x00\x05hello\x00\x03"
+      "bye\x55",
+      13);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_STRING);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_string, *val);
+
+  auto v_bye = Value::MakeString(wpi::StringRef("bye"));
+  val = d.ReadValue(NT_STRING);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_bye, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_STRING));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadBooleanArrayValue2) {
+  wpi::raw_mem_istream is("\x03\x00\x01\x00\x02\x01\x00\xff", 8);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_BOOLEAN_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean_array, *val);
+
+  auto v_boolean_array2 = Value::MakeBooleanArray(std::vector<int>{1, 0});
+  val = d.ReadValue(NT_BOOLEAN_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean_array2, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_BOOLEAN_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadBooleanArrayBigValue2) {
+  std::string s;
+  s.push_back('\xff');
+  s.append(255, '\x00');
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_BOOLEAN_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean_array_big, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_BOOLEAN_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDoubleArrayValue2) {
+  wpi::raw_mem_istream is(
+      "\x02\x3f\xe0\x00\x00\x00\x00\x00\x00"
+      "\x3f\xd0\x00\x00\x00\x00\x00\x00\x55",
+      18);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_DOUBLE_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double_array, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_DOUBLE_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDoubleArrayBigValue2) {
+  std::string s;
+  s.push_back('\xff');
+  s.append(255 * 8, '\x00');
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_DOUBLE_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double_array_big, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_DOUBLE_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadStringArrayValue2) {
+  wpi::raw_mem_istream is("\x02\x00\x05hello\x00\x07goodbye\x55", 18);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_STRING_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_string_array, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_STRING_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadStringArrayBigValue2) {
+  std::string s;
+  s.push_back('\xff');
+  for (int i = 0; i < 255; ++i) s.append("\x00\x01h", 3);
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  auto val = d.ReadValue(NT_STRING_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_string_array_big, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_STRING_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadValueError2) {
+  wpi::raw_mem_istream is("", 0);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  ASSERT_FALSE(d.ReadValue(NT_UNASSIGNED));  // unassigned
+  ASSERT_NE(nullptr, d.error());
+
+  d.Reset();
+  ASSERT_FALSE(d.ReadValue(NT_RAW));  // not supported
+  ASSERT_NE(nullptr, d.error());
+
+  d.Reset();
+  ASSERT_FALSE(d.ReadValue(NT_RPC));  // not supported
+  ASSERT_NE(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadBooleanValue3) {
+  wpi::raw_mem_istream is("\x01\x00", 2);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_BOOLEAN);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean, *val);
+
+  auto v_false = Value::MakeBoolean(false);
+  val = d.ReadValue(NT_BOOLEAN);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_false, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_BOOLEAN));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDoubleValue3) {
+  wpi::raw_mem_istream is(
+      "\x3f\xf0\x00\x00\x00\x00\x00\x00"
+      "\x3f\xf0\x00\x00\x00\x00\x00\x00",
+      16);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_DOUBLE);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double, *val);
+
+  val = d.ReadValue(NT_DOUBLE);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_DOUBLE));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadStringValue3) {
+  wpi::raw_mem_istream is(
+      "\x05hello\x03"
+      "bye\x55",
+      11);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_STRING);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_string, *val);
+
+  auto v_bye = Value::MakeString(wpi::StringRef("bye"));
+  val = d.ReadValue(NT_STRING);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_bye, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_STRING));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadRawValue3) {
+  wpi::raw_mem_istream is(
+      "\x05hello\x03"
+      "bye\x55",
+      11);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_RAW);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_raw, *val);
+
+  auto v_bye = Value::MakeRaw(wpi::StringRef("bye"));
+  val = d.ReadValue(NT_RAW);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_bye, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_RAW));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadBooleanArrayValue3) {
+  wpi::raw_mem_istream is("\x03\x00\x01\x00\x02\x01\x00\xff", 8);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_BOOLEAN_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean_array, *val);
+
+  auto v_boolean_array2 = Value::MakeBooleanArray(std::vector<int>{1, 0});
+  val = d.ReadValue(NT_BOOLEAN_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean_array2, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_BOOLEAN_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadBooleanArrayBigValue3) {
+  std::string s;
+  s.push_back('\xff');
+  s.append(255, '\x00');
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_BOOLEAN_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_boolean_array_big, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_BOOLEAN_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDoubleArrayValue3) {
+  wpi::raw_mem_istream is(
+      "\x02\x3f\xe0\x00\x00\x00\x00\x00\x00"
+      "\x3f\xd0\x00\x00\x00\x00\x00\x00\x55",
+      18);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_DOUBLE_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double_array, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_DOUBLE_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadDoubleArrayBigValue3) {
+  std::string s;
+  s.push_back('\xff');
+  s.append(255 * 8, '\x00');
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_DOUBLE_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_double_array_big, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_DOUBLE_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadStringArrayValue3) {
+  wpi::raw_mem_istream is("\x02\x05hello\x07goodbye\x55", 16);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_STRING_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_string_array, *val);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadValue(NT_STRING_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadStringArrayBigValue3) {
+  std::string s;
+  s.push_back('\xff');
+  for (int i = 0; i < 255; ++i) s.append("\x01h", 2);
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  auto val = d.ReadValue(NT_STRING_ARRAY);
+  ASSERT_TRUE(static_cast<bool>(val));
+  EXPECT_EQ(*v_string_array_big, *val);
+
+  ASSERT_FALSE(d.ReadValue(NT_STRING_ARRAY));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadValueError3) {
+  wpi::raw_mem_istream is("", 0);
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  ASSERT_FALSE(d.ReadValue(NT_UNASSIGNED));  // unassigned
+  ASSERT_NE(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadString2) {
+  std::string s;
+  s.append("\x00\x05", 2);
+  s += s_normal;
+  s.append("\x00\x80", 2);
+  s += s_long;
+  s.append("\xff\xff", 2);
+  s += s_big2;
+  s.push_back('\x55');
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0200u, logger);
+  std::string outs;
+  ASSERT_TRUE(d.ReadString(&outs));
+  EXPECT_EQ(s_normal, outs);
+  ASSERT_TRUE(d.ReadString(&outs));
+  EXPECT_EQ(s_long, outs);
+  ASSERT_TRUE(d.ReadString(&outs));
+  EXPECT_EQ(s_big2, outs);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadString(&outs));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+TEST_F(WireDecoderTest, ReadString3) {
+  std::string s;
+  s.push_back('\x05');
+  s += s_normal;
+  s.append("\x80\x01", 2);
+  s += s_long;
+  s.append("\x81\x80\x04", 3);
+  s += s_big3;
+  s.push_back('\x55');
+  wpi::raw_mem_istream is(s.data(), s.size());
+  wpi::Logger logger;
+  WireDecoder d(is, 0x0300u, logger);
+  std::string outs;
+  ASSERT_TRUE(d.ReadString(&outs));
+  EXPECT_EQ(s_normal, outs);
+  ASSERT_TRUE(d.ReadString(&outs));
+  EXPECT_EQ(s_long, outs);
+  ASSERT_TRUE(d.ReadString(&outs));
+  EXPECT_EQ(s_big3, outs);
+
+  unsigned int b;
+  ASSERT_TRUE(d.Read8(&b));
+  EXPECT_EQ(0x55u, b);
+
+  ASSERT_FALSE(d.ReadString(&outs));
+  ASSERT_EQ(nullptr, d.error());
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/WireEncoderTest.cpp b/ntcore/src/test/native/cpp/WireEncoderTest.cpp
new file mode 100644
index 0000000..fab5a22
--- /dev/null
+++ b/ntcore/src/test/native/cpp/WireEncoderTest.cpp
@@ -0,0 +1,493 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <cfloat>
+#include <climits>
+#include <string>
+
+#include <wpi/StringRef.h>
+
+#include "TestPrinters.h"
+#include "WireEncoder.h"
+#include "gtest/gtest.h"
+
+#define BUFSIZE 1024
+
+namespace nt {
+
+class WireEncoderTest : public ::testing::Test {
+ protected:
+  WireEncoderTest() {
+    v_empty = std::make_shared<Value>();
+    v_boolean = Value::MakeBoolean(true);
+    v_double = Value::MakeDouble(1.0);
+    v_string = Value::MakeString(wpi::StringRef("hello"));
+    v_raw = Value::MakeRaw(wpi::StringRef("hello"));
+    v_boolean_array = Value::MakeBooleanArray(std::vector<int>{0, 1, 0});
+    v_boolean_array_big = Value::MakeBooleanArray(std::vector<int>(256));
+    v_double_array = Value::MakeDoubleArray(std::vector<double>{0.5, 0.25});
+    v_double_array_big = Value::MakeDoubleArray(std::vector<double>(256));
+
+    std::vector<std::string> sa;
+    sa.push_back("hello");
+    sa.push_back("goodbye");
+    v_string_array = Value::MakeStringArray(std::move(sa));
+
+    sa.clear();
+    for (int i = 0; i < 256; ++i) sa.push_back("h");
+    v_string_array_big = Value::MakeStringArray(std::move(sa));
+
+    s_normal = "hello";
+
+    s_long.clear();
+    s_long.append(127, '*');
+    s_long.push_back('x');
+
+    s_big.clear();
+    s_big.append(65534, '*');
+    s_big.append(3, 'x');
+  }
+
+  std::shared_ptr<Value> v_empty;
+  std::shared_ptr<Value> v_boolean, v_double, v_string, v_raw;
+  std::shared_ptr<Value> v_boolean_array, v_boolean_array_big;
+  std::shared_ptr<Value> v_double_array, v_double_array_big;
+  std::shared_ptr<Value> v_string_array, v_string_array_big;
+
+  std::string s_normal, s_long, s_big;
+};
+
+TEST_F(WireEncoderTest, Construct) {
+  WireEncoder e(0x0300u);
+  EXPECT_EQ(0u, e.size());
+  EXPECT_EQ(nullptr, e.error());
+  EXPECT_EQ(0x0300u, e.proto_rev());
+}
+
+TEST_F(WireEncoderTest, SetProtoRev) {
+  WireEncoder e(0x0300u);
+  e.set_proto_rev(0x0200u);
+  EXPECT_EQ(0x0200u, e.proto_rev());
+}
+
+TEST_F(WireEncoderTest, Write8) {
+  size_t off = BUFSIZE - 1;
+  WireEncoder e(0x0300u);
+  for (size_t i = 0; i < off; ++i) e.Write8(0u);  // test across Reserve()
+  e.Write8(5u);
+  e.Write8(0x101u);  // should be truncated
+  e.Write8(0u);
+  ASSERT_EQ(3u, e.size() - off);
+  ASSERT_EQ(wpi::StringRef("\x05\x01\x00", 3),
+            wpi::StringRef(e.data(), e.size()).substr(off));
+}
+
+TEST_F(WireEncoderTest, Write16) {
+  size_t off = BUFSIZE - 2;
+  WireEncoder e(0x0300u);
+  for (size_t i = 0; i < off; ++i) e.Write8(0u);  // test across Reserve()
+  e.Write16(5u);
+  e.Write16(0x10001u);  // should be truncated
+  e.Write16(0x4567u);
+  e.Write16(0u);
+  ASSERT_EQ(8u, e.size() - off);
+  ASSERT_EQ(wpi::StringRef("\x00\x05\x00\x01\x45\x67\x00\x00", 8),
+            wpi::StringRef(e.data(), e.size()).substr(off));
+}
+
+TEST_F(WireEncoderTest, Write32) {
+  size_t off = BUFSIZE - 4;
+  WireEncoder e(0x0300u);
+  for (size_t i = 0; i < off; ++i) e.Write8(0u);  // test across Reserve()
+  e.Write32(5ul);
+  e.Write32(1ul);
+  e.Write32(0xabcdul);
+  e.Write32(0x12345678ul);
+  e.Write32(0ul);
+  ASSERT_EQ(20u, e.size() - off);
+  ASSERT_EQ(wpi::StringRef("\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\xab\xcd"
+                           "\x12\x34\x56\x78\x00\x00\x00\x00",
+                           20),
+            wpi::StringRef(e.data(), e.size()).substr(off));
+}
+
+TEST_F(WireEncoderTest, WriteDouble) {
+  size_t off = BUFSIZE - 8;
+  WireEncoder e(0x0300u);
+  for (size_t i = 0; i < off; ++i) e.Write8(0u);  // test across Reserve()
+  e.WriteDouble(0.0);
+  e.WriteDouble(2.3e5);
+  e.WriteDouble(std::numeric_limits<double>::infinity());
+  e.WriteDouble(DBL_MIN);
+  e.WriteDouble(DBL_MAX);
+  ASSERT_EQ(40u, e.size() - off);
+  // golden values except min and max from
+  // http://www.binaryconvert.com/result_double.html
+  ASSERT_EQ(wpi::StringRef("\x00\x00\x00\x00\x00\x00\x00\x00"
+                           "\x41\x0c\x13\x80\x00\x00\x00\x00"
+                           "\x7f\xf0\x00\x00\x00\x00\x00\x00"
+                           "\x00\x10\x00\x00\x00\x00\x00\x00"
+                           "\x7f\xef\xff\xff\xff\xff\xff\xff",
+                           40),
+            wpi::StringRef(e.data(), e.size()).substr(off));
+}
+
+TEST_F(WireEncoderTest, WriteUleb128) {
+  size_t off = BUFSIZE - 2;
+  WireEncoder e(0x0300u);
+  for (size_t i = 0; i < off; ++i) e.Write8(0u);  // test across Reserve()
+  e.WriteUleb128(0ul);
+  e.WriteUleb128(0x7ful);
+  e.WriteUleb128(0x80ul);
+  ASSERT_EQ(4u, e.size() - off);
+  ASSERT_EQ(wpi::StringRef("\x00\x7f\x80\x01", 4),
+            wpi::StringRef(e.data(), e.size()).substr(off));
+}
+
+TEST_F(WireEncoderTest, WriteType) {
+  size_t off = BUFSIZE - 1;
+  WireEncoder e(0x0300u);
+  for (size_t i = 0; i < off; ++i) e.Write8(0u);  // test across Reserve()
+  e.WriteType(NT_BOOLEAN);
+  e.WriteType(NT_DOUBLE);
+  e.WriteType(NT_STRING);
+  e.WriteType(NT_RAW);
+  e.WriteType(NT_BOOLEAN_ARRAY);
+  e.WriteType(NT_DOUBLE_ARRAY);
+  e.WriteType(NT_STRING_ARRAY);
+  e.WriteType(NT_RPC);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(8u, e.size() - off);
+  ASSERT_EQ(wpi::StringRef("\x00\x01\x02\x03\x10\x11\x12\x20", 8),
+            wpi::StringRef(e.data(), e.size()).substr(off));
+}
+
+TEST_F(WireEncoderTest, WriteTypeError) {
+  WireEncoder e(0x0200u);
+  e.WriteType(NT_UNASSIGNED);
+  EXPECT_EQ(0u, e.size());
+  EXPECT_EQ(std::string("unrecognized type"), e.error());
+
+  e.Reset();
+  e.WriteType(NT_RAW);
+  EXPECT_EQ(0u, e.size());
+  EXPECT_EQ(std::string("raw type not supported in protocol < 3.0"), e.error());
+
+  e.Reset();
+  e.WriteType(NT_RPC);
+  EXPECT_EQ(0u, e.size());
+  EXPECT_EQ(std::string("RPC type not supported in protocol < 3.0"), e.error());
+}
+
+TEST_F(WireEncoderTest, Reset) {
+  WireEncoder e(0x0300u);
+  e.WriteType(NT_UNASSIGNED);
+  EXPECT_NE(nullptr, e.error());
+  e.Reset();
+  EXPECT_EQ(nullptr, e.error());
+
+  e.Write8(0u);
+  EXPECT_EQ(1u, e.size());
+  e.Reset();
+  EXPECT_EQ(0u, e.size());
+}
+
+TEST_F(WireEncoderTest, GetValueSize2) {
+  WireEncoder e(0x0200u);
+  EXPECT_EQ(0u, e.GetValueSize(*v_empty));  // empty
+  EXPECT_EQ(1u, e.GetValueSize(*v_boolean));
+  EXPECT_EQ(8u, e.GetValueSize(*v_double));
+  EXPECT_EQ(7u, e.GetValueSize(*v_string));
+  EXPECT_EQ(0u, e.GetValueSize(*v_raw));  // not supported
+
+  EXPECT_EQ(1u + 3u, e.GetValueSize(*v_boolean_array));
+  // truncated
+  EXPECT_EQ(1u + 255u, e.GetValueSize(*v_boolean_array_big));
+
+  EXPECT_EQ(1u + 2u * 8u, e.GetValueSize(*v_double_array));
+  // truncated
+  EXPECT_EQ(1u + 255u * 8u, e.GetValueSize(*v_double_array_big));
+
+  EXPECT_EQ(1u + 7u + 9u, e.GetValueSize(*v_string_array));
+  // truncated
+  EXPECT_EQ(1u + 255u * 3u, e.GetValueSize(*v_string_array_big));
+}
+
+TEST_F(WireEncoderTest, WriteBooleanValue2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_boolean);
+  auto v_false = Value::MakeBoolean(false);
+  e.WriteValue(*v_false);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(2u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x01\x00", 2), wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteDoubleValue2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_double);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8),
+            wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteStringValue2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_string);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(7u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x00\x05hello", 7),
+            wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteBooleanArrayValue2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_boolean_array);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 3u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x03\x00\x01\x00", 4),
+            wpi::StringRef(e.data(), e.size()));
+
+  // truncated
+  e.Reset();
+  e.WriteValue(*v_boolean_array_big);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 255u, e.size());
+  ASSERT_EQ(wpi::StringRef("\xff\x00", 2), wpi::StringRef(e.data(), 2));
+}
+
+TEST_F(WireEncoderTest, WriteDoubleArrayValue2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_double_array);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 2u * 8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x02\x3f\xe0\x00\x00\x00\x00\x00\x00"
+                           "\x3f\xd0\x00\x00\x00\x00\x00\x00",
+                           17),
+            wpi::StringRef(e.data(), e.size()));
+
+  // truncated
+  e.Reset();
+  e.WriteValue(*v_double_array_big);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 255u * 8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\xff\x00", 2), wpi::StringRef(e.data(), 2));
+}
+
+TEST_F(WireEncoderTest, WriteStringArrayValue2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_string_array);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 7u + 9u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x02\x00\x05hello\x00\x07goodbye", 17),
+            wpi::StringRef(e.data(), e.size()));
+
+  // truncated
+  e.Reset();
+  e.WriteValue(*v_string_array_big);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 255u * 3u, e.size());
+  ASSERT_EQ(wpi::StringRef("\xff\x00\x01", 3), wpi::StringRef(e.data(), 3));
+}
+
+TEST_F(WireEncoderTest, WriteValueError2) {
+  WireEncoder e(0x0200u);
+  e.WriteValue(*v_empty);  // empty
+  ASSERT_EQ(0u, e.size());
+  ASSERT_NE(nullptr, e.error());
+
+  e.Reset();
+  e.WriteValue(*v_raw);  // not supported
+  ASSERT_EQ(0u, e.size());
+  ASSERT_NE(nullptr, e.error());
+}
+
+TEST_F(WireEncoderTest, GetValueSize3) {
+  WireEncoder e(0x0300u);
+  EXPECT_EQ(0u, e.GetValueSize(*v_empty));  // empty
+  EXPECT_EQ(1u, e.GetValueSize(*v_boolean));
+  EXPECT_EQ(8u, e.GetValueSize(*v_double));
+  EXPECT_EQ(6u, e.GetValueSize(*v_string));
+  EXPECT_EQ(6u, e.GetValueSize(*v_raw));
+
+  EXPECT_EQ(1u + 3u, e.GetValueSize(*v_boolean_array));
+  // truncated
+  EXPECT_EQ(1u + 255u, e.GetValueSize(*v_boolean_array_big));
+
+  EXPECT_EQ(1u + 2u * 8u, e.GetValueSize(*v_double_array));
+  // truncated
+  EXPECT_EQ(1u + 255u * 8u, e.GetValueSize(*v_double_array_big));
+
+  EXPECT_EQ(1u + 6u + 8u, e.GetValueSize(*v_string_array));
+  // truncated
+  EXPECT_EQ(1u + 255u * 2u, e.GetValueSize(*v_string_array_big));
+}
+
+TEST_F(WireEncoderTest, WriteBooleanValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_boolean);
+  auto v_false = Value::MakeBoolean(false);
+  e.WriteValue(*v_false);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(2u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x01\x00", 2), wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteDoubleValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_double);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8),
+            wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteStringValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_string);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(6u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x05hello", 6), wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteRawValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_raw);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(6u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x05hello", 6), wpi::StringRef(e.data(), e.size()));
+}
+
+TEST_F(WireEncoderTest, WriteBooleanArrayValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_boolean_array);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 3u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x03\x00\x01\x00", 4),
+            wpi::StringRef(e.data(), e.size()));
+
+  // truncated
+  e.Reset();
+  e.WriteValue(*v_boolean_array_big);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 255u, e.size());
+  ASSERT_EQ(wpi::StringRef("\xff\x00", 2), wpi::StringRef(e.data(), 2));
+}
+
+TEST_F(WireEncoderTest, WriteDoubleArrayValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_double_array);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 2u * 8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x02\x3f\xe0\x00\x00\x00\x00\x00\x00"
+                           "\x3f\xd0\x00\x00\x00\x00\x00\x00",
+                           17),
+            wpi::StringRef(e.data(), e.size()));
+
+  // truncated
+  e.Reset();
+  e.WriteValue(*v_double_array_big);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 255u * 8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\xff\x00", 2), wpi::StringRef(e.data(), 2));
+}
+
+TEST_F(WireEncoderTest, WriteStringArrayValue3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_string_array);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 6u + 8u, e.size());
+  ASSERT_EQ(wpi::StringRef("\x02\x05hello\x07goodbye", 15),
+            wpi::StringRef(e.data(), e.size()));
+
+  // truncated
+  e.Reset();
+  e.WriteValue(*v_string_array_big);
+  ASSERT_EQ(nullptr, e.error());
+  ASSERT_EQ(1u + 255u * 2u, e.size());
+  ASSERT_EQ(wpi::StringRef("\xff\x01", 2), wpi::StringRef(e.data(), 2));
+}
+
+TEST_F(WireEncoderTest, WriteValueError3) {
+  WireEncoder e(0x0300u);
+  e.WriteValue(*v_empty);  // empty
+  ASSERT_EQ(0u, e.size());
+  ASSERT_NE(nullptr, e.error());
+}
+
+TEST_F(WireEncoderTest, GetStringSize2) {
+  // 2-byte length
+  WireEncoder e(0x0200u);
+  EXPECT_EQ(7u, e.GetStringSize(s_normal));
+  EXPECT_EQ(130u, e.GetStringSize(s_long));
+  // truncated
+  EXPECT_EQ(65537u, e.GetStringSize(s_big));
+}
+
+TEST_F(WireEncoderTest, WriteString2) {
+  WireEncoder e(0x0200u);
+  e.WriteString(s_normal);
+  EXPECT_EQ(nullptr, e.error());
+  EXPECT_EQ(7u, e.size());
+  EXPECT_EQ(wpi::StringRef("\x00\x05hello", 7),
+            wpi::StringRef(e.data(), e.size()));
+
+  e.Reset();
+  e.WriteString(s_long);
+  EXPECT_EQ(nullptr, e.error());
+  ASSERT_EQ(130u, e.size());
+  EXPECT_EQ(wpi::StringRef("\x00\x80**", 4), wpi::StringRef(e.data(), 4));
+  EXPECT_EQ('*', e.data()[128]);
+  EXPECT_EQ('x', e.data()[129]);
+
+  // truncated
+  e.Reset();
+  e.WriteString(s_big);
+  EXPECT_EQ(nullptr, e.error());
+  ASSERT_EQ(65537u, e.size());
+  EXPECT_EQ(wpi::StringRef("\xff\xff**", 4), wpi::StringRef(e.data(), 4));
+  EXPECT_EQ('*', e.data()[65535]);
+  EXPECT_EQ('x', e.data()[65536]);
+}
+
+TEST_F(WireEncoderTest, GetStringSize3) {
+  // leb128-encoded length
+  WireEncoder e(0x0300u);
+  EXPECT_EQ(6u, e.GetStringSize(s_normal));
+  EXPECT_EQ(130u, e.GetStringSize(s_long));
+  EXPECT_EQ(65540u, e.GetStringSize(s_big));
+}
+
+TEST_F(WireEncoderTest, WriteString3) {
+  WireEncoder e(0x0300u);
+  e.WriteString(s_normal);
+  EXPECT_EQ(nullptr, e.error());
+  EXPECT_EQ(6u, e.size());
+  EXPECT_EQ(wpi::StringRef("\x05hello", 6), wpi::StringRef(e.data(), e.size()));
+
+  e.Reset();
+  e.WriteString(s_long);
+  EXPECT_EQ(nullptr, e.error());
+  ASSERT_EQ(130u, e.size());
+  EXPECT_EQ(wpi::StringRef("\x80\x01**", 4), wpi::StringRef(e.data(), 4));
+  EXPECT_EQ('*', e.data()[128]);
+  EXPECT_EQ('x', e.data()[129]);
+
+  // NOT truncated
+  e.Reset();
+  e.WriteString(s_big);
+  EXPECT_EQ(nullptr, e.error());
+  ASSERT_EQ(65540u, e.size());
+  EXPECT_EQ(wpi::StringRef("\x81\x80\x04*", 4), wpi::StringRef(e.data(), 4));
+  EXPECT_EQ('*', e.data()[65536]);
+  EXPECT_EQ('x', e.data()[65537]);
+  EXPECT_EQ('x', e.data()[65538]);
+  EXPECT_EQ('x', e.data()[65539]);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/main.cpp b/ntcore/src/test/native/cpp/main.cpp
new file mode 100644
index 0000000..d0b0e3c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/main.cpp
@@ -0,0 +1,23 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-2018 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <climits>
+
+#include "gmock/gmock.h"
+#include "ntcore.h"
+
+int main(int argc, char** argv) {
+  nt::AddLogger(nt::GetDefaultInstance(),
+                [](const nt::LogMessage& msg) {
+                  std::fputs(msg.message.c_str(), stderr);
+                  std::fputc('\n', stderr);
+                },
+                0, UINT_MAX);
+  ::testing::InitGoogleMock(&argc, argv);
+  int ret = RUN_ALL_TESTS();
+  return ret;
+}
