diff --git a/ntcore/.styleguide b/ntcore/.styleguide
index 8cf3a51..ef9cbb7 100644
--- a/ntcore/.styleguide
+++ b/ntcore/.styleguide
@@ -30,4 +30,5 @@
   ^fmt/
   ^support/
   ^wpi/
+  ^wpinet/
 }
diff --git a/ntcore/CMakeLists.txt b/ntcore/CMakeLists.txt
index 44992ef..cd4df28 100644
--- a/ntcore/CMakeLists.txt
+++ b/ntcore/CMakeLists.txt
@@ -3,23 +3,39 @@
 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)
+execute_process(COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/generate_topics.py ${WPILIB_BINARY_DIR}/ntcore RESULT_VARIABLE generateResult)
+if(NOT (generateResult EQUAL "0"))
+  # Try python
+  execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/generate_topics.py ${WPILIB_BINARY_DIR}/ntcore RESULT_VARIABLE generateResult)
+  if(NOT (generateResult EQUAL "0"))
+    message(FATAL_ERROR "python and python3 generate_topics.py failed")
+  endif()
+endif()
+
+file(GLOB ntcore_native_src
+    src/main/native/cpp/*.cpp
+    ${WPILIB_BINARY_DIR}/ntcore/generated/main/native/cpp/*.cpp
+    src/main/native/cpp/net/*.cpp
+    src/main/native/cpp/net3/*.cpp
+    src/main/native/cpp/networktables/*.cpp
+    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
+target_include_directories(ntcore
+                PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/cpp
+                PUBLIC
                 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/include>
+                $<BUILD_INTERFACE:${WPILIB_BINARY_DIR}/ntcore/generated/main/native/include>
                             $<INSTALL_INTERFACE:${include_dest}/ntcore>)
 wpilib_target_warnings(ntcore)
-target_compile_features(ntcore PUBLIC cxx_std_17)
-target_link_libraries(ntcore PUBLIC wpiutil)
+target_compile_features(ntcore PUBLIC cxx_std_20)
+target_link_libraries(ntcore PUBLIC wpinet 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")
+install(DIRECTORY ${WPILIB_BINARY_DIR}/ntcore/generated/main/native/include/ DESTINATION "${include_dest}/ntcore")
 
 if (WITH_FLAT_INSTALL)
     set (ntcore_config_dir ${wpilib_dest})
@@ -38,10 +54,11 @@
     include(UseJava)
     set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
 
-    file(GLOB
-        ntcore_jni_src src/main/native/cpp/jni/NetworkTablesJNI.cpp)
+    file(GLOB ntcore_jni_src
+        src/main/native/cpp/jni/*.cpp
+        ${WPILIB_BINARY_DIR}/ntcore/generated/main/native/cpp/jni/*.cpp)
 
-    file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
+    file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java ${WPILIB_BINARY_DIR}/ntcore/generated/*.java)
     set(CMAKE_JNI_TARGET true)
 
     if(${CMAKE_VERSION} VERSION_LESS "3.11.0")
@@ -78,6 +95,9 @@
 
 endif()
 
+add_executable(ntcoredev src/dev/native/cpp/main.cpp)
+target_link_libraries(ntcoredev ntcore)
+
 if (WITH_TESTS)
     wpilib_add_test(ntcore src/test/native/cpp)
     target_include_directories(ntcore_test PRIVATE src/main/native/cpp)
diff --git a/ntcore/build.gradle b/ntcore/build.gradle
index 67674c6..c5464cc 100644
--- a/ntcore/build.gradle
+++ b/ntcore/build.gradle
@@ -1,29 +1,331 @@
+import groovy.json.JsonSlurper;
+import com.hubspot.jinjava.Jinjava;
+import com.hubspot.jinjava.JinjavaConfig;
+
+def ntcoreTypesInputFile = file("src/generate/types.json")
+def ntcoreJavaTypesInputDir = file("src/generate/java")
+def ntcoreJavaTypesOutputDir = file("$buildDir/generated/main/java/edu/wpi/first/networktables")
+
+task ntcoreGenerateJavaTypes() {
+    description = "Generates ntcore Java type classes"
+    group = "WPILib"
+
+    inputs.file ntcoreTypesInputFile
+    inputs.dir ntcoreJavaTypesInputDir
+    outputs.dir ntcoreJavaTypesOutputDir
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreJavaTypesOutputDir.deleteDir()
+        ntcoreJavaTypesOutputDir.mkdirs()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        ntcoreJavaTypesInputDir.listFiles().each { File file ->
+            def template = file.text
+            def outfn = file.name.substring(0, file.name.length() - 6)
+            if (file.name.startsWith("NetworkTable") || file.name.startsWith("Generic")) {
+                def replacements = new HashMap<String,?>()
+                replacements.put("types", jsonTypes)
+                def output = jinjava.render(template, replacements)
+                new File(ntcoreJavaTypesOutputDir, outfn).write(output)
+            } else {
+                jsonTypes.each { Map<String,?> replacements ->
+                    def output = jinjava.render(template, replacements)
+                    def typename = replacements.get("TypeName")
+                    File outfile
+                    if (outfn == "Timestamped.java") {
+                        outfile = new File(ntcoreJavaTypesOutputDir, "Timestamped${typename}.java")
+                    } else {
+                        outfile = new File(ntcoreJavaTypesOutputDir, "${typename}${outfn}")
+                    }
+                    outfile.write(output)
+                }
+            }
+        }
+    }
+}
+
+def ntcoreCppTypesInputDir = file("src/generate/include/networktables")
+def ntcoreCppTypesOutputDir = file("$buildDir/generated/main/native/include/networktables")
+
+task ntcoreGenerateCppTypes() {
+    description = "Generates ntcore C++ type classes"
+    group = "WPILib"
+
+    inputs.file ntcoreTypesInputFile
+    inputs.dir ntcoreCppTypesInputDir
+    outputs.dir ntcoreCppTypesOutputDir
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreCppTypesOutputDir.deleteDir()
+        ntcoreCppTypesOutputDir.mkdirs()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        ntcoreCppTypesInputDir.listFiles().each { File file ->
+            def template = file.text
+            def outfn = file.name.substring(0, file.name.length() - 6)
+            jsonTypes.each { Map<String,?> replacements ->
+                def output = jinjava.render(template, replacements)
+                def typename = replacements.get("TypeName")
+                def outfile = new File(ntcoreCppTypesOutputDir, "${typename}${outfn}")
+                outfile.write(output)
+            }
+        }
+    }
+}
+
+def ntcoreCppHandleSourceInputFile = file("src/generate/cpp/ntcore_cpp_types.cpp.jinja")
+def ntcoreCppHandleSourceOutputFile = file("$buildDir/generated/main/native/cpp/ntcore_cpp_types.cpp")
+
+task ntcoreGenerateCppHandleSource() {
+    description = "Generates ntcore C++ handle source"
+    group = "WPILib"
+
+    inputs.files([
+        ntcoreTypesInputFile,
+        ntcoreCppHandleSourceInputFile
+    ])
+    outputs.file ntcoreCppHandleSourceOutputFile
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreCppHandleSourceOutputFile.delete()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        def template = ntcoreCppHandleSourceInputFile.text
+        def replacements = new HashMap<String,?>()
+        replacements.put("types", jsonTypes)
+        def output = jinjava.render(template, replacements)
+        ntcoreCppHandleSourceOutputFile.write(output)
+    }
+}
+
+def ntcoreCppHandleHeaderInputFile = file("src/generate/include/ntcore_cpp_types.h.jinja")
+def ntcoreCppHandleHeaderOutputFile = file("$buildDir/generated/main/native/include/ntcore_cpp_types.h")
+
+task ntcoreGenerateCppHandleHeader() {
+    description = "Generates ntcore C++ handle header"
+    group = "WPILib"
+
+    inputs.files([
+        ntcoreTypesInputFile,
+        ntcoreCppHandleHeaderInputFile
+    ])
+    outputs.file ntcoreCppHandleHeaderOutputFile
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreCppHandleHeaderOutputFile.delete()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        def template = ntcoreCppHandleHeaderInputFile.text
+        def replacements = new HashMap<String,?>()
+        replacements.put("types", jsonTypes)
+        def output = jinjava.render(template, replacements)
+        ntcoreCppHandleHeaderOutputFile.write(output)
+    }
+}
+
+def ntcoreCHandleSourceInputFile = file("src/generate/cpp/ntcore_c_types.cpp.jinja")
+def ntcoreCHandleSourceOutputFile = file("$buildDir/generated/main/native/cpp/ntcore_c_types.cpp")
+
+task ntcoreGenerateCHandleSource() {
+    description = "Generates ntcore C handle source"
+    group = "WPILib"
+
+    inputs.files([
+        ntcoreTypesInputFile,
+        ntcoreCHandleSourceInputFile
+    ])
+    outputs.file ntcoreCHandleSourceOutputFile
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreCHandleSourceOutputFile.delete()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        def template = ntcoreCHandleSourceInputFile.text
+        def replacements = new HashMap<String,?>()
+        replacements.put("types", jsonTypes)
+        def output = jinjava.render(template, replacements)
+        ntcoreCHandleSourceOutputFile.write(output)
+    }
+}
+
+def ntcoreCHandleHeaderInputFile = file("src/generate/include/ntcore_c_types.h.jinja")
+def ntcoreCHandleHeaderOutputFile = file("$buildDir/generated/main/native/include/ntcore_c_types.h")
+
+task ntcoreGenerateCHandleHeader() {
+    description = "Generates ntcore C handle header"
+    group = "WPILib"
+
+    inputs.files([
+        ntcoreTypesInputFile,
+        ntcoreCHandleHeaderInputFile
+    ])
+    outputs.file ntcoreCHandleHeaderOutputFile
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreCHandleHeaderOutputFile.delete()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        def template = ntcoreCHandleHeaderInputFile.text
+        def replacements = new HashMap<String,?>()
+        replacements.put("types", jsonTypes)
+        def output = jinjava.render(template, replacements)
+        ntcoreCHandleHeaderOutputFile.write(output)
+    }
+}
+
+def ntcoreJniSourceInputFile = file("src/generate/cpp/jni/types_jni.cpp.jinja")
+def ntcoreJniSourceOutputFile = file("$buildDir/generated/main/native/cpp/jni/types_jni.cpp")
+
+task ntcoreGenerateJniSource() {
+    description = "Generates ntcore JNI types source"
+    group = "WPILib"
+
+    inputs.files([
+        ntcoreTypesInputFile,
+        ntcoreJniSourceInputFile
+    ])
+    outputs.file ntcoreJniSourceOutputFile
+
+    doLast {
+        def jsonSlurper = new JsonSlurper()
+        def jsonTypes = jsonSlurper.parse(ntcoreTypesInputFile)
+
+        ntcoreJniSourceOutputFile.delete()
+
+        def config = new JinjavaConfig()
+        def jinjava = new Jinjava(config)
+
+        def template = ntcoreJniSourceInputFile.text
+        def replacements = new HashMap<String,?>()
+        replacements.put("types", jsonTypes)
+        def output = jinjava.render(template, replacements)
+        ntcoreJniSourceOutputFile.write(output)
+    }
+}
+
 ext {
+    addNtcoreDependency = { binary, shared->
+        binary.tasks.withType(AbstractNativeSourceCompileTask) {
+            it.dependsOn ntcoreGenerateCppTypes
+            it.dependsOn ntcoreGenerateCppHandleHeader
+            it.dependsOn ntcoreGenerateCHandleHeader
+        }
+        binary.lib project: ':ntcore', library: 'ntcore', linkage: shared
+    }
+
+    addNtcoreJniDependency = { binary->
+        binary.tasks.withType(AbstractNativeSourceCompileTask) {
+            it.dependsOn ntcoreGenerateCppTypes
+            it.dependsOn ntcoreGenerateCppHandleHeader
+            it.dependsOn ntcoreGenerateCHandleHeader
+        }
+        binary.lib project: ':ntcore', library: 'ntcoreJNIShared', linkage: 'shared'
+    }
+
     nativeName = 'ntcore'
     devMain = 'edu.wpi.first.ntcore.DevMain'
+    generatedSources = "$buildDir/generated/main/native/cpp"
+    generatedHeaders = "$buildDir/generated/main/native/include"
+    jniSplitSetup = {
+        it.tasks.withType(CppCompile) {
+            it.dependsOn ntcoreGenerateCppTypes
+            it.dependsOn ntcoreGenerateCppHandleSource
+            it.dependsOn ntcoreGenerateCppHandleHeader
+            it.dependsOn ntcoreGenerateCHandleSource
+            it.dependsOn ntcoreGenerateCHandleHeader
+            it.dependsOn ntcoreGenerateJniSource
+        }
+    }
+    splitSetup = {
+        it.tasks.withType(CppCompile) {
+            it.dependsOn ntcoreGenerateCppTypes
+            it.dependsOn ntcoreGenerateCppHandleSource
+            it.dependsOn ntcoreGenerateCppHandleHeader
+            it.dependsOn ntcoreGenerateCHandleSource
+            it.dependsOn ntcoreGenerateCHandleHeader
+            it.dependsOn ntcoreGenerateJniSource
+            it.includes 'src/main/native/cpp'
+        }
+    }
+    exeSplitSetup = {
+        it.tasks.withType(CppCompile) {
+            it.dependsOn ntcoreGenerateCppTypes
+            it.dependsOn ntcoreGenerateCppHandleSource
+            it.dependsOn ntcoreGenerateCppHandleHeader
+            it.dependsOn ntcoreGenerateCHandleSource
+            it.dependsOn ntcoreGenerateCHandleHeader
+        }
+    }
 }
 
 apply from: "${rootDir}/shared/jni/setupBuild.gradle"
 
+model {
+    components {}
+    binaries {
+        all {
+            if (!it.buildable || !(it instanceof NativeBinarySpec)) {
+                return
+            }
+            if (it.component.name == "${nativeName}JNI") {
+                lib project: ':wpinet', library: 'wpinet', linkage: 'static'
+                lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
+            } else {
+                lib project: ':wpinet', library: 'wpinet', linkage: 'shared'
+                lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
+            }
+        }
+    }
+}
+
+sourceSets.main.java.srcDir "${buildDir}/generated/main/java"
+compileJava.dependsOn ntcoreGenerateJavaTypes
+
+cppHeadersZip {
+    dependsOn ntcoreGenerateCppTypes
+    dependsOn ntcoreGenerateCppHandleHeader
+    dependsOn ntcoreGenerateCHandleHeader
+    from(generatedHeaders) {
+        into '/'
+    }
+}
+
 Action<List<String>> symbolFilter = { symbols ->
     symbols.removeIf({ !it.startsWith('NT_') })
 } as Action<List<String>>;
 
 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',
@@ -39,7 +341,6 @@
         ]
     }
     ntcoreJNI {
-        x86SymbolFilter = symbolFilter
         x64SymbolFilter = symbolFilter
     }
 }
diff --git a/ntcore/doc/networktables4.adoc b/ntcore/doc/networktables4.adoc
new file mode 100644
index 0000000..5384ebf
--- /dev/null
+++ b/ntcore/doc/networktables4.adoc
@@ -0,0 +1,819 @@
+= Network Tables Protocol Specification, Version 4.0
+WPILib Developers <wpilib@wpi.edu>
+Protocol Revision 4.0, 2/14/2021
+:toc:
+:toc-placement: preamble
+:sectanchors:
+
+A pub/sub WebSockets protocol based on NetworkTables concepts.
+
+[[motivation]]
+== Motivation
+
+Currently in NetworkTables there is no way to synchronize user value updates and NT update sweeps, and if user value updates occur more frequently than NT update sweeps, the intermediate values are lost.  This prevents NetworkTables from being a viable transport layer for seeing all value changes (e.g. for plotting) at rates higher than the NetworkTables update rate (e.g. for capturing high frequency PID changes).  While custom code can work around the second issue, it is more difficult to work around the first issue (unless full timestamps are also sent).
+
+Adding built-in support for capturing and communicating all timestamped data value changes with minimal additional user code changes will make it much easier for inexperienced teams to get high resolution, accurate data to dashboard displays with the minimal possible bandwidth and airtime usage.  Assuming the dashboard performs record and playback of NT updates, this also meets the desire to provide teams a robust data capture and playback mechanism.
+
+Migration to a pub/sub style protocol layer where the client can request only its desired topics and the frequency in which it wants to receive value changes provides some mitigation for increased network utilization due to other changes.
+
+Using WebSockets (RFC 6455) as the transport layer along with JSON and MessagePack data encoding enables browser-based dashboards and other web technologies to easily access the protocol and minimizes the amount of custom wire protocol implementation required.  Support for this protocol can easily be added in parallel to the existing NetworkTables protocol stack in order to maintain compatibility with older clients/servers and facilitate a gradual transition.
+
+[[references]]
+== References
+
+[[rfc6455,RFC6455,WebSocket]]
+* RFC 6455, The WebSocket Protocol, https://tools.ietf.org/html/rfc6455
+
+[[rfc7159,RFC7159,JSON]]
+* RFC 7159, The JavaScript Object Notation (JSON) Data Interchange Format, https://tools.ietf.org/html/rfc7159
+
+[[messagepack]]
+* MessagePack, MessagePack Specification, https://github.com/msgpack/msgpack/blob/master/spec.md
+
+[[networktables3]]
+* <<networktables3.adoc#, Network Tables Protocol Specification, Version 3.0>>
+
+[[cristians-algorithm]]
+* Cristian's algorithm, https://en.wikipedia.org/wiki/Cristian%27s_algorithm
+
+[[design]]
+== Design
+
+Both text and binary <<WebSocket,WebSocket>> frames are used for transport.  Text frames are <<JSON,JSON>>, and binary frames are <<messagepack,MessagePack>>.  JSON is used for control messages for human readability and ease of debugging.  MessagePack is used only for time and space efficient encoding of values, and the MessagePack subset used in this protocol is small enough that a custom encoder/decoder can be easily implemented for languages that lack good MessagePack libraries.
+
+Consistent with pub/sub nomenclature, this spec uses the term "topic" for what was called an "entry" or "key" in the <<networktables3,NT 3.0 spec>>.
+
+MessagePack messages use numeric IDs for topics to reduce data size; these IDs have a 1:1 mapping to a full topic name (a string).  This mapping is communicated via the JSON <<msg-announce>>.
+
+[[topic-names]]
+=== Topic Names
+
+Topic have UTF-8 string names.  Names starting with `$` are reserved for use by the server (see <<meta-topics>>).  Otherwise names are unrestricted, but convention is for them to start with `/` and be `/`-separated (without consecutive `//`) to make a Unix-path-like structure.
+
+[[timestamps]]
+=== Timestamps
+
+All MessagePack messages are timestamped.  Timestamps are specified in unsigned integer microseconds--for robot programs, microseconds are preferred as the FPGA provides time in microseconds, and integers result in a more compact wire encoding (in typical robot use, integer microseconds timestamps will be half the size of double timestamps until about T=70 minutes, and in the worst case will be no larger).
+
+Timestamps in messages always use the server time base.  The server time base is synchronized across the network by the means described in this section (an implementation of <<cristians-algorithm, Cristian's algorithm>>).
+
+Implementations should expose the actual timestamps for messages as well as provide methods to convert from server time base to local time to facilitate applications that prefer the server time base (e.g. a dashboard showing robot events might prefer to use server time instead of wall clock time).
+
+The topic ID of -1 is reserved for timestamp communication.  Clients shall periodically (e.g. every few seconds) send, in a manner that minimizes transmission delays, a MessagePack message with ID of -1, a timestamp of 0, and an implementation-selected type and data value (typically int or float 64) containing its (the client's) current local time.
+
+When the server receives an -1 ID message from a client, it shall respond to the client, in a manner that minimizes transmission delays, with a MessagePack message with ID=-1, a timestamp of its (the server's) current local time (in microseconds), and the client-provided data value.
+
+When the client receives an -1 ID message from the server, it shall compute the round trip time (RTT) from the delta between the message's data value and the current local time.  If the RTT is less than that from previous measurements, the client shall use the timestamp in the message plus ½ the RTT as the server time equivalent to the current local time, and use this equivalence to compute server time base timestamps from local time for future messages.
+
+Due to the fact there can be multiple publishers for a single topic and unpredictable network delays / clock drift, there is no global total order for timestamps either globally or on a per-topic basis.  While single publishers for real-time data will be the norm, and in that case the timestamps will usually be in order, applications that use timestamps need to be able to handle out-of-order timestamps.
+
+[[reconnection]]
+=== Caching and Reconnection Handling
+
+Servers shall keep a retained value for each topic for the purposes of <<msg-subscribe>> requests; the retained value shall be the value in the largest timestamp (greater-than or equal-to) message received for that topic.  This retained value is deleted if the topic is deleted (e.g. there are no more publishers).
+
+Clients may similarly keep a retained value for each topic for ease of use by user code.  If this is done, this retained value shall be updated by both locally published values and received messages for that topic with greater-than/equal-to timestamps, and the retained value shall be deleted when a <<msg-unannounce>> is received.
+
+Clients should support a "set default" operation for a topic.  This is a "weak" value update that publishes a value with a timestamp of 0 (thereby not causing the retained value of the server or other clients to be updated if they have a current value update with a timestamp > 0).  Typically the "set default" operation should also result in the retained property being set on the topic.
+
+Clients may accept application commands to publish and subscribe while disconnected.  If a client does so, in addition to maintaining a retained value as described above, it must keep track for each application-published topic whether any of the locally published values were "strong" (via a "set" operation), or all of them were "weak" (via a "set default" operation).  While disconnected, there is no reference clock; "strong" timestamps shall be set to 1 and "weak" timestamps shall be set to 0.
+
+When the client disconnects, the client shall delete any topics that are not published by the application and do not have the retained or persistent properties set.  The client shall also reset the application-published retained value timestamps to 0 and 1 as per the previous paragraph.
+
+When the connection to the server is established (either reconnect or initial connection), the client shall publish and send _only_ the retained values to the server that are in application-published topics (those with timestamps of 0 and 1, per above).  Only the values with timestamp 0 may be sent immediately upon reconnection.  The values with timestamp 1 must wait until the client clock is synchronized with the server clock; the timestamps for these values when sent to the server must be either the current server time or, if possible, an estimation of server time when the values were actually written.
+
+Note: the previous paragraphs enable offline, multi-publisher operation under network/server reboot conditions without creating zombie topics, assuming clients use "set default" and the retained property appropriately.  This is achieved mainly via the use of timestamps 0 and 1 to enable tie breaks such that normally-set values (timestamp X) are used in preference to retained values (timestamp 1), and retained values are used in preference to weakly set values (timestamp 0).  An example use case is as follows:
+
+* Server starts
+* Dashboard client connects
+* Coprocessor client connects
+* Coprocessor client publishes configuration topic, sends an initial value using "set default", and subscribes to the topic (to detect configuration changes)
+* Dashboard client sees configuration topic published and subscribes to it
+* Dashboard user changes configuration value--dashboard client publishes to the topic and sends the user value
+* Coprocessor receives the user value and updates its retained value
+* **Server reboots** (this also disconnects the dashboard and coprocessor clients)
+* If the dashboard reconnects first:
+** The user value was published and cached (retained value) on the dashboard client, so the dashboard client re-publishes and sends the cached data with timestamp 1.
+** The coprocessor client reconnects later.  It also published and cached, but it only ever called "set default" and sends the cached data (which is also the user value) with timestamp 0.  It receives the retained value from the server with timestamp 1, and updates locally.
+** The server propagates the timestamp 0 message, but since it has a retained value with timestamp 1, as do other clients, the retained value is not updated and the user value remains active.
+* If the coprocessor reconnects first:
+** The coprocessor client only ever called "set default", so it sends the cached data (the user-set value) with timestamp 0.
+** If the dashboard never reconnects, no new values are published, so the user-set value is active
+** If the dashboard reconnects, it sends a message with timestamp 1 ("strong" set).  This propagates but does not change the value (it's the same user-set as before).
+* If the dashboard updates the value while offline, it's still a "strong set" and wins the tie
+
+A second use case:
+
+* Server starts
+* Dashboard client connects
+* Dashboard client publishes configuration value with the retained property set, and publishes an initial value
+* Dashboard client disconnects.  The topic is *not* deleted on the server because the retained property is set.
+* Coprocessor client connects
+* Server sends announce message for topic and sends retained value (with timestamp 1)
+* Coprocessor client publishes, uses "set default", and subscribes to the topic.  Since "set default" uses a timestamp of 0, it loses to the retained value with timestamp 1, and the coprocessor subscriber will see the value previously set by the dashboard.
+* Dashboard client reconnects
+
+[[server]]
+=== Server Behavior
+
+Topic IDs may be common across all client connections or be connection-specific.  If they are common, the server needs to be careful regarding topic ID reuse due to deleted topics, as the protocol provides no way to change a client topic ID.  Requests (e.g. <<msg-subscribe,`subscribe`>> or <<msg-publish,`publish`>>) are always specific to a single client connection.
+
+The server shall keep a publisher count for each topic.  Persistent and retained topics have an additional implicit publisher.  When the publisher count reaches zero (which only happens for non-persistent and non-retained topics), the server shall delete the topic (including its retained value).  When a client connection is lost, the server shall handle that as an implicit <<msg-unpublish,`unpublish`>> for all topics currently published by that client.
+
+The server may operate in-process to an application (e.g. a robot program).  In this case, the application operationally behaves like a client (e.g. it sends publish requests and receives topic announcements), but of course does not need to estimate delta time, create JSON/MessagePack messages, etc, as all of the necessary operations can be performed programmatically within the same process.
+
+[[client]]
+=== Client Behavior
+
+Clients are responsible for keeping server connections established (e.g. via retries when a connection is lost).  Topic IDs must be treated as connection-specific; if the connection to the server is lost, the client is responsible for sending new <<msg-publish,`publish`>> and <<msg-subscribe,`subscribe`>> messages as required for the application when a new connection is established, and not using old topic IDs, but rather waiting for new <<msg-announce,`announce`>> messages to be received.
+
+Except for offline-published values with timestamps of 0, the client shall not send any other published values to the server until its clock is synchronized with the server per the <<timestamps>> section.
+
+Clients may publish a value at any time following clock synchronization.  Clients may subscribe to meta-topics to determine whether or not to publish a value change (e.g. based on whether there are any subscribers, or based on specific <<sub-options>>).
+
+[[meta-topics]]
+=== Server-Published Meta Topics
+
+The server shall publish a standard set of topics with information about server state.  Clients may subscribe to these topics for diagnostics purposes or to determine when to publish value changes.  These topics are hidden--they are not announced to subscribers to an empty prefix, only to subscribers that have subscribed to `"$"` or  longer prefixes.
+
+[cols="1,1,2", options="header"]
+|===
+|Topic Name|Data Type|Description
+|<<meta-clients,`$clients`>>|`msgpack`|Connected clients
+|<<meta-client-sub,`$clientsub$<client>`>>|`msgpack`|Client `<client>` subscriptions
+|<<meta-server-sub,`$serversub`>>|`msgpack`|Server subscriptions
+|<<meta-sub,`$sub$<topic>`>>|`msgpack`|Subscriptions to `<topic>`
+|<<meta-client-pub,`$clientpub$<client>`>>|`msgpack`|Client `<client>` publishers
+|<<meta-server-pub,`$serverpub`>>|`msgpack`|Server publishers
+|<<meta-pub,`$pub$<topic>`>>|`msgpack`|Publishers to `<topic>`
+|===
+
+[[meta-clients]]
+==== Connected Clients (`$clients`)
+
+The server shall update this topic when a client connects or disconnects.
+
+The MessagePack contents shall be an array of maps.  Each map in the array shall have the following contents:
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`id`
+|String
+|Client name
+|
+
+|`conn`
+|String
+|Connection info
+|Connection information about the client; typically host:port
+|===
+
+[[meta-client-sub]]
+==== Client Subscriptions (`$clientsub$<client>`)
+
+The server shall update this topic when the corresponding client subscribes or unsubscribes to any topic.
+
+The MessagePack contents shall be an array of maps.  Each map in the array shall have the following contents:
+
+[cols="1,2,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`uid`
+|Integer
+|Subscription UID
+|A client-generated unique identifier for this subscription.
+
+|`topics`
+|Array of String
+|Array of topic names or prefixes
+|One or more topic names or prefixes (if the `prefix` option is true) that messages are sent for.
+
+|`options`
+|Map
+|Options
+|<<sub-options>>
+|===
+
+[[meta-server-sub]]
+==== Server Subscriptions (`$serversub`)
+
+Same as `$clientsub`, except it's updated when the server subscribes or unsubscribes to any topic.
+
+[[meta-sub]]
+==== Subscriptions (`$sub$<topic>`)
+
+The server shall update this topic when a client subscribes or unsubscribes to `<topic>`.
+
+The MessagePack contents shall be an array of maps.  Each map in the array shall have the following contents:
+
+[cols="1,2,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`client`
+|String
+|Client name
+|Empty string for server subscriptions.
+
+|`subuid`
+|Integer
+|Subscription UID
+|A client-generated unique identifier for this subscription.
+
+|`options`
+|Map
+|Options
+|<<sub-options>>
+|===
+
+[[meta-client-pub]]
+==== Client Publishers (`$clientpub$<client>`)
+
+The server shall update this topic when the corresponding client publishes or unpublishes any topic.
+
+The MessagePack contents shall be an array of maps.  Each map in the array shall have the following contents:
+
+[cols="1,2,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`uid`
+|Integer
+|Publisher UID
+|A client-generated unique identifier for this publisher.
+
+|`topic`
+|String
+|Topic name
+|
+|===
+
+[[meta-server-pub]]
+==== Server Publishers (`$serverpub`)
+
+Same as `$clientpub`, except it's updated when the server publishes or unpublishes any topic.
+
+[[meta-pub]]
+==== Publishers (`$pub$<topic>`)
+
+The server shall update this topic when a client publishes or unpublishes to `<topic>`.
+
+The MessagePack contents shall be an array of maps.  Each map in the array shall have the following contents:
+
+[cols="1,2,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`client`
+|String
+|Client name
+|Empty string for server publishers.
+
+|`pubuid`
+|Integer
+|Publisher UID
+|A client-generated unique identifier for this publisher.
+|===
+
+[[websockets-config]]
+== WebSockets Protocol Configuration
+
+Both clients and servers shall support unsecure connections (`ws:`) and may support secure connections (`wss:`).  In a trusted network environment (e.g. a robot network), clients that support secure connections should fall back to an unsecure connection if a secure connection is not available.
+
+Servers shall support a resource name of `/nt/<name>`, where `<name>` is an arbitrary string representing the client name.  The client name does not need to be unique; multiple connections to the same name are allowed; the server shall ensure the name is unique (for the purposes of meta-topics) by appending a '@' and a unique number (if necessary).  To support this, the name provided by the client should not contain an embedded '@'.  Clients should provide a way to specify the resource name (in particular, the client name portion).
+
+Both clients and servers shall support/use subprotocol `networktables.first.wpi.edu` for this protocol. Clients and servers shall terminate the connection in accordance with the WebSocket protocol unless both sides support this subprotocol.
+
+The unsecure standard server port number shall be 5810, the secure standard port number shall be 5811.
+
+[[data-types]]
+== Supported Data Types
+
+The following data types are supported.  Note: implementations may map integer and float to double internally.  Any data type string not in the table below shall be handled in the binary protocol as data type 5 (binary); some specific binary examples are included in the table below.
+
+[cols="1,1,1,1,4",options="header"]
+|===
+|Data type|MessagePack format family|NT 3 data type|Data Type string
+|Notes
+
+|0|bool|Boolean|`boolean`
+|
+
+|1|float 64|Number (double)|`double`
+|
+
+|2|int|Number (double)|`int`
+.2+|Current NetworkTables protocol and user APIs only support double-precision float numeric values; implementations may choose to upgrade APIs to support integer and/or single-precision float values.
+
+|3|float 32|Number (double)|`float`
+
+.2+|4
+.2+|str
+.2+|String
+|`string`
+|
+
+|`json`
+|JSON data (e.g. structured data)
+
+.4+|5
+.4+|bin
+.4+|Raw
+|`raw`
+|Raw data, no specified format
+
+|`rpc`
+|For backwards compatibility with NT 3.0
+
+|`msgpack`
+|Nested MessagePack data (e.g. structured data)
+
+|`protobuf`
+|Google Protocol Buffers data (structured).  Uses property `protobuf` to communicate the data description.
+
+|16|array of all bool|Boolean Array|`boolean[]`
+|All elements of the array must be boolean
+
+|17|array of all float 64|Number Array|`double[]`
+|All elements of the array must be double-precision floats
+
+|18|array of all int|Number Array|`int[]`
+|All elements of the array must be integers.  See note on Number
+
+|19|array of all float 32|Number Array|`float[]`
+|All elements of the array must be single-precision floats.  See note on Number
+
+|20|array of all str|String Array|`string[]`
+|All elements of the array must be text strings
+|===
+
+[[properties]]
+== Properties
+
+Each published topic may also have properties associated to it.  Properties are represented in the protocol as JSON and thus property values may be any JSON type.  Property keys must be strings.  The following properties have a defined meaning in this spec.  Servers shall support arbitrary properties being set outside of this set.  Clients shall ignore properties they do not recognize.  Properties are initially set on publish and may be changed (by any client) using <<msg-setproperties>>.
+
+[cols="1,1,1,6",options="header"]
+|===
+|Property|Type|Description|Notes
+|`persistent`|boolean|Persistent Flag|If true, the last set value will be periodically saved to persistent storage on the server and be restored during server startup.  Topics with this property set to true will not be deleted by the server when the last publisher stops publishing.
+|`retained`|boolean|Retained Flag|Topics with this property set to true will not be deleted by the server when the last publisher stops publishing.
+|===
+
+[[sub-options]]
+== Subscription Options
+
+Each subscription may have options set.  The following options have a defined meaning in this spec.  Servers shall preserve arbitrary options, as servers and clients may support arbitrary options outside of this set.  Options are set using <<msg-subscribe>> and cannot be changed.
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`periodic` (optional)
+|Number
+|Periodic sweep time (in seconds)
+|How frequently the server should send changes.  The server may send more frequently than this (e.g. use a combined minimum period for all values) or apply a restricted range to this value. The default if unspecified is 100 ms (same as NT 3.0).
+
+|`all` (optional)
+|Boolean
+|All Changes Flag
+|If true, the server should send all value changes over the wire.  If false, only the most recent value is sent (same as NT 3.0 behavior).  If not specified, defaults to false.
+
+|`topicsonly` (optional)
+|Boolean
+|No Value Changes Flag
+|If true, the server should not send any value changes over the wire regardless of other options.  This is useful for only getting topic announcements.  If false, value changes are sent in accordance with other options.  If not specified, defaults to false.
+
+|`prefix` (optional)
+|Boolean
+|Prefix Flag
+|If true, any topic starting with the name in the subscription `topics` list is subscribed to, not just exact matches.  If not specified, defaults to false.
+|===
+
+[[text-frames]]
+== Text Data Frames
+
+Each WebSockets text data frame shall consist of a list of <<JSON,JSON>> objects ("JSON messages").
+
+Each JSON message shall be a JSON object with two keys: a `method` key containing a lowercase string value describing the type of message as per the following table, and a `params` key containing the message parameters as a JSON object.  The contents of the params object depends on the method; see the sections for each message for details.
+
+Clients and servers shall ignore JSON messages that:
+
+* are not objects
+* have no `method` key or `params` key
+* have a `method` value that is not a string
+* have a `params` value that is not an object
+* have a `method` value that is not listed in the below table
+
+[cols="1,2,2,3",options="header"]
+|===
+|Method
+|Description
+|Direction
+|Response
+
+4+|Publish Messages (Client to Server)
+
+|<<msg-publish,`publish`>>
+|Publish Request
+|Client to Server
+|<<msg-announce,`announce`>>
+
+|<<msg-unpublish,`unpublish`>>
+|Publish Release
+|Client to Server
+|<<msg-unannounce,`unannounce`>> (if topic deleted)
+
+|<<msg-setproperties,`setproperties`>>
+|Set Properties
+|Client to Server
+|<<msg-properties,`properties`>>
+
+4+|Value/Subscription Messages (Client to Server)
+
+|<<msg-subscribe,`subscribe`>>
+|Subscribe
+|Client to Server
+|<<binary-frames,MessagePack messages>> (once topic is announced)
+
+|<<msg-unsubscribe,`unsubscribe`>>
+|Unsubscribe
+|Client to Server
+|---
+
+4+|Announcement Messages (Server to Client)
+
+|<<msg-announce,`announce`>>
+|Topic Announcement
+|Server to Client
+|---
+
+|<<msg-unannounce,`unannounce`>>
+|Topic Removed
+|Server to Client
+|---
+
+|<<msg-properties,`properties`>>
+|Properties Update
+|Server to Client
+|---
+|===
+
+[[publish-messages]]
+=== Publish Messages (Client to Server)
+
+[[msg-publish]]
+==== Publish Request Message (`publish`)
+
+Sent from a client to the server to indicate the client wants to start publishing values at the given topic.  The server shall respond with a <<msg-announce>>, even if the topic was previously announced.  The client can start publishing data values via MessagePack messages immediately after sending this message, but the messages will be ignored by the server if the publisher data type does not match the topic data type.
+
+The `publish` JSON message shall contain the following parameters:
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`name`
+|String
+|Publish name
+|The topic name being published
+
+|`pubuid`
+|Integer
+|Publisher UID
+|A client-generated unique identifier for this publisher.  Use the same UID later to unpublish.  This is also the identifier that the client will use in MessagePack messages for this topic.
+
+|`type`
+|String
+|Type of data
+|The requested data type (as a string).
+
+If the topic is newly created (e.g. there are no other publishers) this sets the value type.  If the topic was previously published, this is ignored.  The <<msg-announce,`announce`>> message contains the actual topic value type that the client shall use when publishing values.
+
+Implementations should indicate an error if the user tries to publish an incompatible type to that already set for the topic.
+
+|`properties`
+|Map
+|Properties
+|Initial topic properties.
+
+If the topic is newly created (e.g. there are no other publishers) this sets the topic properties.  If the topic was previously published, this is ignored.  The <<msg-announce,`announce`>> message contains the actual topic properties.  Clients can use the <<msg-setproperties,`setproperties`>> message to change properties after topic creation.
+|===
+
+[[msg-unpublish]]
+==== Publish Release Message (`unpublish`)
+
+Sent from a client to the server to indicate the client wants to stop publishing values for the given topic and publisher.  The client should stop publishing data value updates via binary MessagePack messages for this publisher prior to sending this message.
+
+When there are no remaining publishers for a non-persistent topic, the server shall delete the topic and send a <<msg-unannounce>> to all clients who have been sent a previous <<msg-announce>> for the topic.
+
+The `unpublish` JSON message shall contain the following parameters:
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`pubuid`
+|Integer
+|Publisher UID
+|The same unique identifier passed to the <<msg-publish,`publish`>> message
+|===
+
+[[msg-setproperties]]
+==== Set Properties Message (`setproperties`)
+
+Sent from a client to the server to change properties (see <<properties>>) for a given topic.  The server will send a corresponding <<msg-properties>> to all subscribers to the topic (if the topic is published).  This message shall be ignored by the server if the topic is not published.
+
+The `setproperties` JSON message shall contain the following parameters:
+
+[cols="1,2,4",options="header"]
+|===
+|Key
+|Value type
+|Description
+
+|`name`
+|String
+|Topic name
+
+|`update`
+|Map
+|Properties to update
+|===
+
+If a property is not included in the update map, its value is not changed.  If a property is provided in the update map with a value of null, the property is deleted.
+
+[[subscription-messages]]
+=== Value/Subscription Messages (Client to Server)
+
+[[msg-subscribe]]
+==== Subscribe Message (`subscribe`)
+
+Sent from a client to the server to indicate the client wants to subscribe to value changes for the specified topics / groups of topics.  The server shall send MessagePack messages containing the current values for any existing topics upon receipt, and continue sending MessagePack messages for future value changes.  If a topic does not yet exist, no message is sent until it is created (via a publish), at which point a <<msg-announce>> will be sent and MessagePack messages will automatically follow as they are published.
+
+Subscriptions may overlap; only one MessagePack message is sent per value change regardless of the number of subscriptions.  Sending a `subscribe` message with the same subscription UID as a previous `subscribe` message results in updating the subscription (replacing the array of identifiers and updating any specified options).
+
+The `subscribe` JSON message shall contain the following parameters:
+
+[cols="1,2,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`topics`
+|Array of String
+|Array of topic names or prefixes
+|One or more topic names or prefixes (if the `prefix` option is true) to start receiving messages for.
+
+|`subuid`
+|Integer
+|Subscription UID
+|A client-generated unique identifier for this subscription.  Use the same UID later to unsubscribe.
+
+|`options`
+|Map
+|Options
+|<<sub-options>>
+|===
+
+[[msg-unsubscribe]]
+==== Unsubscribe Message (`unsubscribe`)
+
+Sent from a client to the server to indicate the client wants to stop subscribing to messages for the given subscription.
+
+The `unsubscribe` JSON message shall contain the following parameters:
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`subuid`
+|Integer
+|Subscription UID
+|The same unique identifier passed to the <<msg-subscribe,`subscribe`>> message
+|===
+
+[[announcement-messages]]
+=== Announcement Messages (Server to Client)
+
+[[msg-announce]]
+==== Topic Announcement Message (`announce`)
+
+The server shall send this message for each of the following conditions:
+
+- To all clients subscribed to a matching prefix when a topic is created
+
+- To a client in response to an <<msg-publish>> from that client
+
+The `announce` JSON message shall contain the following parameters:
+
+[cols="1,2,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`name`
+|String
+|Topic name
+|
+
+|`id`
+|Integer
+|Topic ID
+|The identifier that the server will use in MessagePack messages for this topic
+
+|`type`
+|String
+|Data type
+|The data type for the topic (as a string)
+
+|`pubuid` (optional)
+|Integer
+|Publisher UID
+|If this message was sent in response to a <<msg-publish,`publish`>> message, the Publisher UID provided in that message.  Otherwise absent.
+
+|`properties`
+|Map
+|Properties
+|Topic <<properties>>
+|===
+
+[[msg-unannounce]]
+==== Topic Removed Message (`unannounce`)
+
+The server shall send this message when a previously announced (via a <<msg-announce>>) topic is deleted.
+
+The `unannounce` JSON message shall contain the following parameters:
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`name`
+|String
+|Topic name
+|
+
+|`id`
+|Integer
+|Topic ID
+|The identifier that the server was using for value updates
+|===
+
+[[msg-properties]]
+==== Properties Update Message (`properties`)
+
+The server shall send this message when a previously announced (via a <<msg-announce>>) topic has its properties changed (via <<msg-setproperties>>).
+
+The `properties` JSON message shall contain the following parameters:
+
+[cols="1,1,2,6",options="header"]
+|===
+|Key
+|Value type
+|Description
+|Notes
+
+|`name`
+|String
+|Topic name
+|
+
+|`ack`
+|Boolean
+|Acknowledgement
+|True if this message is in response to a <<msg-setproperties,`setproperties`>> message from the same client.  Otherwise absent.
+
+|`update`
+|Map
+|Properties to update (from <<msg-setproperties,`setproperties`>>)
+|===
+
+The client shall handle the `update` value as follows.  If a property is not included in the update map, its value is not changed.  If a property is provided in the update map with a value of null, the property is deleted.
+
+[[binary-frames]]
+== Binary Data Frames
+
+Each WebSockets binary data frame shall consist of a <<messagepack,MessagePack>> data stream with one or more complete MessagePack arrays ("MessagePack messages").  MessagePack messages shall not span across WebSockets data frames.  It is up to implementations to decide how many MessagePack messages to put into each transmitted WebSockets data frame (as there is an efficiency/latency tradeoff).
+
+Each MessagePack message shall be a MessagePack array with 4 elements.  Implementations can either ignore other types of messages (e.g. non-arrays, other numbers of elements) or terminate the connection (allowing this enables use of simplified decoder implementations).
+
+Messages shall consist of (in this order):
+
+* Topic/Publisher ID: unsigned integer, or -1 (RTT measurement)
+* Timestamp: integer microseconds
+* Data type: unsigned integer
+* Data value (see below)
+
+Topic IDs are used for server to client messages.  Topic IDs shall be assigned via JSON <<msg-announce,`announce`>> messages.  Client implementations shall ignore messages with topic IDs they do not recognize.  Server implementations shall not send messages with topic IDs that were not assigned previously with a JSON message.
+
+Publisher IDs are used for client to server messages.  Publisher IDs shall be assigned by the client and be communicated to the server via JSON <<msg-publish,`publish`>> messages.  Server implementations shall ignore messages with publisher IDs they do not recognize.  Client implementations shall not send messages with publisher IDs that were not assigned previously with a JSON message.
+
+Implementations must ignore messages with data values they cannot decode (either by ignoring the message or by terminating the connection), and shall send messages with data values consistent with the above table.
+
+An example double value update would be 17 bytes:
+
+`94` (array with 4 elements)
+
+`32` (topic/publisher ID=50)
+
+`D2 07 27 0E 00` (timestamp of exactly 2 minutes in integer microseconds)
+
+`01` (data type: double-precision float)
+
+`CB 3F BF 97 24 74 53 8E F3` (double value of 0.1234)
+
+For comparison, a double value update in NT 3.0 is 14 bytes (and does not contain a timestamp).
+
+[[drawbacks]]
+== Drawbacks
+
+[[drawback-api]]
+=== API Changes
+
+While the server (robot) APIs can have minimal to no changes, the current NetworkTables API doesn’t directly map to a pub/sub approach, except for the listener API.  A new API will be required to take full advantage of the features of this protocol.  One big advantage of the current APIs is that the client and server APIs are the same, so if we update the client API it should work on the server as well.
+
+[[drawback-tcp]]
+=== TCP Only
+
+Everything is sent via the WebSockets pipe, which can result in latency spikes due to TCP retransmissions, even for timestamp updates.  Should there be a send-via-UDP option?  Web technologies generally can’t use UDP but this feature could be useful for other use cases.  However, adding this would add significant complexity and might be better left to MQTT or other full-stack alternatives.
+
+[[drawback-client-server]]
+=== No peer-to-peer client connections
+
+This protocol continues the previous NT approach of having all traffic go through the central NT server, rather than supporting direct peer to peer connections.  This adds latency but simplifies the overall protocol design and makes it possible to have clients that can’t set up servers (e.g. web browsers).
+
+[[alternatives]]
+== Alternatives
+
+[[alt-do-nothing]]
+=== Do nothing
+
+The major features in this proposal (accessibility to web technologies and timestamping and sending all changes) would not be made available to users.  Users would continue to need to deal with these issues manually or by using third-party workarounds.
+
+[[alt-raw-protocol]]
+=== Update the raw NetworkTables protocol (without using WebSockets)
+
+This does not provide one of the major benefits to moving to a WebSockets protocol, which is easy to use by browsers.  While current workarounds like pynetworktables2js exist, a protocol revision which does not address this need feels shortsighted.
+
+[[alt-encapsulation]]
+=== Encapsulate the current NT 3.0 protocol in WebSockets
+
+While this makes the current protocol more easily accessible to web technologies, the current protocol does not have integrated support for timestamping or sending all changes.  It also requires substantially more custom decoder implementation work than MessagePack, and does not offer human-readable control messages.
+
+[[alt-mqtt]]
+=== Use MQTT or another existing protocol
+
+MQTT requires running a separate server from the robot program, and the robot program to be a client to it (unlike NT, it has no means of doing value updates within the server itself).  MQTT natively does not use WebSockets (it’s a custom wire protocol like the current NetworkTables), although there is a WebSockets variant.  MQTT is a significantly more complicated protocol with support for things like full QOS.
+
+[[trades]]
+== Trades
+
+[[trade-json-updates]]
+=== JSON option for value updates (rejected)
+
+This was considered, but rejected for two reasons: encoding overhead and spec/implementation effort.  In benchmarking on desktop systems, JSON was 25% the speed of MessagePack when encoding doubles (due to text conversion), and in typical robot use, this overhead would largely land on the robot controller, which also has the fewest resources.  In addition, requiring implementation of both JSON and MessagePack encoding nearly doubles the amount of encode/decode implementation effort, particularly as JSON does not have good binary data support and would require Base64 or something similar to encode binary data as a string.
+
+[[trade-timestamp]]
+=== Timestamp format
+
+The spec uses integer microseconds.  This seems to be a reasonable enough resolution for FRC use and is common with the FPGA clock resolution.
+
+[[unresolved-questions]]
+== Unresolved Questions
diff --git a/ntcore/generate_topics.py b/ntcore/generate_topics.py
new file mode 100644
index 0000000..ece7df2
--- /dev/null
+++ b/ntcore/generate_topics.py
@@ -0,0 +1,121 @@
+import glob
+import os
+import sys
+from jinja2 import Environment, FileSystemLoader
+import json
+
+
+def Output(outPath, outfn, contents):
+    if not os.path.exists(outPath):
+        os.makedirs(outPath)
+
+    outpathname = f"{outPath}/{outfn}"
+
+    if os.path.exists(outpathname):
+        with open(outpathname, "r") as f:
+            if f.read() == contents:
+                return
+
+    # File either doesn't exist or has different contents
+    with open(outpathname, "w") as f:
+        f.write(contents)
+
+
+def main():
+    dirname, _ = os.path.split(os.path.abspath(__file__))
+    cmake_binary_dir = sys.argv[1]
+
+    with open(f"{dirname}/src/generate/types.json") as f:
+        types = json.load(f)
+
+    # Java files
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/java"), autoescape=False
+    )
+    rootPath = f"{cmake_binary_dir}/generated/main/java/edu/wpi/first/networktables"
+    for fn in glob.glob(f"{dirname}/src/generate/java/*.jinja"):
+        template = env.get_template(os.path.basename(fn))
+        outfn = os.path.basename(fn)[:-6]  # drop ".jinja"
+        if os.path.basename(fn).startswith("NetworkTable") or os.path.basename(
+            fn
+        ).startswith("Generic"):
+            output = template.render(types=types)
+            Output(rootPath, outfn, output)
+        else:
+            for replacements in types:
+                output = template.render(replacements)
+                if outfn == "Timestamped.java":
+                    outfn2 = f"Timestamped{replacements['TypeName']}.java"
+                else:
+                    outfn2 = f"{replacements['TypeName']}{outfn}"
+                Output(rootPath, outfn2, output)
+
+    # C++ classes
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/include/networktables"),
+        autoescape=False,
+    )
+    rootPath = f"{cmake_binary_dir}/generated/main/native/include/networktables"
+    for fn in glob.glob(f"{dirname}/src/generate/include/networktables/*.jinja"):
+        template = env.get_template(os.path.basename(fn))
+        outfn = os.path.basename(fn)[:-6]  # drop ".jinja"
+        for replacements in types:
+            output = template.render(replacements)
+            outfn2 = f"{replacements['TypeName']}{outfn}"
+            Output(rootPath, outfn2, output)
+
+    # C++ handle API (header)
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/include"), autoescape=False
+    )
+    template = env.get_template("ntcore_cpp_types.h.jinja")
+    output = template.render(types=types)
+    Output(
+        f"{cmake_binary_dir}/generated/main/native/include",
+        "ntcore_cpp_types.h",
+        output,
+    )
+
+    # C++ handle API (source)
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/cpp"), autoescape=False
+    )
+    template = env.get_template("ntcore_cpp_types.cpp.jinja")
+    output = template.render(types=types)
+    Output(
+        f"{cmake_binary_dir}/generated/main/native/cpp", "ntcore_cpp_types.cpp", output
+    )
+
+    # C handle API (header)
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/include"), autoescape=False
+    )
+    template = env.get_template("ntcore_c_types.h.jinja")
+    output = template.render(types=types)
+    Output(
+        f"{cmake_binary_dir}/generated/main/native/include",
+        "ntcore_c_types.h",
+        output,
+    )
+
+    # C handle API (source)
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/cpp"), autoescape=False
+    )
+    template = env.get_template("ntcore_c_types.cpp.jinja")
+    output = template.render(types=types)
+    Output(
+        f"{cmake_binary_dir}/generated/main/native/cpp", "ntcore_c_types.cpp", output
+    )
+
+    # JNI
+    env = Environment(
+        loader=FileSystemLoader(f"{dirname}/src/generate/cpp/jni"), autoescape=False
+    )
+    template = env.get_template("types_jni.cpp.jinja")
+    output = template.render(types=types)
+    Output(f"{cmake_binary_dir}/generated/main/native/cpp/jni", "types_jni.cpp", output)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/ntcore/src/dev/native/cpp/main.cpp b/ntcore/src/dev/native/cpp/main.cpp
index f863018..fac64e7 100644
--- a/ntcore/src/dev/native/cpp/main.cpp
+++ b/ntcore/src/dev/native/cpp/main.cpp
@@ -2,14 +2,107 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#include <fmt/core.h>
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <cstdlib>
+#include <numeric>
+#include <string_view>
+#include <thread>
+
+#include <fmt/format.h>
+#include <wpi/Synchronization.h>
 
 #include "ntcore.h"
+#include "ntcore_cpp.h"
 
-int main() {
+void bench();
+
+int main(int argc, char* argv[]) {
+  if (argc == 2 && std::string_view{argv[1]} == "bench") {
+    bench();
+    return EXIT_SUCCESS;
+  }
   auto myValue = nt::GetEntry(nt::GetDefaultInstance(), "MyValue");
 
   nt::SetEntryValue(myValue, nt::Value::MakeString("Hello World"));
 
-  fmt::print("{}\n", nt::GetEntryValue(myValue)->GetString());
+  fmt::print("{}\n", nt::GetEntryValue(myValue).GetString());
+}
+
+void PrintTimes(std::vector<int64_t>& times) {
+  std::sort(times.begin(), times.end());
+  int64_t min = times[0];
+  int64_t max = times[times.size() - 1];
+  double mean =
+      static_cast<double>(std::accumulate(times.begin(), times.end(), 0)) /
+      times.size();
+  double sq_sum =
+      std::inner_product(times.begin(), times.end(), times.begin(), 0);
+  double stdev = std::sqrt(sq_sum / times.size() - mean * mean);
+
+  fmt::print("min: {} max: {}, mean: {}, stdev: {}\n", min, max, mean, stdev);
+  fmt::print("min 10: {}\n", fmt::join(times.begin(), times.begin() + 10, ","));
+  fmt::print("max 10: {}\n", fmt::join(times.end() - 10, times.end(), ","));
+}
+
+// benchmark
+void bench() {
+  // set up instances
+  auto client = nt::CreateInstance();
+  auto server = nt::CreateInstance();
+
+  // connect client and server
+  nt::StartServer(server, "bench.json", "127.0.0.1", 0, 10000);
+  nt::StartClient4(client, "client");
+  nt::SetServer(client, "127.0.0.1", 10000);
+
+  using namespace std::chrono_literals;
+  std::this_thread::sleep_for(1s);
+
+  // add "typical" set of subscribers on client and server
+  nt::SubscribeMultiple(client, {{std::string_view{}}});
+  nt::Subscribe(nt::GetTopic(client, "highrate"), NT_DOUBLE, "double",
+                {.sendAll = true, .keepDuplicates = true});
+  nt::SubscribeMultiple(server, {{std::string_view{}}});
+  auto pub = nt::Publish(nt::GetTopic(server, "highrate"), NT_DOUBLE, "double");
+  nt::SetDouble(pub, 0);
+
+  // warm up
+  for (int i = 1; i <= 10000; ++i) {
+    nt::SetDouble(pub, i * 0.01);
+    if (i % 2000 == 0) {
+      std::this_thread::sleep_for(0.02s);
+    }
+  }
+
+  std::vector<int64_t> flushTimes;
+  flushTimes.reserve(100);
+
+  std::vector<int64_t> times;
+  times.reserve(100001);
+
+  // benchmark
+  auto start = std::chrono::high_resolution_clock::now();
+  int64_t now = nt::Now();
+  for (int i = 1; i <= 100000; ++i) {
+    nt::SetDouble(pub, i * 0.01, now);
+    int64_t prev = now;
+    now = nt::Now();
+    times.emplace_back(now - prev);
+    if (i % 2000 == 0) {
+      nt::Flush(server);
+      flushTimes.emplace_back(nt::Now() - now);
+      std::this_thread::sleep_for(0.02s);
+      now = nt::Now();
+    }
+  }
+  auto stop = std::chrono::high_resolution_clock::now();
+
+  fmt::print("total time: {}us\n",
+             std::chrono::duration_cast<std::chrono::microseconds>(stop - start)
+                 .count());
+  PrintTimes(times);
+  fmt::print("-- Flush --\n");
+  PrintTimes(flushTimes);
 }
diff --git a/ntcore/src/generate/cpp/jni/types_jni.cpp.jinja b/ntcore/src/generate/cpp/jni/types_jni.cpp.jinja
new file mode 100644
index 0000000..a105278
--- /dev/null
+++ b/ntcore/src/generate/cpp/jni/types_jni.cpp.jinja
@@ -0,0 +1,245 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "edu_wpi_first_networktables_NetworkTablesJNI.h"
+#include "ntcore.h"
+
+using namespace wpi::java;
+
+//
+// Globals and load/unload
+//
+{% for t in types %}
+static JClass timestamped{{ t.TypeName }}Cls;
+{%- endfor %}
+{%- for t in types %}
+{%- if t.jni.ToJavaArray == "MakeJObjectArray" %}
+static JClass {{ t.jni.jtype }}Cls;
+{%- endif %}
+{%- endfor %}
+static JException nullPointerEx;
+
+static const JClassInit classes[] = {
+{%- for t in types %}
+    {"edu/wpi/first/networktables/Timestamped{{ t.TypeName }}", &timestamped{{ t.TypeName }}Cls},
+{%- endfor %}
+{%- for t in types %}
+{%- if t.jni.ToJavaArray == "MakeJObjectArray" %}
+    {"{{ t.jni.jtypestr }}", &{{ t.jni.jtype }}Cls},
+{%- endif %}
+{%- endfor %}
+};
+
+static const JExceptionInit exceptions[] = {
+    {"java/lang/NullPointerException", &nullPointerEx},
+};
+
+namespace nt {
+
+bool JNI_LoadTypes(JNIEnv* env) {
+  // Cache references to classes
+  for (auto& c : classes) {
+    *c.cls = JClass(env, c.name);
+    if (!*c.cls) {
+      return false;
+    }
+  }
+
+  for (auto& c : exceptions) {
+    *c.cls = JException(env, c.name);
+    if (!*c.cls) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void JNI_UnloadTypes(JNIEnv* env) {
+  // Delete global references
+  for (auto& c : classes) {
+    c.cls->free(env);
+  }
+}
+
+}  // namespace nt
+
+static std::vector<int> FromJavaBooleanArray(JNIEnv* env, jbooleanArray jarr) {
+  CriticalJBooleanArrayRef ref{env, jarr};
+  if (!ref) {
+    return {};
+  }
+  std::span<const 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 arr;
+}
+
+static std::vector<std::string> FromJavaStringArray(JNIEnv* env, jobjectArray jarr) {
+  size_t len = env->GetArrayLength(jarr);
+  std::vector<std::string> arr;
+  arr.reserve(len);
+  for (size_t i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(jarr, i))};
+    if (!elem) {
+      return {};
+    }
+    arr.emplace_back(JStringRef{env, elem}.str());
+  }
+  return arr;
+}
+
+{% for t in types %}
+static jobject MakeJObject(JNIEnv* env, nt::Timestamped{{ t.TypeName }} value) {
+  static jmethodID constructor = env->GetMethodID(
+      timestamped{{ t.TypeName }}Cls, "<init>", "(JJ{{ t.jni.jtypestr }})V");
+{%- if t.jni.JavaObject %}
+  JLocal<{{ t.jni.jtype }}> val{env, {{ t.jni.ToJavaBegin }}value.value{{ t.jni.ToJavaEnd }}};
+  return env->NewObject(timestamped{{ t.TypeName }}Cls, constructor,
+                        static_cast<jlong>(value.time),
+                        static_cast<jlong>(value.serverTime), val.obj());
+{%- else %}
+  return env->NewObject(timestamped{{ t.TypeName }}Cls, constructor,
+                        static_cast<jlong>(value.time),
+                        static_cast<jlong>(value.serverTime),
+                        {{ t.jni.ToJavaBegin }}value.value{{ t.jni.ToJavaEnd }});
+{%- endif %}
+}
+{% endfor %}
+{%- for t in types %}
+static jobjectArray MakeJObject(JNIEnv* env,
+                                std::span<const nt::Timestamped{{ t.TypeName }}> arr) {
+  jobjectArray jarr =
+      env->NewObjectArray(arr.size(), timestamped{{ t.TypeName }}Cls, nullptr);
+  if (!jarr) {
+    return nullptr;
+  }
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> elem{env, MakeJObject(env, arr[i])};
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+{% endfor %}
+{%- for t in types %}
+{%- if t.jni.ToJavaArray == "MakeJObjectArray" %}
+static jobjectArray MakeJObjectArray(JNIEnv* env, std::span<const {{ t.cpp.ValueType }}> arr) {
+  jobjectArray jarr =
+      env->NewObjectArray(arr.size(), {{ t.jni.jtype }}Cls, nullptr);
+  if (!jarr) {
+    return nullptr;
+  }
+  for (size_t i = 0; i < arr.size(); ++i) {
+    JLocal<jobject> elem{env, {{ t.jni.ToJavaBegin }}arr[i]{{ t.jni.ToJavaEnd }}};
+    env->SetObjectArrayElement(jarr, i, elem.obj());
+  }
+  return jarr;
+}
+{% endif %}
+{%- endfor %}
+
+extern "C" {
+{% for t in types %}
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getAtomic{{ t.TypeName }}
+ * Signature: (I{{ t.jni.jtypestr }})Ledu/wpi/first/networktables/Timestamped{{ t.TypeName }};
+ */
+JNIEXPORT jobject JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getAtomic{{ t.TypeName }}
+  (JNIEnv* env, jclass, jint subentry, {{ t.jni.jtype }} defaultValue)
+{
+  return MakeJObject(env, nt::GetAtomic{{ t.TypeName }}(subentry, {{ t.jni.FromJavaBegin }}defaultValue{{ t.jni.FromJavaEnd }}));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    readQueue{{ t.TypeName }}
+ * Signature: (I)[Ledu/wpi/first/networktables/Timestamped{{ t.TypeName }};
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_readQueue{{ t.TypeName }}
+  (JNIEnv* env, jclass, jint subentry)
+{
+  return MakeJObject(env, nt::ReadQueue{{ t.TypeName }}(subentry));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    readQueueValues{{ t.TypeName }}
+ * Signature: (I)[{{ t.jni.jtypestr }}
+ */
+JNIEXPORT {% if t.jni.JavaObject %}jobject{% else %}{{ t.jni.jtype }}{% endif %}Array JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_readQueueValues{{ t.TypeName }}
+  (JNIEnv* env, jclass, jint subentry)
+{
+  return {{ t.jni.ToJavaArray }}(env, nt::ReadQueueValues{{ t.TypeName }}(subentry));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    set{{ t.TypeName }}
+ * Signature: (IJ{{ t.jni.jtypestr }})Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_set{{ t.TypeName }}
+  (JNIEnv*{% if t.jni.JavaObject %} env{% endif %}, jclass, jint entry, jlong time, {{ t.jni.jtype }} value)
+{
+{%- if t.jni.JavaObject %}
+  if (!value) {
+    nullPointerEx.Throw(env, "value cannot be null");
+    return false;
+  }
+{%- endif %}
+  return nt::Set{{ t.TypeName }}(entry, {{ t.jni.FromJavaBegin }}value{{ t.jni.FromJavaEnd }}, time);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    get{{ t.TypeName }}
+ * Signature: (I{{ t.jni.jtypestr }}){{ t.jni.jtypestr }}
+ */
+JNIEXPORT {{ t.jni.jtype }} JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_get{{ t.TypeName }}
+  (JNIEnv*{% if t.jni.JavaObject %} env{% endif %}, jclass, jint entry, {{ t.jni.jtype }} defaultValue)
+{
+{%- if t.jni.JavaObject %}
+  auto val = nt::GetEntryValue(entry);
+  if (!val || !val.Is{{ t.TypeName }}()) {
+    return defaultValue;
+  }
+  return {{ t.jni.ToJavaBegin }}val.Get{{ t.TypeName }}(){{ t.jni.ToJavaEnd }};
+{%- else %}
+  return nt::Get{{ t.TypeName }}(entry, defaultValue);
+{%- endif %}
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setDefault{{ t.TypeName }}
+ * Signature: (IJ{{ t.jni.jtypestr }})Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefault{{ t.TypeName }}
+  (JNIEnv*{% if t.jni.JavaObject %} env{% endif %}, jclass, jint entry, jlong, {{ t.jni.jtype }} defaultValue)
+{
+{%- if t.jni.JavaObject %}
+  if (!defaultValue) {
+    nullPointerEx.Throw(env, "defaultValue cannot be null");
+    return false;
+  }
+{%- endif %}
+  return nt::SetDefault{{ t.TypeName }}(entry, {{ t.jni.FromJavaBegin }}defaultValue{{ t.jni.FromJavaEnd }});
+}
+{% endfor %}
+}  // extern "C"
diff --git a/ntcore/src/generate/cpp/ntcore_c_types.cpp.jinja b/ntcore/src/generate/cpp/ntcore_c_types.cpp.jinja
new file mode 100644
index 0000000..e74e5cf
--- /dev/null
+++ b/ntcore/src/generate/cpp/ntcore_c_types.cpp.jinja
@@ -0,0 +1,106 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ntcore_c_types.h"
+
+#include "Value_internal.h"
+#include "ntcore_cpp.h"
+
+using namespace nt;
+
+template <typename T>
+static inline std::span<const T> ConvertFromC(const T* arr, size_t size) {
+  return {arr, size};
+}
+
+static inline std::string_view ConvertFromC(const char* arr, size_t size) {
+  return {arr, size};
+}
+
+static std::vector<std::string> ConvertFromC(const NT_String* arr, size_t size) {
+  std::vector<std::string> v;
+  v.reserve(size);
+  for (size_t i = 0; i < size; ++i) {
+    v.emplace_back(ConvertFromC(arr[i]));
+  }
+  return v;
+}
+
+{% for t in types %}
+static void ConvertToC(const nt::Timestamped{{ t.TypeName }}& in, NT_Timestamped{{ t.TypeName }}* out) {
+  out->time = in.time;
+  out->serverTime = in.serverTime;
+{%- if t.c.IsArray %}
+  out->value = ConvertToC<{{ t.c.ValueType[:-1] }}>(in.value, &out->len);
+{% else %}
+  out->value = in.value;
+{% endif -%}
+}
+{% endfor %}
+
+extern "C" {
+{% for t in types %}
+NT_Bool NT_Set{{ t.TypeName }}(NT_Handle pubentry, int64_t time, {{ t.c.ParamType }} value{% if t.c.IsArray %}, size_t len{% endif %}) {
+{%- if t.c.IsArray %}
+  return nt::Set{{ t.TypeName }}(pubentry, ConvertFromC(value, len), time);
+{%- else %}
+  return nt::Set{{ t.TypeName }}(pubentry, value, time);
+{%- endif %}
+}
+
+NT_Bool NT_SetDefault{{ t.TypeName }}(NT_Handle pubentry, {{ t.c.ParamType }} defaultValue{% if t.c.IsArray %}, size_t defaultValueLen{% endif %}) {
+{%- if t.c.IsArray %}
+  return nt::SetDefault{{ t.TypeName }}(pubentry, ConvertFromC(defaultValue, defaultValueLen));
+{%- else %}
+  return nt::SetDefault{{ t.TypeName }}(pubentry, defaultValue);
+{%- endif %}
+}
+
+{{ t.c.ValueType }} NT_Get{{ t.TypeName }}(NT_Handle subentry, {{ t.c.ParamType }} defaultValue{% if t.c.IsArray %}, size_t defaultValueLen, size_t* len{% endif %}) {
+{%- if t.c.IsArray %}
+  auto cppValue = nt::Get{{ t.TypeName }}(subentry, ConvertFromC(defaultValue, defaultValueLen));
+  return ConvertToC<{{ t.c.ValueType[:-1] }}>(cppValue, len);
+{%- else %}
+  return nt::Get{{ t.TypeName }}(subentry, defaultValue);
+{%- endif %}
+}
+
+void NT_GetAtomic{{ t.TypeName }}(NT_Handle subentry, {{ t.c.ParamType }} defaultValue{% if t.c.IsArray %}, size_t defaultValueLen{% endif %}, struct NT_Timestamped{{ t.TypeName }}* value) {
+{%- if t.c.IsArray %}
+  auto cppValue = nt::GetAtomic{{ t.TypeName }}(subentry, ConvertFromC(defaultValue, defaultValueLen));
+{%- else %}
+  auto cppValue = nt::GetAtomic{{ t.TypeName }}(subentry, defaultValue);
+{%- endif %}
+  ConvertToC(cppValue, value);
+}
+
+void NT_DisposeTimestamped{{ t.TypeName }}(struct NT_Timestamped{{ t.TypeName }}* value) {
+{%- if t.TypeName == "StringArray" %}
+  NT_FreeStringArray(value->value, value->len);
+{%- elif t.c.IsArray %}
+  std::free(value->value);
+{%- endif %}
+}
+
+struct NT_Timestamped{{ t.TypeName }}* NT_ReadQueue{{ t.TypeName }}(NT_Handle subentry, size_t* len) {
+  auto arr = nt::ReadQueue{{ t.TypeName }}(subentry);
+  return ConvertToC<NT_Timestamped{{ t.TypeName }}>(arr, len);
+}
+
+void NT_FreeQueue{{ t.TypeName }}(struct NT_Timestamped{{ t.TypeName }}* arr, size_t len) {
+  for (size_t i = 0; i < len; ++i) {
+    NT_DisposeTimestamped{{ t.TypeName }}(&arr[i]);
+  }
+  std::free(arr);
+}
+
+{%- if not t.c.IsArray %}
+{{ t.c.ValueType }}* NT_ReadQueueValues{{ t.TypeName }}(NT_Handle subentry, size_t* len) {
+  auto arr = nt::ReadQueueValues{{ t.TypeName }}(subentry);
+  return ConvertToC<{{ t.c.ValueType }}>(arr, len);
+}
+{%- endif %}
+
+{% endfor %}
+}  // extern "C"
diff --git a/ntcore/src/generate/cpp/ntcore_cpp_types.cpp.jinja b/ntcore/src/generate/cpp/ntcore_cpp_types.cpp.jinja
new file mode 100644
index 0000000..ba8bca7
--- /dev/null
+++ b/ntcore/src/generate/cpp/ntcore_cpp_types.cpp.jinja
@@ -0,0 +1,76 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ntcore_cpp_types.h"
+
+#include "Handle.h"
+#include "InstanceImpl.h"
+
+namespace nt {
+{% for t in types %}
+bool Set{{ t.TypeName }}(NT_Handle pubentry, {{ t.cpp.ParamType }} value, int64_t time) {
+  if (auto ii = InstanceImpl::Get(Handle{pubentry}.GetInst())) {
+    return ii->localStorage.SetEntryValue(pubentry,
+        Value::Make{{ t.TypeName }}(value, time == 0 ? Now() : time));
+  } else {
+    return {};
+  }
+}
+
+bool SetDefault{{ t.TypeName }}(NT_Handle pubentry, {{ t.cpp.ParamType }} defaultValue) {
+  if (auto ii = InstanceImpl::Get(Handle{pubentry}.GetInst())) {
+    return ii->localStorage.SetDefaultEntryValue(pubentry,
+        Value::Make{{ t.TypeName }}(defaultValue, 1));
+  } else {
+    return {};
+  }
+}
+
+{{ t.cpp.ValueType }} Get{{ t.TypeName }}(NT_Handle subentry, {{ t.cpp.ParamType }} defaultValue) {
+  return GetAtomic{{ t.TypeName }}(subentry, defaultValue).value;
+}
+
+Timestamped{{ t.TypeName }} GetAtomic{{ t.TypeName }}(NT_Handle subentry, {{ t.cpp.ParamType }} defaultValue) {
+  if (auto ii = InstanceImpl::Get(Handle{subentry}.GetInst())) {
+    return ii->localStorage.GetAtomic{{ t.TypeName }}(subentry, defaultValue);
+  } else {
+    return {};
+  }
+}
+
+std::vector<Timestamped{{ t.TypeName }}> ReadQueue{{ t.TypeName }}(NT_Handle subentry) {
+  if (auto ii = InstanceImpl::Get(Handle{subentry}.GetInst())) {
+    return ii->localStorage.ReadQueue{{ t.TypeName }}(subentry);
+  } else {
+    return {};
+  }
+}
+
+std::vector<{% if t.cpp.ValueType == "bool" %}int{% else %}{{ t.cpp.ValueType }}{% endif %}> ReadQueueValues{{ t.TypeName }}(NT_Handle subentry) {
+  std::vector<{% if t.cpp.ValueType == "bool" %}int{% else %}{{ t.cpp.ValueType }}{% endif %}> rv;
+  auto arr = ReadQueue{{ t.TypeName }}(subentry);
+  rv.reserve(arr.size());
+  for (auto&& elem : arr) {
+    rv.emplace_back(std::move(elem.value));
+  }
+  return rv;
+}
+{% if t.cpp.SmallRetType and t.cpp.SmallElemType %}
+{{ t.cpp.SmallRetType }} Get{{ t.TypeName }}(NT_Handle subentry, wpi::SmallVectorImpl<{{ t.cpp.SmallElemType }}>& buf, {{ t.cpp.ParamType }} defaultValue) {
+  return GetAtomic{{ t.TypeName }}(subentry, buf, defaultValue).value;
+}
+
+Timestamped{{ t.TypeName }}View GetAtomic{{ t.TypeName }}(
+    NT_Handle subentry,
+    wpi::SmallVectorImpl<{{ t.cpp.SmallElemType }}>& buf,
+    {{ t.cpp.ParamType }} defaultValue) {
+  if (auto ii = InstanceImpl::Get(Handle{subentry}.GetInst())) {
+    return ii->localStorage.GetAtomic{{ t.TypeName }}(subentry, buf, defaultValue);
+  } else {
+    return {};
+  }
+}
+{% endif %}
+{% endfor %}
+}  // namespace nt
diff --git a/ntcore/src/generate/include/networktables/Topic.h.jinja b/ntcore/src/generate/include/networktables/Topic.h.jinja
new file mode 100644
index 0000000..84e80ec
--- /dev/null
+++ b/ntcore/src/generate/include/networktables/Topic.h.jinja
@@ -0,0 +1,436 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+{{ cpp.INCLUDES }}
+#include <span>
+#include <string_view>
+#include <vector>
+
+#include "networktables/Topic.h"
+
+namespace wpi {
+template <typename T>
+class SmallVectorImpl;
+class json;
+}  // namespace wpi
+
+namespace nt {
+
+class {{ TypeName }}Topic;
+
+/**
+ * NetworkTables {{ TypeName }} subscriber.
+ */
+class {{ TypeName }}Subscriber : public Subscriber {
+ public:
+  using TopicType = {{ TypeName }}Topic;
+  using ValueType = {{ cpp.ValueType }};
+  using ParamType = {{ cpp.ParamType }};
+  using TimestampedValueType = Timestamped{{ TypeName }};
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+  using SmallRetType = {{ cpp.SmallRetType }};
+  using SmallElemType = {{ cpp.SmallElemType }};
+  using TimestampedValueViewType = Timestamped{{ TypeName }}View;
+{% endif %}
+
+  {{ TypeName }}Subscriber() = default;
+
+  /**
+   * Construct from a subscriber handle; recommended to use
+   * {{TypeName}}Topic::Subscribe() instead.
+   *
+   * @param handle Native handle
+   * @param defaultValue Default value
+   */
+  {{ TypeName }}Subscriber(NT_Subscriber handle, ParamType defaultValue);
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the stored default value.
+   *
+   * @return value
+   */
+  ValueType Get() const;
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the passed defaultValue.
+   *
+   * @param defaultValue default value to return if no value has been published
+   * @return value
+   */
+  ValueType Get(ParamType defaultValue) const;
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the stored default value.
+   *
+   * @param buf storage for returned value
+   * @return value
+   */
+  SmallRetType Get(wpi::SmallVectorImpl<SmallElemType>& buf) const;
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the passed defaultValue.
+   *
+   * @param buf storage for returned value
+   * @param defaultValue default value to return if no value has been published
+   * @return value
+   */
+  SmallRetType Get(wpi::SmallVectorImpl<SmallElemType>& buf, ParamType defaultValue) const;
+{% endif %}
+  /**
+   * Get the last published value along with its timestamp
+   * If no value has been published, returns the stored default value and a
+   * timestamp of 0.
+   *
+   * @return timestamped value
+   */
+  TimestampedValueType GetAtomic() const;
+
+  /**
+   * Get the last published value along with its timestamp.
+   * If no value has been published, returns the passed defaultValue and a
+   * timestamp of 0.
+   *
+   * @param defaultValue default value to return if no value has been published
+   * @return timestamped value
+   */
+  TimestampedValueType GetAtomic(ParamType defaultValue) const;
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+  /**
+   * Get the last published value along with its timestamp.
+   * If no value has been published, returns the stored default value and a
+   * timestamp of 0.
+   *
+   * @param buf storage for returned value
+   * @return timestamped value
+   */
+  TimestampedValueViewType GetAtomic(
+      wpi::SmallVectorImpl<SmallElemType>& buf) const;
+
+  /**
+   * Get the last published value along with its timestamp.
+   * If no value has been published, returns the passed defaultValue and a
+   * timestamp of 0.
+   *
+   * @param buf storage for returned value
+   * @param defaultValue default value to return if no value has been published
+   * @return timestamped value
+   */
+  TimestampedValueViewType GetAtomic(
+      wpi::SmallVectorImpl<SmallElemType>& buf,
+      ParamType defaultValue) const;
+{% endif %}
+  /**
+   * Get an array of all value changes since the last call to ReadQueue.
+   * Also provides a timestamp for each value.
+   *
+   * @note The "poll storage" subscribe option can be used to set the queue
+   *     depth.
+   *
+   * @return Array of timestamped values; empty array if no new changes have
+   *     been published since the previous call.
+   */
+  std::vector<TimestampedValueType> ReadQueue();
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+
+ private:
+  ValueType m_defaultValue;
+};
+
+/**
+ * NetworkTables {{ TypeName }} publisher.
+ */
+class {{ TypeName }}Publisher : public Publisher {
+ public:
+  using TopicType = {{ TypeName }}Topic;
+  using ValueType = {{ cpp.ValueType }};
+  using ParamType = {{ cpp.ParamType }};
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+  using SmallRetType = {{ cpp.SmallRetType }};
+  using SmallElemType = {{ cpp.SmallElemType }};
+{% endif %}
+  using TimestampedValueType = Timestamped{{ TypeName }};
+
+  {{ TypeName }}Publisher() = default;
+
+  /**
+   * Construct from a publisher handle; recommended to use
+   * {{TypeName}}Topic::Publish() instead.
+   *
+   * @param handle Native handle
+   */
+  explicit {{ TypeName }}Publisher(NT_Publisher handle);
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @param time timestamp; 0 indicates current NT time should be used
+   */
+  void Set(ParamType value, int64_t time = 0);
+
+  /**
+   * Publish a default value.
+   * On reconnect, a default value will never be used in preference to a
+   * published value.
+   *
+   * @param value value
+   */
+  void SetDefault(ParamType value);
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+};
+
+/**
+ * NetworkTables {{ TypeName }} entry.
+ *
+ * @note Unlike NetworkTableEntry, the entry goes away when this is destroyed.
+ */
+class {{ TypeName }}Entry final : public {{ TypeName }}Subscriber,
+                                  public {{ TypeName }}Publisher {
+ public:
+  using SubscriberType = {{ TypeName }}Subscriber;
+  using PublisherType = {{ TypeName }}Publisher;
+  using TopicType = {{ TypeName }}Topic;
+  using ValueType = {{ cpp.ValueType }};
+  using ParamType = {{ cpp.ParamType }};
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+  using SmallRetType = {{ cpp.SmallRetType }};
+  using SmallElemType = {{ cpp.SmallElemType }};
+{% endif %}
+  using TimestampedValueType = Timestamped{{ TypeName }};
+
+  {{ TypeName }}Entry() = default;
+
+  /**
+   * Construct from an entry handle; recommended to use
+   * {{TypeName}}Topic::GetEntry() instead.
+   *
+   * @param handle Native handle
+   * @param defaultValue Default value
+   */
+  {{ TypeName }}Entry(NT_Entry handle, ParamType defaultValue);
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return m_subHandle != 0; }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  NT_Entry GetHandle() const { return m_subHandle; }
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+
+  /**
+   * Stops publishing the entry if it's published.
+   */
+  void Unpublish();
+};
+
+/**
+ * NetworkTables {{ TypeName }} topic.
+ */
+class {{ TypeName }}Topic final : public Topic {
+ public:
+  using SubscriberType = {{ TypeName }}Subscriber;
+  using PublisherType = {{ TypeName }}Publisher;
+  using EntryType = {{ TypeName }}Entry;
+  using ValueType = {{ cpp.ValueType }};
+  using ParamType = {{ cpp.ParamType }};
+  using TimestampedValueType = Timestamped{{ TypeName }};
+{%- if TypeString %}
+  /** The default type string for this topic type. */
+  static constexpr std::string_view kTypeString = {{ TypeString }};
+{%- endif %}
+
+  {{ TypeName }}Topic() = default;
+
+  /**
+   * Construct from a topic handle; recommended to use
+   * NetworkTableInstance::Get{{TypeName}}Topic() instead.
+   *
+   * @param handle Native handle
+   */
+  explicit {{ TypeName }}Topic(NT_Topic handle) : Topic{handle} {}
+
+  /**
+   * Construct from a generic topic.
+   *
+   * @param topic Topic
+   */
+  explicit {{ TypeName }}Topic(Topic topic) : Topic{topic} {}
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note Subscribers that do not match the published data type do not return
+   *     any values. To determine if the data type matches, use the appropriate
+   *     Topic functions.
+   *
+{%- if not TypeString %}
+   * @param typeString type string
+{% endif %}
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options subscribe options
+   * @return subscriber
+   */
+  [[nodiscard]]
+  SubscriberType Subscribe(
+      {% if not TypeString %}std::string_view typeString, {% endif %}ParamType defaultValue,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+{%- if TypeString %}
+  /**
+   * Create a new subscriber to the topic, with specific type string.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note Subscribers that do not match the published data type do not return
+   *     any values. To determine if the data type matches, use the appropriate
+   *     Topic functions.
+   *
+   * @param typeString type string
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options subscribe options
+   * @return subscriber
+   */
+  [[nodiscard]]
+  SubscriberType SubscribeEx(
+      std::string_view typeString, ParamType defaultValue,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+{% endif %}
+  /**
+   * Create a new publisher to the topic.
+   *
+   * The publisher is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note It is not possible to publish two different data types to the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored). To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+{%- if not TypeString %}
+   * @param typeString type string
+{% endif %}
+   * @param options publish options
+   * @return publisher
+   */
+  [[nodiscard]]
+  PublisherType Publish({% if not TypeString %}std::string_view typeString, {% endif %}const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new publisher to the topic, with type string and initial
+   * properties.
+   *
+   * The publisher is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note It is not possible to publish two different data types to the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored). To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param properties JSON properties
+   * @param options publish options
+   * @return publisher
+   */
+  [[nodiscard]]
+  PublisherType PublishEx(std::string_view typeString,
+    const wpi::json& properties, const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new entry for the topic.
+   *
+   * Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not destroyed. The publisher
+   * is created when the entry is first written to, and remains active until
+   * either Unpublish() is called or the entry is destroyed.
+   *
+   * @note It is not possible to use two different data types with the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored), and the entry
+   *     will show no new values if the data type does not match. To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+{%- if not TypeString %}
+   * @param typeString type string
+{% endif %}
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  [[nodiscard]]
+  EntryType GetEntry({% if not TypeString %}std::string_view typeString, {% endif %}ParamType defaultValue,
+                     const PubSubOptions& options = kDefaultPubSubOptions);
+{%- if TypeString %}
+  /**
+   * Create a new entry for the topic, with specific type string.
+   *
+   * Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not destroyed. The publisher
+   * is created when the entry is first written to, and remains active until
+   * either Unpublish() is called or the entry is destroyed.
+   *
+   * @note It is not possible to use two different data types with the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored), and the entry
+   *     will show no new values if the data type does not match. To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  [[nodiscard]]
+  EntryType GetEntryEx(std::string_view typeString, ParamType defaultValue,
+                       const PubSubOptions& options = kDefaultPubSubOptions);
+{% endif %}
+};
+
+}  // namespace nt
+
+#include "networktables/{{ TypeName }}Topic.inc"
diff --git a/ntcore/src/generate/include/networktables/Topic.inc.jinja b/ntcore/src/generate/include/networktables/Topic.inc.jinja
new file mode 100644
index 0000000..4e7a167
--- /dev/null
+++ b/ntcore/src/generate/include/networktables/Topic.inc.jinja
@@ -0,0 +1,135 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include "networktables/{{ TypeName }}Topic.h"
+#include "networktables/NetworkTableType.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+inline {{ TypeName }}Subscriber::{{ TypeName }}Subscriber(
+    NT_Subscriber handle, {{ cpp.ParamType }} defaultValue)
+    : Subscriber{handle},
+      m_defaultValue{{ '{' }}{{ cpp.DefaultValueCopy|default('defaultValue') }}} {}
+
+inline {{ cpp.ValueType }} {{ TypeName }}Subscriber::Get() const {
+  return Get(m_defaultValue);
+}
+
+inline {{ cpp.ValueType }} {{ TypeName }}Subscriber::Get(
+    {{ cpp.ParamType }} defaultValue) const {
+  return ::nt::Get{{ TypeName }}(m_subHandle, defaultValue);
+}
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+inline {{ cpp.SmallRetType }} {{ TypeName }}Subscriber::Get(wpi::SmallVectorImpl<{{ cpp.SmallElemType }}>& buf) const {
+  return Get(buf, m_defaultValue);
+}
+
+inline {{ cpp.SmallRetType }} {{ TypeName }}Subscriber::Get(wpi::SmallVectorImpl<{{ cpp.SmallElemType }}>& buf, {{ cpp.ParamType }} defaultValue) const {
+  return nt::Get{{ TypeName }}(m_subHandle, buf, defaultValue);
+}
+{% endif %}
+inline Timestamped{{ TypeName }} {{ TypeName }}Subscriber::GetAtomic() const {
+  return GetAtomic(m_defaultValue);
+}
+
+inline Timestamped{{ TypeName }} {{ TypeName }}Subscriber::GetAtomic(
+    {{ cpp.ParamType }} defaultValue) const {
+  return ::nt::GetAtomic{{ TypeName }}(m_subHandle, defaultValue);
+}
+{% if cpp.SmallRetType and cpp.SmallElemType %}
+inline Timestamped{{ TypeName }}View {{ TypeName }}Subscriber::GetAtomic(wpi::SmallVectorImpl<{{ cpp.SmallElemType }}>& buf) const {
+  return GetAtomic(buf, m_defaultValue);
+}
+
+inline Timestamped{{ TypeName }}View {{ TypeName }}Subscriber::GetAtomic(wpi::SmallVectorImpl<{{ cpp.SmallElemType }}>& buf, {{ cpp.ParamType }} defaultValue) const {
+  return nt::GetAtomic{{ TypeName }}(m_subHandle, buf, defaultValue);
+}
+{% endif %}
+inline std::vector<Timestamped{{ TypeName }}>
+{{ TypeName }}Subscriber::ReadQueue() {
+  return ::nt::ReadQueue{{ TypeName }}(m_subHandle);
+}
+
+inline {{ TypeName }}Topic {{ TypeName }}Subscriber::GetTopic() const {
+  return {{ TypeName }}Topic{::nt::GetTopicFromHandle(m_subHandle)};
+}
+
+inline {{ TypeName }}Publisher::{{ TypeName }}Publisher(NT_Publisher handle)
+    : Publisher{handle} {}
+
+inline void {{ TypeName }}Publisher::Set({{ cpp.ParamType }} value,
+                                         int64_t time) {
+  ::nt::Set{{ TypeName }}(m_pubHandle, value, time);
+}
+
+inline void {{ TypeName }}Publisher::SetDefault({{ cpp.ParamType }} value) {
+  ::nt::SetDefault{{ TypeName }}(m_pubHandle, value);
+}
+
+inline {{ TypeName }}Topic {{ TypeName }}Publisher::GetTopic() const {
+  return {{ TypeName }}Topic{::nt::GetTopicFromHandle(m_pubHandle)};
+}
+
+inline {{ TypeName }}Entry::{{ TypeName }}Entry(
+    NT_Entry handle, {{ cpp.ParamType }} defaultValue)
+    : {{ TypeName }}Subscriber{handle, defaultValue},
+      {{ TypeName }}Publisher{handle} {}
+
+inline {{ TypeName }}Topic {{ TypeName }}Entry::GetTopic() const {
+  return {{ TypeName }}Topic{::nt::GetTopicFromHandle(m_subHandle)};
+}
+
+inline void {{ TypeName }}Entry::Unpublish() {
+  ::nt::Unpublish(m_pubHandle);
+}
+
+inline {{ TypeName }}Subscriber {{ TypeName }}Topic::Subscribe(
+    {% if not TypeString %}std::string_view typeString, {% endif %}{{ cpp.ParamType }} defaultValue,
+    const PubSubOptions& options) {
+  return {{ TypeName }}Subscriber{
+      ::nt::Subscribe(m_handle, NT_{{ cpp.TYPE_NAME }}, {{ TypeString|default('typeString') }}, options),
+      defaultValue};
+}
+{%- if TypeString %}
+inline {{ TypeName }}Subscriber {{ TypeName }}Topic::SubscribeEx(
+    std::string_view typeString, {{ cpp.ParamType }} defaultValue,
+    const PubSubOptions& options) {
+  return {{ TypeName }}Subscriber{
+      ::nt::Subscribe(m_handle, NT_{{ cpp.TYPE_NAME }}, typeString, options),
+      defaultValue};
+}
+{% endif %}
+inline {{ TypeName }}Publisher {{ TypeName }}Topic::Publish(
+    {% if not TypeString %}std::string_view typeString, {% endif %}const PubSubOptions& options) {
+  return {{ TypeName }}Publisher{
+      ::nt::Publish(m_handle, NT_{{ cpp.TYPE_NAME }}, {{ TypeString|default('typeString') }}, options)};
+}
+
+inline {{ TypeName }}Publisher {{ TypeName }}Topic::PublishEx(
+    std::string_view typeString,
+    const wpi::json& properties, const PubSubOptions& options) {
+  return {{ TypeName }}Publisher{
+      ::nt::PublishEx(m_handle, NT_{{ cpp.TYPE_NAME }}, typeString, properties, options)};
+}
+
+inline {{ TypeName }}Entry {{ TypeName }}Topic::GetEntry(
+    {% if not TypeString %}std::string_view typeString, {% endif %}{{ cpp.ParamType }} defaultValue,
+    const PubSubOptions& options) {
+  return {{ TypeName }}Entry{
+      ::nt::GetEntry(m_handle, NT_{{ cpp.TYPE_NAME }}, {{ TypeString|default('typeString') }}, options),
+      defaultValue};
+}
+{%- if TypeString %}
+inline {{ TypeName }}Entry {{ TypeName }}Topic::GetEntryEx(
+    std::string_view typeString, {{ cpp.ParamType }} defaultValue,
+    const PubSubOptions& options) {
+  return {{ TypeName }}Entry{
+      ::nt::GetEntry(m_handle, NT_{{ cpp.TYPE_NAME }}, typeString, options),
+      defaultValue};
+}
+{% endif %}
+}  // namespace nt
diff --git a/ntcore/src/generate/include/ntcore_c_types.h.jinja b/ntcore/src/generate/include/ntcore_c_types.h.jinja
new file mode 100644
index 0000000..d5b2448
--- /dev/null
+++ b/ntcore/src/generate/include/ntcore_c_types.h.jinja
@@ -0,0 +1,151 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include "ntcore_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+{% for t in types %}
+/**
+ * Timestamped {{ t.TypeName }}.
+ * @ingroup ntcore_c_handle_api
+ */
+struct NT_Timestamped{{ t.TypeName }} {
+  /**
+   * Time in local time base.
+   */
+  int64_t time;
+
+  /**
+   * Time in server time base.  May be 0 or 1 for locally set values.
+   */
+  int64_t serverTime;
+
+  /**
+   * Value.
+   */
+  {{ t.c.ValueType }} value;
+{%- if t.c.IsArray %}
+  /**
+   * Value length.
+   */
+  size_t len;
+{% endif %}
+};
+
+/**
+ * @defgroup ntcore_{{ t.TypeName }}_cfunc {{ t.TypeName }} Functions
+ * @ingroup ntcore_c_handle_api
+ * @{
+ */
+
+/**
+ * Publish a new value.
+ *
+ * @param pubentry publisher or entry handle
+ * @param time timestamp; 0 indicates current NT time should be used
+ * @param value value to publish
+{%- if t.c.IsArray %}
+ * @param len length of value
+{% endif %}
+ */
+NT_Bool NT_Set{{ t.TypeName }}(NT_Handle pubentry, int64_t time, {{ t.c.ParamType }} value{% if t.c.IsArray %}, size_t len{% endif %});
+
+/**
+ * Publish a default value.
+ * On reconnect, a default value will never be used in preference to a
+ * published value.
+ *
+ * @param pubentry publisher or entry handle
+ * @param defaultValue default value
+{%- if t.c.IsArray %}
+ * @param defaultValueLen length of default value
+{% endif %}
+ */
+NT_Bool NT_SetDefault{{ t.TypeName }}(NT_Handle pubentry, {{ t.c.ParamType }} defaultValue{% if t.c.IsArray %}, size_t defaultValueLen{% endif %});
+
+/**
+ * Get the last published value.
+ * If no value has been published, returns the passed defaultValue.
+ *
+ * @param subentry subscriber or entry handle
+ * @param defaultValue default value to return if no value has been published
+{%- if t.c.IsArray %}
+ * @param defaultValueLen length of default value
+ * @param len length of returned value (output)
+{% endif %}
+ * @return value
+ */
+{{ t.c.ValueType }} NT_Get{{ t.TypeName }}(NT_Handle subentry, {{ t.c.ParamType }} defaultValue{% if t.c.IsArray %}, size_t defaultValueLen, size_t* len{% endif %});
+
+/**
+ * Get the last published value along with its timestamp.
+ * If no value has been published, returns the passed defaultValue and a
+ * timestamp of 0.
+ *
+ * @param subentry subscriber or entry handle
+ * @param defaultValue default value to return if no value has been published
+{%- if t.c.IsArray %}
+ * @param defaultValueLen length of default value
+{% endif %}
+ * @param value timestamped value (output)
+ */
+void NT_GetAtomic{{ t.TypeName }}(NT_Handle subentry, {{ t.c.ParamType }} defaultValue{% if t.c.IsArray %}, size_t defaultValueLen{% endif %}, struct NT_Timestamped{{ t.TypeName }}* value);
+
+/**
+ * Disposes a timestamped value (as returned by NT_GetAtomic{{ t.TypeName }}).
+ *
+ * @param value timestamped value
+ */
+void NT_DisposeTimestamped{{ t.TypeName }}(struct NT_Timestamped{{ t.TypeName }}* value);
+
+/**
+ * Get an array of all value changes since the last call to ReadQueue.
+ * Also provides a timestamp for each value.
+ *
+ * @note The "poll storage" subscribe option can be used to set the queue
+ *     depth.
+ *
+ * @param subentry subscriber or entry handle
+ * @param len length of returned array (output)
+ * @return Array of timestamped values; NULL if no new changes have
+ *     been published since the previous call.
+ */
+struct NT_Timestamped{{ t.TypeName }}* NT_ReadQueue{{ t.TypeName }}(NT_Handle subentry, size_t* len);
+
+/**
+ * Frees a timestamped array of values (as returned by NT_ReadQueue{{ t.TypeName }}).
+ *
+ * @param arr array
+ * @param len length of array
+ */
+void NT_FreeQueue{{ t.TypeName }}(struct NT_Timestamped{{ t.TypeName }}* arr, size_t len);
+
+{%- if not t.c.IsArray %}
+/**
+ * Get an array of all value changes since the last call to ReadQueue.
+ *
+ * @note The "poll storage" subscribe option can be used to set the queue
+ *     depth.
+ *
+ * @param subentry subscriber or entry handle
+ * @param len length of returned array (output)
+ * @return Array of values; NULL if no new changes have
+ *     been published since the previous call.
+ */
+{{ t.c.ValueType }}* NT_ReadQueueValues{{ t.TypeName }}(NT_Handle subentry, size_t* len);
+{%- endif %}
+
+/** @} */
+{% endfor %}
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/ntcore/src/generate/include/ntcore_cpp_types.h.jinja b/ntcore/src/generate/include/ntcore_cpp_types.h.jinja
new file mode 100644
index 0000000..e987186
--- /dev/null
+++ b/ntcore/src/generate/include/ntcore_cpp_types.h.jinja
@@ -0,0 +1,154 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "ntcore_c.h"
+
+namespace wpi {
+template <typename T>
+class SmallVectorImpl;
+}  // namespace wpi
+
+namespace nt {
+{% for t in types %}
+/**
+ * Timestamped {{ t.TypeName }}.
+ * @ingroup ntcore_cpp_handle_api
+ */
+struct Timestamped{{ t.TypeName }} {
+  Timestamped{{ t.TypeName }}() = default;
+  Timestamped{{ t.TypeName }}(int64_t time, int64_t serverTime, {{ t.cpp.ValueType }} value)
+    : time{time}, serverTime{serverTime}, value{std::move(value)} {}
+
+  /**
+   * Time in local time base.
+   */
+  int64_t time = 0;
+
+  /**
+   * Time in server time base.  May be 0 or 1 for locally set values.
+   */
+  int64_t serverTime = 0;
+
+  /**
+   * Value.
+   */
+  {{ t.cpp.ValueType }} value = {};
+};
+{% if t.cpp.SmallRetType %}
+/**
+ * Timestamped {{ t.TypeName }} view (for SmallVector-taking functions).
+ * @ingroup ntcore_cpp_handle_api
+ */
+struct Timestamped{{ t.TypeName }}View {
+  Timestamped{{ t.TypeName }}View() = default;
+  Timestamped{{ t.TypeName }}View(int64_t time, int64_t serverTime, {{ t.cpp.SmallRetType }} value)
+    : time{time}, serverTime{serverTime}, value{std::move(value)} {}
+
+  /**
+   * Time in local time base.
+   */
+  int64_t time = 0;
+
+  /**
+   * Time in server time base.  May be 0 or 1 for locally set values.
+   */
+  int64_t serverTime = 0;
+
+  /**
+   * Value.
+   */
+  {{ t.cpp.SmallRetType }} value = {};
+};
+{% endif %}
+/**
+ * @defgroup ntcore_{{ t.TypeName }}_func {{ t.TypeName }} Functions
+ * @ingroup ntcore_cpp_handle_api
+ * @{
+ */
+
+/**
+ * Publish a new value.
+ *
+ * @param pubentry publisher or entry handle
+ * @param value value to publish
+ * @param time timestamp; 0 indicates current NT time should be used
+ */
+bool Set{{ t.TypeName }}(NT_Handle pubentry, {{ t.cpp.ParamType }} value, int64_t time = 0);
+
+/**
+ * Publish a default value.
+ * On reconnect, a default value will never be used in preference to a
+ * published value.
+ *
+ * @param pubentry publisher or entry handle
+ * @param defaultValue default value
+ */
+bool SetDefault{{ t.TypeName }}(NT_Handle pubentry, {{ t.cpp.ParamType }} defaultValue);
+
+/**
+ * Get the last published value.
+ * If no value has been published, returns the passed defaultValue.
+ *
+ * @param subentry subscriber or entry handle
+ * @param defaultValue default value to return if no value has been published
+ * @return value
+ */
+{{ t.cpp.ValueType }} Get{{ t.TypeName }}(NT_Handle subentry, {{ t.cpp.ParamType }} defaultValue);
+
+/**
+ * Get the last published value along with its timestamp.
+ * If no value has been published, returns the passed defaultValue and a
+ * timestamp of 0.
+ *
+ * @param subentry subscriber or entry handle
+ * @param defaultValue default value to return if no value has been published
+ * @return timestamped value
+ */
+Timestamped{{ t.TypeName }} GetAtomic{{ t.TypeName}}(NT_Handle subentry, {{ t.cpp.ParamType }} defaultValue);
+
+/**
+ * Get an array of all value changes since the last call to ReadQueue.
+ * Also provides a timestamp for each value.
+ *
+ * @note The "poll storage" subscribe option can be used to set the queue
+ *     depth.
+ *
+ * @param subentry subscriber or entry handle
+ * @return Array of timestamped values; empty array if no new changes have
+ *     been published since the previous call.
+ */
+std::vector<Timestamped{{ t.TypeName }}> ReadQueue{{ t.TypeName }}(NT_Handle subentry);
+
+/**
+ * Get an array of all value changes since the last call to ReadQueue.
+ *
+ * @note The "poll storage" subscribe option can be used to set the queue
+ *     depth.
+ *
+ * @param subentry subscriber or entry handle
+ * @return Array of values; empty array if no new changes have
+ *     been published since the previous call.
+ */
+std::vector<{% if t.cpp.ValueType == "bool" %}int{% else %}{{ t.cpp.ValueType }}{% endif %}> ReadQueueValues{{ t.TypeName }}(NT_Handle subentry);
+{% if t.cpp.SmallRetType and t.cpp.SmallElemType %}
+{{ t.cpp.SmallRetType }} Get{{ t.TypeName }}(NT_Handle subentry, wpi::SmallVectorImpl<{{ t.cpp.SmallElemType }}>& buf, {{ t.cpp.ParamType }} defaultValue);
+
+Timestamped{{ t.TypeName }}View GetAtomic{{ t.TypeName }}(
+      NT_Handle subentry,
+      wpi::SmallVectorImpl<{{ t.cpp.SmallElemType }}>& buf,
+      {{ t.cpp.ParamType }} defaultValue);
+{% endif %}
+/** @} */
+{% endfor %}
+}  // namespace nt
diff --git a/ntcore/src/generate/java/Entry.java.jinja b/ntcore/src/generate/java/Entry.java.jinja
new file mode 100644
index 0000000..cbaa782
--- /dev/null
+++ b/ntcore/src/generate/java/Entry.java.jinja
@@ -0,0 +1,15 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables {{ TypeName }} entry.
+ *
+ * <p>Unlike NetworkTableEntry, the entry goes away when close() is called.
+ */
+public interface {{ TypeName }}Entry extends {{ TypeName }}Subscriber, {{ TypeName }}Publisher {
+  /** Stops publishing the entry if it's published. */
+  void unpublish();
+}
diff --git a/ntcore/src/generate/java/EntryImpl.java.jinja b/ntcore/src/generate/java/EntryImpl.java.jinja
new file mode 100644
index 0000000..43b31e4
--- /dev/null
+++ b/ntcore/src/generate/java/EntryImpl.java.jinja
@@ -0,0 +1,75 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables {{ TypeName }} implementation. */
+@SuppressWarnings("PMD.ArrayIsStoredDirectly")
+final class {{ TypeName }}EntryImpl extends EntryBase implements {{ TypeName }}Entry {
+  /**
+   * Constructor.
+   *
+   * @param topic Topic
+   * @param handle Native handle
+   * @param defaultValue Default value for get()
+   */
+  {{ TypeName }}EntryImpl({{ TypeName }}Topic topic, int handle, {{ java.ValueType }} defaultValue) {
+    super(handle);
+    m_topic = topic;
+    m_defaultValue = defaultValue;
+  }
+
+  @Override
+  public {{ TypeName }}Topic getTopic() {
+    return m_topic;
+  }
+
+  @Override
+  public {{ java.ValueType }} get() {
+    return NetworkTablesJNI.get{{ TypeName }}(m_handle, m_defaultValue);
+  }
+
+  @Override
+  public {{ java.ValueType }} get({{ java.ValueType }} defaultValue) {
+    return NetworkTablesJNI.get{{TypeName}}(m_handle, defaultValue);
+  }
+
+  @Override
+  public Timestamped{{ TypeName }} getAtomic() {
+    return NetworkTablesJNI.getAtomic{{ TypeName }}(m_handle, m_defaultValue);
+  }
+
+  @Override
+  public Timestamped{{ TypeName }} getAtomic({{ java.ValueType }} defaultValue) {
+    return NetworkTablesJNI.getAtomic{{ TypeName }}(m_handle, defaultValue);
+  }
+
+  @Override
+  public Timestamped{{ TypeName }}[] readQueue() {
+    return NetworkTablesJNI.readQueue{{ TypeName }}(m_handle);
+  }
+
+  @Override
+  public {{ java.ValueType }}[] readQueueValues() {
+    return NetworkTablesJNI.readQueueValues{{ TypeName }}(m_handle);
+  }
+
+  @Override
+  public void set({{ java.ValueType }} value, long time) {
+    NetworkTablesJNI.set{{ TypeName }}(m_handle, time, value);
+  }
+
+  @Override
+  public void setDefault({{ java.ValueType }} value) {
+    NetworkTablesJNI.setDefault{{ TypeName }}(m_handle, 0, value);
+  }
+
+  @Override
+  public void unpublish() {
+    NetworkTablesJNI.unpublish(m_handle);
+  }
+
+  private final {{ TypeName }}Topic m_topic;
+  private final {{ java.ValueType }} m_defaultValue;
+}
diff --git a/ntcore/src/generate/java/GenericEntryImpl.java.jinja b/ntcore/src/generate/java/GenericEntryImpl.java.jinja
new file mode 100644
index 0000000..e4296d7
--- /dev/null
+++ b/ntcore/src/generate/java/GenericEntryImpl.java.jinja
@@ -0,0 +1,317 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables generic implementation. */
+final class GenericEntryImpl extends EntryBase implements GenericEntry {
+  /**
+   * Constructor.
+   *
+   * @param topic Topic
+   * @param handle Native handle
+   */
+  GenericEntryImpl(Topic topic, int handle) {
+    super(handle);
+    m_topic = topic;
+  }
+
+  @Override
+  public Topic getTopic() {
+    return m_topic;
+  }
+
+  @Override
+  public NetworkTableValue get() {
+    return NetworkTablesJNI.getValue(m_handle);
+  }
+{% for t in types %}
+  /**
+   * Gets the entry's value as a {{ t.java.ValueType }}. 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
+   */
+  @Override
+  public {{ t.java.ValueType }} get{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
+    return NetworkTablesJNI.get{{ t.TypeName }}(m_handle, defaultValue);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * 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
+   */
+  @Override
+  public {{ t.java.WrapValueType }} get{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
+    return NetworkTableValue.fromNative{{ t.TypeName }}(
+        get{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue)));
+  }
+{% endif -%}
+{% endfor %}
+  @Override
+  public NetworkTableValue[] readQueue() {
+    return NetworkTablesJNI.readQueueValue(m_handle);
+  }
+
+  @Override
+  public boolean set(NetworkTableValue value) {
+    long time = value.getTime();
+    Object otherValue = value.getValue();
+    switch (value.getType()) {
+      case kBoolean:
+        return NetworkTablesJNI.setBoolean(m_handle, time, (Boolean) otherValue);
+      case kInteger:
+        return NetworkTablesJNI.setInteger(
+            m_handle, time, ((Number) otherValue).longValue());
+      case kFloat:
+        return NetworkTablesJNI.setFloat(
+            m_handle, time, ((Number) otherValue).floatValue());
+      case kDouble:
+        return NetworkTablesJNI.setDouble(
+            m_handle, time, ((Number) otherValue).doubleValue());
+      case kString:
+        return NetworkTablesJNI.setString(m_handle, time, (String) otherValue);
+      case kRaw:
+        return NetworkTablesJNI.setRaw(m_handle, time, (byte[]) otherValue);
+      case kBooleanArray:
+        return NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[]) otherValue);
+      case kIntegerArray:
+        return NetworkTablesJNI.setIntegerArray(m_handle, time, (long[]) otherValue);
+      case kFloatArray:
+        return NetworkTablesJNI.setFloatArray(m_handle, time, (float[]) otherValue);
+      case kDoubleArray:
+        return NetworkTablesJNI.setDoubleArray(m_handle, time, (double[]) otherValue);
+      case kStringArray:
+        return NetworkTablesJNI.setStringArray(m_handle, time, (String[]) otherValue);
+      default:
+        return true;
+    }
+  }
+
+  /**
+   * 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
+   */
+  @Override
+  public boolean setValue(Object value, long time) {
+    if (value instanceof NetworkTableValue) {
+      return set((NetworkTableValue) value);
+    } else if (value instanceof Boolean) {
+      return setBoolean((Boolean) value, time);
+    } else if (value instanceof Long) {
+      return setInteger((Long) value, time);
+    } else if (value instanceof Float) {
+      return setFloat((Float) value, time);
+    } else if (value instanceof Number) {
+      return setNumber((Number) value, time);
+    } else if (value instanceof String) {
+      return setString((String) value, time);
+    } else if (value instanceof byte[]) {
+      return setRaw((byte[]) value, time);
+    } else if (value instanceof boolean[]) {
+      return setBooleanArray((boolean[]) value, time);
+    } else if (value instanceof long[]) {
+      return setIntegerArray((long[]) value, time);
+    } else if (value instanceof float[]) {
+      return setFloatArray((float[]) value, time);
+    } else if (value instanceof double[]) {
+      return setDoubleArray((double[]) value, time);
+    } else if (value instanceof Boolean[]) {
+      return setBooleanArray((Boolean[]) value, time);
+    } else if (value instanceof Long[]) {
+      return setIntegerArray((Long[]) value, time);
+    } else if (value instanceof Float[]) {
+      return setFloatArray((Float[]) value, time);
+    } else if (value instanceof Number[]) {
+      return setNumberArray((Number[]) value, time);
+    } else if (value instanceof String[]) {
+      return setStringArray((String[]) value, time);
+    } else {
+      throw new IllegalArgumentException(
+          "Value of type " + value.getClass().getName() + " cannot be put into a table");
+    }
+  }
+{% for t in types %}
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  @Override
+  public boolean set{{ t.TypeName }}({{ t.java.ValueType }} value, long time) {
+    return NetworkTablesJNI.set{{ t.TypeName }}(m_handle, time, value);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  @Override
+  public boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value, long time) {
+    return set{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(value), time);
+  }
+{% endif -%}
+{% endfor %}
+  /**
+   * 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, long time) {
+    return setDouble(value.doubleValue(), time);
+  }
+
+  /**
+   * 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, long time) {
+    return setDoubleArray(NetworkTableValue.toNativeDoubleArray(value), time);
+  }
+
+  @Override
+  public boolean setDefault(NetworkTableValue defaultValue) {
+    long time = defaultValue.getTime();
+    Object otherValue = defaultValue.getValue();
+    switch (defaultValue.getType()) {
+      case kBoolean:
+        return NetworkTablesJNI.setDefaultBoolean(m_handle, time, (Boolean) otherValue);
+      case kInteger:
+        return NetworkTablesJNI.setDefaultInteger(
+            m_handle, time, ((Number) otherValue).longValue());
+      case kFloat:
+        return NetworkTablesJNI.setDefaultFloat(
+            m_handle, time, ((Number) otherValue).floatValue());
+      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 kIntegerArray:
+        return NetworkTablesJNI.setDefaultIntegerArray(m_handle, time, (long[]) otherValue);
+      case kFloatArray:
+        return NetworkTablesJNI.setDefaultFloatArray(m_handle, time, (float[]) otherValue);
+      case kDoubleArray:
+        return NetworkTablesJNI.setDefaultDoubleArray(m_handle, time, (double[]) otherValue);
+      case kStringArray:
+        return NetworkTablesJNI.setDefaultStringArray(m_handle, time, (String[]) otherValue);
+      default:
+        return true;
+    }
+  }
+
+  /**
+   * 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
+   */
+  @Override
+  public boolean setDefaultValue(Object defaultValue) {
+    if (defaultValue instanceof NetworkTableValue) {
+      return setDefault((NetworkTableValue) defaultValue);
+    } else if (defaultValue instanceof Boolean) {
+      return setDefaultBoolean((Boolean) defaultValue);
+    } else if (defaultValue instanceof Integer) {
+      return setDefaultInteger((Integer) defaultValue);
+    } else if (defaultValue instanceof Float) {
+      return setDefaultFloat((Float) 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 long[]) {
+      return setDefaultIntegerArray((long[]) defaultValue);
+    } else if (defaultValue instanceof float[]) {
+      return setDefaultFloatArray((float[]) defaultValue);
+    } else if (defaultValue instanceof double[]) {
+      return setDefaultDoubleArray((double[]) defaultValue);
+    } else if (defaultValue instanceof Boolean[]) {
+      return setDefaultBooleanArray((Boolean[]) defaultValue);
+    } else if (defaultValue instanceof Long[]) {
+      return setDefaultIntegerArray((Long[]) defaultValue);
+    } else if (defaultValue instanceof Float[]) {
+      return setDefaultFloatArray((Float[]) 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");
+    }
+  }
+{% for t in types %}
+  /**
+   * 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
+   */
+  @Override
+  public boolean setDefault{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
+    return NetworkTablesJNI.setDefault{{ t.TypeName }}(m_handle, 0, defaultValue);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * 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
+   */
+  @Override
+  public boolean setDefault{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
+    return setDefault{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue));
+  }
+{% endif -%}
+{% endfor %}
+  /**
+   * 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 setDefaultDouble(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 setDefaultNumberArray(Number[] defaultValue) {
+    return setDefaultDoubleArray(NetworkTableValue.toNativeDoubleArray(defaultValue));
+  }
+
+  @Override
+  public void unpublish() {
+    NetworkTablesJNI.unpublish(m_handle);
+  }
+
+  private final Topic m_topic;
+}
diff --git a/ntcore/src/generate/java/GenericPublisher.java.jinja b/ntcore/src/generate/java/GenericPublisher.java.jinja
new file mode 100644
index 0000000..d747f17
--- /dev/null
+++ b/ntcore/src/generate/java/GenericPublisher.java.jinja
@@ -0,0 +1,119 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import java.util.function.Consumer;
+
+/** NetworkTables generic publisher. */
+public interface GenericPublisher extends Publisher, Consumer<NetworkTableValue> {
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  @Override
+  Topic getTopic();
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @return False if the topic already exists with a different type
+   */
+  boolean set(NetworkTableValue value);
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @return False if the topic already exists with a different type
+   * @throws IllegalArgumentException if the value is not a known type
+   */
+  default boolean setValue(Object value) {
+    return setValue(value, 0);
+  }
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @param time timestamp; 0 indicates current NT time should be used
+   * @return False if the topic already exists with a different type
+   * @throws IllegalArgumentException if the value is not a known type
+   */
+  boolean setValue(Object value, long time);
+{% for t in types %}
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @return False if the topic already exists with a different type
+   */
+  default boolean set{{ t.TypeName }}({{ t.java.ValueType }} value) {
+    return set{{ t.TypeName }}(value, 0);
+  }
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @param time timestamp; 0 indicates current NT time should be used
+   * @return False if the topic already exists with a different type
+   */
+  boolean set{{ t.TypeName }}({{ t.java.ValueType }} value, long time);
+{% if t.java.WrapValueType %}
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @return False if the topic already exists with a different type
+   */
+  default boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value) {
+    return set{{ t.TypeName }}(value, 0);
+  }
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @param time timestamp; 0 indicates current NT time should be used
+   * @return False if the topic already exists with a different type
+   */
+  boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value, long time);
+{% endif -%}
+{% endfor %}
+  /**
+   * 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
+   */
+  boolean setDefault(NetworkTableValue 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
+   * @throws IllegalArgumentException if the value is not a known type
+   */
+  boolean setDefaultValue(Object defaultValue);
+{% for t in types %}
+  /**
+   * 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
+   */
+  boolean setDefault{{ t.TypeName }}({{ t.java.ValueType }} defaultValue);
+{% if t.java.WrapValueType %}
+  boolean setDefault{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue);
+{% endif -%}
+{% endfor %}
+  @Override
+  default void accept(NetworkTableValue value) {
+    set(value);
+  }
+}
diff --git a/ntcore/src/generate/java/GenericSubscriber.java.jinja b/ntcore/src/generate/java/GenericSubscriber.java.jinja
new file mode 100644
index 0000000..63ecebc
--- /dev/null
+++ b/ntcore/src/generate/java/GenericSubscriber.java.jinja
@@ -0,0 +1,58 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import java.util.function.Supplier;
+
+/** NetworkTables generic subscriber. */
+@SuppressWarnings("PMD.MissingOverride")
+public interface GenericSubscriber extends Subscriber, Supplier<NetworkTableValue> {
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  @Override
+  Topic getTopic();
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns a value with type NetworkTableType.kUnassigned.
+   *
+   * @return value
+   */
+  NetworkTableValue get();
+{% for t in types %}
+  /**
+   * Gets the entry's value as a {{ t.java.ValueType }}. 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
+   */
+  {{ t.java.ValueType }} get{{ t.TypeName }}({{ t.java.ValueType }} defaultValue);
+{% if t.java.WrapValueType %}
+  /**
+   * 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
+   */
+  {{ t.java.WrapValueType }} get{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue);
+{% endif -%}
+{% endfor %}
+  /**
+   * Get an array of all value changes since the last call to readQueue.
+   * Also provides a timestamp for each value.
+   *
+   * <p>The "poll storage" subscribe option can be used to set the queue
+   * depth.
+   *
+   * @return Array of timestamped values; empty array if no new changes have
+   *     been published since the previous call.
+   */
+  NetworkTableValue[] readQueue();
+}
diff --git a/ntcore/src/generate/java/NetworkTableEntry.java.jinja b/ntcore/src/generate/java/NetworkTableEntry.java.jinja
new file mode 100644
index 0000000..783ec6f
--- /dev/null
+++ b/ntcore/src/generate/java/NetworkTableEntry.java.jinja
@@ -0,0 +1,537 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables Entry.
+ *
+ * <p>For backwards compatibility, the NetworkTableEntry close() does not release the entry.
+ */
+@SuppressWarnings("UnnecessaryParentheses")
+public final class NetworkTableEntry implements Publisher, Subscriber {
+  /**
+   * Flag values (as returned by {@link #getFlags()}).
+   *
+   * @deprecated Use isPersistent() instead.
+   */
+  @Deprecated(since = "2022", forRemoval = true)
+  public static final int kPersistent = 0x01;
+
+  /**
+   * Construct from native handle.
+   *
+   * @param inst Instance
+   * @param handle Native handle
+   */
+  public NetworkTableEntry(NetworkTableInstance inst, int handle) {
+    this(new Topic(inst, NetworkTablesJNI.getTopicFromHandle(handle)), handle);
+  }
+
+  /**
+   * Construct from native handle.
+   *
+   * @param topic Topic
+   * @param handle Native handle
+   */
+  public NetworkTableEntry(Topic topic, int handle) {
+    m_topic = topic;
+    m_handle = handle;
+  }
+
+  @Override
+  public void close() {}
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  @Override
+  public boolean isValid() {
+    return m_handle != 0;
+  }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  @Override
+  public int getHandle() {
+    return m_handle;
+  }
+
+  /**
+   * Gets the subscribed-to / published-to topic.
+   *
+   * @return Topic
+   */
+  @Override
+  public Topic getTopic() {
+    return m_topic;
+  }
+
+  /**
+   * Gets the instance for the entry.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_topic.getInstance();
+  }
+
+  /**
+   * Determines if the entry currently exists.
+   *
+   * @return True if the entry exists, false otherwise.
+   */
+  @Override
+  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)
+   * @deprecated Use isPersistent() or topic properties instead
+   */
+  @Deprecated(since = "2022", forRemoval = true)
+  public int getFlags() {
+    return NetworkTablesJNI.getEntryFlags(m_handle);
+  }
+
+  /**
+   * Gets the last time the entry's value was changed.
+   *
+   * @return Entry last change time
+   */
+  @Override
+  public long getLastChange() {
+    return NetworkTablesJNI.getEntryLastChange(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);
+  }
+{% for t in types %}
+  /**
+   * Gets the entry's value as a {{ t.java.ValueType }}. 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 {{ t.java.ValueType }} get{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
+    return NetworkTablesJNI.get{{ t.TypeName }}(m_handle, defaultValue);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * 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 {{ t.java.WrapValueType }} get{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
+    return NetworkTableValue.fromNative{{ t.TypeName }}(
+        get{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue)));
+  }
+{% endif -%}
+{% endfor %}
+  /**
+   * 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 getDouble(defaultValue.doubleValue());
+  }
+
+  /**
+   * 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.fromNativeDoubleArray(
+        getDoubleArray(NetworkTableValue.toNativeDoubleArray(defaultValue)));
+  }
+
+  /**
+   * Get an array of all value changes since the last call to readQueue.
+   *
+   * <p>The "poll storage" subscribe option can be used to set the queue
+   * depth.
+   *
+   * @return Array of values; empty array if no new changes have been
+   *     published since the previous call.
+   */
+  public NetworkTableValue[] readQueue() {
+    return NetworkTablesJNI.readQueueValue(m_handle);
+  }
+
+  /**
+   * 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 long[]
+        || data instanceof Long[]
+        || data instanceof float[]
+        || data instanceof Float[]
+        || 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 kInteger:
+          return NetworkTablesJNI.setDefaultInteger(
+              m_handle, time, ((Number) otherValue).longValue());
+        case kFloat:
+          return NetworkTablesJNI.setDefaultFloat(
+              m_handle, time, ((Number) otherValue).floatValue());
+        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 kIntegerArray:
+          return NetworkTablesJNI.setDefaultIntegerArray(m_handle, time, (long[]) otherValue);
+        case kFloatArray:
+          return NetworkTablesJNI.setDefaultFloatArray(m_handle, time, (float[]) otherValue);
+        case kDoubleArray:
+          return NetworkTablesJNI.setDefaultDoubleArray(m_handle, time, (double[]) otherValue);
+        case kStringArray:
+          return NetworkTablesJNI.setDefaultStringArray(m_handle, time, (String[]) otherValue);
+        default:
+          return true;
+      }
+    } else if (defaultValue instanceof Boolean) {
+      return setDefaultBoolean((Boolean) defaultValue);
+    } else if (defaultValue instanceof Integer) {
+      return setDefaultInteger((Integer) defaultValue);
+    } else if (defaultValue instanceof Float) {
+      return setDefaultFloat((Float) 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 long[]) {
+      return setDefaultIntegerArray((long[]) defaultValue);
+    } else if (defaultValue instanceof float[]) {
+      return setDefaultFloatArray((float[]) defaultValue);
+    } else if (defaultValue instanceof double[]) {
+      return setDefaultDoubleArray((double[]) defaultValue);
+    } else if (defaultValue instanceof Boolean[]) {
+      return setDefaultBooleanArray((Boolean[]) defaultValue);
+    } else if (defaultValue instanceof Long[]) {
+      return setDefaultIntegerArray((Long[]) defaultValue);
+    } else if (defaultValue instanceof Float[]) {
+      return setDefaultFloatArray((Float[]) 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");
+    }
+  }
+{% for t in types %}
+  /**
+   * 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 setDefault{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
+    return NetworkTablesJNI.setDefault{{ t.TypeName }}(m_handle, 0, defaultValue);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * 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 setDefault{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
+    return setDefault{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue));
+  }
+{% endif -%}
+{% endfor %}
+  /**
+   * 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 setDefaultDouble(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 setDefaultNumberArray(Number[] defaultValue) {
+    return setDefaultDoubleArray(NetworkTableValue.toNativeDoubleArray(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);
+        case kInteger:
+          return NetworkTablesJNI.setInteger(
+              m_handle, time, ((Number) otherValue).longValue());
+        case kFloat:
+          return NetworkTablesJNI.setFloat(
+              m_handle, time, ((Number) otherValue).floatValue());
+        case kDouble:
+          return NetworkTablesJNI.setDouble(
+              m_handle, time, ((Number) otherValue).doubleValue());
+        case kString:
+          return NetworkTablesJNI.setString(m_handle, time, (String) otherValue);
+        case kRaw:
+          return NetworkTablesJNI.setRaw(m_handle, time, (byte[]) otherValue);
+        case kBooleanArray:
+          return NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[]) otherValue);
+        case kIntegerArray:
+          return NetworkTablesJNI.setIntegerArray(m_handle, time, (long[]) otherValue);
+        case kFloatArray:
+          return NetworkTablesJNI.setFloatArray(m_handle, time, (float[]) otherValue);
+        case kDoubleArray:
+          return NetworkTablesJNI.setDoubleArray(m_handle, time, (double[]) otherValue);
+        case kStringArray:
+          return NetworkTablesJNI.setStringArray(m_handle, time, (String[]) otherValue);
+        default:
+          return true;
+      }
+    } else if (value instanceof Boolean) {
+      return setBoolean((Boolean) value);
+    } else if (value instanceof Long) {
+      return setInteger((Long) value);
+    } else if (value instanceof Float) {
+      return setFloat((Float) 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 long[]) {
+      return setIntegerArray((long[]) value);
+    } else if (value instanceof float[]) {
+      return setFloatArray((float[]) value);
+    } else if (value instanceof double[]) {
+      return setDoubleArray((double[]) value);
+    } else if (value instanceof Boolean[]) {
+      return setBooleanArray((Boolean[]) value);
+    } else if (value instanceof Long[]) {
+      return setIntegerArray((Long[]) value);
+    } else if (value instanceof Float[]) {
+      return setFloatArray((Float[]) 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");
+    }
+  }
+{% for t in types %}
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean set{{ t.TypeName }}({{ t.java.ValueType }} value) {
+    return NetworkTablesJNI.set{{ t.TypeName }}(m_handle, 0, value);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @return False if the entry exists with a different type
+   */
+  public boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value) {
+    return set{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(value));
+  }
+{% endif -%}
+{% endfor %}
+  /**
+   * 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 setDouble(value.doubleValue());
+  }
+
+  /**
+   * 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 setDoubleArray(NetworkTableValue.toNativeDoubleArray(value));
+  }
+
+  /**
+   * Sets flags.
+   *
+   * @param flags the flags to set (bitmask)
+   * @deprecated Use setPersistent() or topic properties instead
+   */
+  @Deprecated(since = "2022", forRemoval = true)
+  public void setFlags(int flags) {
+    NetworkTablesJNI.setEntryFlags(m_handle, getFlags() | flags);
+  }
+
+  /**
+   * Clears flags.
+   *
+   * @param flags the flags to clear (bitmask)
+   * @deprecated Use setPersistent() or topic properties instead
+   */
+  @Deprecated(since = "2022", forRemoval = true)
+  public void clearFlags(int flags) {
+    NetworkTablesJNI.setEntryFlags(m_handle, getFlags() & ~flags);
+  }
+
+  /** Make value persistent through program restarts. */
+  public void setPersistent() {
+    NetworkTablesJNI.setTopicPersistent(m_topic.getHandle(), true);
+  }
+
+  /** Stop making value persistent through program restarts. */
+  public void clearPersistent() {
+    NetworkTablesJNI.setTopicPersistent(m_topic.getHandle(), false);
+  }
+
+  /**
+   * Returns whether the value is persistent through program restarts.
+   *
+   * @return True if the value is persistent.
+   */
+  public boolean isPersistent() {
+    return NetworkTablesJNI.getTopicPersistent(m_topic.getHandle());
+  }
+
+  /** Stops publishing the entry if it's been published. */
+  public void unpublish() {
+    NetworkTablesJNI.unpublish(m_handle);
+  }
+
+  /**
+   * Deletes the entry.
+   *
+   * @deprecated Use unpublish() instead.
+   */
+  @Deprecated(since = "2022", forRemoval = true)
+  public void delete() {
+    unpublish();
+  }
+
+  @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 final Topic m_topic;
+  protected int m_handle;
+}
diff --git a/ntcore/src/generate/java/NetworkTableInstance.java.jinja b/ntcore/src/generate/java/NetworkTableInstance.java.jinja
new file mode 100644
index 0000000..ba5e33f
--- /dev/null
+++ b/ntcore/src/generate/java/NetworkTableInstance.java.jinja
@@ -0,0 +1,1064 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import edu.wpi.first.util.WPIUtilJNI;
+import edu.wpi.first.util.concurrent.Event;
+import edu.wpi.first.util.datalog.DataLog;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.OptionalLong;
+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.
+ */
+@SuppressWarnings("PMD.CouplingBetweenObjects")
+public final class NetworkTableInstance implements AutoCloseable {
+  /** Client/server mode flag values (as returned by {@link #getNetworkMode()}). */
+  public enum NetworkMode {
+    /** Running in server mode. */
+    kServer(0x01),
+
+    /** Running in NT3 client mode. */
+    kClient3(0x02),
+
+    /** Running in NT4 client mode. */
+    kClient4(0x04),
+
+    /** Currently starting up (either client or server). */
+    kStarting(0x08),
+
+    /** Running in local-only mode. */
+    kLocal(0x10);
+
+    private final int value;
+
+    NetworkMode(int value) {
+      this.value = value;
+    }
+
+    public int getValue() {
+      return value;
+    }
+  }
+
+  /** The default port that network tables operates on for NT3. */
+  public static final int kDefaultPort3 = 1735;
+
+  /** The default port that network tables operates on for NT4. */
+  public static final int kDefaultPort4 = 5810;
+
+  /**
+   * 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) {
+      m_listeners.close();
+      NetworkTablesJNI.destroyInstance(m_handle);
+      m_handle = 0;
+    }
+  }
+
+  /**
+   * 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 instance.
+   *
+   * @return Native handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  /**
+   * Get (generic) topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  public Topic getTopic(String name) {
+    Topic topic = m_topics.get(name);
+    if (topic == null) {
+      int handle = NetworkTablesJNI.getTopic(m_handle, name);
+      topic = new Topic(this, handle);
+      Topic oldTopic = m_topics.putIfAbsent(name, topic);
+      if (oldTopic != null) {
+        topic = oldTopic;
+      }
+      // also cache by handle
+      m_topicsByHandle.putIfAbsent(handle, topic);
+    }
+    return topic;
+  }
+{% for t in types %}
+  /**
+   * Get {{ t.java.ValueType }} topic.
+   *
+   * @param name topic name
+   * @return {{ t.TypeName }}Topic
+   */
+  public {{ t.TypeName }}Topic get{{ t.TypeName }}Topic(String name) {
+    Topic topic = m_topics.get(name);
+    if (topic instanceof {{ t.TypeName }}Topic) {
+      return ({{ t.TypeName }}Topic) topic;
+    }
+
+    int handle;
+    if (topic == null) {
+      handle = NetworkTablesJNI.getTopic(m_handle, name);
+    } else {
+      handle = topic.getHandle();
+    }
+
+    topic = new {{ t.TypeName }}Topic(this, handle);
+    m_topics.put(name, topic);
+
+    // also cache by handle
+    m_topicsByHandle.put(handle, topic);
+
+    return ({{ t.TypeName }}Topic) topic;
+  }
+{% endfor %}
+  private Topic[] topicHandlesToTopics(int[] handles) {
+    Topic[] topics = new Topic[handles.length];
+    for (int i = 0; i < handles.length; i++) {
+      topics[i] = getCachedTopic(handles[i]);
+    }
+    return topics;
+  }
+
+  /**
+   * Get all published topics.
+   *
+   * @return Array of topics.
+   */
+  public Topic[] getTopics() {
+    return topicHandlesToTopics(NetworkTablesJNI.getTopics(m_handle, "", 0));
+  }
+
+  /**
+   * Get published topics starting with the given prefix. The results are optionally filtered by
+   * string prefix to only return a subset of all topics.
+   *
+   * @param prefix topic name required prefix; only topics whose name starts with this string are
+   *     returned
+   * @return Array of topic information.
+   */
+  public Topic[] getTopics(String prefix) {
+    return topicHandlesToTopics(NetworkTablesJNI.getTopics(m_handle, prefix, 0));
+  }
+
+  /**
+   * Get published topics starting with the given prefix. The results are optionally filtered by
+   * string prefix and data type to only return a subset of all topics.
+   *
+   * @param prefix topic name required prefix; only topics whose name starts with this string are
+   *     returned
+   * @param types bitmask of data types; 0 is treated as a "don't care"
+   * @return Array of topic information.
+   */
+  public Topic[] getTopics(String prefix, int types) {
+    return topicHandlesToTopics(NetworkTablesJNI.getTopics(m_handle, prefix, types));
+  }
+
+  /**
+   * Get published topics starting with the given prefix. The results are optionally filtered by
+   * string prefix and data type to only return a subset of all topics.
+   *
+   * @param prefix topic name required prefix; only topics whose name starts with this string are
+   *     returned
+   * @param types array of data type strings
+   * @return Array of topic information.
+   */
+  public Topic[] getTopics(String prefix, String[] types) {
+    return topicHandlesToTopics(NetworkTablesJNI.getTopicsStr(m_handle, prefix, types));
+  }
+
+  /**
+   * Get information about all topics.
+   *
+   * @return Array of topic information.
+   */
+  public TopicInfo[] getTopicInfo() {
+    return NetworkTablesJNI.getTopicInfos(this, m_handle, "", 0);
+  }
+
+  /**
+   * Get information about topics starting with the given prefix. The results are optionally
+   * filtered by string prefix to only return a subset of all topics.
+   *
+   * @param prefix topic name required prefix; only topics whose name starts with this string are
+   *     returned
+   * @return Array of topic information.
+   */
+  public TopicInfo[] getTopicInfo(String prefix) {
+    return NetworkTablesJNI.getTopicInfos(this, m_handle, prefix, 0);
+  }
+
+  /**
+   * Get information about topics starting with the given prefix. The results are optionally
+   * filtered by string prefix and data type to only return a subset of all topics.
+   *
+   * @param prefix topic name required prefix; only topics whose name starts with this string are
+   *     returned
+   * @param types bitmask of data types; 0 is treated as a "don't care"
+   * @return Array of topic information.
+   */
+  public TopicInfo[] getTopicInfo(String prefix, int types) {
+    return NetworkTablesJNI.getTopicInfos(this, m_handle, prefix, types);
+  }
+
+  /**
+   * Get information about topics starting with the given prefix. The results are optionally
+   * filtered by string prefix and data type to only return a subset of all topics.
+   *
+   * @param prefix topic name required prefix; only topics whose name starts with this string are
+   *     returned
+   * @param types array of data type strings
+   * @return Array of topic information.
+   */
+  public TopicInfo[] getTopicInfo(String prefix, String[] types) {
+    return NetworkTablesJNI.getTopicInfosStr(this, m_handle, prefix, types);
+  }
+
+  /* Cache of created entries. */
+  private final ConcurrentMap<String, NetworkTableEntry> m_entries = new ConcurrentHashMap<>();
+
+  /**
+   * Gets the entry for a key.
+   *
+   * @param name Key
+   * @return Network table entry.
+   */
+  public NetworkTableEntry getEntry(String name) {
+    NetworkTableEntry entry = m_entries.get(name);
+    if (entry == null) {
+      entry = new NetworkTableEntry(this, NetworkTablesJNI.getEntry(m_handle, name));
+      NetworkTableEntry oldEntry = m_entries.putIfAbsent(name, entry);
+      if (oldEntry != null) {
+        entry = oldEntry;
+      }
+    }
+    return entry;
+  }
+
+  /* Cache of created topics. */
+  private final ConcurrentMap<String, Topic> m_topics = new ConcurrentHashMap<>();
+  private final ConcurrentMap<Integer, Topic> m_topicsByHandle = new ConcurrentHashMap<>();
+
+  Topic getCachedTopic(String name) {
+    Topic topic = m_topics.get(name);
+    if (topic == null) {
+      int handle = NetworkTablesJNI.getTopic(m_handle, name);
+      topic = new Topic(this, handle);
+      Topic oldTopic = m_topics.putIfAbsent(name, topic);
+      if (oldTopic != null) {
+        topic = oldTopic;
+      }
+      // also cache by handle
+      m_topicsByHandle.putIfAbsent(handle, topic);
+    }
+    return topic;
+  }
+
+  Topic getCachedTopic(int handle) {
+    Topic topic = m_topicsByHandle.get(handle);
+    if (topic == null) {
+      topic = new Topic(this, handle);
+      Topic oldTopic = m_topicsByHandle.putIfAbsent(handle, topic);
+      if (oldTopic != null) {
+        topic = oldTopic;
+      }
+    }
+    return topic;
+  }
+
+  /* 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() || "/".equals(key)) {
+      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;
+  }
+
+  /*
+   * Callback Creation Functions
+   */
+
+  private static class ListenerStorage implements AutoCloseable {
+    private final ReentrantLock m_lock = new ReentrantLock();
+    private final Map<Integer, Consumer<NetworkTableEvent>> m_listeners = new HashMap<>();
+    private Thread m_thread;
+    private int m_poller;
+    private boolean m_waitQueue;
+    private final Event m_waitQueueEvent = new Event();
+    private final Condition m_waitQueueCond = m_lock.newCondition();
+    private final NetworkTableInstance m_inst;
+
+    ListenerStorage(NetworkTableInstance inst) {
+      m_inst = inst;
+    }
+
+    int add(
+        String[] prefixes,
+        EnumSet<NetworkTableEvent.Kind> eventKinds,
+        Consumer<NetworkTableEvent> listener) {
+      m_lock.lock();
+      try {
+        if (m_poller == 0) {
+          m_poller = NetworkTablesJNI.createListenerPoller(m_inst.getHandle());
+          startThread();
+        }
+        int h = NetworkTablesJNI.addListener(m_poller, prefixes, eventKinds);
+        m_listeners.put(h, listener);
+        return h;
+      } finally {
+        m_lock.unlock();
+      }
+    }
+
+    int add(
+        int handle,
+        EnumSet<NetworkTableEvent.Kind> eventKinds,
+        Consumer<NetworkTableEvent> listener) {
+      m_lock.lock();
+      try {
+        if (m_poller == 0) {
+          m_poller = NetworkTablesJNI.createListenerPoller(m_inst.getHandle());
+          startThread();
+        }
+        int h = NetworkTablesJNI.addListener(m_poller, handle, eventKinds);
+        m_listeners.put(h, listener);
+        return h;
+      } finally {
+        m_lock.unlock();
+      }
+    }
+
+    int addLogger(int minLevel, int maxLevel, Consumer<NetworkTableEvent> listener) {
+      m_lock.lock();
+      try {
+        if (m_poller == 0) {
+          m_poller = NetworkTablesJNI.createListenerPoller(m_inst.getHandle());
+          startThread();
+        }
+        int h = NetworkTablesJNI.addLogger(m_poller, minLevel, maxLevel);
+        m_listeners.put(h, listener);
+        return h;
+      } finally {
+        m_lock.unlock();
+      }
+    }
+
+    void remove(int listener) {
+      m_lock.lock();
+      try {
+        m_listeners.remove(listener);
+      } finally {
+        m_lock.unlock();
+      }
+      NetworkTablesJNI.removeListener(listener);
+    }
+
+    @Override
+    public void close() {
+      if (m_poller != 0) {
+        NetworkTablesJNI.destroyListenerPoller(m_poller);
+      }
+      m_poller = 0;
+    }
+
+    private void startThread() {
+      m_thread =
+          new Thread(
+              () -> {
+                boolean wasInterrupted = false;
+                int[] handles = new int[] { m_poller, m_waitQueueEvent.getHandle() };
+                while (!Thread.interrupted()) {
+                  try {
+                    WPIUtilJNI.waitForObjects(handles);
+                  } catch (InterruptedException ex) {
+                    m_lock.lock();
+                    try {
+                      if (m_waitQueue) {
+                        m_waitQueue = false;
+                        m_waitQueueCond.signalAll();
+                      }
+                    } finally {
+                      m_lock.unlock();
+                    }
+                    Thread.currentThread().interrupt();
+                    // don't try to destroy poller, as its handle is likely no longer valid
+                    wasInterrupted = true;
+                    break;
+                  }
+                  for (NetworkTableEvent event :
+                      NetworkTablesJNI.readListenerQueue(m_inst, m_poller)) {
+                    Consumer<NetworkTableEvent> listener;
+                    m_lock.lock();
+                    try {
+                      listener = m_listeners.get(event.listener);
+                    } finally {
+                      m_lock.unlock();
+                    }
+                    if (listener != null) {
+                      try {
+                        listener.accept(event);
+                      } catch (Throwable throwable) {
+                        System.err.println(
+                            "Unhandled exception during listener callback: "
+                            + throwable.toString());
+                        throwable.printStackTrace();
+                      }
+                    }
+                  }
+                  m_lock.lock();
+                  try {
+                    if (m_waitQueue) {
+                      m_waitQueue = false;
+                      m_waitQueueCond.signalAll();
+                    }
+                  } finally {
+                    m_lock.unlock();
+                  }
+                }
+                m_lock.lock();
+                try {
+                  if (!wasInterrupted) {
+                    NetworkTablesJNI.destroyListenerPoller(m_poller);
+                  }
+                  m_poller = 0;
+                } finally {
+                  m_lock.unlock();
+                }
+              },
+              "NTListener");
+      m_thread.setDaemon(true);
+      m_thread.start();
+    }
+
+    boolean waitForQueue(double timeout) {
+      m_lock.lock();
+      try {
+        if (m_poller != 0) {
+          m_waitQueue = true;
+          m_waitQueueEvent.set();
+          while (m_waitQueue) {
+            try {
+              if (timeout < 0) {
+                m_waitQueueCond.await();
+              } else {
+                return m_waitQueueCond.await((long) (timeout * 1e9), TimeUnit.NANOSECONDS);
+              }
+            } catch (InterruptedException ex) {
+              Thread.currentThread().interrupt();
+              return true;
+            }
+          }
+        }
+      } finally {
+        m_lock.unlock();
+      }
+      return true;
+    }
+  }
+
+  private ListenerStorage m_listeners = new ListenerStorage(this);
+
+  /**
+   * Remove a connection listener.
+   *
+   * @param listener Listener handle to remove
+   */
+  public void removeListener(int listener) {
+    m_listeners.remove(listener);
+  }
+
+  /**
+   * Wait for the listener queue to be empty. This is primarily useful for deterministic
+   * testing. This blocks until either the 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 waitForListenerQueue(double timeout) {
+    return m_listeners.waitForQueue(timeout);
+  }
+
+  /**
+   * Add a connection listener. The callback function is called asynchronously on a separate
+   * thread, so it's important to use synchronization or atomics when accessing any shared state
+   * from the callback function.
+   *
+   * @param immediateNotify Notify listener of all existing connections
+   * @param listener Listener to add
+   * @return Listener handle
+   */
+  public int addConnectionListener(
+      boolean immediateNotify, Consumer<NetworkTableEvent> listener) {
+    EnumSet<NetworkTableEvent.Kind> eventKinds = EnumSet.of(NetworkTableEvent.Kind.kConnection);
+    if (immediateNotify) {
+      eventKinds.add(NetworkTableEvent.Kind.kImmediate);
+    }
+    return m_listeners.add(m_handle, eventKinds, listener);
+  }
+
+  /**
+   * Add a time synchronization listener. The callback function is called asynchronously on a
+   * separate thread, so it's important to use synchronization or atomics when accessing any shared
+   * state from the callback function.
+   *
+   * @param immediateNotify Notify listener of current time synchronization value
+   * @param listener Listener to add
+   * @return Listener handle
+   */
+  public int addTimeSyncListener(
+      boolean immediateNotify, Consumer<NetworkTableEvent> listener) {
+    EnumSet<NetworkTableEvent.Kind> eventKinds = EnumSet.of(NetworkTableEvent.Kind.kTimeSync);
+    if (immediateNotify) {
+      eventKinds.add(NetworkTableEvent.Kind.kImmediate);
+    }
+    return m_listeners.add(m_handle, eventKinds, listener);
+  }
+
+  /**
+   * Add a listener for changes on a particular topic. The callback function is called
+   * asynchronously on a separate thread, so it's important to use synchronization or atomics when
+   * accessing any shared state from the callback function.
+   *
+   * <p>This creates a corresponding internal subscriber with the lifetime of the
+   * listener.
+   *
+   * @param topic Topic
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  public int addListener(
+      Topic topic,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    if (topic.getInstance().getHandle() != m_handle) {
+      throw new IllegalArgumentException("topic is not from this instance");
+    }
+    return m_listeners.add(topic.getHandle(), eventKinds, listener);
+  }
+
+  /**
+   * Add a listener for changes on a subscriber. The callback function is called
+   * asynchronously on a separate thread, so it's important to use synchronization or atomics when
+   * accessing any shared state from the callback function. This does NOT keep the subscriber
+   * active.
+   *
+   * @param subscriber Subscriber
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  public int addListener(
+      Subscriber subscriber,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    if (subscriber.getTopic().getInstance().getHandle() != m_handle) {
+      throw new IllegalArgumentException("subscriber is not from this instance");
+    }
+    return m_listeners.add(subscriber.getHandle(), eventKinds, listener);
+  }
+
+  /**
+   * Add a listener for changes on a subscriber. The callback function is called
+   * asynchronously on a separate thread, so it's important to use synchronization or atomics when
+   * accessing any shared state from the callback function. This does NOT keep the subscriber
+   * active.
+   *
+   * @param subscriber Subscriber
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  public int addListener(
+      MultiSubscriber subscriber,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    if (subscriber.getInstance().getHandle() != m_handle) {
+      throw new IllegalArgumentException("subscriber is not from this instance");
+    }
+    return m_listeners.add(subscriber.getHandle(), eventKinds, listener);
+  }
+
+  /**
+   * Add a listener for changes on an entry. The callback function is called
+   * asynchronously on a separate thread, so it's important to use synchronization or atomics when
+   * accessing any shared state from the callback function.
+   *
+   * @param entry Entry
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  public int addListener(
+      NetworkTableEntry entry,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    if (entry.getTopic().getInstance().getHandle() != m_handle) {
+      throw new IllegalArgumentException("entry is not from this instance");
+    }
+    return m_listeners.add(entry.getHandle(), eventKinds, listener);
+  }
+
+  /**
+   * Add a listener for changes to topics with names that start with any of the given
+   * prefixes. The callback function is called asynchronously on a separate thread, so it's
+   * important to use synchronization or atomics when accessing any shared state from the callback
+   * function.
+   *
+   * <p>This creates a corresponding internal subscriber with the lifetime of the
+   * listener.
+   *
+   * @param prefixes Topic name string prefixes
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  public int addListener(
+      String[] prefixes,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    return m_listeners.add(prefixes, eventKinds, listener);
+  }
+
+  /*
+   * Client/Server Functions
+   */
+
+  /**
+   * Get the current network mode.
+   *
+   * @return Enum set of NetworkMode.
+   */
+  public EnumSet<NetworkMode> getNetworkMode() {
+    int flags = NetworkTablesJNI.getNetworkMode(m_handle);
+    EnumSet<NetworkMode> rv = EnumSet.noneOf(NetworkMode.class);
+    for (NetworkMode mode : NetworkMode.values()) {
+      if ((flags & mode.getValue()) != 0) {
+        rv.add(mode);
+      }
+    }
+    return rv;
+  }
+
+  /**
+   * 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.json as the persistent file, using the default
+   * listening address and port.
+   */
+  public void startServer() {
+    startServer("networktables.json");
+  }
+
+  /**
+   * 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, kDefaultPort3, kDefaultPort4);
+  }
+
+  /**
+   * 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 port3 port to communicate over (NT3)
+   */
+  public void startServer(String persistFilename, String listenAddress, int port3) {
+    startServer(persistFilename, listenAddress, port3, kDefaultPort4);
+  }
+
+  /**
+   * 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 port3 port to communicate over (NT3)
+   * @param port4 port to communicate over (NT4)
+   */
+  public void startServer(String persistFilename, String listenAddress, int port3, int port4) {
+    NetworkTablesJNI.startServer(m_handle, persistFilename, listenAddress, port3, port4);
+  }
+
+  /** Stops the server if it is running. */
+  public void stopServer() {
+    NetworkTablesJNI.stopServer(m_handle);
+  }
+
+  /**
+   * Starts a NT3 client. Use SetServer or SetServerTeam to set the server name and port.
+   *
+   * @param identity network identity to advertise (cannot be empty string)
+   */
+  public void startClient3(String identity) {
+    NetworkTablesJNI.startClient3(m_handle, identity);
+  }
+
+  /**
+   * Starts a NT4 client. Use SetServer or SetServerTeam to set the server name and port.
+   *
+   * @param identity network identity to advertise (cannot be empty string)
+   */
+  public void startClient4(String identity) {
+    NetworkTablesJNI.startClient4(m_handle, identity);
+  }
+
+  /** 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, 0);
+  }
+
+  /**
+   * Sets server address and port for client (without restarting client).
+   *
+   * @param serverName server name
+   * @param port port to communicate over (0=default)
+   */
+  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, 0);
+  }
+
+  /**
+   * 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 (0=default)
+   */
+  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 (0=default)
+   */
+  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, 0);
+  }
+
+  /**
+   * 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 (0=default)
+   */
+  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(0);
+  }
+
+  /**
+   * 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 (0=default)
+   */
+  public void startDSClient(int port) {
+    NetworkTablesJNI.startDSClient(m_handle, port);
+  }
+
+  /** Stops requesting server address from Driver Station. */
+  public void stopDSClient() {
+    NetworkTablesJNI.stopDSClient(m_handle);
+  }
+
+  /**
+   * Flushes all updated values immediately to the local client/server. This does not flush to the
+   * network.
+   */
+  public void flushLocal() {
+    NetworkTablesJNI.flushLocal(m_handle);
+  }
+
+  /**
+   * 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);
+  }
+
+  /**
+   * Get the time offset between server time and local time. Add this value to local time to get
+   * the estimated equivalent server time. In server mode, this always returns 0. In client mode,
+   * this returns the time offset only if the client and server are connected and have exchanged
+   * synchronization messages. Note the time offset may change over time as it is periodically
+   * updated; to receive updates as events, add a listener to the "time sync" event.
+   *
+   * @return Time offset in microseconds (optional)
+   */
+  public OptionalLong getServerTimeOffset() {
+    return NetworkTablesJNI.getServerTimeOffset(m_handle);
+  }
+
+  /**
+   * Starts logging entry changes to a DataLog.
+   *
+   * @param log data log object; lifetime must extend until StopEntryDataLog is called or the
+   *     instance is destroyed
+   * @param prefix only store entries with names that start with this prefix; the prefix is not
+   *     included in the data log entry name
+   * @param logPrefix prefix to add to data log entry names
+   * @return Data logger handle
+   */
+  public int startEntryDataLog(DataLog log, String prefix, String logPrefix) {
+    return NetworkTablesJNI.startEntryDataLog(m_handle, log, prefix, logPrefix);
+  }
+
+  /**
+   * Stops logging entry changes to a DataLog.
+   *
+   * @param logger data logger handle
+   */
+  public static void stopEntryDataLog(int logger) {
+    NetworkTablesJNI.stopEntryDataLog(logger);
+  }
+
+  /**
+   * Starts logging connection changes to a DataLog.
+   *
+   * @param log data log object; lifetime must extend until StopConnectionDataLog is called or the
+   *     instance is destroyed
+   * @param name data log entry name
+   * @return Data logger handle
+   */
+  public int startConnectionDataLog(DataLog log, String name) {
+    return NetworkTablesJNI.startConnectionDataLog(m_handle, log, name);
+  }
+
+  /**
+   * Stops logging connection changes to a DataLog.
+   *
+   * @param logger data logger handle
+   */
+  public static void stopConnectionDataLog(int logger) {
+    NetworkTablesJNI.stopConnectionDataLog(logger);
+  }
+
+  /**
+   * 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 minLevel minimum log level
+   * @param maxLevel maximum log level
+   * @param func callback function
+   * @return Listener handle
+   */
+  public int addLogger(int minLevel, int maxLevel, Consumer<NetworkTableEvent> func) {
+    return m_listeners.addLogger(minLevel, maxLevel, func);
+  }
+
+  @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/generate/java/NetworkTableValue.java.jinja b/ntcore/src/generate/java/NetworkTableValue.java.jinja
new file mode 100644
index 0000000..d2c8d11
--- /dev/null
+++ b/ntcore/src/generate/java/NetworkTableValue.java.jinja
@@ -0,0 +1,248 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import java.util.Objects;
+
+/** A network table entry value. */
+@SuppressWarnings({"UnnecessaryParentheses", "PMD.MethodReturnsInternalArray"})
+public final class NetworkTableValue {
+  NetworkTableValue(NetworkTableType type, Object value, long time, long serverTime) {
+    m_type = type;
+    m_value = value;
+    m_time = time;
+    m_serverTime = serverTime;
+  }
+
+  NetworkTableValue(NetworkTableType type, Object value, long time) {
+    this(type, value, time, time == 0 ? 0 : 1);
+  }
+
+  NetworkTableValue(NetworkTableType type, Object value) {
+    this(type, value, NetworkTablesJNI.now(), 1);
+  }
+
+  NetworkTableValue(int type, Object value, long time, long serverTime) {
+    this(NetworkTableType.getFromInt(type), value, time, serverTime);
+  }
+
+  /**
+   * 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 in local time.
+   *
+   * @return The time, in the units returned by NetworkTablesJNI.now().
+   */
+  public long getTime() {
+    return m_time;
+  }
+
+  /**
+   * Get the creation time of the value in server time.
+   *
+   * @return The server time.
+   */
+  public long getServerTime() {
+    return m_serverTime;
+  }
+
+  /*
+   * 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;
+  }
+{% for t in types %}
+  /**
+   * Determine if entry value contains a {{ t.java.ValueType }}.
+   *
+   * @return True if the entry value is of {{ t.java.ValueType }} type.
+   */
+  public boolean is{{ t.TypeName }}() {
+    return m_type == NetworkTableType.k{{ t.TypeName }};
+  }
+{% endfor %}
+  /*
+   * Type-Safe Getters
+   */
+{% for t in types %}
+  /**
+   * Get the {{ t.java.ValueType }} value.
+   *
+   * @return The {{ t.java.ValueType }} value.
+   * @throws ClassCastException if the entry value is not of {{ t.java.ValueType }} type.
+   */
+  public {{ t.java.ValueType }} get{{ t.TypeName }}() {
+    if (m_type != NetworkTableType.k{{ t.TypeName }}) {
+      throw new ClassCastException("cannot convert " + m_type + " to {{ t.java.ValueType }}");
+    }
+    return {{ t.java.FromStorageBegin }}m_value{{ t.java.FromStorageEnd }};
+  }
+{% endfor %}
+  /*
+   * Factory functions.
+   */
+{% for t in types %}
+  /**
+   * Creates a {{ t.java.ValueType }} value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue make{{ t.TypeName }}({{ t.java.ValueType }} value) {
+    return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, {{ t.java.ToWrapObject }}(value));
+  }
+
+  /**
+   * Creates a {{ t.java.ValueType }} value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue make{{ t.TypeName }}({{ t.java.ValueType }} value, long time) {
+    return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, {{ t.java.ToWrapObject }}(value), time);
+  }
+{% if t.java.WrapValueType %}
+  /**
+   * Creates a {{ t.java.ValueType }} value.
+   *
+   * @param value the value
+   * @return The entry value
+   */
+  public static NetworkTableValue make{{ t.TypeName }}({{ t.java.WrapValueType }} value) {
+    return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, toNative{{ t.TypeName }}(value));
+  }
+
+  /**
+   * Creates a {{ t.java.ValueType }} value.
+   *
+   * @param value the value
+   * @param time the creation time to use (instead of the current time)
+   * @return The entry value
+   */
+  public static NetworkTableValue make{{ t.TypeName }}({{ t.java.WrapValueType }} value, long time) {
+    return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, toNative{{ t.TypeName }}(value), time);
+  }
+{% endif -%}
+{% endfor %}
+  @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);
+  }
+
+  // arraycopy() doesn't know how to unwrap boxed values; this is a false positive in PMD
+  // (see https://sourceforge.net/p/pmd/bugs/804/)
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static boolean[] toNativeBooleanArray(Boolean[] arr) {
+    boolean[] out = new boolean[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i];
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static double[] toNativeDoubleArray(Number[] arr) {
+    double[] out = new double[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i].doubleValue();
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static long[] toNativeIntegerArray(Number[] arr) {
+    long[] out = new long[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i].longValue();
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static float[] toNativeFloatArray(Number[] arr) {
+    float[] out = new float[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i].floatValue();
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static Boolean[] fromNativeBooleanArray(boolean[] arr) {
+    Boolean[] out = new Boolean[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i];
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static Long[] fromNativeIntegerArray(long[] arr) {
+    Long[] out = new Long[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i];
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static Float[] fromNativeFloatArray(float[] arr) {
+    Float[] out = new Float[arr.length];
+    for (int i = 0; i < arr.length; i++) {
+      out[i] = arr[i];
+    }
+    return out;
+  }
+
+  @SuppressWarnings("PMD.AvoidArrayLoops")
+  static Double[] fromNativeDoubleArray(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;
+  private long m_serverTime;
+}
diff --git a/ntcore/src/generate/java/NetworkTablesJNI.java.jinja b/ntcore/src/generate/java/NetworkTablesJNI.java.jinja
new file mode 100644
index 0000000..2f119fe
--- /dev/null
+++ b/ntcore/src/generate/java/NetworkTablesJNI.java.jinja
@@ -0,0 +1,287 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import edu.wpi.first.util.RuntimeLoader;
+import edu.wpi.first.util.datalog.DataLog;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.OptionalLong;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+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.
+   *
+   * @throws IOException if the library fails to load
+   */
+  public static synchronized void forceLoad() throws IOException {
+    if (libraryLoaded) {
+      return;
+    }
+    loader =
+        new RuntimeLoader<>(
+            "ntcorejni", RuntimeLoader.getDefaultExtractionRoot(), NetworkTablesJNI.class);
+    loader.loadLibrary();
+    libraryLoaded = true;
+  }
+
+  private static PubSubOptions buildOptions(PubSubOption... options) {
+    if (options.length == 0) {
+      return null;  // optimize common case (JNI checks for null)
+    }
+    return new PubSubOptions(options);
+  }
+
+  public static native int getDefaultInstance();
+
+  public static native int createInstance();
+
+  public static native void destroyInstance(int inst);
+
+  public static native int getInstanceFromHandle(int handle);
+
+  private static native int getEntryImpl(
+      int topic, int type, String typeStr, PubSubOptions options);
+
+  public static native int getEntry(int inst, String key);
+
+  public static int getEntry(
+      int topic, int type, String typeStr, PubSubOptions options) {
+    return getEntryImpl(topic, type, typeStr, options);
+  }
+
+  public static int getEntry(
+      int topic, int type, String typeStr, PubSubOption... options) {
+    return getEntryImpl(topic, type, typeStr, buildOptions(options));
+  }
+
+  public static native String getEntryName(int entry);
+
+  public static native long getEntryLastChange(int entry);
+
+  public static native int getType(int entry);
+
+  /* Topic functions */
+
+  public static native int[] getTopics(int inst, String prefix, int types);
+
+  public static native int[] getTopicsStr(int inst, String prefix, String[] types);
+
+  public static native TopicInfo[] getTopicInfos(
+      NetworkTableInstance instObject, int inst, String prefix, int types);
+
+  public static native TopicInfo[] getTopicInfosStr(
+      NetworkTableInstance instObject, int inst, String prefix, String[] types);
+
+  public static native int getTopic(int inst, String name);
+
+  public static native String getTopicName(int topic);
+
+  public static native int getTopicType(int topic);
+
+  public static native void setTopicPersistent(int topic, boolean value);
+
+  public static native boolean getTopicPersistent(int topic);
+
+  public static native void setTopicRetained(int topic, boolean value);
+
+  public static native boolean getTopicRetained(int topic);
+
+  public static native String getTopicTypeString(int topic);
+
+  public static native boolean getTopicExists(int topic);
+
+  public static native String getTopicProperty(int topic, String name);
+
+  public static native void setTopicProperty(int topic, String name, String value);
+
+  public static native void deleteTopicProperty(int topic, String name);
+
+  public static native String getTopicProperties(int topic);
+
+  public static native void setTopicProperties(int topic, String properties);
+
+  public static native int subscribe(
+      int topic, int type, String typeStr, PubSubOptions options);
+
+  public static int subscribe(
+      int topic, int type, String typeStr, PubSubOption... options) {
+    return subscribe(topic, type, typeStr, buildOptions(options));
+  }
+
+  public static native void unsubscribe(int sub);
+
+  public static native int publish(
+      int topic, int type, String typeStr, PubSubOptions options);
+
+  public static int publish(
+      int topic, int type, String typeStr, PubSubOption... options) {
+    return publish(topic, type, typeStr, buildOptions(options));
+  }
+
+  public static native int publishEx(
+      int topic, int type, String typeStr, String properties, PubSubOptions options);
+
+  public static int publishEx(
+      int topic, int type, String typeStr, String properties, PubSubOption... options) {
+    return publishEx(topic, type, typeStr, properties, buildOptions(options));
+  }
+
+  public static native void unpublish(int pubentry);
+
+  public static native void releaseEntry(int entry);
+
+  public static native void release(int pubsubentry);
+
+  public static native int getTopicFromHandle(int pubsubentry);
+
+  public static native int subscribeMultiple(int inst, String[] prefixes, PubSubOptions options);
+
+  public static int subscribeMultiple(int inst, String[] prefixes, PubSubOption... options) {
+    return subscribeMultiple(inst, prefixes, buildOptions(options));
+  }
+
+  public static native void unsubscribeMultiple(int sub);
+{% for t in types %}
+  public static native Timestamped{{ t.TypeName }} getAtomic{{ t.TypeName }}(
+      int subentry, {{ t.java.ValueType }} defaultValue);
+
+  public static native Timestamped{{ t.TypeName }}[] readQueue{{ t.TypeName }}(int subentry);
+
+  public static native {{ t.java.ValueType }}[] readQueueValues{{ t.TypeName }}(int subentry);
+
+  public static native boolean set{{ t.TypeName }}(int entry, long time, {{ t.java.ValueType }} value);
+
+  public static native {{ t.java.ValueType }} get{{ t.TypeName }}(int entry, {{ t.java.ValueType }} defaultValue);
+
+  public static native boolean setDefault{{ t.TypeName }}(int entry, long time, {{ t.java.ValueType }} defaultValue);
+{% endfor %}
+  public static native NetworkTableValue[] readQueueValue(int subentry);
+
+  public static native NetworkTableValue getValue(int entry);
+
+  public static native void setEntryFlags(int entry, int flags);
+
+  public static native int getEntryFlags(int entry);
+
+  public static native TopicInfo getTopicInfo(NetworkTableInstance inst, int topic);
+
+  public static native int createListenerPoller(int inst);
+
+  public static native void destroyListenerPoller(int poller);
+
+  private static int kindsToMask(EnumSet<NetworkTableEvent.Kind> kinds) {
+    int mask = 0;
+    for (NetworkTableEvent.Kind kind : kinds) {
+      mask |= kind.getValue();
+    }
+    return mask;
+  }
+
+  public static int addListener(int poller, String[] prefixes, EnumSet<NetworkTableEvent.Kind> kinds) {
+    return addListener(poller, prefixes, kindsToMask(kinds));
+  }
+
+  public static int addListener(int poller, int handle, EnumSet<NetworkTableEvent.Kind> kinds) {
+    return addListener(poller, handle, kindsToMask(kinds));
+  }
+
+  public static native int addListener(int poller, String[] prefixes, int mask);
+
+  public static native int addListener(int poller, int handle, int mask);
+
+  public static native NetworkTableEvent[] readListenerQueue(
+      NetworkTableInstance inst, int poller);
+
+  public static native void removeListener(int listener);
+
+  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 port3, int port4);
+
+  public static native void stopServer(int inst);
+
+  public static native void startClient3(int inst, String identity);
+
+  public static native void startClient4(int inst, String identity);
+
+  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 flushLocal(int inst);
+
+  public static native void flush(int inst);
+
+  public static native ConnectionInfo[] getConnections(int inst);
+
+  public static native boolean isConnected(int inst);
+
+  public static native OptionalLong getServerTimeOffset(int inst);
+
+  public static native long now();
+
+  private static native int startEntryDataLog(int inst, long log, String prefix, String logPrefix);
+
+  public static int startEntryDataLog(int inst, DataLog log, String prefix, String logPrefix) {
+    return startEntryDataLog(inst, log.getImpl(), prefix, logPrefix);
+  }
+
+  public static native void stopEntryDataLog(int logger);
+
+  private static native int startConnectionDataLog(int inst, long log, String name);
+
+  public static int startConnectionDataLog(int inst, DataLog log, String name) {
+    return startConnectionDataLog(inst, log.getImpl(), name);
+  }
+
+  public static native void stopConnectionDataLog(int logger);
+
+  public static native int addLogger(int poller, int minLevel, int maxLevel);
+}
diff --git a/ntcore/src/generate/java/Publisher.java.jinja b/ntcore/src/generate/java/Publisher.java.jinja
new file mode 100644
index 0000000..19ead36
--- /dev/null
+++ b/ntcore/src/generate/java/Publisher.java.jinja
@@ -0,0 +1,49 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import {{ java.ConsumerFunctionPackage|default('java.util.function') }}.{{ java.FunctionTypePrefix }}Consumer;
+
+/** NetworkTables {{ TypeName }} publisher. */
+public interface {{ TypeName }}Publisher extends Publisher, {{ java.FunctionTypePrefix }}Consumer{{ java.FunctionTypeSuffix }} {
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  @Override
+  {{ TypeName }}Topic getTopic();
+
+  /**
+   * Publish a new value using current NT time.
+   *
+   * @param value value to publish
+   */
+  default void set({{ java.ValueType }} value) {
+    set(value, 0);
+  }
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @param time timestamp; 0 indicates current NT time should be used
+   */
+  void set({{ java.ValueType }} value, long time);
+
+  /**
+   * Publish a default value.
+   * On reconnect, a default value will never be used in preference to a
+   * published value.
+   *
+   * @param value value
+   */
+  void setDefault({{ java.ValueType }} value);
+
+  @Override
+  default void accept({{ java.ValueType }} value) {
+    set(value);
+  }
+}
diff --git a/ntcore/src/generate/java/Subscriber.java.jinja b/ntcore/src/generate/java/Subscriber.java.jinja
new file mode 100644
index 0000000..0ea09a3
--- /dev/null
+++ b/ntcore/src/generate/java/Subscriber.java.jinja
@@ -0,0 +1,83 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import {{ java.SupplierFunctionPackage|default('java.util.function') }}.{{ java.FunctionTypePrefix }}Supplier;
+
+/** NetworkTables {{ TypeName }} subscriber. */
+@SuppressWarnings("PMD.MissingOverride")
+public interface {{ TypeName }}Subscriber extends Subscriber, {{ java.FunctionTypePrefix }}Supplier{{ java.FunctionTypeSuffix }} {
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  @Override
+  {{ TypeName }}Topic getTopic();
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the stored default value.
+   *
+   * @return value
+   */
+  {{ java.ValueType }} get();
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the passed defaultValue.
+   *
+   * @param defaultValue default value to return if no value has been published
+   * @return value
+   */
+  {{ java.ValueType }} get({{ java.ValueType }} defaultValue);
+{% if java.FunctionTypePrefix %}
+  @Override
+  default {{ java.ValueType }} getAs{{ java.FunctionTypePrefix }}() {
+    return get();
+  }
+{% endif %}
+  /**
+   * Get the last published value along with its timestamp
+   * If no value has been published, returns the stored default value and a
+   * timestamp of 0.
+   *
+   * @return timestamped value
+   */
+  Timestamped{{ TypeName }} getAtomic();
+
+  /**
+   * Get the last published value along with its timestamp
+   * If no value has been published, returns the passed defaultValue and a
+   * timestamp of 0.
+   *
+   * @param defaultValue default value to return if no value has been published
+   * @return timestamped value
+   */
+  Timestamped{{ TypeName }} getAtomic({{ java.ValueType }} defaultValue);
+
+  /**
+   * Get an array of all value changes since the last call to readQueue.
+   * Also provides a timestamp for each value.
+   *
+   * <p>The "poll storage" subscribe option can be used to set the queue
+   * depth.
+   *
+   * @return Array of timestamped values; empty array if no new changes have
+   *     been published since the previous call.
+   */
+  Timestamped{{ TypeName }}[] readQueue();
+
+  /**
+   * Get an array of all value changes since the last call to readQueue.
+   *
+   * <p>The "poll storage" subscribe option can be used to set the queue
+   * depth.
+   *
+   * @return Array of values; empty array if no new changes have been
+   *     published since the previous call.
+   */
+  {{ java.ValueType }}[] readQueueValues();
+}
diff --git a/ntcore/src/generate/java/Timestamped.java.jinja b/ntcore/src/generate/java/Timestamped.java.jinja
new file mode 100644
index 0000000..288af81
--- /dev/null
+++ b/ntcore/src/generate/java/Timestamped.java.jinja
@@ -0,0 +1,40 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables timestamped {{ TypeName }}. */
+@SuppressWarnings("PMD.ArrayIsStoredDirectly")
+public final class Timestamped{{ TypeName }} {
+  /**
+   * Create a timestamped value.
+   *
+   * @param timestamp timestamp in local time base
+   * @param serverTime timestamp in server time base
+   * @param value value
+   */
+  public Timestamped{{ TypeName }}(long timestamp, long serverTime, {{ java.ValueType }} value) {
+    this.timestamp = timestamp;
+    this.serverTime = serverTime;
+    this.value = value;
+  }
+
+  /**
+   * Timestamp in local time base.
+   */
+  @SuppressWarnings("MemberName")
+  public final long timestamp;
+
+  /**
+   * Timestamp in server time base.  May be 0 or 1 for locally set values.
+   */
+  @SuppressWarnings("MemberName")
+  public final long serverTime;
+
+  /**
+   * Value.
+   */
+  @SuppressWarnings("MemberName")
+  public final {{ java.ValueType }} value;
+}
diff --git a/ntcore/src/generate/java/Topic.java.jinja b/ntcore/src/generate/java/Topic.java.jinja
new file mode 100644
index 0000000..e22fa3b
--- /dev/null
+++ b/ntcore/src/generate/java/Topic.java.jinja
@@ -0,0 +1,223 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables {{ TypeName }} topic. */
+public final class {{ TypeName }}Topic extends Topic {
+{%- if TypeString %}
+  /** The default type string for this topic type. */
+  public static final String kTypeString = {{ TypeString }};
+{% endif %}
+  /**
+   * Construct from a generic topic.
+   *
+   * @param topic Topic
+   */
+  public {{ TypeName }}Topic(Topic topic) {
+    super(topic.m_inst, topic.m_handle);
+  }
+
+  /**
+   * Constructor; use NetworkTableInstance.get{{TypeName}}Topic() instead.
+   *
+   * @param inst Instance
+   * @param handle Native handle
+   */
+  public {{ TypeName }}Topic(NetworkTableInstance inst, int handle) {
+    super(inst, handle);
+  }
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not closed.
+   *
+   * <p>Subscribers that do not match the published data type do not return
+   * any values. To determine if the data type matches, use the appropriate
+   * Topic functions.
+   *
+{%- if not TypeString %}
+   * @param typeString type string
+{% endif %}
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options subscribe options
+   * @return subscriber
+   */
+  public {{ TypeName }}Subscriber subscribe(
+{%- if not TypeString %}
+      String typeString,
+{% endif %}
+      {{ java.ValueType }} defaultValue,
+      PubSubOption... options) {
+    return new {{ TypeName }}EntryImpl(
+        this,
+        NetworkTablesJNI.subscribe(
+            m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
+            {{ TypeString|default('typeString') }}, options),
+        defaultValue);
+  }
+{% if TypeString %}
+  /**
+   * Create a new subscriber to the topic, with specified type string.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not closed.
+   *
+   * <p>Subscribers that do not match the published data type do not return
+   * any values. To determine if the data type matches, use the appropriate
+   * Topic functions.
+   *
+   * @param typeString type string
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options subscribe options
+   * @return subscriber
+   */
+  public {{ TypeName }}Subscriber subscribeEx(
+      String typeString,
+      {{ java.ValueType }} defaultValue,
+      PubSubOption... options) {
+    return new {{ TypeName }}EntryImpl(
+        this,
+        NetworkTablesJNI.subscribe(
+            m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
+            typeString, options),
+        defaultValue);
+  }
+{% endif %}
+  /**
+   * Create a new publisher to the topic.
+   *
+   * <p>The publisher is only active as long as the returned object
+   * is not closed.
+   *
+   * <p>It is not possible to publish two different data types to the same
+   * topic. Conflicts between publishers are typically resolved by the server on
+   * a first-come, first-served basis. Any published values that do not match
+   * the topic's data type are dropped (ignored). To determine if the data type
+   * matches, use the appropriate Topic functions.
+   *
+{%- if not TypeString %}
+   * @param typeString type string
+{% endif %}
+   * @param options publish options
+   * @return publisher
+   */
+  public {{ TypeName }}Publisher publish(
+{%- if not TypeString %}
+      String typeString,
+{% endif %}
+      PubSubOption... options) {
+    return new {{ TypeName }}EntryImpl(
+        this,
+        NetworkTablesJNI.publish(
+            m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
+            {{ TypeString|default('typeString') }}, options),
+        {{ java.EmptyValue }});
+  }
+
+  /**
+   * Create a new publisher to the topic, with type string and initial properties.
+   *
+   * <p>The publisher is only active as long as the returned object
+   * is not closed.
+   *
+   * <p>It is not possible to publish two different data types to the same
+   * topic. Conflicts between publishers are typically resolved by the server on
+   * a first-come, first-served basis. Any published values that do not match
+   * the topic's data type are dropped (ignored). To determine if the data type
+   * matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param properties JSON properties
+   * @param options publish options
+   * @return publisher
+   * @throws IllegalArgumentException if properties is not a JSON object
+   */
+  public {{ TypeName }}Publisher publishEx(
+      String typeString,
+      String properties,
+      PubSubOption... options) {
+    return new {{ TypeName }}EntryImpl(
+        this,
+        NetworkTablesJNI.publishEx(
+            m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
+            typeString, properties, options),
+        {{ java.EmptyValue }});
+  }
+
+  /**
+   * Create a new entry for the topic.
+   *
+   * <p>Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not closed. The publisher is
+   * created when the entry is first written to, and remains active until either
+   * unpublish() is called or the entry is closed.
+   *
+   * <p>It is not possible to use two different data types with the same
+   * topic. Conflicts between publishers are typically resolved by the server on
+   * a first-come, first-served basis. Any published values that do not match
+   * the topic's data type are dropped (ignored), and the entry will show no new
+   * values if the data type does not match. To determine if the data type
+   * matches, use the appropriate Topic functions.
+   *
+{%- if not TypeString %}
+   * @param typeString type string
+{% endif %}
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  public {{ TypeName }}Entry getEntry(
+{%- if not TypeString %}
+      String typeString,
+{% endif %}
+      {{ java.ValueType }} defaultValue,
+      PubSubOption... options) {
+    return new {{ TypeName }}EntryImpl(
+        this,
+        NetworkTablesJNI.getEntry(
+            m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
+            {{ TypeString|default('typeString') }}, options),
+        defaultValue);
+  }
+{% if TypeString %}
+  /**
+   * Create a new entry for the topic, with specified type string.
+   *
+   * <p>Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not closed. The publisher is
+   * created when the entry is first written to, and remains active until either
+   * unpublish() is called or the entry is closed.
+   *
+   * <p>It is not possible to use two different data types with the same
+   * topic. Conflicts between publishers are typically resolved by the server on
+   * a first-come, first-served basis. Any published values that do not match
+   * the topic's data type are dropped (ignored), and the entry will show no new
+   * values if the data type does not match. To determine if the data type
+   * matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  public {{ TypeName }}Entry getEntryEx(
+      String typeString,
+      {{ java.ValueType }} defaultValue,
+      PubSubOption... options) {
+    return new {{ TypeName }}EntryImpl(
+        this,
+        NetworkTablesJNI.getEntry(
+            m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
+            typeString, options),
+        defaultValue);
+  }
+{% endif %}
+}
diff --git a/ntcore/src/generate/types.json b/ntcore/src/generate/types.json
new file mode 100644
index 0000000..31a71b3
--- /dev/null
+++ b/ntcore/src/generate/types.json
@@ -0,0 +1,366 @@
+[
+    {
+        "TypeName": "Boolean",
+        "TypeString": "\"boolean\"",
+        "c": {
+            "ValueType": "NT_Bool",
+            "ParamType": "NT_Bool"
+        },
+        "cpp": {
+            "ValueType": "bool",
+            "ParamType": "bool",
+            "TYPE_NAME": "BOOLEAN"
+        },
+        "java": {
+            "ValueType": "boolean",
+            "EmptyValue": "false",
+            "ConsumerFunctionPackage": "edu.wpi.first.util.function",
+            "FunctionTypePrefix": "Boolean",
+            "ToWrapObject": "Boolean.valueOf",
+            "FromStorageBegin": "(Boolean) "
+        },
+        "jni": {
+            "jtype": "jboolean",
+            "jtypestr": "Z",
+            "JavaObject": false,
+            "FromJavaBegin": "",
+            "FromJavaEnd": " != JNI_FALSE",
+            "ToJavaBegin": "static_cast<jboolean>(",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJBooleanArray"
+        }
+    },
+    {
+        "TypeName": "Integer",
+        "TypeString": "\"int\"",
+        "c": {
+            "ValueType": "int64_t",
+            "ParamType": "int64_t"
+        },
+        "cpp": {
+            "ValueType": "int64_t",
+            "ParamType": "int64_t",
+            "TYPE_NAME": "INTEGER"
+        },
+        "java": {
+            "ValueType": "long",
+            "EmptyValue": "0",
+            "FunctionTypePrefix": "Long",
+            "ToWrapObject": "Long.valueOf",
+            "FromStorageBegin": "((Number) ",
+            "FromStorageEnd": ").longValue()"
+        },
+        "jni": {
+            "jtype": "jlong",
+            "jtypestr": "J",
+            "JavaObject": false,
+            "FromJavaBegin": "",
+            "FromJavaEnd": "",
+            "ToJavaBegin": "static_cast<jlong>(",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJLongArray"
+        }
+    },
+    {
+        "TypeName": "Float",
+        "TypeString": "\"float\"",
+        "c": {
+            "ValueType": "float",
+            "ParamType": "float"
+        },
+        "cpp": {
+            "ValueType": "float",
+            "ParamType": "float",
+            "TYPE_NAME": "FLOAT"
+        },
+        "java": {
+            "ValueType": "float",
+            "EmptyValue": "0",
+            "ConsumerFunctionPackage": "edu.wpi.first.util.function",
+            "SupplierFunctionPackage": "edu.wpi.first.util.function",
+            "FunctionTypePrefix": "Float",
+            "ToWrapObject": "Float.valueOf",
+            "FromStorageBegin": "((Number) ",
+            "FromStorageEnd": ").floatValue()"
+        },
+        "jni": {
+            "jtype": "jfloat",
+            "jtypestr": "F",
+            "JavaObject": false,
+            "FromJavaBegin": "",
+            "FromJavaEnd": "",
+            "ToJavaBegin": "static_cast<jfloat>(",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJFloatArray"
+        }
+    },
+    {
+        "TypeName": "Double",
+        "TypeString": "\"double\"",
+        "c": {
+            "ValueType": "double",
+            "ParamType": "double"
+        },
+        "cpp": {
+            "ValueType": "double",
+            "ParamType": "double",
+            "TYPE_NAME": "DOUBLE"
+        },
+        "java": {
+            "ValueType": "double",
+            "EmptyValue": "0",
+            "FunctionTypePrefix": "Double",
+            "ToWrapObject": "Double.valueOf",
+            "FromStorageBegin": "((Number) ",
+            "FromStorageEnd": ").doubleValue()"
+        },
+        "jni": {
+            "jtype": "jdouble",
+            "jtypestr": "D",
+            "JavaObject": false,
+            "FromJavaBegin": "",
+            "FromJavaEnd": "",
+            "ToJavaBegin": "static_cast<jdouble>(",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJDoubleArray"
+        }
+    },
+    {
+        "TypeName": "String",
+        "TypeString": "\"string\"",
+        "c": {
+            "ValueType": "char*",
+            "ParamType": "const char*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::string",
+            "ParamType": "std::string_view",
+            "TYPE_NAME": "STRING",
+            "INCLUDES": "#include <string>\n#include <string_view>\n#include <utility>",
+            "SmallRetType": "std::string_view",
+            "SmallElemType": "char"
+        },
+        "java": {
+            "ValueType": "String",
+            "EmptyValue": "\"\"",
+            "FunctionTypeSuffix": "<String>",
+            "FromStorageBegin": "(String) "
+        },
+        "jni": {
+            "jtype": "jstring",
+            "jtypestr": "Ljava/lang/String;",
+            "JavaObject": true,
+            "FromJavaBegin": "JStringRef{env, ",
+            "FromJavaEnd": "}",
+            "ToJavaBegin": "MakeJString(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJStringArray"
+        }
+    },
+    {
+        "TypeName": "Raw",
+        "c": {
+            "ValueType": "uint8_t*",
+            "ParamType": "const uint8_t*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::vector<uint8_t>",
+            "ParamType": "std::span<const uint8_t>",
+            "DefaultValueCopy": "defaultValue.begin(), defaultValue.end()",
+            "TYPE_NAME": "RAW",
+            "INCLUDES": "#include <utility>",
+            "SmallRetType": "std::span<uint8_t>",
+            "SmallElemType": "uint8_t"
+        },
+        "java": {
+            "ValueType": "byte[]",
+            "EmptyValue": "new byte[] {}",
+            "FunctionTypeSuffix": "<byte[]>",
+            "FromStorageBegin": "(byte[]) "
+        },
+        "jni": {
+            "jtype": "jbyteArray",
+            "jtypestr": "[B",
+            "JavaObject": true,
+            "FromJavaBegin": "CriticalJByteArrayRef{env, ",
+            "FromJavaEnd": "}.uarray()",
+            "ToJavaBegin": "MakeJByteArray(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJObjectArray"
+        }
+    },
+    {
+        "TypeName": "BooleanArray",
+        "TypeString": "\"boolean[]\"",
+        "c": {
+            "ValueType": "NT_Bool*",
+            "ParamType": "const NT_Bool*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::vector<int>",
+            "ParamType": "std::span<const int>",
+            "DefaultValueCopy": "defaultValue.begin(), defaultValue.end()",
+            "TYPE_NAME": "BOOLEAN_ARRAY",
+            "INCLUDES": "#include <utility>",
+            "SmallRetType": "std::span<int>",
+            "SmallElemType": "int"
+        },
+        "java": {
+            "ValueType": "boolean[]",
+            "WrapValueType": "Boolean[]",
+            "EmptyValue": "new boolean[] {}",
+            "FunctionTypeSuffix": "<boolean[]>",
+            "FromStorageBegin": "(boolean[]) "
+        },
+        "jni": {
+            "jtype": "jbooleanArray",
+            "jtypestr": "[Z",
+            "JavaObject": true,
+            "FromJavaBegin": "FromJavaBooleanArray(env, ",
+            "FromJavaEnd": ")",
+            "ToJavaBegin": "MakeJBooleanArray(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJObjectArray"
+        }
+    },
+    {
+        "TypeName": "IntegerArray",
+        "TypeString": "\"int[]\"",
+        "c": {
+            "ValueType": "int64_t*",
+            "ParamType": "const int64_t*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::vector<int64_t>",
+            "ParamType": "std::span<const int64_t>",
+            "DefaultValueCopy": "defaultValue.begin(), defaultValue.end()",
+            "TYPE_NAME": "INTEGER_ARRAY",
+            "INCLUDES": "#include <utility>",
+            "SmallRetType": "std::span<int64_t>",
+            "SmallElemType": "int64_t"
+        },
+        "java": {
+            "ValueType": "long[]",
+            "WrapValueType": "Long[]",
+            "EmptyValue": "new long[] {}",
+            "FunctionTypeSuffix": "<long[]>",
+            "FromStorageBegin": "(long[]) "
+        },
+        "jni": {
+            "jtype": "jlongArray",
+            "jtypestr": "[J",
+            "JavaObject": true,
+            "FromJavaBegin": "CriticalJLongArrayRef{env, ",
+            "FromJavaEnd": "}",
+            "ToJavaBegin": "MakeJLongArray(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJObjectArray"
+        }
+    },
+    {
+        "TypeName": "FloatArray",
+        "TypeString": "\"float[]\"",
+        "c": {
+            "ValueType": "float*",
+            "ParamType": "const float*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::vector<float>",
+            "ParamType": "std::span<const float>",
+            "DefaultValueCopy": "defaultValue.begin(), defaultValue.end()",
+            "TYPE_NAME": "FLOAT_ARRAY",
+            "INCLUDES": "#include <utility>",
+            "SmallRetType": "std::span<float>",
+            "SmallElemType": "float"
+        },
+        "java": {
+            "ValueType": "float[]",
+            "WrapValueType": "Float[]",
+            "EmptyValue": "new float[] {}",
+            "FunctionTypeSuffix": "<float[]>",
+            "FromStorageBegin": "(float[]) "
+        },
+        "jni": {
+            "jtype": "jfloatArray",
+            "jtypestr": "[F",
+            "JavaObject": true,
+            "FromJavaBegin": "CriticalJFloatArrayRef{env, ",
+            "FromJavaEnd": "}",
+            "ToJavaBegin": "MakeJFloatArray(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJObjectArray"
+        }
+    },
+    {
+        "TypeName": "DoubleArray",
+        "TypeString": "\"double[]\"",
+        "c": {
+            "ValueType": "double*",
+            "ParamType": "const double*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::vector<double>",
+            "ParamType": "std::span<const double>",
+            "DefaultValueCopy": "defaultValue.begin(), defaultValue.end()",
+            "TYPE_NAME": "DOUBLE_ARRAY",
+            "INCLUDES": "#include <utility>",
+            "SmallRetType": "std::span<double>",
+            "SmallElemType": "double"
+        },
+        "java": {
+            "ValueType": "double[]",
+            "WrapValueType": "Double[]",
+            "EmptyValue": "new double[] {}",
+            "FunctionTypeSuffix": "<double[]>",
+            "FromStorageBegin": "(double[]) "
+        },
+        "jni": {
+            "jtype": "jdoubleArray",
+            "jtypestr": "[D",
+            "JavaObject": true,
+            "FromJavaBegin": "CriticalJDoubleArrayRef{env, ",
+            "FromJavaEnd": "}",
+            "ToJavaBegin": "MakeJDoubleArray(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJObjectArray"
+        }
+    },
+    {
+        "TypeName": "StringArray",
+        "TypeString": "\"string[]\"",
+        "c": {
+            "ValueType": "struct NT_String*",
+            "ParamType": "const struct NT_String*",
+            "IsArray": true
+        },
+        "cpp": {
+            "ValueType": "std::vector<std::string>",
+            "ParamType": "std::span<const std::string>",
+            "DefaultValueCopy": "defaultValue.begin(), defaultValue.end()",
+            "TYPE_NAME": "STRING_ARRAY",
+            "INCLUDES": "#include <utility>"
+        },
+        "java": {
+            "ValueType": "String[]",
+            "EmptyValue": "new String[] {}",
+            "FunctionTypeSuffix": "<String[]>",
+            "FromStorageBegin": "(String[]) "
+        },
+        "jni": {
+            "jtype": "jobjectArray",
+            "jtypestr": "[Ljava/lang/Object;",
+            "JavaObject": true,
+            "FromJavaBegin": "FromJavaStringArray(env, ",
+            "FromJavaEnd": ")",
+            "ToJavaBegin": "MakeJStringArray(env, ",
+            "ToJavaEnd": ")",
+            "ToJavaArray": "MakeJObjectArray"
+        }
+    }
+]
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java
index 477d53b..147b2ea 100644
--- a/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionInfo.java
@@ -5,34 +5,30 @@
 package edu.wpi.first.networktables;
 
 /** NetworkTables Connection information. */
+@SuppressWarnings("MemberName")
 public final class ConnectionInfo {
   /**
    * The remote identifier (as set on the remote node by {@link
-   * NetworkTableInstance#setNetworkIdentity(String)}).
+   * NetworkTableInstance#startClient4(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;
 
   /**
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionNotification.java b/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionNotification.java
deleted file mode 100644
index 544e075..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/ConnectionNotification.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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/EntryBase.java b/ntcore/src/main/java/edu/wpi/first/networktables/EntryBase.java
new file mode 100644
index 0000000..48d4a9c
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/EntryBase.java
@@ -0,0 +1,44 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables entry base implementation. */
+public abstract class EntryBase implements Subscriber, Publisher {
+  /**
+   * Constructor.
+   *
+   * @param handle handle
+   */
+  public EntryBase(int handle) {
+    m_handle = handle;
+  }
+
+  @Override
+  public boolean isValid() {
+    return m_handle != 0;
+  }
+
+  @Override
+  public int getHandle() {
+    return m_handle;
+  }
+
+  @Override
+  public void close() {
+    NetworkTablesJNI.release(m_handle);
+  }
+
+  @Override
+  public boolean exists() {
+    return NetworkTablesJNI.getTopicExists(m_handle);
+  }
+
+  @Override
+  public long getLastChange() {
+    return NetworkTablesJNI.getEntryLastChange(m_handle);
+  }
+
+  protected int m_handle;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/EntryInfo.java b/ntcore/src/main/java/edu/wpi/first/networktables/EntryInfo.java
deleted file mode 100644
index 471edc8..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/EntryInfo.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 856c962..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/EntryListenerFlags.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 0f5cb51..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/EntryNotification.java
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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/GenericEntry.java b/ntcore/src/main/java/edu/wpi/first/networktables/GenericEntry.java
new file mode 100644
index 0000000..77e7502
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/GenericEntry.java
@@ -0,0 +1,15 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables generic entry.
+ *
+ * <p>Unlike NetworkTableEntry, the entry goes away when close() is called.
+ */
+public interface GenericEntry extends GenericSubscriber, GenericPublisher {
+  /** Stops publishing the entry if it's published. */
+  void unpublish();
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java b/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java
index 5d77d8b..fd090af 100644
--- a/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/LogMessage.java
@@ -5,6 +5,7 @@
 package edu.wpi.first.networktables;
 
 /** NetworkTables log message. */
+@SuppressWarnings("MemberName")
 public final class LogMessage {
   /** Logging levels. */
   public static final int kCritical = 50;
@@ -18,49 +19,30 @@
   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;
+  public LogMessage(int level, String filename, int line, String message) {
     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/MultiSubscriber.java b/ntcore/src/main/java/edu/wpi/first/networktables/MultiSubscriber.java
new file mode 100644
index 0000000..8386c1e
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/MultiSubscriber.java
@@ -0,0 +1,61 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/**
+ * Subscribe to multiple topics based on one or more topic name prefixes. Can be used in combination
+ * with ValueListenerPoller to listen for value changes across all matching topics.
+ */
+public final class MultiSubscriber implements AutoCloseable {
+  /**
+   * Create a multiple subscriber.
+   *
+   * @param inst instance
+   * @param prefixes topic name prefixes
+   * @param options subscriber options
+   */
+  public MultiSubscriber(NetworkTableInstance inst, String[] prefixes, PubSubOption... options) {
+    m_inst = inst;
+    m_handle = NetworkTablesJNI.subscribeMultiple(inst.getHandle(), prefixes, options);
+  }
+
+  @Override
+  public synchronized void close() {
+    if (m_handle != 0) {
+      NetworkTablesJNI.unsubscribeMultiple(m_handle);
+      m_handle = 0;
+    }
+  }
+
+  /**
+   * Gets the instance for the subscriber.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+
+  /**
+   * 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.
+   *
+   * @return Handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  private final NetworkTableInstance m_inst;
+  private int m_handle;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NTSendableBuilder.java b/ntcore/src/main/java/edu/wpi/first/networktables/NTSendableBuilder.java
index 65bfbca..4d5e6a5 100644
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NTSendableBuilder.java
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NTSendableBuilder.java
@@ -5,8 +5,6 @@
 package edu.wpi.first.networktables;
 
 import edu.wpi.first.util.sendable.SendableBuilder;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
 
 public interface NTSendableBuilder extends SendableBuilder {
   /**
@@ -23,19 +21,9 @@
    * function called by setUpdateTable().
    *
    * @param key property name
-   * @return Network table entry
+   * @return Network table topic
    */
-  NetworkTableEntry getEntry(String key);
-
-  /**
-   * Add a NetworkTableValue property.
-   *
-   * @param key property name
-   * @param getter getter function (returns current value)
-   * @param setter setter function (sets new value)
-   */
-  void addValueProperty(
-      String key, Supplier<NetworkTableValue> getter, Consumer<NetworkTableValue> setter);
+  Topic getTopic(String key);
 
   /**
    * Get the network table.
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java
index 7837a21..cc38239 100644
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTable.java
@@ -5,6 +5,7 @@
 package edu.wpi.first.networktables;
 
 import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
@@ -129,6 +130,126 @@
     return "NetworkTable: " + m_path;
   }
 
+  /**
+   * Get (generic) topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  public Topic getTopic(String name) {
+    return m_inst.getTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get boolean topic.
+   *
+   * @param name topic name
+   * @return BooleanTopic
+   */
+  public BooleanTopic getBooleanTopic(String name) {
+    return m_inst.getBooleanTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get long topic.
+   *
+   * @param name topic name
+   * @return IntegerTopic
+   */
+  public IntegerTopic getIntegerTopic(String name) {
+    return m_inst.getIntegerTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get float topic.
+   *
+   * @param name topic name
+   * @return FloatTopic
+   */
+  public FloatTopic getFloatTopic(String name) {
+    return m_inst.getFloatTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get double topic.
+   *
+   * @param name topic name
+   * @return DoubleTopic
+   */
+  public DoubleTopic getDoubleTopic(String name) {
+    return m_inst.getDoubleTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get String topic.
+   *
+   * @param name topic name
+   * @return StringTopic
+   */
+  public StringTopic getStringTopic(String name) {
+    return m_inst.getStringTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get raw topic.
+   *
+   * @param name topic name
+   * @return RawTopic
+   */
+  public RawTopic getRawTopic(String name) {
+    return m_inst.getRawTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get boolean[] topic.
+   *
+   * @param name topic name
+   * @return BooleanArrayTopic
+   */
+  public BooleanArrayTopic getBooleanArrayTopic(String name) {
+    return m_inst.getBooleanArrayTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get long[] topic.
+   *
+   * @param name topic name
+   * @return IntegerArrayTopic
+   */
+  public IntegerArrayTopic getIntegerArrayTopic(String name) {
+    return m_inst.getIntegerArrayTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get float[] topic.
+   *
+   * @param name topic name
+   * @return FloatArrayTopic
+   */
+  public FloatArrayTopic getFloatArrayTopic(String name) {
+    return m_inst.getFloatArrayTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get double[] topic.
+   *
+   * @param name topic name
+   * @return DoubleArrayTopic
+   */
+  public DoubleArrayTopic getDoubleArrayTopic(String name) {
+    return m_inst.getDoubleArrayTopic(m_pathWithSep + name);
+  }
+
+  /**
+   * Get String[] topic.
+   *
+   * @param name topic name
+   * @return StringArrayTopic
+   */
+  public StringArrayTopic getStringArrayTopic(String name) {
+    return m_inst.getStringArrayTopic(m_pathWithSep + name);
+  }
+
   private final ConcurrentMap<String, NetworkTableEntry> m_entries = new ConcurrentHashMap<>();
 
   /**
@@ -141,106 +262,15 @@
     NetworkTableEntry entry = m_entries.get(key);
     if (entry == null) {
       entry = m_inst.getEntry(m_pathWithSep + key);
-      m_entries.putIfAbsent(key, entry);
+      NetworkTableEntry oldEntry = m_entries.putIfAbsent(key, entry);
+      if (oldEntry != null) {
+        entry = oldEntry;
+      }
     }
     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
    *
@@ -258,7 +288,7 @@
    * @return true if the table as a value assigned to the given key
    */
   public boolean containsKey(String key) {
-    return !("".equals(key)) && getEntry(key).exists();
+    return !("".equals(key)) && getTopic(key).exists();
   }
 
   /**
@@ -269,9 +299,64 @@
    *     its own
    */
   public boolean containsSubTable(String key) {
-    int[] handles =
-        NetworkTablesJNI.getEntries(m_inst.getHandle(), m_pathWithSep + key + PATH_SEPARATOR, 0);
-    return handles.length != 0;
+    Topic[] topics = m_inst.getTopics(m_pathWithSep + key + PATH_SEPARATOR, 0);
+    return topics.length != 0;
+  }
+
+  /**
+   * Gets topic information for all keys in the table (not including sub-tables).
+   *
+   * @param types bitmask of types (NetworkTableType values); 0 is treated as a "don't care".
+   * @return topic information for keys currently in the table
+   */
+  public List<TopicInfo> getTopicInfo(int types) {
+    List<TopicInfo> infos = new ArrayList<>();
+    int prefixLen = m_path.length() + 1;
+    for (TopicInfo info : m_inst.getTopicInfo(m_pathWithSep, types)) {
+      String relativeKey = info.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1) {
+        continue;
+      }
+      infos.add(info);
+    }
+    return infos;
+  }
+
+  /**
+   * Gets topic information for all keys in the table (not including sub-tables).
+   *
+   * @return topic information for keys currently in the table
+   */
+  public List<TopicInfo> getTopicInfo() {
+    return getTopicInfo(0);
+  }
+
+  /**
+   * Gets all topics in the table (not including sub-tables).
+   *
+   * @param types bitmask of types (NetworkTableType values); 0 is treated as a "don't care".
+   * @return topic for keys currently in the table
+   */
+  public List<Topic> getTopics(int types) {
+    List<Topic> topics = new ArrayList<>();
+    int prefixLen = m_path.length() + 1;
+    for (TopicInfo info : m_inst.getTopicInfo(m_pathWithSep, types)) {
+      String relativeKey = info.name.substring(prefixLen);
+      if (relativeKey.indexOf(PATH_SEPARATOR) != -1) {
+        continue;
+      }
+      topics.add(info.getTopic());
+    }
+    return topics;
+  }
+
+  /**
+   * Gets all topics in the table (not including sub-tables).
+   *
+   * @return topic for keys currently in the table
+   */
+  public List<Topic> getTopics() {
+    return getTopics(0);
   }
 
   /**
@@ -283,16 +368,12 @@
   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)) {
+    for (TopicInfo info : m_inst.getTopicInfo(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;
   }
@@ -314,7 +395,7 @@
   public Set<String> getSubTables() {
     Set<String> keys = new HashSet<>();
     int prefixLen = m_path.length() + 1;
-    for (EntryInfo info : m_inst.getEntryInfo(m_pathWithSep, 0)) {
+    for (TopicInfo info : m_inst.getTopicInfo(m_pathWithSep, 0)) {
       String relativeKey = info.name.substring(prefixLen);
       int endSubTable = relativeKey.indexOf(PATH_SEPARATOR);
       if (endSubTable == -1) {
@@ -326,22 +407,13 @@
   }
 
   /**
-   * 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) {
+  public boolean putValue(String key, NetworkTableValue value) {
     return getEntry(key).setValue(value);
   }
 
@@ -352,7 +424,7 @@
    * @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) {
+  public boolean setDefaultValue(String key, NetworkTableValue defaultValue) {
     return getEntry(key).setDefaultValue(defaultValue);
   }
 
@@ -362,7 +434,7 @@
    * @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) {
+  public NetworkTableValue getValue(String key) {
     return getEntry(key).getValue();
   }
 
@@ -375,26 +447,121 @@
     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);
+  /** A listener that listens to events on topics in a {@link NetworkTable}. */
+  @FunctionalInterface
+  public interface TableEventListener {
+    /**
+     * Called when an event occurs on a topic in a {@link NetworkTable}.
+     *
+     * @param table the table the topic exists in
+     * @param key the key associated with the topic that changed
+     * @param event the event
+     */
+    void accept(NetworkTable table, String key, NetworkTableEvent event);
   }
 
   /**
-   * Load table values from a file. The file format used is identical to that used for
-   * SavePersistent / LoadPersistent.
+   * Listen to topics only within this table.
    *
-   * @param filename filename
-   * @return List of warnings (errors result in an exception instead)
-   * @throws PersistentException if error saving file
+   * @param eventKinds set of event kinds to listen to
+   * @param listener listener to add
+   * @return Listener handle
    */
-  public String[] loadEntries(String filename) throws PersistentException {
-    return m_inst.loadEntries(filename, m_pathWithSep);
+  public int addListener(EnumSet<NetworkTableEvent.Kind> eventKinds, TableEventListener listener) {
+    final int prefixLen = m_path.length() + 1;
+    return m_inst.addListener(
+        new String[] {m_pathWithSep},
+        eventKinds,
+        event -> {
+          String topicName = null;
+          if (event.topicInfo != null) {
+            topicName = event.topicInfo.name;
+          } else if (event.valueData != null) {
+            topicName = event.valueData.getTopic().getName();
+          }
+          if (topicName == null) {
+            return;
+          }
+          String relativeKey = topicName.substring(prefixLen);
+          if (relativeKey.indexOf(PATH_SEPARATOR) != -1) {
+            // part of a sub table
+            return;
+          }
+          listener.accept(this, relativeKey, event);
+        });
+  }
+
+  /**
+   * Listen to a single key.
+   *
+   * @param key the key name
+   * @param eventKinds set of event kinds to listen to
+   * @param listener listener to add
+   * @return Listener handle
+   */
+  public int addListener(
+      String key, EnumSet<NetworkTableEvent.Kind> eventKinds, TableEventListener listener) {
+    NetworkTableEntry entry = getEntry(key);
+    return m_inst.addListener(entry, eventKinds, event -> listener.accept(this, key, event));
+  }
+
+  /** A listener that listens to new tables in a {@link NetworkTable}. */
+  @FunctionalInterface
+  public interface SubTableListener {
+    /**
+     * 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);
+  }
+
+  /**
+   * 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
+   * @return Listener handle
+   */
+  public int addSubTableListener(SubTableListener listener) {
+    final int prefixLen = m_path.length() + 1;
+    final NetworkTable parent = this;
+
+    return m_inst.addListener(
+        new String[] {m_pathWithSep},
+        EnumSet.of(NetworkTableEvent.Kind.kPublish, NetworkTableEvent.Kind.kImmediate),
+        new Consumer<NetworkTableEvent>() {
+          final Set<String> m_notifiedTables = new HashSet<>();
+
+          @Override
+          public void accept(NetworkTableEvent event) {
+            if (event.topicInfo == null) {
+              return; // should not happen
+            }
+            String relativeKey = event.topicInfo.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));
+          }
+        });
+  }
+
+  /**
+   * Remove a listener.
+   *
+   * @param listener listener handle
+   */
+  public void removeListener(int listener) {
+    m_inst.removeListener(listener);
   }
 
   @Override
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEntry.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEntry.java
deleted file mode 100644
index 872bc89..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEntry.java
+++ /dev/null
@@ -1,858 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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 final NetworkTableInstance m_inst;
-  private final int m_handle;
-}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEvent.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEvent.java
new file mode 100644
index 0000000..97883c8
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableEvent.java
@@ -0,0 +1,152 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/**
+ * NetworkTables event.
+ *
+ * <p>There are different kinds of events. When creating a listener, a combination of event kinds
+ * can be listened to by building an EnumSet of NetworkTableEvent.Kind.
+ */
+@SuppressWarnings("MemberName")
+public final class NetworkTableEvent {
+  public enum Kind {
+    /**
+     * Initial listener addition. Set this to receive immediate notification of matches to other
+     * criteria.
+     */
+    kImmediate(0x0001),
+
+    /** Client connected (on server, any client connected). */
+    kConnected(0x0002),
+
+    /** Client disconnected (on server, any client disconnected). */
+    kDisconnected(0x0004),
+
+    /** Any connection event (connect or disconnect). */
+    kConnection(0x0004 | 0x0002),
+
+    /** New topic published. */
+    kPublish(0x0008),
+
+    /** Topic unpublished. */
+    kUnpublish(0x0010),
+
+    /** Topic properties changed. */
+    kProperties(0x0020),
+
+    /** Any topic event (publish, unpublish, or properties changed). */
+    kTopic(0x0020 | 0x0010 | 0x0008),
+
+    /** Topic value updated (via network). */
+    kValueRemote(0x0040),
+
+    /** Topic value updated (local). */
+    kValueLocal(0x0080),
+
+    /** Topic value updated (network or local). */
+    kValueAll(0x0080 | 0x0040),
+
+    /** Log message. */
+    kLogMessage(0x0100),
+
+    /** Time synchronized with server. */
+    kTimeSync(0x0200);
+
+    private final int value;
+
+    Kind(int value) {
+      this.value = value;
+    }
+
+    public int getValue() {
+      return value;
+    }
+  }
+
+  /**
+   * Handle of listener that was triggered. The value returned when adding the listener can be used
+   * to map this to a specific added listener.
+   */
+  public final int listener;
+
+  /**
+   * Determine if event is of a particular kind. For example, kPublish if the topic was not
+   * previously published. Also indicates the data included with the event:
+   *
+   * <ul>
+   *   <li>kConnected or kDisconnected: connInfo
+   *   <li>kPublish, kUnpublish, or kProperties: topicInfo
+   *   <li>kValueRemote, kValueLocal: valueData
+   *   <li>kLogMessage: logMessage
+   * </ul>
+   *
+   * @param kind Kind
+   * @return True if event matches kind
+   */
+  public boolean is(Kind kind) {
+    return (m_flags & kind.getValue()) != 0;
+  }
+
+  private final int m_flags;
+
+  /** Connection information (for connection events). */
+  public final ConnectionInfo connInfo;
+
+  /** Topic information (for topic events). */
+  public final TopicInfo topicInfo;
+
+  /** Value data (for value events). */
+  public final ValueEventData valueData;
+
+  /** Log message (for log message events). */
+  public final LogMessage logMessage;
+
+  /** Log message (for log message events). */
+  public final TimeSyncEventData timeSyncData;
+
+  /**
+   * Constructor. This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param listener Listener that was triggered
+   * @param flags Event flags
+   * @param connInfo Connection information
+   * @param topicInfo Topic information
+   * @param valueData Value data
+   * @param logMessage Log message
+   * @param timeSyncData Time sync data
+   */
+  public NetworkTableEvent(
+      NetworkTableInstance inst,
+      int listener,
+      int flags,
+      ConnectionInfo connInfo,
+      TopicInfo topicInfo,
+      ValueEventData valueData,
+      LogMessage logMessage,
+      TimeSyncEventData timeSyncData) {
+    this.m_inst = inst;
+    this.listener = listener;
+    this.m_flags = flags;
+    this.connInfo = connInfo;
+    this.topicInfo = topicInfo;
+    this.valueData = valueData;
+    this.logMessage = logMessage;
+    this.timeSyncData = timeSyncData;
+  }
+
+  /* Network table instance. */
+  private final NetworkTableInstance m_inst;
+
+  /**
+   * Gets the instance associated with this event.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableInstance.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableInstance.java
deleted file mode 100644
index 162327e..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableInstance.java
+++ /dev/null
@@ -1,1153 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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() || "/".equals(key)) {
-      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 int m_entryListenerPoller;
-  private boolean m_entryListenerWaitQueue;
-  private final Condition m_entryListenerWaitQueueCond = m_entryListenerLock.newCondition();
-
-  @SuppressWarnings("PMD.AvoidCatchingThrowable")
-  private void startEntryListenerThread() {
-    var 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");
-    entryListenerThread.setDaemon(true);
-    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 int m_connectionListenerPoller;
-  private boolean m_connectionListenerWaitQueue;
-  private final Condition m_connectionListenerWaitQueueCond =
-      m_connectionListenerLock.newCondition();
-
-  @SuppressWarnings("PMD.AvoidCatchingThrowable")
-  private void startConnectionListenerThread() {
-    var 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");
-    connectionListenerThread.setDaemon(true);
-    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 int m_rpcCallPoller;
-  private boolean m_rpcCallWaitQueue;
-  private final Condition m_rpcCallWaitQueueCond = m_rpcCallLock.newCondition();
-
-  @SuppressWarnings("PMD.AvoidCatchingThrowable")
-  private void startRpcCallThread() {
-    var 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");
-    rpcCallThread.setDaemon(true);
-    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 int m_loggerPoller;
-  private boolean m_loggerWaitQueue;
-  private final Condition m_loggerWaitQueueCond = m_loggerLock.newCondition();
-
-  @SuppressWarnings("PMD.AvoidCatchingThrowable")
-  private void startLogThread() {
-    var 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");
-    loggerThread.setDaemon(true);
-    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 final int m_handle;
-}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableListener.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableListener.java
new file mode 100644
index 0000000..2568738
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableListener.java
@@ -0,0 +1,189 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import java.util.EnumSet;
+import java.util.function.Consumer;
+
+/**
+ * Event listener. This calls back to a callback function when an event matching the specified mask
+ * occurs. The callback function is called asynchronously on a separate thread, so it's important to
+ * use synchronization or atomics when accessing any shared state from the callback function.
+ */
+public final class NetworkTableListener implements AutoCloseable {
+  /**
+   * Create a listener for changes to topics with names that start with any of the given prefixes.
+   * This creates a corresponding internal subscriber with the lifetime of the listener.
+   *
+   * @param inst Instance
+   * @param prefixes Topic name string prefixes
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createListener(
+      NetworkTableInstance inst,
+      String[] prefixes,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    return new NetworkTableListener(inst, inst.addListener(prefixes, eventKinds, listener));
+  }
+
+  /**
+   * Create a listener for changes on a particular topic. This creates a corresponding internal
+   * subscriber with the lifetime of the listener.
+   *
+   * @param topic Topic
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createListener(
+      Topic topic,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    NetworkTableInstance inst = topic.getInstance();
+    return new NetworkTableListener(inst, inst.addListener(topic, eventKinds, listener));
+  }
+
+  /**
+   * Create a listener for topic changes on a subscriber. This does NOT keep the subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createListener(
+      Subscriber subscriber,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    NetworkTableInstance inst = subscriber.getTopic().getInstance();
+    return new NetworkTableListener(inst, inst.addListener(subscriber, eventKinds, listener));
+  }
+
+  /**
+   * Create a listener for topic changes on a subscriber. This does NOT keep the subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createListener(
+      MultiSubscriber subscriber,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    NetworkTableInstance inst = subscriber.getInstance();
+    return new NetworkTableListener(inst, inst.addListener(subscriber, eventKinds, listener));
+  }
+
+  /**
+   * Create a listener for topic changes on an entry.
+   *
+   * @param entry Entry
+   * @param eventKinds set of event kinds to listen to
+   * @param listener Listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createListener(
+      NetworkTableEntry entry,
+      EnumSet<NetworkTableEvent.Kind> eventKinds,
+      Consumer<NetworkTableEvent> listener) {
+    NetworkTableInstance inst = entry.getInstance();
+    return new NetworkTableListener(inst, inst.addListener(entry, eventKinds, listener));
+  }
+
+  /**
+   * Create a connection listener.
+   *
+   * @param inst instance
+   * @param immediateNotify notify listener of all existing connections
+   * @param listener listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createConnectionListener(
+      NetworkTableInstance inst, boolean immediateNotify, Consumer<NetworkTableEvent> listener) {
+    return new NetworkTableListener(inst, inst.addConnectionListener(immediateNotify, listener));
+  }
+
+  /**
+   * Create a time synchronization listener.
+   *
+   * @param inst instance
+   * @param immediateNotify notify listener of current time synchonization value
+   * @param listener listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createTimeSyncListener(
+      NetworkTableInstance inst, boolean immediateNotify, Consumer<NetworkTableEvent> listener) {
+    return new NetworkTableListener(inst, inst.addTimeSyncListener(immediateNotify, listener));
+  }
+
+  /**
+   * Create a listener for log messages. 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 inst instance
+   * @param minLevel minimum log level
+   * @param maxLevel maximum log level
+   * @param listener listener function
+   * @return Listener
+   */
+  public static NetworkTableListener createLogger(
+      NetworkTableInstance inst, int minLevel, int maxLevel, Consumer<NetworkTableEvent> listener) {
+    return new NetworkTableListener(inst, inst.addLogger(minLevel, maxLevel, listener));
+  }
+
+  @Override
+  public synchronized void close() {
+    if (m_handle != 0) {
+      m_inst.removeListener(m_handle);
+      m_handle = 0;
+    }
+  }
+
+  /**
+   * 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.
+   *
+   * @return Native handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  /**
+   * Wait for the topic listener queue to be empty. This is primarily useful for deterministic
+   * testing. This blocks until either the topic 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 waitForQueue(double timeout) {
+    return m_inst.waitForListenerQueue(timeout);
+  }
+
+  private NetworkTableListener(NetworkTableInstance inst, int handle) {
+    m_inst = inst;
+    m_handle = handle;
+  }
+
+  private final NetworkTableInstance m_inst;
+  private int m_handle;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableListenerPoller.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableListenerPoller.java
new file mode 100644
index 0000000..3a504f3
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableListenerPoller.java
@@ -0,0 +1,173 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import java.util.EnumSet;
+
+/**
+ * Event listener poller. This queues events matching the specified mask. Code using the listener
+ * must periodically call readQueue() to read the events.
+ */
+public final class NetworkTableListenerPoller implements AutoCloseable {
+  /**
+   * Construct a topic listener poller.
+   *
+   * @param inst Instance
+   */
+  public NetworkTableListenerPoller(NetworkTableInstance inst) {
+    m_inst = inst;
+    m_handle = NetworkTablesJNI.createListenerPoller(inst.getHandle());
+  }
+
+  /**
+   * Start listening to topic changes for topics with names that start with any of the given
+   * prefixes. This creates a corresponding internal subscriber with the lifetime of the listener.
+   *
+   * @param prefixes Topic name string prefixes
+   * @param eventKinds set of event kinds to listen to
+   * @return Listener handle
+   */
+  public int addListener(String[] prefixes, EnumSet<NetworkTableEvent.Kind> eventKinds) {
+    return NetworkTablesJNI.addListener(m_handle, prefixes, eventKinds);
+  }
+
+  /**
+   * Start listening to changes to a particular topic. This creates a corresponding internal
+   * subscriber with the lifetime of the listener.
+   *
+   * @param topic Topic
+   * @param eventKinds set of event kinds to listen to
+   * @return Listener handle
+   */
+  public int addListener(Topic topic, EnumSet<NetworkTableEvent.Kind> eventKinds) {
+    return NetworkTablesJNI.addListener(m_handle, topic.getHandle(), eventKinds);
+  }
+
+  /**
+   * Start listening to topic changes on a subscriber. This does NOT keep the subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param eventKinds set of event kinds to listen to
+   * @return Listener handle
+   */
+  public int addListener(Subscriber subscriber, EnumSet<NetworkTableEvent.Kind> eventKinds) {
+    return NetworkTablesJNI.addListener(m_handle, subscriber.getHandle(), eventKinds);
+  }
+
+  /**
+   * Start listening to topic changes on a subscriber. This does NOT keep the subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param eventKinds set of event kinds to listen to
+   * @return Listener handle
+   */
+  public int addListener(MultiSubscriber subscriber, EnumSet<NetworkTableEvent.Kind> eventKinds) {
+    return NetworkTablesJNI.addListener(m_handle, subscriber.getHandle(), eventKinds);
+  }
+
+  /**
+   * Start listening to topic changes on an entry.
+   *
+   * @param entry Entry
+   * @param eventKinds set of event kinds to listen to
+   * @return Listener handle
+   */
+  public int addListener(NetworkTableEntry entry, EnumSet<NetworkTableEvent.Kind> eventKinds) {
+    return NetworkTablesJNI.addListener(m_handle, entry.getHandle(), eventKinds);
+  }
+
+  /**
+   * Add a connection listener. The callback function is called asynchronously on a separate thread,
+   * so it's important to use synchronization or atomics when accessing any shared state from the
+   * callback function.
+   *
+   * @param immediateNotify notify listener of all existing connections
+   * @return Listener handle
+   */
+  public int addConnectionListener(boolean immediateNotify) {
+    EnumSet<NetworkTableEvent.Kind> eventKinds = EnumSet.of(NetworkTableEvent.Kind.kConnection);
+    if (immediateNotify) {
+      eventKinds.add(NetworkTableEvent.Kind.kImmediate);
+    }
+    return NetworkTablesJNI.addListener(m_handle, m_inst.getHandle(), eventKinds);
+  }
+
+  /**
+   * Add a time synchronization listener. The callback function is called asynchronously on a
+   * separate thread, so it's important to use synchronization or atomics when accessing any shared
+   * state from the callback function.
+   *
+   * @param immediateNotify notify listener of current time synchronization value
+   * @return Listener handle
+   */
+  public int addTimeSyncListener(boolean immediateNotify) {
+    EnumSet<NetworkTableEvent.Kind> eventKinds = EnumSet.of(NetworkTableEvent.Kind.kTimeSync);
+    if (immediateNotify) {
+      eventKinds.add(NetworkTableEvent.Kind.kImmediate);
+    }
+    return NetworkTablesJNI.addListener(m_handle, m_inst.getHandle(), eventKinds);
+  }
+
+  /**
+   * 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 minLevel minimum log level
+   * @param maxLevel maximum log level
+   * @return Listener handle
+   */
+  public int addLogger(int minLevel, int maxLevel) {
+    return NetworkTablesJNI.addLogger(m_handle, minLevel, maxLevel);
+  }
+
+  /**
+   * Remove a listener.
+   *
+   * @param listener Listener handle
+   */
+  public void removeListener(int listener) {
+    NetworkTablesJNI.removeListener(listener);
+  }
+
+  /**
+   * Read topic notifications.
+   *
+   * @return Topic notifications since the previous call to readQueue()
+   */
+  public NetworkTableEvent[] readQueue() {
+    return NetworkTablesJNI.readListenerQueue(m_inst, m_handle);
+  }
+
+  @Override
+  public synchronized void close() {
+    if (m_handle != 0) {
+      NetworkTablesJNI.destroyListenerPoller(m_handle);
+    }
+    m_handle = 0;
+  }
+
+  /**
+   * 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.
+   *
+   * @return Handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  private final NetworkTableInstance m_inst;
+  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
index a173bb2..2350b49 100644
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableType.java
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableType.java
@@ -6,24 +6,33 @@
 
 /** 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);
+  kUnassigned(0, ""),
+  kBoolean(0x01, "boolean"),
+  kDouble(0x02, "double"),
+  kString(0x04, "string"),
+  kRaw(0x08, "raw"),
+  kBooleanArray(0x10, "boolean[]"),
+  kDoubleArray(0x20, "double[]"),
+  kStringArray(0x40, "string[]"),
+  kInteger(0x100, "int"),
+  kFloat(0x200, "float"),
+  kIntegerArray(0x400, "int[]"),
+  kFloatArray(0x800, "float[]");
 
-  private final int value;
+  private final int m_value;
+  private final String m_valueStr;
 
-  NetworkTableType(int value) {
-    this.value = value;
+  NetworkTableType(int value, String valueStr) {
+    m_value = value;
+    m_valueStr = valueStr;
   }
 
   public int getValue() {
-    return value;
+    return m_value;
+  }
+
+  public String getValueStr() {
+    return m_valueStr;
   }
 
   /**
@@ -48,10 +57,89 @@
         return kDoubleArray;
       case 0x40:
         return kStringArray;
-      case 0x80:
-        return kRpc;
+      case 0x100:
+        return kInteger;
+      case 0x200:
+        return kFloat;
+      case 0x400:
+        return kIntegerArray;
+      case 0x800:
+        return kFloatArray;
       default:
         return kUnassigned;
     }
   }
+
+  /**
+   * Convert from a type string to an enum type.
+   *
+   * @param typeString type string
+   * @return The kind
+   */
+  public static NetworkTableType getFromString(String typeString) {
+    switch (typeString) {
+      case "boolean":
+        return kBoolean;
+      case "double":
+        return kDouble;
+      case "float":
+        return kFloat;
+      case "int":
+        return kInteger;
+      case "string":
+      case "json":
+        return kString;
+      case "boolean[]":
+        return kBooleanArray;
+      case "double[]":
+        return kDoubleArray;
+      case "float[]":
+        return kFloatArray;
+      case "int[]":
+        return kIntegerArray;
+      case "string[]":
+        return kStringArray;
+      case "":
+        return kUnassigned;
+      default:
+        return kRaw;
+    }
+  }
+
+  /**
+   * Gets string from generic data value.
+   *
+   * @param data the data to check
+   * @return type string of the data, or empty string if no match
+   */
+  public static String getStringFromObject(Object data) {
+    if (data instanceof Boolean) {
+      return "boolean";
+    } else if (data instanceof Float) {
+      return "float";
+    } else if (data instanceof Long) {
+      // Checking Long because NT supports 64-bit integers
+      return "int";
+    } else if (data instanceof Double || data instanceof Number) {
+      // If typeof Number class, return "double" as the type. Functions as a "catch-all".
+      return "double";
+    } else if (data instanceof String) {
+      return "string";
+    } else if (data instanceof boolean[] || data instanceof Boolean[]) {
+      return "boolean[]";
+    } else if (data instanceof float[] || data instanceof Float[]) {
+      return "float[]";
+    } else if (data instanceof long[] || data instanceof Long[]) {
+      return "int[]";
+    } else if (data instanceof double[] || data instanceof Double[] || data instanceof Number[]) {
+      // If typeof Number class, return "double[]" as the type. Functions as a "catch-all".
+      return "double[]";
+    } else if (data instanceof String[]) {
+      return "string[]";
+    } else if (data instanceof byte[] || data instanceof Byte[]) {
+      return "raw";
+    } else {
+      return "";
+    }
+  }
 }
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableValue.java b/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableValue.java
deleted file mode 100644
index f4b9290..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTableValue.java
+++ /dev/null
@@ -1,522 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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.
-   */
-  @SuppressWarnings("PMD.MethodReturnsInternalArray")
-  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.
-   */
-  @SuppressWarnings("PMD.MethodReturnsInternalArray")
-  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.
-   */
-  @SuppressWarnings("PMD.MethodReturnsInternalArray")
-  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.
-   */
-  @SuppressWarnings("PMD.MethodReturnsInternalArray")
-  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.
-   */
-  @SuppressWarnings("PMD.MethodReturnsInternalArray")
-  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);
-  }
-
-  // arraycopy() doesn't know how to unwrap boxed values; this is a false positive in PMD
-  // (see https://sourceforge.net/p/pmd/bugs/804/)
-  @SuppressWarnings("PMD.AvoidArrayLoops")
-  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;
-  }
-
-  @SuppressWarnings("PMD.AvoidArrayLoops")
-  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;
-  }
-
-  @SuppressWarnings("PMD.AvoidArrayLoops")
-  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;
-  }
-
-  @SuppressWarnings("PMD.AvoidArrayLoops")
-  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
deleted file mode 100644
index 8c4916f..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/NetworkTablesJNI.java
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-package edu.wpi.first.networktables;
-
-import edu.wpi.first.util.RuntimeLoader;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-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.
-   *
-   * @throws IOException if the library fails to load
-   */
-  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
deleted file mode 100644
index 1c61595..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/PersistentException.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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/PubSub.java b/ntcore/src/main/java/edu/wpi/first/networktables/PubSub.java
new file mode 100644
index 0000000..7beaf9e
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/PubSub.java
@@ -0,0 +1,32 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables publisher or subscriber. */
+public interface PubSub extends AutoCloseable {
+  @Override
+  void close();
+
+  /**
+   * Gets the subscribed-to / published-to topic.
+   *
+   * @return Topic
+   */
+  Topic getTopic();
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  boolean isValid();
+
+  /**
+   * Gets the native handle.
+   *
+   * @return Handle
+   */
+  int getHandle();
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/PubSubOption.java b/ntcore/src/main/java/edu/wpi/first/networktables/PubSubOption.java
new file mode 100644
index 0000000..dd96eec
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/PubSubOption.java
@@ -0,0 +1,156 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables publish/subscribe option. */
+public class PubSubOption {
+  enum Kind {
+    periodic,
+    sendAll,
+    topicsOnly,
+    pollStorage,
+    keepDuplicates,
+    disableRemote,
+    disableLocal,
+    excludePublisher,
+    excludeSelf
+  }
+
+  PubSubOption(Kind kind, boolean value) {
+    m_kind = kind;
+    m_bValue = value;
+    m_iValue = 0;
+    m_dValue = 0;
+  }
+
+  PubSubOption(Kind kind, int value) {
+    m_kind = kind;
+    m_bValue = false;
+    m_iValue = value;
+    m_dValue = 0;
+  }
+
+  PubSubOption(Kind kind, double value) {
+    m_kind = kind;
+    m_bValue = false;
+    m_iValue = 0;
+    m_dValue = value;
+  }
+
+  /**
+   * How frequently changes will be sent over the network. NetworkTables may send more frequently
+   * than this (e.g. use a combined minimum period for all values) or apply a restricted range to
+   * this value. The default if unspecified is 100 ms.
+   *
+   * @param period time between updates, in seconds
+   * @return option
+   */
+  public static PubSubOption periodic(double period) {
+    return new PubSubOption(Kind.periodic, period);
+  }
+
+  /**
+   * If enabled, sends all value changes over the network. This option defaults to disabled.
+   *
+   * @param enabled True to enable, false to disable
+   * @return option
+   */
+  public static PubSubOption sendAll(boolean enabled) {
+    return new PubSubOption(Kind.sendAll, enabled);
+  }
+
+  /**
+   * If enabled on a subscription, does not request value changes. This option defaults to disabled.
+   *
+   * @param enabled True to enable, false to disable
+   * @return option
+   */
+  public static PubSubOption topicsOnly(boolean enabled) {
+    return new PubSubOption(Kind.topicsOnly, enabled);
+  }
+
+  /**
+   * If enabled, preserves duplicate value changes (rather than ignoring them). This option defaults
+   * to disabled.
+   *
+   * @param enabled True to enable, false to disable
+   * @return option
+   */
+  public static PubSubOption keepDuplicates(boolean enabled) {
+    return new PubSubOption(Kind.keepDuplicates, enabled);
+  }
+
+  /**
+   * Polling storage for subscription. Specifies the maximum number of updates NetworkTables should
+   * store between calls to the subscriber's readQueue() function. Defaults to 1 if sendAll is
+   * false, 20 if sendAll is true.
+   *
+   * @param depth number of entries to save for polling.
+   * @return option
+   */
+  public static PubSubOption pollStorage(int depth) {
+    return new PubSubOption(Kind.pollStorage, depth);
+  }
+
+  /**
+   * For subscriptions, specify whether remote value updates should not be queued for readQueue().
+   * See also disableLocal(). Defaults to false (remote value updates are queued).
+   *
+   * @param disabled True to disable, false to enable
+   * @return option
+   */
+  public static PubSubOption disableRemote(boolean disabled) {
+    return new PubSubOption(Kind.disableRemote, disabled);
+  }
+
+  /**
+   * For subscriptions, specify whether local value updates should not be queued for readQueue().
+   * See also disableRemote(). Defaults to false (local value updates are queued).
+   *
+   * @param disabled True to disable, false to enable
+   * @return option
+   */
+  public static PubSubOption disableLocal(boolean disabled) {
+    return new PubSubOption(Kind.disableLocal, disabled);
+  }
+
+  /**
+   * Don't queue value updates for the given publisher. Only has an effect on subscriptions. Only
+   * one exclusion may be set.
+   *
+   * @param publisher publisher handle to exclude
+   * @return option
+   */
+  public static PubSubOption excludePublisher(int publisher) {
+    return new PubSubOption(Kind.excludePublisher, publisher);
+  }
+
+  /**
+   * Don't queue value updates for the given publisher. Only has an effect on subscriptions. Only
+   * one exclusion may be set.
+   *
+   * @param publisher publisher to exclude
+   * @return option
+   */
+  public static PubSubOption excludePublisher(Publisher publisher) {
+    return excludePublisher(publisher != null ? publisher.getHandle() : 0);
+  }
+
+  /**
+   * Don't queue value updates for the internal publisher for an entry. Only has an effect on
+   * entries.
+   *
+   * @param enabled True to enable, false to disable
+   * @return option
+   */
+  public static PubSubOption excludeSelf(boolean enabled) {
+    return new PubSubOption(Kind.excludeSelf, enabled);
+  }
+
+  final Kind m_kind;
+  final boolean m_bValue;
+  final int m_iValue;
+  final double m_dValue;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/PubSubOptions.java b/ntcore/src/main/java/edu/wpi/first/networktables/PubSubOptions.java
new file mode 100644
index 0000000..18557b9
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/PubSubOptions.java
@@ -0,0 +1,126 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables publish/subscribe options. */
+@SuppressWarnings("MemberName")
+public class PubSubOptions {
+  /**
+   * Construct from a list of options.
+   *
+   * @param options options
+   */
+  public PubSubOptions(PubSubOption... options) {
+    for (PubSubOption option : options) {
+      switch (option.m_kind) {
+        case periodic:
+          periodic = option.m_dValue;
+          break;
+        case sendAll:
+          sendAll = option.m_bValue;
+          break;
+        case topicsOnly:
+          topicsOnly = option.m_bValue;
+          break;
+        case pollStorage:
+          pollStorage = option.m_iValue;
+          break;
+        case keepDuplicates:
+          keepDuplicates = option.m_bValue;
+          break;
+        case disableRemote:
+          disableRemote = option.m_bValue;
+          break;
+        case disableLocal:
+          disableLocal = option.m_bValue;
+          break;
+        case excludePublisher:
+          excludePublisher = option.m_iValue;
+          break;
+        case excludeSelf:
+          excludeSelf = option.m_bValue;
+          break;
+        default:
+          break;
+      }
+    }
+  }
+
+  PubSubOptions(
+      int pollStorage,
+      double periodic,
+      int excludePublisher,
+      boolean sendAll,
+      boolean topicsOnly,
+      boolean keepDuplicates,
+      boolean prefixMatch,
+      boolean disableRemote,
+      boolean disableLocal,
+      boolean excludeSelf) {
+    this.pollStorage = pollStorage;
+    this.periodic = periodic;
+    this.excludePublisher = excludePublisher;
+    this.sendAll = sendAll;
+    this.topicsOnly = topicsOnly;
+    this.keepDuplicates = keepDuplicates;
+    this.prefixMatch = prefixMatch;
+    this.disableRemote = disableRemote;
+    this.disableLocal = disableLocal;
+    this.excludeSelf = excludeSelf;
+  }
+
+  /** Default value of periodic. */
+  public static final double kDefaultPeriodic = 0.1;
+
+  /**
+   * Polling storage size for a subscription. Specifies the maximum number of updates NetworkTables
+   * should store between calls to the subscriber's readQueue() function. If zero, defaults to 1 if
+   * sendAll is false, 20 if sendAll is true.
+   */
+  public int pollStorage;
+
+  /**
+   * How frequently changes will be sent over the network, in seconds. NetworkTables may send more
+   * frequently than this (e.g. use a combined minimum period for all values) or apply a restricted
+   * range to this value. The default is 100 ms.
+   */
+  public double periodic = kDefaultPeriodic;
+
+  /**
+   * For subscriptions, if non-zero, value updates for readQueue() are not queued for this
+   * publisher.
+   */
+  public int excludePublisher;
+
+  /** Send all value changes over the network. */
+  public boolean sendAll;
+
+  /** For subscriptions, don't ask for value changes (only topic announcements). */
+  public boolean topicsOnly;
+
+  /** Preserve duplicate value changes (rather than ignoring them). */
+  public boolean keepDuplicates;
+
+  /**
+   * Perform prefix match on subscriber topic names. Is ignored/overridden by subscribe() functions;
+   * only present in struct for the purposes of getting information about subscriptions.
+   */
+  public boolean prefixMatch;
+
+  /**
+   * For subscriptions, if remote value updates should not be queued for readQueue(). See also
+   * disableLocal.
+   */
+  public boolean disableRemote;
+
+  /**
+   * For subscriptions, if local value updates should not be queued for readQueue(). See also
+   * disableRemote.
+   */
+  public boolean disableLocal;
+
+  /** For entries, don't queue (for readQueue) value updates for the entry's internal publisher. */
+  public boolean excludeSelf;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/Publisher.java b/ntcore/src/main/java/edu/wpi/first/networktables/Publisher.java
new file mode 100644
index 0000000..616c7ab
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/Publisher.java
@@ -0,0 +1,8 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables publisher. */
+public interface Publisher extends PubSub {}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/RpcAnswer.java b/ntcore/src/main/java/edu/wpi/first/networktables/RpcAnswer.java
deleted file mode 100644
index a244bde..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/RpcAnswer.java
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
-   */
-  @SuppressWarnings("PMD.ArrayIsStoredDirectly")
-  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
deleted file mode 100644
index 790ff5f..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/RpcCall.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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/Subscriber.java b/ntcore/src/main/java/edu/wpi/first/networktables/Subscriber.java
new file mode 100644
index 0000000..08f825d
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/Subscriber.java
@@ -0,0 +1,22 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables subscriber. */
+public interface Subscriber extends PubSub {
+  /**
+   * Determines if the entry currently exists.
+   *
+   * @return True if the entry exists, false otherwise.
+   */
+  boolean exists();
+
+  /**
+   * Gets the last time the entry's value was changed.
+   *
+   * @return Entry last change time
+   */
+  long getLastChange();
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/TableEntryListener.java b/ntcore/src/main/java/edu/wpi/first/networktables/TableEntryListener.java
deleted file mode 100644
index e0781e1..0000000
--- a/ntcore/src/main/java/edu/wpi/first/networktables/TableEntryListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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/TimeSyncEventData.java b/ntcore/src/main/java/edu/wpi/first/networktables/TimeSyncEventData.java
new file mode 100644
index 0000000..f8710ad
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/TimeSyncEventData.java
@@ -0,0 +1,37 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables time sync event data. */
+@SuppressWarnings("MemberName")
+public final class TimeSyncEventData {
+  /**
+   * Offset between local time and server time, in microseconds. Add this value to local time to get
+   * the estimated equivalent server time.
+   */
+  public final long serverTimeOffset;
+
+  /** Measured round trip time divided by 2, in microseconds. */
+  public final long rtt2;
+
+  /**
+   * If serverTimeOffset and RTT are valid. An event with this set to false is sent when the client
+   * disconnects.
+   */
+  public final boolean valid;
+
+  /**
+   * Constructor. This should generally only be used internally to NetworkTables.
+   *
+   * @param serverTimeOffset Server time offset
+   * @param rtt2 Round trip time divided by 2
+   * @param valid If other parameters are valid
+   */
+  public TimeSyncEventData(long serverTimeOffset, long rtt2, boolean valid) {
+    this.serverTimeOffset = serverTimeOffset;
+    this.rtt2 = rtt2;
+    this.valid = valid;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/Topic.java b/ntcore/src/main/java/edu/wpi/first/networktables/Topic.java
new file mode 100644
index 0000000..db08a34
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/Topic.java
@@ -0,0 +1,322 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables Topic. */
+public class Topic {
+  /**
+   * Constructor; use NetworkTableInstance.getTopic() instead.
+   *
+   * @param inst Instance
+   * @param handle Native handle
+   */
+  Topic(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 topic.
+   *
+   * @return Native handle
+   */
+  public int getHandle() {
+    return m_handle;
+  }
+
+  /**
+   * Gets the instance for the topic.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+
+  /**
+   * Gets the name of the topic.
+   *
+   * @return the topic's name
+   */
+  public String getName() {
+    return NetworkTablesJNI.getTopicName(m_handle);
+  }
+
+  /**
+   * Gets the type of the topic.
+   *
+   * @return the topic's type
+   */
+  public NetworkTableType getType() {
+    return NetworkTableType.getFromInt(NetworkTablesJNI.getType(m_handle));
+  }
+
+  /**
+   * Gets the type string of the topic. This may have more information than the numeric type
+   * (especially for raw values).
+   *
+   * @return the topic's type
+   */
+  public String getTypeString() {
+    return NetworkTablesJNI.getTopicTypeString(m_handle);
+  }
+
+  /**
+   * Gets combined information about the topic.
+   *
+   * @return Topic information
+   */
+  public TopicInfo getInfo() {
+    return NetworkTablesJNI.getTopicInfo(m_inst, m_handle);
+  }
+
+  /**
+   * Make value persistent through server restarts.
+   *
+   * @param persistent True for persistent, false for not persistent.
+   */
+  public void setPersistent(boolean persistent) {
+    NetworkTablesJNI.setTopicPersistent(m_handle, persistent);
+  }
+
+  /**
+   * Returns whether the value is persistent through server restarts.
+   *
+   * @return True if the value is persistent.
+   */
+  public boolean isPersistent() {
+    return NetworkTablesJNI.getTopicPersistent(m_handle);
+  }
+
+  /**
+   * Make the server retain the topic even when there are no publishers.
+   *
+   * @param retained True for retained, false for not retained.
+   */
+  public void setRetained(boolean retained) {
+    NetworkTablesJNI.setTopicRetained(m_handle, retained);
+  }
+
+  /**
+   * Returns whether the topic is retained by server when there are no publishers.
+   *
+   * @return True if the topic is retained.
+   */
+  public boolean isRetained() {
+    return NetworkTablesJNI.getTopicRetained(m_handle);
+  }
+
+  /**
+   * Determines if the topic is currently being published.
+   *
+   * @return True if the topic exists, false otherwise.
+   */
+  public boolean exists() {
+    return NetworkTablesJNI.getTopicExists(m_handle);
+  }
+
+  /**
+   * Gets the current value of a property (as a JSON string).
+   *
+   * @param name property name
+   * @return JSON string; "null" if the property does not exist.
+   */
+  public String getProperty(String name) {
+    return NetworkTablesJNI.getTopicProperty(m_handle, name);
+  }
+
+  /**
+   * Sets a property value.
+   *
+   * @param name property name
+   * @param value property value (JSON string)
+   * @throws IllegalArgumentException if properties is not parseable as JSON
+   */
+  public void setProperty(String name, String value) {
+    NetworkTablesJNI.setTopicProperty(m_handle, name, value);
+  }
+
+  /**
+   * Deletes a property. Has no effect if the property does not exist.
+   *
+   * @param name property name
+   */
+  public void deleteProperty(String name) {
+    NetworkTablesJNI.deleteTopicProperty(m_handle, name);
+  }
+
+  /**
+   * Gets all topic properties as a JSON object string. Each key in the object is the property name,
+   * and the corresponding value is the property value.
+   *
+   * @return JSON string
+   */
+  public String getProperties() {
+    return NetworkTablesJNI.getTopicProperties(m_handle);
+  }
+
+  /**
+   * Updates multiple topic properties. Each key in the passed-in object is the name of the property
+   * to add/update, and the corresponding value is the property value to set for that property. Null
+   * values result in deletion of the corresponding property.
+   *
+   * @param properties JSON object string with keys to add/update/delete
+   * @throws IllegalArgumentException if properties is not a JSON object
+   */
+  public void setProperties(String properties) {
+    NetworkTablesJNI.setTopicProperties(m_handle, properties);
+  }
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object is not closed.
+   *
+   * @param options subscribe options
+   * @return subscriber
+   */
+  public GenericSubscriber genericSubscribe(PubSubOption... options) {
+    return genericSubscribe("", options);
+  }
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object is not closed.
+   *
+   * <p>Subscribers that do not match the published data type do not return any values. To determine
+   * if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param options subscribe options
+   * @return subscriber
+   */
+  public GenericSubscriber genericSubscribe(String typeString, PubSubOption... options) {
+    return new GenericEntryImpl(
+        this,
+        NetworkTablesJNI.subscribe(
+            m_handle, NetworkTableType.getFromString(typeString).getValue(), typeString, options));
+  }
+
+  /**
+   * Create a new publisher to the topic.
+   *
+   * <p>The publisher is only active as long as the returned object is not closed.
+   *
+   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
+   * publishers are typically resolved by the server on a first-come, first-served basis. Any
+   * published values that do not match the topic's data type are dropped (ignored). To determine if
+   * the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param options publish options
+   * @return publisher
+   */
+  public GenericPublisher genericPublish(String typeString, PubSubOption... options) {
+    return new GenericEntryImpl(
+        this,
+        NetworkTablesJNI.publish(
+            m_handle, NetworkTableType.getFromString(typeString).getValue(), typeString, options));
+  }
+
+  /**
+   * Create a new publisher to the topic, with type string and initial properties.
+   *
+   * <p>The publisher is only active as long as the returned object is not closed.
+   *
+   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
+   * publishers are typically resolved by the server on a first-come, first-served basis. Any
+   * published values that do not match the topic's data type are dropped (ignored). To determine if
+   * the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param properties JSON properties
+   * @param options publish options
+   * @return publisher
+   * @throws IllegalArgumentException if properties is not a JSON object
+   */
+  public GenericPublisher genericPublishEx(
+      String typeString, String properties, PubSubOption... options) {
+    return new GenericEntryImpl(
+        this,
+        NetworkTablesJNI.publishEx(
+            m_handle,
+            NetworkTableType.getFromString(typeString).getValue(),
+            typeString,
+            properties,
+            options));
+  }
+
+  /**
+   * Create a new generic entry for the topic.
+   *
+   * <p>Entries act as a combination of a subscriber and a weak publisher. The subscriber is active
+   * as long as the entry is not closed. The publisher is created when the entry is first written
+   * to, and remains active until either unpublish() is called or the entry is closed.
+   *
+   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
+   * publishers are typically resolved by the server on a first-come, first-served basis. Any
+   * published values that do not match the topic's data type are dropped (ignored). To determine if
+   * the data type matches, use the appropriate Topic functions.
+   *
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  public GenericEntry getGenericEntry(PubSubOption... options) {
+    return getGenericEntry("", options);
+  }
+
+  /**
+   * Create a new generic entry for the topic.
+   *
+   * <p>Entries act as a combination of a subscriber and a weak publisher. The subscriber is active
+   * as long as the entry is not closed. The publisher is created when the entry is first written
+   * to, and remains active until either unpublish() is called or the entry is closed.
+   *
+   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
+   * publishers are typically resolved by the server on a first-come, first-served basis. Any
+   * published values that do not match the topic's data type are dropped (ignored). To determine if
+   * the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  public GenericEntry getGenericEntry(String typeString, PubSubOption... options) {
+    return new GenericEntryImpl(
+        this,
+        NetworkTablesJNI.getEntry(
+            m_handle, NetworkTableType.getFromString(typeString).getValue(), typeString, options));
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof Topic)) {
+      return false;
+    }
+
+    return m_handle == ((Topic) other).m_handle;
+  }
+
+  @Override
+  public int hashCode() {
+    return m_handle;
+  }
+
+  protected NetworkTableInstance m_inst;
+  protected int m_handle;
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/TopicInfo.java b/ntcore/src/main/java/edu/wpi/first/networktables/TopicInfo.java
new file mode 100644
index 0000000..abd8c2a
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/TopicInfo.java
@@ -0,0 +1,65 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables topic information. */
+@SuppressWarnings("MemberName")
+public final class TopicInfo {
+  /** Topic handle. */
+  public final int topic;
+
+  /** Topic name. */
+  public final String name;
+
+  /** Topic type. */
+  public final NetworkTableType type;
+
+  /** Topic type string. */
+  public final String typeStr;
+
+  /**
+   * Constructor. This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param handle Topic handle
+   * @param name Name
+   * @param type Type (integer version of {@link NetworkTableType})
+   * @param typeStr Type string
+   */
+  public TopicInfo(NetworkTableInstance inst, int handle, String name, int type, String typeStr) {
+    this.m_inst = inst;
+    this.topic = handle;
+    this.name = name;
+    this.type = NetworkTableType.getFromInt(type);
+    this.typeStr = typeStr;
+  }
+
+  /* Network table instance. */
+  private final NetworkTableInstance m_inst;
+
+  /* Cached topic object. */
+  private Topic m_topicObject;
+
+  /**
+   * Get the instance.
+   *
+   * @return Instance
+   */
+  public NetworkTableInstance getInstance() {
+    return m_inst;
+  }
+
+  /**
+   * Get the topic as an object.
+   *
+   * @return Topic
+   */
+  public Topic getTopic() {
+    if (m_topicObject == null) {
+      m_topicObject = new Topic(m_inst, topic);
+    }
+    return m_topicObject;
+  }
+}
diff --git a/ntcore/src/main/java/edu/wpi/first/networktables/ValueEventData.java b/ntcore/src/main/java/edu/wpi/first/networktables/ValueEventData.java
new file mode 100644
index 0000000..511bb66
--- /dev/null
+++ b/ntcore/src/main/java/edu/wpi/first/networktables/ValueEventData.java
@@ -0,0 +1,54 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+/** NetworkTables value event data. */
+@SuppressWarnings("MemberName")
+public final class ValueEventData {
+  /** Topic handle. Topic.getHandle() can be used to map this to the corresponding Topic object. */
+  public final int topic;
+
+  /**
+   * Subscriber/entry handle. Subscriber.getHandle() or entry.getHandle() can be used to map this to
+   * the corresponding Subscriber or Entry object.
+   */
+  public final int subentry;
+
+  /** The new value. */
+  public final NetworkTableValue value;
+
+  /**
+   * Constructor. This should generally only be used internally to NetworkTables.
+   *
+   * @param inst Instance
+   * @param topic Topic handle
+   * @param subentry Subscriber/entry handle
+   * @param value The new value
+   */
+  public ValueEventData(
+      NetworkTableInstance inst, int topic, int subentry, NetworkTableValue value) {
+    this.m_inst = inst;
+    this.topic = topic;
+    this.subentry = subentry;
+    this.value = value;
+  }
+
+  /* Cached topic object. */
+  private Topic m_topicObject;
+
+  private final NetworkTableInstance m_inst;
+
+  /**
+   * Get the topic as an object.
+   *
+   * @return Topic for this notification.
+   */
+  public Topic getTopic() {
+    if (m_topicObject == null) {
+      m_topicObject = new Topic(m_inst, topic);
+    }
+    return m_topicObject;
+  }
+}
diff --git a/ntcore/src/main/native/cpp/ConnectionList.cpp b/ntcore/src/main/native/cpp/ConnectionList.cpp
new file mode 100644
index 0000000..4781f52
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ConnectionList.cpp
@@ -0,0 +1,126 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ConnectionList.h"
+
+#include <wpi/SmallVector.h>
+#include <wpi/json_serializer.h>
+#include <wpi/raw_ostream.h>
+
+#include "IListenerStorage.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+using namespace nt;
+
+static std::string ConnInfoToJson(bool connected, const ConnectionInfo& info) {
+  std::string str;
+  wpi::raw_string_ostream os{str};
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"connected\":" << (connected ? "true" : "false");
+  os << ",\"remote_id\":\"";
+  s.dump_escaped(info.remote_id, false);
+  os << "\",\"remote_ip\":\"";
+  s.dump_escaped(info.remote_ip, false);
+  os << "\",\"remote_port\":";
+  s.dump_integer(static_cast<uint64_t>(info.remote_port));
+  os << ",\"protocol_version\":";
+  s.dump_integer(static_cast<uint64_t>(info.protocol_version));
+  os << "}";
+  os.flush();
+  return str;
+}
+
+ConnectionList::ConnectionList(int inst, IListenerStorage& listenerStorage)
+    : m_inst{inst}, m_listenerStorage{listenerStorage} {}
+
+ConnectionList::~ConnectionList() = default;
+
+int ConnectionList::AddConnection(const ConnectionInfo& info) {
+  std::scoped_lock lock{m_mutex};
+  m_connected = true;
+  m_listenerStorage.Notify({}, NT_EVENT_CONNECTED, &info);
+  if (!m_dataloggers.empty()) {
+    auto now = Now();
+    for (auto&& datalogger : m_dataloggers) {
+      datalogger->entry.Append(ConnInfoToJson(true, info), now);
+    }
+  }
+  return m_connections.emplace_back(info);
+}
+
+void ConnectionList::RemoveConnection(int handle) {
+  std::scoped_lock lock{m_mutex};
+  auto val = m_connections.erase(handle);
+  if (m_connections.empty()) {
+    m_connected = false;
+  }
+  if (val) {
+    m_listenerStorage.Notify({}, NT_EVENT_DISCONNECTED, &(*val));
+    if (!m_dataloggers.empty()) {
+      auto now = Now();
+      for (auto&& datalogger : m_dataloggers) {
+        datalogger->entry.Append(ConnInfoToJson(false, *val), now);
+      }
+    }
+  }
+}
+
+void ConnectionList::ClearConnections() {
+  std::scoped_lock lock{m_mutex};
+  m_connected = false;
+  for (auto&& conn : m_connections) {
+    m_listenerStorage.Notify({}, NT_EVENT_DISCONNECTED, &(*conn));
+  }
+  m_connections.clear();
+}
+
+std::vector<ConnectionInfo> ConnectionList::GetConnections() const {
+  std::scoped_lock lock{m_mutex};
+  std::vector<ConnectionInfo> info;
+  info.reserve(m_connections.size());
+  for (auto&& conn : m_connections) {
+    info.emplace_back(*conn);
+  }
+  return info;
+}
+
+bool ConnectionList::IsConnected() const {
+  return m_connected;
+}
+
+void ConnectionList::AddListener(NT_Listener listener, unsigned int eventMask) {
+  std::scoped_lock lock{m_mutex};
+  eventMask &= (NT_EVENT_CONNECTION | NT_EVENT_IMMEDIATE);
+  m_listenerStorage.Activate(listener, eventMask);
+  if ((eventMask & (NT_EVENT_CONNECTED | NT_EVENT_IMMEDIATE)) ==
+          (NT_EVENT_CONNECTED | NT_EVENT_IMMEDIATE) &&
+      !m_connections.empty()) {
+    wpi::SmallVector<const ConnectionInfo*, 16> infos;
+    infos.reserve(m_connections.size());
+    for (auto&& conn : m_connections) {
+      infos.emplace_back(&(*conn));
+    }
+    m_listenerStorage.Notify({&listener, 1},
+                             NT_EVENT_CONNECTED | NT_EVENT_IMMEDIATE, infos);
+  }
+}
+
+NT_ConnectionDataLogger ConnectionList::StartDataLog(wpi::log::DataLog& log,
+                                                     std::string_view name) {
+  std::scoped_lock lock{m_mutex};
+  auto now = Now();
+  auto datalogger = m_dataloggers.Add(m_inst, log, name, now);
+  for (auto&& conn : m_connections) {
+    datalogger->entry.Append(ConnInfoToJson(true, *conn), now);
+  }
+  return datalogger->handle;
+}
+
+void ConnectionList::StopDataLog(NT_ConnectionDataLogger logger) {
+  std::scoped_lock lock{m_mutex};
+  if (auto datalogger = m_dataloggers.Remove(logger)) {
+    datalogger->entry.Finish(Now());
+  }
+}
diff --git a/ntcore/src/main/native/cpp/ConnectionList.h b/ntcore/src/main/native/cpp/ConnectionList.h
new file mode 100644
index 0000000..c46266d
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ConnectionList.h
@@ -0,0 +1,74 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <optional>
+#include <string_view>
+#include <vector>
+
+#include <wpi/DataLog.h>
+#include <wpi/UidVector.h>
+#include <wpi/mutex.h>
+
+#include "Handle.h"
+#include "HandleMap.h"
+#include "IConnectionList.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IListenerStorage;
+
+class ConnectionList final : public IConnectionList {
+ public:
+  ConnectionList(int inst, IListenerStorage& listenerStorage);
+  ~ConnectionList() final;
+
+  // IConnectionList interface
+  int AddConnection(const ConnectionInfo& info) final;
+  void RemoveConnection(int handle) final;
+  void ClearConnections() final;
+
+  // user-facing functions
+  std::vector<ConnectionInfo> GetConnections() const final;
+  bool IsConnected() const final;
+
+  void AddListener(NT_Listener listener, unsigned int eventMask);
+
+  NT_ConnectionDataLogger StartDataLog(wpi::log::DataLog& log,
+                                       std::string_view name);
+  void StopDataLog(NT_ConnectionDataLogger logger);
+
+ private:
+  int m_inst;
+  IListenerStorage& m_listenerStorage;
+  mutable wpi::mutex m_mutex;
+
+  // shared with user (must be atomic or mutex-protected)
+  std::atomic_bool m_connected{false};
+  wpi::UidVector<std::optional<ConnectionInfo>, 8> m_connections;
+
+  struct DataLoggerData {
+    static constexpr auto kType = Handle::kConnectionDataLogger;
+
+    DataLoggerData(NT_ConnectionDataLogger handle, wpi::log::DataLog& log,
+                   std::string_view name, int64_t time)
+        : handle{handle},
+          entry{log, name,
+                "{\"schema\":\"NTConnectionInfo\",\"source\":\"NT\"}", "json",
+                time} {}
+
+    NT_ConnectionDataLogger handle;
+    wpi::log::StringLogEntry entry;
+  };
+  HandleMap<DataLoggerData, 8> m_dataloggers;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/ConnectionNotifier.cpp b/ntcore/src/main/native/cpp/ConnectionNotifier.cpp
deleted file mode 100644
index 60e7303..0000000
--- a/ntcore/src/main/native/cpp/ConnectionNotifier.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index fab4733..0000000
--- a/ntcore/src/main/native/cpp/ConnectionNotifier.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_CONNECTIONNOTIFIER_H_
-#define NTCORE_CONNECTIONNOTIFIER_H_
-
-#include <utility>
-
-#include <wpi/CallbackManager.h>
-
-#include "Handle.h"
-#include "IConnectionNotifier.h"
-#include "ntcore_cpp.h"
-
-namespace nt {
-
-namespace impl {
-
-class ConnectionNotifierThread
-    : public wpi::CallbackThread<ConnectionNotifierThread,
-                                 ConnectionNotification> {
- public:
-  ConnectionNotifierThread(std::function<void()> on_start,
-                           std::function<void()> on_exit, int inst)
-      : CallbackThread(std::move(on_start), std::move(on_exit)), 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 wpi::CallbackManager<ConnectionNotifier,
-                                  impl::ConnectionNotifierThread> {
-  friend class ConnectionNotifierTest;
-  friend class wpi::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
deleted file mode 100644
index 84d9698..0000000
--- a/ntcore/src/main/native/cpp/Dispatcher.cpp
+++ /dev/null
@@ -1,711 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "Dispatcher.h"
-
-#include <algorithm>
-#include <iterator>
-
-#include <wpi/SmallVector.h>
-#include <wpi/StringExtras.h>
-#include <wpi/TCPAcceptor.h>
-#include <wpi/TCPConnector.h>
-#include <wpi/timestamp.h>
-
-#include "IConnectionNotifier.h"
-#include "IStorage.h"
-#include "Log.h"
-#include "NetworkConnection.h"
-
-using namespace nt;
-
-void Dispatcher::StartServer(std::string_view persist_filename,
-                             const char* listen_address, unsigned int port) {
-  std::string listen_address_copy(wpi::trim(listen_address));
-  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(wpi::trim(server_name));
-  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(
-    wpi::span<const std::pair<std::string_view, unsigned int>> servers) {
-  wpi::SmallVector<std::pair<std::string, int>, 16> servers_copy;
-  for (const auto& server : servers) {
-    servers_copy.emplace_back(std::string{wpi::trim(server.first)},
-                              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<std::string_view, unsigned int> servers[5];
-
-  // 10.te.am.2
-  auto fixed = fmt::format("10.{}.{}.2", static_cast<int>(team / 100),
-                           static_cast<int>(team % 100));
-  servers[0] = {fixed, port};
-
-  // 172.22.11.2
-  servers[1] = {"172.22.11.2", port};
-
-  // roboRIO-<team>-FRC.local
-  auto mdns = fmt::format("roboRIO-{}-FRC.local", team);
-  servers[2] = {mdns, port};
-
-  // roboRIO-<team>-FRC.lan
-  auto mdns_lan = fmt::format("roboRIO-{}-FRC.lan", team);
-  servers[3] = {mdns_lan, port};
-
-  // roboRIO-<team>-FRC.frc-field.local
-  auto field_local = fmt::format("roboRIO-{}-FRC.frc-field.local", team);
-  servers[4] = {field_local, port};
-
-  SetServer(servers);
-}
-
-void Dispatcher::SetServerOverride(const char* server_name, unsigned int port) {
-  std::string server_name_copy(wpi::trim(server_name));
-  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(
-    std::string_view 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;
-  m_server_acceptor = std::move(acceptor);
-
-  // Load persistent file.  Ignore errors, but pass along warnings.
-  if (!persist_filename.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 5 ms or slower than 1 second
-  if (interval < 0.005) {
-    interval = 0.005;
-  } else if (interval > 1.0) {
-    interval = 1.0;
-  }
-  m_update_rate = static_cast<unsigned int>(interval * 1000);
-}
-
-void DispatcherBase::SetIdentity(std::string_view name) {
-  std::scoped_lock lock(m_user_mutex);
-  m_identity = name;
-}
-
-void DispatcherBase::Flush() {
-  auto now = wpi::Now();
-  {
-    std::scoped_lock lock(m_flush_mutex);
-    // don't allow flushes more often than every 5 ms
-    if ((now - m_last_flush) < 5000) {
-      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;
-  }
-
-  if (m_networkMode == NT_NET_MODE_LOCAL) {
-    return true;
-  }
-
-  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 {} connections", m_connections.size());
-        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 {} port {}", stream->getPeerIP(),
-           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),   // NOLINT
-        std::bind(&IStorage::GetMessageEntryType, &m_storage, _1));  // NOLINT
-    conn->set_process_incoming(
-        std::bind(&IStorage::ProcessIncoming, &m_storage, _1, _2,  // NOLINT
-                  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),   // NOLINT
-        std::bind(&IStorage::GetMessageEntryType, &m_storage, _1));  // NOLINT
-    conn->set_process_incoming(
-        std::bind(&IStorage::ProcessIncoming, &m_storage, _1, _2,  // NOLINT
-                  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::span<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");
-  auto msg = Message::ClientHello(self_id);
-  send_msgs(wpi::span(&msg, 1));
-
-  // wait for response
-  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={} id={} seq_num={}", msg->str(), msg->id(),
-           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 ({}) other than entry assignment during "
-          "initial handshake",
-          msg->type());
-      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 {} port {}", conn.stream().getPeerIP(),
-       conn.stream().getPeerPort());
-  return true;
-}
-
-bool DispatcherBase::ServerHandshake(
-    NetworkConnection& conn, std::function<std::shared_ptr<Message>()> get_msg,
-    std::function<void(wpi::span<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");
-    auto toSend = Message::ProtoUnsup();
-    send_msgs(wpi::span(&toSend, 1));
-    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 ({}) other than entry assignment during "
-            "initial handshake",
-            msg->type());
-        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: {} port {}", conn.stream().getPeerIP(),
-       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
deleted file mode 100644
index 51b8ec7..0000000
--- a/ntcore/src/main/native/cpp/Dispatcher.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_DISPATCHER_H_
-#define NTCORE_DISPATCHER_H_
-
-#include <atomic>
-#include <functional>
-#include <memory>
-#include <string>
-#include <string_view>
-#include <thread>
-#include <utility>
-#include <vector>
-
-#include <wpi/condition_variable.h>
-#include <wpi/mutex.h>
-#include <wpi/span.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:
-  using Connector = std::function<std::unique_ptr<wpi::NetworkStream>()>;
-
-  DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
-                 wpi::Logger& logger);
-  ~DispatcherBase() override;
-
-  unsigned int GetNetworkMode() const;
-  void StartLocal();
-  void StartServer(std::string_view persist_filename,
-                   std::unique_ptr<wpi::NetworkAcceptor> acceptor);
-  void StartClient();
-  void Stop();
-  void SetUpdateRate(double interval);
-  void SetIdentity(std::string_view 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::span<std::shared_ptr<Message>>)> send_msgs);
-  bool ServerHandshake(
-      NetworkConnection& conn,
-      std::function<std::shared_ptr<Message>()> get_msg,
-      std::function<void(wpi::span<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;
-  uint64_t m_last_flush = 0;
-  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(std::string_view persist_filename,
-                   const char* listen_address, unsigned int port);
-
-  void SetServer(const char* server_name, unsigned int port);
-  void SetServer(
-      wpi::span<const std::pair<std::string_view, 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
deleted file mode 100644
index 9ed1850..0000000
--- a/ntcore/src/main/native/cpp/DsClient.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "DsClient.h"
-
-#include <wpi/SmallString.h>
-#include <wpi/StringExtras.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() override;
-
-  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 == std::string_view::npos) {
-        continue;  // could not find?
-      }
-      pos += 9;
-      pos = json.find(':', pos);
-      if (pos == std::string_view::npos) {
-        continue;  // could not find?
-      }
-      size_t endpos = json.find_first_not_of("0123456789", pos + 1);
-      DEBUG3("found robotIP={}", wpi::slice(json, pos + 1, endpos));
-
-      // Parse into number
-      unsigned int ip = 0;
-      if (auto v = wpi::parse_integer<unsigned int>(
-              wpi::slice(json, pos + 1, endpos), 10)) {
-        ip = v.value();
-      } else {
-        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
-      auto newip = fmt::format("{}.{}.{}.{}", (ip >> 24) & 0xff,
-                               (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
-      INFO("client: DS overriding server IP to {}", newip);
-      m_dispatcher.SetServerOverride(newip.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
deleted file mode 100644
index 73fc3d3..0000000
--- a/ntcore/src/main/native/cpp/DsClient.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 6f251a3..0000000
--- a/ntcore/src/main/native/cpp/EntryNotifier.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "EntryNotifier.h"
-
-#include <wpi/StringExtras.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::starts_with(data.name, listener.prefix)) {
-    return false;
-  }
-
-  return true;
-}
-
-unsigned int EntryNotifier::Add(
-    std::function<void(const EntryNotification& event)> callback,
-    std::string_view 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,
-                                      std::string_view 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, std::string_view 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 '{}' (local={}), flags={}", name, local_id, 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
deleted file mode 100644
index bbe2172..0000000
--- a/ntcore/src/main/native/cpp/EntryNotifier.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_ENTRYNOTIFIER_H_
-#define NTCORE_ENTRYNOTIFIER_H_
-
-#include <atomic>
-#include <memory>
-#include <string>
-#include <string_view>
-#include <utility>
-
-#include <wpi/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 wpi::CallbackListenerData<
-          std::function<void(const EntryNotification& event)>> {
-  EntryListenerData() = default;
-  EntryListenerData(
-      std::function<void(const EntryNotification& event)> callback_,
-      std::string_view prefix_, unsigned int flags_)
-      : CallbackListenerData(callback_), prefix(prefix_), flags(flags_) {}
-  EntryListenerData(
-      std::function<void(const EntryNotification& event)> callback_,
-      NT_Entry entry_, unsigned int flags_)
-      : CallbackListenerData(callback_), entry(entry_), flags(flags_) {}
-  EntryListenerData(unsigned int poller_uid_, std::string_view prefix_,
-                    unsigned int flags_)
-      : CallbackListenerData(poller_uid_), prefix(prefix_), flags(flags_) {}
-  EntryListenerData(unsigned int poller_uid_, NT_Entry entry_,
-                    unsigned int flags_)
-      : CallbackListenerData(poller_uid_), entry(entry_), flags(flags_) {}
-
-  std::string prefix;
-  NT_Entry entry = 0;
-  unsigned int flags;
-};
-
-class EntryNotifierThread
-    : public wpi::CallbackThread<EntryNotifierThread, EntryNotification,
-                                 EntryListenerData> {
- public:
-  EntryNotifierThread(std::function<void()> on_start,
-                      std::function<void()> on_exit, int inst)
-      : CallbackThread(std::move(on_start), std::move(on_exit)), 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 wpi::CallbackManager<EntryNotifier, impl::EntryNotifierThread> {
-  friend class EntryNotifierTest;
-  friend class wpi::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,
-                   std::string_view 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, std::string_view 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, std::string_view 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
index df12381..0eb9041 100644
--- a/ntcore/src/main/native/cpp/Handle.h
+++ b/ntcore/src/main/native/cpp/Handle.h
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_HANDLE_H_
-#define NTCORE_HANDLE_H_
+#pragma once
 
 #include <wpi/Synchronization.h>
 
@@ -19,17 +18,19 @@
 class Handle {
  public:
   enum Type {
-    kConnectionListener = wpi::kHandleTypeNTBase,
-    kConnectionListenerPoller,
+    kListener = wpi::kHandleTypeNTBase,
+    kListenerPoller,
     kEntry,
-    kEntryListener,
-    kEntryListenerPoller,
     kInstance,
-    kLogger,
-    kLoggerPoller,
-    kRpcCall,
-    kRpcCallPoller
+    kDataLogger,
+    kConnectionDataLogger,
+    kMultiSubscriber,
+    kTopic,
+    kSubscriber,
+    kPublisher,
+    kTypeMax
   };
+  static_assert(kTypeMax <= wpi::kHandleTypeHALBase);
   enum { kIndexMax = 0xfffff };
 
   explicit Handle(NT_Handle handle) : m_handle(handle) {}
@@ -46,7 +47,9 @@
                (index & 0xfffff);
   }
 
-  int GetIndex() const { return static_cast<int>(m_handle) & 0xfffff; }
+  unsigned int GetIndex() const {
+    return static_cast<unsigned int>(m_handle) & 0xfffff;
+  }
   Type GetType() const {
     return static_cast<Type>((static_cast<int>(m_handle) >> 24) & 0x7f);
   }
@@ -60,5 +63,3 @@
 };
 
 }  // namespace nt
-
-#endif  // NTCORE_HANDLE_H_
diff --git a/ntcore/src/main/native/cpp/HandleMap.h b/ntcore/src/main/native/cpp/HandleMap.h
new file mode 100644
index 0000000..03e73f9
--- /dev/null
+++ b/ntcore/src/main/native/cpp/HandleMap.h
@@ -0,0 +1,54 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <memory>
+#include <utility>
+
+#include <wpi/UidVector.h>
+
+#include "Handle.h"
+
+namespace nt {
+
+// Utility wrapper class for our UidVectors
+template <typename T, size_t Size>
+class HandleMap : public wpi::UidVector<std::unique_ptr<T>, Size> {
+ public:
+  template <typename... Args>
+  T* Add(int inst, Args&&... args) {
+    auto i = this->emplace_back();
+    auto& it = (*this)[i];
+    it = std::make_unique<T>(Handle(inst, i, T::kType),
+                             std::forward<Args>(args)...);
+    return it.get();
+  }
+
+  std::unique_ptr<T> Remove(NT_Handle handle) {
+    Handle h{handle};
+    if (!h.IsType(T::kType)) {
+      return {};
+    }
+    unsigned int i = h.GetIndex();
+    if (i >= this->size()) {
+      return {};
+    }
+    return this->erase(i);
+  }
+
+  T* Get(NT_Handle handle) {
+    Handle h{handle};
+    if (!h.IsType(T::kType)) {
+      return {};
+    }
+    unsigned int i = h.GetIndex();
+    if (i >= this->size()) {
+      return {};
+    }
+    return (*this)[i].get();
+  }
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/IConnectionList.h b/ntcore/src/main/native/cpp/IConnectionList.h
new file mode 100644
index 0000000..a4a59e3
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IConnectionList.h
@@ -0,0 +1,24 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <vector>
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IConnectionList {
+ public:
+  virtual ~IConnectionList() = default;
+
+  virtual int AddConnection(const ConnectionInfo& info) = 0;
+  virtual void RemoveConnection(int handle) = 0;
+  virtual void ClearConnections() = 0;
+  virtual std::vector<ConnectionInfo> GetConnections() const = 0;
+  virtual bool IsConnected() const = 0;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/IConnectionNotifier.h b/ntcore/src/main/native/cpp/IConnectionNotifier.h
deleted file mode 100644
index 5983866..0000000
--- a/ntcore/src/main/native/cpp/IConnectionNotifier.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 4cf8a5f..0000000
--- a/ntcore/src/main/native/cpp/IDispatcher.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index b3f91b2..0000000
--- a/ntcore/src/main/native/cpp/IEntryNotifier.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_IENTRYNOTIFIER_H_
-#define NTCORE_IENTRYNOTIFIER_H_
-
-#include <climits>
-#include <memory>
-#include <string_view>
-
-#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,
-      std::string_view 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,
-                                 std::string_view 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, std::string_view 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/IListenerStorage.h b/ntcore/src/main/native/cpp/IListenerStorage.h
new file mode 100644
index 0000000..82d7432
--- /dev/null
+++ b/ntcore/src/main/native/cpp/IListenerStorage.h
@@ -0,0 +1,52 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <span>
+#include <string_view>
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class IListenerStorage {
+ public:
+  // Return false if event should not be issued (final check).
+  // This is called only during Notify() processing.
+  using FinishEventFunc = std::function<bool(unsigned int mask, Event* event)>;
+
+  virtual ~IListenerStorage() = default;
+
+  virtual void Activate(NT_Listener listener, unsigned int mask,
+                        FinishEventFunc finishEvent = {}) = 0;
+
+  // If handles is not empty, notifies ONLY those listeners
+  virtual void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+                      std::span<ConnectionInfo const* const> infos) = 0;
+  virtual void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+                      std::span<const TopicInfo> infos) = 0;
+  virtual void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+                      NT_Topic topic, NT_Handle subentry,
+                      const Value& value) = 0;
+  virtual void Notify(unsigned int flags, unsigned int level,
+                      std::string_view filename, unsigned int line,
+                      std::string_view message) = 0;
+  virtual void NotifyTimeSync(std::span<const NT_Listener> handles,
+                              unsigned int flags, int64_t serverTimeOffset,
+                              int64_t rtt2, bool valid) = 0;
+
+  void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+              const ConnectionInfo* info) {
+    Notify(handles, flags, {&info, 1});
+  }
+  void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+              const TopicInfo& info) {
+    Notify(handles, flags, {&info, 1});
+  }
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/INetworkClient.h b/ntcore/src/main/native/cpp/INetworkClient.h
new file mode 100644
index 0000000..986f43a
--- /dev/null
+++ b/ntcore/src/main/native/cpp/INetworkClient.h
@@ -0,0 +1,29 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string>
+#include <utility>
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class INetworkClient {
+ public:
+  virtual ~INetworkClient() = default;
+
+  virtual void SetServers(
+      std::span<const std::pair<std::string, unsigned int>> servers) = 0;
+
+  virtual void StartDSClient(unsigned int port) = 0;
+  virtual void StopDSClient() = 0;
+
+  virtual void FlushLocal() = 0;
+  virtual void Flush() = 0;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/INetworkConnection.h b/ntcore/src/main/native/cpp/INetworkConnection.h
deleted file mode 100644
index 94e9bb1..0000000
--- a/ntcore/src/main/native/cpp/INetworkConnection.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index aa16084..0000000
--- a/ntcore/src/main/native/cpp/IRpcServer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_IRPCSERVER_H_
-#define NTCORE_IRPCSERVER_H_
-
-#include <memory>
-#include <string_view>
-
-#include "Message.h"
-#include "ntcore_cpp.h"
-
-namespace nt {
-
-class IRpcServer {
- public:
-  using SendResponseFunc = std::function<void(std::string_view result)>;
-
-  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,
-                          std::string_view name, std::string_view 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
deleted file mode 100644
index 795d032..0000000
--- a/ntcore/src/main/native/cpp/IStorage.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_ISTORAGE_H_
-#define NTCORE_ISTORAGE_H_
-
-#include <functional>
-#include <memory>
-#include <string_view>
-#include <vector>
-
-#include <wpi/span.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::span<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(std::string_view filename,
-                                     bool periodic) const = 0;
-  virtual const char* LoadPersistent(
-      std::string_view 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
index 8d59a0b..b34db73 100644
--- a/ntcore/src/main/native/cpp/InstanceImpl.cpp
+++ b/ntcore/src/main/native/cpp/InstanceImpl.cpp
@@ -13,22 +13,16 @@
 using namespace std::placeholders;
 
 InstanceImpl::InstanceImpl(int inst)
-    : logger_impl(inst),
-      logger(
-          std::bind(&LoggerImpl::Log, &logger_impl, _1, _2, _3, _4)),  // NOLINT
-      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) {
+    : listenerStorage{inst},
+      logger_impl{listenerStorage},
+      logger{
+          std::bind(&LoggerImpl::Log, &logger_impl, _1, _2, _3, _4)},  // NOLINT
+      connectionList{inst, listenerStorage},
+      localStorage{inst, listenerStorage, logger},
+      m_inst{inst} {
   logger.set_min_level(logger_impl.GetMinLevel());
 }
 
-InstanceImpl::~InstanceImpl() {
-  logger.SetLogger(nullptr);
-}
-
 InstanceImpl* InstanceImpl::GetDefault() {
   return Get(GetDefaultIndex());
 }
@@ -83,7 +77,164 @@
     return;
   }
 
-  InstanceImpl* ptr = nullptr;
-  s_instances[inst].exchange(ptr);
-  delete ptr;
+  delete s_instances[inst].exchange(nullptr);
+}
+
+void InstanceImpl::StartLocal() {
+  std::scoped_lock lock{m_mutex};
+  if (networkMode != NT_NET_MODE_NONE) {
+    return;
+  }
+  networkMode = NT_NET_MODE_LOCAL;
+}
+
+void InstanceImpl::StopLocal() {
+  std::scoped_lock lock{m_mutex};
+  if ((networkMode & NT_NET_MODE_LOCAL) == 0) {
+    return;
+  }
+  networkMode = NT_NET_MODE_NONE;
+}
+
+void InstanceImpl::StartServer(std::string_view persistFilename,
+                               std::string_view listenAddress,
+                               unsigned int port3, unsigned int port4) {
+  std::scoped_lock lock{m_mutex};
+  if (networkMode != NT_NET_MODE_NONE) {
+    return;
+  }
+  m_networkServer = std::make_shared<NetworkServer>(
+      persistFilename, listenAddress, port3, port4, localStorage,
+      connectionList, logger, [this] {
+        std::scoped_lock lock{m_mutex};
+        networkMode &= ~NT_NET_MODE_STARTING;
+      });
+  networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_STARTING;
+  listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, 0, 0, true);
+  m_serverTimeOffset = 0;
+  m_rtt2 = 0;
+}
+
+void InstanceImpl::StopServer() {
+  std::shared_ptr<NetworkServer> server;
+  {
+    std::scoped_lock lock{m_mutex};
+    if ((networkMode & NT_NET_MODE_SERVER) == 0) {
+      return;
+    }
+    server = std::move(m_networkServer);
+    networkMode = NT_NET_MODE_NONE;
+    listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, 0, 0, false);
+    m_serverTimeOffset.reset();
+    m_rtt2 = 0;
+  }
+}
+
+void InstanceImpl::StartClient3(std::string_view identity) {
+  std::scoped_lock lock{m_mutex};
+  if (networkMode != NT_NET_MODE_NONE) {
+    return;
+  }
+  m_networkClient = std::make_shared<NetworkClient3>(
+      m_inst, identity, localStorage, connectionList, logger);
+  if (!m_servers.empty()) {
+    m_networkClient->SetServers(m_servers);
+  }
+  networkMode = NT_NET_MODE_CLIENT3;
+}
+
+void InstanceImpl::StartClient4(std::string_view identity) {
+  std::scoped_lock lock{m_mutex};
+  if (networkMode != NT_NET_MODE_NONE) {
+    return;
+  }
+  m_networkClient = std::make_shared<NetworkClient>(
+      m_inst, identity, localStorage, connectionList, logger,
+      [this](int64_t serverTimeOffset, int64_t rtt2, bool valid) {
+        std::scoped_lock lock{m_mutex};
+        listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, serverTimeOffset,
+                                       rtt2, valid);
+        if (valid) {
+          m_serverTimeOffset = serverTimeOffset;
+          m_rtt2 = rtt2;
+        } else {
+          m_serverTimeOffset.reset();
+          m_rtt2 = 0;
+        }
+      });
+  if (!m_servers.empty()) {
+    m_networkClient->SetServers(m_servers);
+  }
+  networkMode = NT_NET_MODE_CLIENT4;
+}
+
+void InstanceImpl::StopClient() {
+  std::shared_ptr<INetworkClient> client;
+  {
+    std::scoped_lock lock{m_mutex};
+    if ((networkMode & (NT_NET_MODE_CLIENT3 | NT_NET_MODE_CLIENT4)) == 0) {
+      return;
+    }
+    client = std::move(m_networkClient);
+    networkMode = NT_NET_MODE_NONE;
+  }
+  client.reset();
+  {
+    std::scoped_lock lock{m_mutex};
+    listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, 0, 0, false);
+    m_serverTimeOffset.reset();
+    m_rtt2 = 0;
+  }
+}
+
+void InstanceImpl::SetServers(
+    std::span<const std::pair<std::string, unsigned int>> servers) {
+  std::scoped_lock lock{m_mutex};
+  m_servers = {servers.begin(), servers.end()};
+  if (m_networkClient) {
+    m_networkClient->SetServers(servers);
+  }
+}
+
+std::shared_ptr<NetworkServer> InstanceImpl::GetServer() {
+  std::scoped_lock lock{m_mutex};
+  return m_networkServer;
+}
+
+std::shared_ptr<INetworkClient> InstanceImpl::GetClient() {
+  std::scoped_lock lock{m_mutex};
+  return m_networkClient;
+}
+
+std::optional<int64_t> InstanceImpl::GetServerTimeOffset() {
+  std::scoped_lock lock{m_mutex};
+  return m_serverTimeOffset;
+}
+
+void InstanceImpl::AddTimeSyncListener(NT_Listener listener,
+                                       unsigned int eventMask) {
+  std::scoped_lock lock{m_mutex};
+  eventMask &= (NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE);
+  listenerStorage.Activate(listener, eventMask);
+  if ((eventMask & (NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE)) ==
+          (NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE) &&
+      m_serverTimeOffset) {
+    listenerStorage.NotifyTimeSync({&listener, 1},
+                                   NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE,
+                                   *m_serverTimeOffset, m_rtt2, true);
+  }
+}
+
+void InstanceImpl::Reset() {
+  std::scoped_lock lock{m_mutex};
+  m_networkServer.reset();
+  m_networkClient.reset();
+  m_servers.clear();
+  networkMode = NT_NET_MODE_NONE;
+  m_serverTimeOffset.reset();
+  m_rtt2 = 0;
+
+  listenerStorage.Reset();
+  // connectionList should have been cleared by destroying networkClient/server
+  localStorage.Reset();
 }
diff --git a/ntcore/src/main/native/cpp/InstanceImpl.h b/ntcore/src/main/native/cpp/InstanceImpl.h
index 22d94f5..a7b4742 100644
--- a/ntcore/src/main/native/cpp/InstanceImpl.h
+++ b/ntcore/src/main/native/cpp/InstanceImpl.h
@@ -2,45 +2,72 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_INSTANCEIMPL_H_
-#define NTCORE_INSTANCEIMPL_H_
+#pragma once
 
 #include <atomic>
 #include <memory>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
 
 #include <wpi/mutex.h>
 
-#include "ConnectionNotifier.h"
-#include "Dispatcher.h"
-#include "DsClient.h"
-#include "EntryNotifier.h"
+#include "ConnectionList.h"
+#include "Handle.h"
+#include "ListenerStorage.h"
+#include "LocalStorage.h"
 #include "Log.h"
 #include "LoggerImpl.h"
-#include "RpcServer.h"
-#include "Storage.h"
+#include "NetworkClient.h"
+#include "NetworkServer.h"
 
 namespace nt {
 
 class InstanceImpl {
  public:
   explicit InstanceImpl(int inst);
-  ~InstanceImpl();
 
   // Instance repository
   static InstanceImpl* GetDefault();
   static InstanceImpl* Get(int inst);
+  static InstanceImpl* GetHandle(NT_Handle handle) {
+    return Get(Handle{handle}.GetInst());
+  }
+  static InstanceImpl* GetTyped(NT_Handle handle, Handle::Type type) {
+    return Get(Handle{handle}.GetTypedInst(type));
+  }
   static int GetDefaultIndex();
   static int Alloc();
   static void Destroy(int inst);
 
+  void StartLocal();
+  void StopLocal();
+  void StartServer(std::string_view persistFilename,
+                   std::string_view listenAddress, unsigned int port3,
+                   unsigned int port4);
+  void StopServer();
+  void StartClient3(std::string_view identity);
+  void StartClient4(std::string_view identity);
+  void StopClient();
+  void SetServers(
+      std::span<const std::pair<std::string, unsigned int>> servers);
+
+  std::shared_ptr<NetworkServer> GetServer();
+  std::shared_ptr<INetworkClient> GetClient();
+
+  std::optional<int64_t> GetServerTimeOffset();
+  void AddTimeSyncListener(NT_Listener listener, unsigned int eventMask);
+
+  void Reset();
+
+  ListenerStorage listenerStorage;
   LoggerImpl logger_impl;
   wpi::Logger logger;
-  ConnectionNotifier connection_notifier;
-  EntryNotifier entry_notifier;
-  RpcServer rpc_server;
-  Storage storage;
-  Dispatcher dispatcher;
-  DsClient ds_client;
+  ConnectionList connectionList;
+  LocalStorage localStorage;
+  std::atomic<int> networkMode{NT_NET_MODE_NONE};
 
  private:
   static int AllocImpl();
@@ -49,8 +76,14 @@
   static constexpr int kNumInstances = 16;
   static std::atomic<InstanceImpl*> s_instances[kNumInstances];
   static wpi::mutex s_mutex;
+
+  wpi::mutex m_mutex;
+  std::shared_ptr<NetworkServer> m_networkServer;
+  std::shared_ptr<INetworkClient> m_networkClient;
+  std::vector<std::pair<std::string, unsigned int>> m_servers;
+  std::optional<int64_t> m_serverTimeOffset;
+  int64_t m_rtt2 = 0;
+  int m_inst;
 };
 
 }  // namespace nt
-
-#endif  // NTCORE_INSTANCEIMPL_H_
diff --git a/ntcore/src/main/native/cpp/ListenerStorage.cpp b/ntcore/src/main/native/cpp/ListenerStorage.cpp
new file mode 100644
index 0000000..fdbf03b
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ListenerStorage.cpp
@@ -0,0 +1,405 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ListenerStorage.h"
+
+#include <algorithm>
+
+#include <wpi/DenseMap.h>
+#include <wpi/SmallVector.h>
+
+#include "ntcore_c.h"
+
+using namespace nt;
+
+class ListenerStorage::Thread final : public wpi::SafeThreadEvent {
+ public:
+  explicit Thread(NT_ListenerPoller poller) : m_poller{poller} {}
+
+  void Main() final;
+
+  NT_ListenerPoller m_poller;
+  wpi::DenseMap<NT_Listener, ListenerCallback> m_callbacks;
+  wpi::Event m_waitQueueWakeup;
+  wpi::Event m_waitQueueWaiter;
+};
+
+void ListenerStorage::Thread::Main() {
+  while (m_active) {
+    WPI_Handle signaledBuf[3];
+    auto signaled = wpi::WaitForObjects(
+        {m_poller, m_stopEvent.GetHandle(), m_waitQueueWakeup.GetHandle()},
+        signaledBuf);
+    if (signaled.empty() || !m_active) {
+      return;
+    }
+    // call all the way back out to the C++ API to ensure valid handle
+    auto events = nt::ReadListenerQueue(m_poller);
+    if (!events.empty()) {
+      std::unique_lock lock{m_mutex};
+      for (auto&& event : events) {
+        auto callbackIt = m_callbacks.find(event.listener);
+        if (callbackIt != m_callbacks.end()) {
+          auto callback = callbackIt->second;
+          lock.unlock();
+          callback(event);
+          lock.lock();
+        }
+      }
+    }
+    if (std::find(signaled.begin(), signaled.end(),
+                  m_waitQueueWakeup.GetHandle()) != signaled.end()) {
+      m_waitQueueWaiter.Set();
+    }
+  }
+}
+
+ListenerStorage::ListenerStorage(int inst) : m_inst{inst} {}
+
+ListenerStorage::~ListenerStorage() = default;
+
+void ListenerStorage::Activate(NT_Listener listenerHandle, unsigned int mask,
+                               FinishEventFunc finishEvent) {
+  std::scoped_lock lock{m_mutex};
+  if (auto listener = m_listeners.Get(listenerHandle)) {
+    listener->sources.emplace_back(std::move(finishEvent), mask);
+    unsigned int deltaMask = mask & (~listener->eventMask);
+    listener->eventMask |= mask;
+
+    if ((deltaMask & NT_EVENT_CONNECTION) != 0) {
+      m_connListeners.Add(listener);
+    }
+    if ((deltaMask & NT_EVENT_TOPIC) != 0) {
+      m_topicListeners.Add(listener);
+    }
+    if ((deltaMask & NT_EVENT_VALUE_ALL) != 0) {
+      m_valueListeners.Add(listener);
+    }
+    // detect the higher log bits too; see LoggerImpl
+    if ((deltaMask & NT_EVENT_LOGMESSAGE) != 0 ||
+        (deltaMask & 0x1ff0000) != 0) {
+      m_logListeners.Add(listener);
+    }
+    if ((deltaMask & NT_EVENT_TIMESYNC) != 0) {
+      m_timeSyncListeners.Add(listener);
+    }
+  }
+}
+
+void ListenerStorage::Notify(std::span<const NT_Listener> handles,
+                             unsigned int flags,
+                             std::span<ConnectionInfo const* const> infos) {
+  if (flags == 0) {
+    return;
+  }
+  std::scoped_lock lock{m_mutex};
+
+  auto doSignal = [&](ListenerData& listener) {
+    if ((flags & listener.eventMask) != 0) {
+      for (auto&& [finishEvent, mask] : listener.sources) {
+        if ((flags & mask) != 0) {
+          for (auto&& info : infos) {
+            listener.poller->queue.emplace_back(listener.handle, flags, *info);
+            // finishEvent is never set (see ConnectionList)
+          }
+        }
+      }
+      listener.handle.Set();
+      listener.poller->handle.Set();
+    }
+  };
+
+  if (!handles.empty()) {
+    for (auto handle : handles) {
+      if (auto listener = m_listeners.Get(handle)) {
+        doSignal(*listener);
+      }
+    }
+  } else {
+    for (auto&& listener : m_connListeners) {
+      doSignal(*listener);
+    }
+  }
+}
+
+void ListenerStorage::Notify(std::span<const NT_Listener> handles,
+                             unsigned int flags,
+                             std::span<const TopicInfo> infos) {
+  if (flags == 0) {
+    return;
+  }
+  std::scoped_lock lock{m_mutex};
+
+  auto doSignal = [&](ListenerData& listener) {
+    if ((flags & listener.eventMask) != 0) {
+      int count = 0;
+      for (auto&& [finishEvent, mask] : listener.sources) {
+        if ((flags & mask) != 0) {
+          for (auto&& info : infos) {
+            listener.poller->queue.emplace_back(listener.handle, flags, info);
+            if (finishEvent &&
+                !finishEvent(mask, &listener.poller->queue.back())) {
+              listener.poller->queue.pop_back();
+            } else {
+              ++count;
+            }
+          }
+        }
+      }
+      if (count > 0) {
+        listener.handle.Set();
+        listener.poller->handle.Set();
+      }
+    }
+  };
+
+  if (!handles.empty()) {
+    for (auto handle : handles) {
+      if (auto listener = m_listeners.Get(handle)) {
+        doSignal(*listener);
+      }
+    }
+  } else {
+    for (auto&& listener : m_topicListeners) {
+      doSignal(*listener);
+    }
+  }
+}
+
+void ListenerStorage::Notify(std::span<const NT_Listener> handles,
+                             unsigned int flags, NT_Topic topic,
+                             NT_Handle subentry, const Value& value) {
+  if (flags == 0) {
+    return;
+  }
+  std::scoped_lock lock{m_mutex};
+
+  auto doSignal = [&](ListenerData& listener) {
+    if ((flags & listener.eventMask) != 0) {
+      int count = 0;
+      for (auto&& [finishEvent, mask] : listener.sources) {
+        if ((flags & mask) != 0) {
+          listener.poller->queue.emplace_back(listener.handle, flags, topic,
+                                              subentry, value);
+          if (finishEvent &&
+              !finishEvent(mask, &listener.poller->queue.back())) {
+            listener.poller->queue.pop_back();
+          } else {
+            ++count;
+          }
+        }
+      }
+      if (count > 0) {
+        listener.handle.Set();
+        listener.poller->handle.Set();
+      }
+    }
+  };
+
+  if (!handles.empty()) {
+    for (auto handle : handles) {
+      if (auto listener = m_listeners.Get(handle)) {
+        doSignal(*listener);
+      }
+    }
+  } else {
+    for (auto&& listener : m_valueListeners) {
+      doSignal(*listener);
+    }
+  }
+}
+
+void ListenerStorage::Notify(unsigned int flags, unsigned int level,
+                             std::string_view filename, unsigned int line,
+                             std::string_view message) {
+  if (flags == 0) {
+    return;
+  }
+  std::scoped_lock lock{m_mutex};
+  for (auto&& listener : m_logListeners) {
+    if ((flags & listener->eventMask) != 0) {
+      int count = 0;
+      for (auto&& [finishEvent, mask] : listener->sources) {
+        if ((flags & mask) != 0) {
+          listener->poller->queue.emplace_back(listener->handle, flags, level,
+                                               filename, line, message);
+          if (finishEvent &&
+              !finishEvent(mask, &listener->poller->queue.back())) {
+            listener->poller->queue.pop_back();
+          } else {
+            ++count;
+          }
+        }
+      }
+      if (count > 0) {
+        listener->handle.Set();
+        listener->poller->handle.Set();
+      }
+    }
+  }
+}
+
+void ListenerStorage::NotifyTimeSync(std::span<const NT_Listener> handles,
+                                     unsigned int flags,
+                                     int64_t serverTimeOffset, int64_t rtt2,
+                                     bool valid) {
+  if (flags == 0) {
+    return;
+  }
+  std::scoped_lock lock{m_mutex};
+
+  auto doSignal = [&](ListenerData& listener) {
+    if ((flags & listener.eventMask) != 0) {
+      for (auto&& [finishEvent, mask] : listener.sources) {
+        if ((flags & mask) != 0) {
+          listener.poller->queue.emplace_back(listener.handle, flags,
+                                              serverTimeOffset, rtt2, valid);
+          // finishEvent is never set (see InstanceImpl)
+        }
+      }
+      listener.handle.Set();
+      listener.poller->handle.Set();
+    }
+  };
+
+  if (!handles.empty()) {
+    for (auto handle : handles) {
+      if (auto listener = m_listeners.Get(handle)) {
+        doSignal(*listener);
+      }
+    }
+  } else {
+    for (auto&& listener : m_timeSyncListeners) {
+      doSignal(*listener);
+    }
+  }
+}
+
+NT_Listener ListenerStorage::AddListener(ListenerCallback callback) {
+  std::scoped_lock lock{m_mutex};
+  if (!m_thread) {
+    m_thread.Start(m_pollers.Add(m_inst)->handle);
+  }
+  if (auto thr = m_thread.GetThread()) {
+    auto listener = DoAddListener(thr->m_poller);
+    if (listener) {
+      thr->m_callbacks.try_emplace(listener, std::move(callback));
+    }
+    return listener;
+  } else {
+    return {};
+  }
+}
+
+NT_Listener ListenerStorage::AddListener(NT_ListenerPoller pollerHandle) {
+  std::scoped_lock lock{m_mutex};
+  return DoAddListener(pollerHandle);
+}
+
+NT_Listener ListenerStorage::DoAddListener(NT_ListenerPoller pollerHandle) {
+  if (auto poller = m_pollers.Get(pollerHandle)) {
+    return m_listeners.Add(m_inst, poller)->handle;
+  } else {
+    return {};
+  }
+}
+
+NT_ListenerPoller ListenerStorage::CreateListenerPoller() {
+  std::scoped_lock lock{m_mutex};
+  return m_pollers.Add(m_inst)->handle;
+}
+
+std::vector<std::pair<NT_Listener, unsigned int>>
+ListenerStorage::DestroyListenerPoller(NT_ListenerPoller pollerHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto poller = m_pollers.Remove(pollerHandle)) {
+    // ensure all listeners that use this poller are removed
+    wpi::SmallVector<NT_Listener, 16> toRemove;
+    for (auto&& listener : m_listeners) {
+      if (listener->poller == poller.get()) {
+        toRemove.emplace_back(listener->handle);
+      }
+    }
+    return DoRemoveListeners(toRemove);
+  } else {
+    return {};
+  }
+}
+
+std::vector<Event> ListenerStorage::ReadListenerQueue(
+    NT_ListenerPoller pollerHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto poller = m_pollers.Get(pollerHandle)) {
+    std::vector<Event> rv;
+    rv.swap(poller->queue);
+    return rv;
+  } else {
+    return {};
+  }
+}
+
+std::vector<std::pair<NT_Listener, unsigned int>>
+ListenerStorage::RemoveListener(NT_Listener listenerHandle) {
+  std::scoped_lock lock{m_mutex};
+  return DoRemoveListeners({&listenerHandle, 1});
+}
+
+bool ListenerStorage::WaitForListenerQueue(double timeout) {
+  WPI_EventHandle h;
+  {
+    std::scoped_lock lock{m_mutex};
+    if (auto thr = m_thread.GetThread()) {
+      h = thr->m_waitQueueWaiter.GetHandle();
+      thr->m_waitQueueWakeup.Set();
+    } else {
+      return false;
+    }
+  }
+  bool timedOut;
+  wpi::WaitForObject(h, timeout, &timedOut);
+  return !timedOut;
+}
+
+void ListenerStorage::Reset() {
+  std::scoped_lock lock{m_mutex};
+  m_pollers.clear();
+  m_listeners.clear();
+  m_connListeners.clear();
+  m_topicListeners.clear();
+  m_valueListeners.clear();
+  m_logListeners.clear();
+  if (m_thread) {
+    m_thread.Stop();
+  }
+}
+
+std::vector<std::pair<NT_Listener, unsigned int>>
+ListenerStorage::DoRemoveListeners(std::span<const NT_Listener> handles) {
+  std::vector<std::pair<NT_Listener, unsigned int>> rv;
+  auto thr = m_thread.GetThread();
+  for (auto handle : handles) {
+    if (auto listener = m_listeners.Remove(handle)) {
+      rv.emplace_back(handle, listener->eventMask);
+      if (thr) {
+        if (thr->m_poller == listener->poller->handle) {
+          thr->m_callbacks.erase(handle);
+        }
+      }
+      if ((listener->eventMask & NT_EVENT_CONNECTION) != 0) {
+        m_connListeners.Remove(listener.get());
+      }
+      if ((listener->eventMask & NT_EVENT_TOPIC) != 0) {
+        m_topicListeners.Remove(listener.get());
+      }
+      if ((listener->eventMask & NT_EVENT_VALUE_ALL) != 0) {
+        m_valueListeners.Remove(listener.get());
+      }
+      if ((listener->eventMask & NT_EVENT_LOGMESSAGE) != 0 ||
+          (listener->eventMask & 0x1ff0000) != 0) {
+        m_logListeners.Remove(listener.get());
+      }
+    }
+  }
+  return rv;
+}
diff --git a/ntcore/src/main/native/cpp/ListenerStorage.h b/ntcore/src/main/native/cpp/ListenerStorage.h
new file mode 100644
index 0000000..b291a12
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ListenerStorage.h
@@ -0,0 +1,116 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <span>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include <wpi/SafeThread.h>
+#include <wpi/SmallVector.h>
+#include <wpi/Synchronization.h>
+#include <wpi/mutex.h>
+
+#include "Handle.h"
+#include "HandleMap.h"
+#include "IListenerStorage.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class ListenerStorage final : public IListenerStorage {
+ public:
+  explicit ListenerStorage(int inst);
+  ListenerStorage(const ListenerStorage&) = delete;
+  ListenerStorage& operator=(const ListenerStorage&) = delete;
+  ~ListenerStorage() final;
+
+  // IListenerStorage interface
+  void Activate(NT_Listener listenerHandle, unsigned int mask,
+                FinishEventFunc finishEvent = {}) final;
+  void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+              std::span<ConnectionInfo const* const> infos) final;
+  void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+              std::span<const TopicInfo> infos) final;
+  void Notify(std::span<const NT_Listener> handles, unsigned int flags,
+              NT_Topic topic, NT_Handle subentry, const Value& value) final;
+  void Notify(unsigned int flags, unsigned int level, std::string_view filename,
+              unsigned int line, std::string_view message) final;
+  void NotifyTimeSync(std::span<const NT_Listener> handles, unsigned int flags,
+                      int64_t serverTimeOffset, int64_t rtt2, bool valid) final;
+
+  // user-facing functions
+  NT_Listener AddListener(ListenerCallback callback);
+  NT_Listener AddListener(NT_ListenerPoller pollerHandle);
+  NT_ListenerPoller CreateListenerPoller();
+
+  // returns listener handle and mask for each listener that was destroyed
+  [[nodiscard]] std::vector<std::pair<NT_Listener, unsigned int>>
+  DestroyListenerPoller(NT_ListenerPoller pollerHandle);
+
+  std::vector<Event> ReadListenerQueue(NT_ListenerPoller pollerHandle);
+
+  // returns listener handle and mask for each listener that was destroyed
+  [[nodiscard]] std::vector<std::pair<NT_Listener, unsigned int>>
+  RemoveListener(NT_Listener listenerHandle);
+
+  bool WaitForListenerQueue(double timeout);
+
+  void Reset();
+
+ private:
+  // these assume the mutex is already held
+  NT_Listener DoAddListener(NT_ListenerPoller pollerHandle);
+  std::vector<std::pair<NT_Listener, unsigned int>> DoRemoveListeners(
+      std::span<const NT_Listener> handles);
+
+  int m_inst;
+  mutable wpi::mutex m_mutex;
+
+  struct PollerData {
+    static constexpr auto kType = Handle::kListenerPoller;
+
+    explicit PollerData(NT_ListenerPoller handle) : handle{handle} {}
+
+    wpi::SignalObject<NT_ListenerPoller> handle;
+    std::vector<Event> queue;
+  };
+  HandleMap<PollerData, 8> m_pollers;
+
+  struct ListenerData {
+    static constexpr auto kType = Handle::kListener;
+
+    ListenerData(NT_Listener handle, PollerData* poller)
+        : handle{handle}, poller{poller} {}
+
+    wpi::SignalObject<NT_Listener> handle;
+    PollerData* poller;
+    wpi::SmallVector<std::pair<FinishEventFunc, unsigned int>, 2> sources;
+    unsigned int eventMask{0};
+  };
+  HandleMap<ListenerData, 8> m_listeners;
+
+  // Utility wrapper for making a set-like vector
+  template <typename T>
+  class VectorSet : public std::vector<T> {
+   public:
+    void Add(T value) { this->push_back(value); }
+    void Remove(T value) { std::erase(*this, value); }
+  };
+
+  VectorSet<ListenerData*> m_connListeners;
+  VectorSet<ListenerData*> m_topicListeners;
+  VectorSet<ListenerData*> m_valueListeners;
+  VectorSet<ListenerData*> m_logListeners;
+  VectorSet<ListenerData*> m_timeSyncListeners;
+
+  class Thread;
+  wpi::SafeThreadOwner<Thread> m_thread;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/LocalStorage.cpp b/ntcore/src/main/native/cpp/LocalStorage.cpp
new file mode 100644
index 0000000..db8e065
--- /dev/null
+++ b/ntcore/src/main/native/cpp/LocalStorage.cpp
@@ -0,0 +1,2264 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "LocalStorage.h"
+
+#include <algorithm>
+
+#include <wpi/DataLog.h>
+#include <wpi/StringExtras.h>
+#include <wpi/StringMap.h>
+#include <wpi/Synchronization.h>
+#include <wpi/UidVector.h>
+#include <wpi/circular_buffer.h>
+#include <wpi/json.h>
+
+#include "Handle.h"
+#include "HandleMap.h"
+#include "IListenerStorage.h"
+#include "Log.h"
+#include "PubSubOptions.h"
+#include "Types_internal.h"
+#include "Value_internal.h"
+#include "networktables/NetworkTableValue.h"
+#include "ntcore_c.h"
+
+using namespace nt;
+
+// maximum number of local publishers / subscribers to any given topic
+static constexpr size_t kMaxPublishers = 512;
+static constexpr size_t kMaxSubscribers = 512;
+static constexpr size_t kMaxMultiSubscribers = 512;
+static constexpr size_t kMaxListeners = 512;
+
+namespace {
+
+static constexpr bool IsSpecial(std::string_view name) {
+  return name.empty() ? false : name.front() == '$';
+}
+
+static constexpr bool PrefixMatch(std::string_view name,
+                                  std::string_view prefix, bool special) {
+  return (!special || !prefix.empty()) && wpi::starts_with(name, prefix);
+}
+
+// Utility wrapper for making a set-like vector
+template <typename T>
+class VectorSet : public std::vector<T> {
+ public:
+  void Add(T value) { this->push_back(value); }
+  void Remove(T value) { std::erase(*this, value); }
+};
+
+struct EntryData;
+struct PublisherData;
+struct SubscriberData;
+struct MultiSubscriberData;
+
+struct DataLoggerEntry {
+  DataLoggerEntry(wpi::log::DataLog& log, int entry, NT_DataLogger logger)
+      : log{&log}, entry{entry}, logger{logger} {}
+
+  static std::string MakeMetadata(std::string_view properties) {
+    return fmt::format("{{\"properties\":{},\"source\":\"NT\"}}", properties);
+  }
+
+  void Append(const Value& v);
+
+  wpi::log::DataLog* log;
+  int entry;
+  NT_DataLogger logger;
+};
+
+struct TopicData {
+  static constexpr auto kType = Handle::kTopic;
+
+  TopicData(NT_Topic handle, std::string_view name)
+      : handle{handle}, name{name}, special{IsSpecial(name)} {}
+
+  bool Exists() const { return onNetwork || !localPublishers.empty(); }
+
+  TopicInfo GetTopicInfo() const;
+
+  // invariants
+  wpi::SignalObject<NT_Topic> handle;
+  std::string name;
+  bool special;
+
+  Value lastValue;  // also stores timestamp
+  Value lastValueNetwork;
+  NT_Type type{NT_UNASSIGNED};
+  std::string typeStr;
+  unsigned int flags{0};            // for NT3 APIs
+  std::string propertiesStr{"{}"};  // cached string for GetTopicInfo() et al
+  wpi::json properties = wpi::json::object();
+  NT_Entry entry{0};  // cached entry for GetEntry()
+
+  bool onNetwork{false};  // true if there are any remote publishers
+
+  wpi::SmallVector<DataLoggerEntry, 1> datalogs;
+  NT_Type datalogType{NT_UNASSIGNED};
+
+  VectorSet<PublisherData*> localPublishers;
+  VectorSet<SubscriberData*> localSubscribers;
+  VectorSet<MultiSubscriberData*> multiSubscribers;
+  VectorSet<EntryData*> entries;
+  VectorSet<NT_Listener> listeners;
+};
+
+struct PubSubConfig : public PubSubOptionsImpl {
+  PubSubConfig() = default;
+  PubSubConfig(NT_Type type, std::string_view typeStr,
+               const PubSubOptions& options)
+      : PubSubOptionsImpl{options}, type{type}, typeStr{typeStr} {
+    prefixMatch = false;
+  }
+
+  NT_Type type{NT_UNASSIGNED};
+  std::string typeStr;
+};
+
+struct PublisherData {
+  static constexpr auto kType = Handle::kPublisher;
+
+  PublisherData(NT_Publisher handle, TopicData* topic, PubSubConfig config)
+      : handle{handle}, topic{topic}, config{std::move(config)} {}
+
+  void UpdateActive();
+
+  // invariants
+  wpi::SignalObject<NT_Publisher> handle;
+  TopicData* topic;
+  PubSubConfig config;
+
+  // whether or not the publisher should actually publish values
+  bool active{false};
+};
+
+struct SubscriberData {
+  static constexpr auto kType = Handle::kSubscriber;
+
+  SubscriberData(NT_Subscriber handle, TopicData* topic, PubSubConfig config)
+      : handle{handle},
+        topic{topic},
+        config{std::move(config)},
+        pollStorage{config.pollStorage} {}
+
+  void UpdateActive();
+
+  // invariants
+  wpi::SignalObject<NT_Subscriber> handle;
+  TopicData* topic;
+  PubSubConfig config;
+
+  // whether or not the subscriber should actually receive values
+  bool active{false};
+
+  // polling storage
+  wpi::circular_buffer<Value> pollStorage;
+
+  // value listeners
+  VectorSet<NT_Listener> valueListeners;
+};
+
+struct EntryData {
+  static constexpr auto kType = Handle::kEntry;
+
+  EntryData(NT_Entry handle, SubscriberData* subscriber)
+      : handle{handle}, topic{subscriber->topic}, subscriber{subscriber} {}
+
+  // invariants
+  wpi::SignalObject<NT_Entry> handle;
+  TopicData* topic;
+  SubscriberData* subscriber;
+
+  // the publisher (created on demand)
+  PublisherData* publisher{nullptr};
+};
+
+struct MultiSubscriberData {
+  static constexpr auto kType = Handle::kMultiSubscriber;
+
+  MultiSubscriberData(NT_MultiSubscriber handle,
+                      std::span<const std::string_view> prefixes,
+                      const PubSubOptionsImpl& options)
+      : handle{handle}, options{options} {
+    this->options.prefixMatch = true;
+    this->prefixes.reserve(prefixes.size());
+    for (auto&& prefix : prefixes) {
+      this->prefixes.emplace_back(prefix);
+    }
+  }
+
+  bool Matches(std::string_view name, bool special);
+
+  // invariants
+  wpi::SignalObject<NT_MultiSubscriber> handle;
+  std::vector<std::string> prefixes;
+  PubSubOptionsImpl options;
+
+  // value listeners
+  VectorSet<NT_Listener> valueListeners;
+};
+
+bool MultiSubscriberData::Matches(std::string_view name, bool special) {
+  for (auto&& prefix : prefixes) {
+    if (PrefixMatch(name, prefix, special)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+struct ListenerData {
+  ListenerData(NT_Listener handle, SubscriberData* subscriber,
+               unsigned int eventMask, bool subscriberOwned)
+      : handle{handle},
+        eventMask{eventMask},
+        subscriber{subscriber},
+        subscriberOwned{subscriberOwned} {}
+  ListenerData(NT_Listener handle, MultiSubscriberData* subscriber,
+               unsigned int eventMask, bool subscriberOwned)
+      : handle{handle},
+        eventMask{eventMask},
+        multiSubscriber{subscriber},
+        subscriberOwned{subscriberOwned} {}
+
+  NT_Listener handle;
+  unsigned int eventMask;
+  SubscriberData* subscriber{nullptr};
+  MultiSubscriberData* multiSubscriber{nullptr};
+  bool subscriberOwned;
+};
+
+struct DataLoggerData {
+  static constexpr auto kType = Handle::kDataLogger;
+
+  DataLoggerData(NT_DataLogger handle, wpi::log::DataLog& log,
+                 std::string_view prefix, std::string_view logPrefix)
+      : handle{handle}, log{log}, prefix{prefix}, logPrefix{logPrefix} {}
+
+  int Start(TopicData* topic, int64_t time) {
+    return log.Start(fmt::format("{}{}", logPrefix,
+                                 wpi::drop_front(topic->name, prefix.size())),
+                     topic->typeStr,
+                     DataLoggerEntry::MakeMetadata(topic->propertiesStr), time);
+  }
+
+  NT_DataLogger handle;
+  wpi::log::DataLog& log;
+  std::string prefix;
+  std::string logPrefix;
+};
+
+struct LSImpl {
+  LSImpl(int inst, IListenerStorage& listenerStorage, wpi::Logger& logger)
+      : m_inst{inst}, m_listenerStorage{listenerStorage}, m_logger{logger} {}
+
+  int m_inst;
+  IListenerStorage& m_listenerStorage;
+  wpi::Logger& m_logger;
+  net::NetworkInterface* m_network{nullptr};
+
+  // handle mappings
+  HandleMap<TopicData, 16> m_topics;
+  HandleMap<PublisherData, 16> m_publishers;
+  HandleMap<SubscriberData, 16> m_subscribers;
+  HandleMap<EntryData, 16> m_entries;
+  HandleMap<MultiSubscriberData, 16> m_multiSubscribers;
+  HandleMap<DataLoggerData, 16> m_dataloggers;
+
+  // name mappings
+  wpi::StringMap<TopicData*> m_nameTopics;
+
+  // listeners
+  wpi::DenseMap<NT_Listener, std::unique_ptr<ListenerData>> m_listeners;
+
+  // string-based listeners
+  VectorSet<ListenerData*> m_topicPrefixListeners;
+
+  // topic functions
+  void NotifyTopic(TopicData* topic, unsigned int eventFlags);
+
+  void CheckReset(TopicData* topic);
+
+  bool SetValue(TopicData* topic, const Value& value, unsigned int eventFlags,
+                bool isDuplicate, const PublisherData* publisher);
+  void NotifyValue(TopicData* topic, unsigned int eventFlags, bool isDuplicate,
+                   const PublisherData* publisher);
+
+  void SetFlags(TopicData* topic, unsigned int flags);
+  void SetPersistent(TopicData* topic, bool value);
+  void SetRetained(TopicData* topic, bool value);
+  void SetProperties(TopicData* topic, const wpi::json& update,
+                     bool sendNetwork);
+  void PropertiesUpdated(TopicData* topic, const wpi::json& update,
+                         unsigned int eventFlags, bool sendNetwork,
+                         bool updateFlags = true);
+
+  void RefreshPubSubActive(TopicData* topic, bool warnOnSubMismatch);
+
+  void NetworkAnnounce(TopicData* topic, std::string_view typeStr,
+                       const wpi::json& properties, NT_Publisher pubHandle);
+  void RemoveNetworkPublisher(TopicData* topic);
+  void NetworkPropertiesUpdate(TopicData* topic, const wpi::json& update,
+                               bool ack);
+
+  PublisherData* AddLocalPublisher(TopicData* topic,
+                                   const wpi::json& properties,
+                                   const PubSubConfig& options);
+  std::unique_ptr<PublisherData> RemoveLocalPublisher(NT_Publisher pubHandle);
+
+  SubscriberData* AddLocalSubscriber(TopicData* topic,
+                                     const PubSubConfig& options);
+  std::unique_ptr<SubscriberData> RemoveLocalSubscriber(
+      NT_Subscriber subHandle);
+
+  EntryData* AddEntry(SubscriberData* subscriber);
+  std::unique_ptr<EntryData> RemoveEntry(NT_Entry entryHandle);
+
+  MultiSubscriberData* AddMultiSubscriber(
+      std::span<const std::string_view> prefixes, const PubSubOptions& options);
+  std::unique_ptr<MultiSubscriberData> RemoveMultiSubscriber(
+      NT_MultiSubscriber subHandle);
+
+  void AddListenerImpl(NT_Listener listenerHandle, TopicData* topic,
+                       unsigned int eventMask);
+  void AddListenerImpl(NT_Listener listenerHandle, SubscriberData* subscriber,
+                       unsigned int eventMask, NT_Handle subentryHandle,
+                       bool subscriberOwned);
+  void AddListenerImpl(NT_Listener listenerHandle,
+                       MultiSubscriberData* subscriber, unsigned int eventMask,
+                       bool subscriberOwned);
+  void AddListenerImpl(NT_Listener listenerHandle,
+                       std::span<const std::string_view> prefixes,
+                       unsigned int eventMask);
+
+  void AddListener(NT_Listener listenerHandle,
+                   std::span<const std::string_view> prefixes,
+                   unsigned int mask);
+  void AddListener(NT_Listener listenerHandle, NT_Handle handle,
+                   unsigned int mask);
+  void RemoveListener(NT_Listener listenerHandle, unsigned int mask);
+
+  TopicData* GetOrCreateTopic(std::string_view name);
+  TopicData* GetTopic(NT_Handle handle);
+  SubscriberData* GetSubEntry(NT_Handle subentryHandle);
+  PublisherData* PublishEntry(EntryData* entry, NT_Type type);
+  Value* GetSubEntryValue(NT_Handle subentryHandle);
+
+  bool PublishLocalValue(PublisherData* publisher, const Value& value,
+                         bool force = false);
+
+  bool SetEntryValue(NT_Handle pubentryHandle, const Value& value);
+  bool SetDefaultEntryValue(NT_Handle pubsubentryHandle, const Value& value);
+
+  void RemoveSubEntry(NT_Handle subentryHandle);
+};
+
+}  // namespace
+
+void DataLoggerEntry::Append(const Value& v) {
+  auto time = v.time();
+  switch (v.type()) {
+    case NT_BOOLEAN:
+      log->AppendBoolean(entry, v.GetBoolean(), time);
+      break;
+    case NT_INTEGER:
+      log->AppendInteger(entry, v.GetInteger(), time);
+      break;
+    case NT_FLOAT:
+      log->AppendFloat(entry, v.GetFloat(), time);
+      break;
+    case NT_DOUBLE:
+      log->AppendDouble(entry, v.GetDouble(), time);
+      break;
+    case NT_STRING:
+      log->AppendString(entry, v.GetString(), time);
+      break;
+    case NT_RAW: {
+      auto val = v.GetRaw();
+      log->AppendRaw(entry,
+                     {reinterpret_cast<const uint8_t*>(val.data()), val.size()},
+                     time);
+      break;
+    }
+    case NT_BOOLEAN_ARRAY:
+      log->AppendBooleanArray(entry, v.GetBooleanArray(), time);
+      break;
+    case NT_INTEGER_ARRAY:
+      log->AppendIntegerArray(entry, v.GetIntegerArray(), time);
+      break;
+    case NT_FLOAT_ARRAY:
+      log->AppendFloatArray(entry, v.GetFloatArray(), time);
+      break;
+    case NT_DOUBLE_ARRAY:
+      log->AppendDoubleArray(entry, v.GetDoubleArray(), time);
+      break;
+    case NT_STRING_ARRAY:
+      log->AppendStringArray(entry, v.GetStringArray(), time);
+      break;
+    default:
+      break;
+  }
+}
+
+TopicInfo TopicData::GetTopicInfo() const {
+  TopicInfo info;
+  info.topic = handle;
+  info.name = name;
+  info.type = type;
+  info.type_str = typeStr;
+  info.properties = propertiesStr;
+  return info;
+}
+
+void PublisherData::UpdateActive() {
+  active = config.type == topic->type && config.typeStr == topic->typeStr;
+}
+
+void SubscriberData::UpdateActive() {
+  // for subscribers, unassigned is a wildcard
+  // also allow numerically compatible subscribers
+  active = config.type == NT_UNASSIGNED ||
+           (config.type == topic->type && config.typeStr == topic->typeStr) ||
+           IsNumericCompatible(config.type, topic->type);
+}
+
+void LSImpl::NotifyTopic(TopicData* topic, unsigned int eventFlags) {
+  DEBUG4("NotifyTopic({}, {})", topic->name, eventFlags);
+  auto topicInfo = topic->GetTopicInfo();
+  if (!topic->listeners.empty()) {
+    m_listenerStorage.Notify(topic->listeners, eventFlags, topicInfo);
+  }
+
+  wpi::SmallVector<NT_Listener, 32> listeners;
+  for (auto listener : m_topicPrefixListeners) {
+    if (listener->multiSubscriber &&
+        listener->multiSubscriber->Matches(topic->name, topic->special)) {
+      listeners.emplace_back(listener->handle);
+    }
+  }
+  if (!listeners.empty()) {
+    m_listenerStorage.Notify(listeners, eventFlags, topicInfo);
+  }
+
+  if ((eventFlags & (NT_EVENT_PUBLISH | NT_EVENT_UNPUBLISH)) != 0) {
+    if (!m_dataloggers.empty()) {
+      auto now = Now();
+      for (auto&& datalogger : m_dataloggers) {
+        if (wpi::starts_with(topic->name, datalogger->prefix)) {
+          auto it = std::find_if(topic->datalogs.begin(), topic->datalogs.end(),
+                                 [&](const auto& elem) {
+                                   return elem.logger == datalogger->handle;
+                                 });
+          if ((eventFlags & NT_EVENT_PUBLISH) != 0 &&
+              it == topic->datalogs.end()) {
+            topic->datalogs.emplace_back(datalogger->log,
+                                         datalogger->Start(topic, now),
+                                         datalogger->handle);
+            topic->datalogType = topic->type;
+          } else if ((eventFlags & NT_EVENT_UNPUBLISH) != 0 &&
+                     it != topic->datalogs.end()) {
+            it->log->Finish(it->entry, now);
+            topic->datalogType = NT_UNASSIGNED;
+            topic->datalogs.erase(it);
+          }
+        }
+      }
+    }
+  } else if ((eventFlags & NT_EVENT_PROPERTIES) != 0) {
+    if (!topic->datalogs.empty()) {
+      auto metadata = DataLoggerEntry::MakeMetadata(topic->propertiesStr);
+      for (auto&& datalog : topic->datalogs) {
+        datalog.log->SetMetadata(datalog.entry, metadata);
+      }
+    }
+  }
+}
+
+void LSImpl::CheckReset(TopicData* topic) {
+  if (topic->Exists()) {
+    return;
+  }
+  topic->lastValue = {};
+  topic->lastValueNetwork = {};
+  topic->type = NT_UNASSIGNED;
+  topic->typeStr.clear();
+  topic->flags = 0;
+  topic->properties = wpi::json::object();
+  topic->propertiesStr = "{}";
+}
+
+bool LSImpl::SetValue(TopicData* topic, const Value& value,
+                      unsigned int eventFlags, bool isDuplicate,
+                      const PublisherData* publisher) {
+  DEBUG4("SetValue({}, {}, {}, {})", topic->name, value.time(), eventFlags,
+         isDuplicate);
+  if (topic->type != NT_UNASSIGNED && topic->type != value.type()) {
+    return false;
+  }
+  if (!topic->lastValue || value.time() >= topic->lastValue.time()) {
+    // TODO: notify option even if older value
+    topic->type = value.type();
+    topic->lastValue = value;
+    NotifyValue(topic, eventFlags, isDuplicate, publisher);
+  }
+  if (!isDuplicate && topic->datalogType == value.type()) {
+    for (auto&& datalog : topic->datalogs) {
+      datalog.Append(value);
+    }
+  }
+  return true;
+}
+
+void LSImpl::NotifyValue(TopicData* topic, unsigned int eventFlags,
+                         bool isDuplicate, const PublisherData* publisher) {
+  bool isNetwork = (eventFlags & NT_EVENT_VALUE_REMOTE) != 0;
+  for (auto&& subscriber : topic->localSubscribers) {
+    if (subscriber->active &&
+        (subscriber->config.keepDuplicates || !isDuplicate) &&
+        ((isNetwork && !subscriber->config.disableRemote) ||
+         (!isNetwork && !subscriber->config.disableLocal)) &&
+        (!publisher || (publisher && (subscriber->config.excludePublisher !=
+                                      publisher->handle)))) {
+      subscriber->pollStorage.emplace_back(topic->lastValue);
+      subscriber->handle.Set();
+      if (!subscriber->valueListeners.empty()) {
+        m_listenerStorage.Notify(subscriber->valueListeners, eventFlags,
+                                 topic->handle, 0, topic->lastValue);
+      }
+    }
+  }
+
+  for (auto&& subscriber : topic->multiSubscribers) {
+    if (subscriber->options.keepDuplicates || !isDuplicate) {
+      subscriber->handle.Set();
+      if (!subscriber->valueListeners.empty()) {
+        m_listenerStorage.Notify(subscriber->valueListeners, eventFlags,
+                                 topic->handle, 0, topic->lastValue);
+      }
+    }
+  }
+}
+
+void LSImpl::SetFlags(TopicData* topic, unsigned int flags) {
+  wpi::json update = wpi::json::object();
+  if ((flags & NT_PERSISTENT) != 0) {
+    topic->properties["persistent"] = true;
+    update["persistent"] = true;
+  } else {
+    topic->properties.erase("persistent");
+    update["persistent"] = wpi::json();
+  }
+  if ((flags & NT_RETAINED) != 0) {
+    topic->properties["retained"] = true;
+    update["retained"] = true;
+  } else {
+    topic->properties.erase("retained");
+    update["retained"] = wpi::json();
+  }
+  topic->flags = flags;
+  if (!update.empty()) {
+    PropertiesUpdated(topic, update, NT_EVENT_NONE, true, false);
+  }
+}
+
+void LSImpl::SetPersistent(TopicData* topic, bool value) {
+  wpi::json update = wpi::json::object();
+  if (value) {
+    topic->flags |= NT_PERSISTENT;
+    topic->properties["persistent"] = true;
+    update["persistent"] = true;
+  } else {
+    topic->flags &= ~NT_PERSISTENT;
+    topic->properties.erase("persistent");
+    update["persistent"] = wpi::json();
+  }
+  PropertiesUpdated(topic, update, NT_EVENT_NONE, true, false);
+}
+
+void LSImpl::SetRetained(TopicData* topic, bool value) {
+  wpi::json update = wpi::json::object();
+  if (value) {
+    topic->flags |= NT_RETAINED;
+    topic->properties["retained"] = true;
+    update["retained"] = true;
+  } else {
+    topic->flags &= ~NT_RETAINED;
+    topic->properties.erase("retained");
+    update["retained"] = wpi::json();
+  }
+  PropertiesUpdated(topic, update, NT_EVENT_NONE, true, false);
+}
+
+void LSImpl::SetProperties(TopicData* topic, const wpi::json& update,
+                           bool sendNetwork) {
+  if (!update.is_object()) {
+    return;
+  }
+  DEBUG4("SetProperties({},{})", topic->name, sendNetwork);
+  for (auto&& change : update.items()) {
+    if (change.value().is_null()) {
+      topic->properties.erase(change.key());
+    } else {
+      topic->properties[change.key()] = change.value();
+    }
+  }
+  PropertiesUpdated(topic, update, NT_EVENT_NONE, sendNetwork);
+}
+
+void LSImpl::PropertiesUpdated(TopicData* topic, const wpi::json& update,
+                               unsigned int eventFlags, bool sendNetwork,
+                               bool updateFlags) {
+  DEBUG4("PropertiesUpdated({}, {}, {}, {}, {})", topic->name, update.dump(),
+         eventFlags, sendNetwork, updateFlags);
+  if (updateFlags) {
+    // set flags from properties
+    auto it = topic->properties.find("persistent");
+    if (it != topic->properties.end()) {
+      if (auto val = it->get_ptr<bool*>()) {
+        if (*val) {
+          topic->flags |= NT_PERSISTENT;
+        } else {
+          topic->flags &= ~NT_PERSISTENT;
+        }
+      }
+    }
+    it = topic->properties.find("retained");
+    if (it != topic->properties.end()) {
+      if (auto val = it->get_ptr<bool*>()) {
+        if (*val) {
+          topic->flags |= NT_RETAINED;
+        } else {
+          topic->flags &= ~NT_RETAINED;
+        }
+      }
+    }
+  }
+
+  topic->propertiesStr = topic->properties.dump();
+  NotifyTopic(topic, eventFlags | NT_EVENT_PROPERTIES);
+  // check local flag so we don't echo back received properties changes
+  if (m_network && sendNetwork) {
+    m_network->SetProperties(topic->handle, topic->name, update);
+  }
+}
+
+void LSImpl::RefreshPubSubActive(TopicData* topic, bool warnOnSubMismatch) {
+  for (auto&& publisher : topic->localPublishers) {
+    publisher->UpdateActive();
+  }
+  for (auto&& subscriber : topic->localSubscribers) {
+    subscriber->UpdateActive();
+    if (warnOnSubMismatch && topic->Exists() && !subscriber->active) {
+      // warn on type mismatch
+      INFO(
+          "local subscribe to '{}' disabled due to type mismatch (wanted '{}', "
+          "published as '{}')",
+          topic->name, subscriber->config.typeStr, topic->typeStr);
+    }
+  }
+}
+
+void LSImpl::NetworkAnnounce(TopicData* topic, std::string_view typeStr,
+                             const wpi::json& properties,
+                             NT_Publisher pubHandle) {
+  DEBUG4("LS NetworkAnnounce({}, {}, {}, {})", topic->name, typeStr,
+         properties.dump(), pubHandle);
+  if (pubHandle != 0) {
+    return;  // ack of our publish; ignore
+  }
+
+  unsigned int event = NT_EVENT_NONE;
+  // fresh non-local publish; the network publish always sets the type even
+  // if it was locally published, but output a diagnostic for this case
+  bool didExist = topic->Exists();
+  topic->onNetwork = true;
+  NT_Type type = StringToType(typeStr);
+  if (topic->type != type || topic->typeStr != typeStr) {
+    if (didExist) {
+      INFO(
+          "network announce of '{}' overriding local publish (was '{}', now "
+          "'{}')",
+          topic->name, topic->typeStr, typeStr);
+    }
+    topic->type = type;
+    topic->typeStr = typeStr;
+    RefreshPubSubActive(topic, true);
+  }
+  if (!didExist) {
+    event |= NT_EVENT_PUBLISH;
+  }
+
+  // may be properties update, but need to compare to see if it actually
+  // changed to determine whether to update string / send event
+  wpi::json update = wpi::json::object();
+  // added/changed
+  for (auto&& prop : properties.items()) {
+    auto it = topic->properties.find(prop.key());
+    if (it == topic->properties.end() || *it != prop.value()) {
+      update[prop.key()] = prop.value();
+    }
+  }
+  // removed
+  for (auto&& prop : topic->properties.items()) {
+    if (properties.find(prop.key()) == properties.end()) {
+      update[prop.key()] = wpi::json();
+    }
+  }
+  if (!update.empty()) {
+    topic->properties = properties;
+    PropertiesUpdated(topic, update, event, false);
+  } else if (event != NT_EVENT_NONE) {
+    NotifyTopic(topic, event);
+  }
+}
+
+void LSImpl::RemoveNetworkPublisher(TopicData* topic) {
+  DEBUG4("LS RemoveNetworkPublisher({}, {})", topic->handle, topic->name);
+  // this acts as an unpublish
+  bool didExist = topic->Exists();
+  topic->onNetwork = false;
+  if (didExist && !topic->Exists()) {
+    DEBUG4("Unpublished {}", topic->name);
+    CheckReset(topic);
+    NotifyTopic(topic, NT_EVENT_UNPUBLISH);
+  }
+
+  if (!topic->localPublishers.empty()) {
+    // some other publisher still exists; if it has a different type, refresh
+    // and publish it over the network
+    auto& nextPub = topic->localPublishers.front();
+    if (nextPub->config.type != topic->type ||
+        nextPub->config.typeStr != topic->typeStr) {
+      topic->type = nextPub->config.type;
+      topic->typeStr = nextPub->config.typeStr;
+      RefreshPubSubActive(topic, false);
+      // this may result in a duplicate publish warning on the server side,
+      // but send one anyway in this case just to be sure
+      if (nextPub->active && m_network) {
+        m_network->Publish(nextPub->handle, topic->handle, topic->name,
+                           topic->typeStr, topic->properties, nextPub->config);
+      }
+    }
+  }
+}
+
+void LSImpl::NetworkPropertiesUpdate(TopicData* topic, const wpi::json& update,
+                                     bool ack) {
+  DEBUG4("NetworkPropertiesUpdate({},{})", topic->name, ack);
+  if (ack) {
+    return;  // ignore acks
+  }
+  SetProperties(topic, update, false);
+}
+
+PublisherData* LSImpl::AddLocalPublisher(TopicData* topic,
+                                         const wpi::json& properties,
+                                         const PubSubConfig& config) {
+  bool didExist = topic->Exists();
+  auto publisher = m_publishers.Add(m_inst, topic, config);
+  topic->localPublishers.Add(publisher);
+
+  if (!didExist) {
+    DEBUG4("AddLocalPublisher: setting {} type {} typestr {}", topic->name,
+           static_cast<int>(config.type), config.typeStr);
+    // set the type to the published type
+    topic->type = config.type;
+    topic->typeStr = config.typeStr;
+    RefreshPubSubActive(topic, true);
+
+    if (properties.is_null()) {
+      topic->properties = wpi::json::object();
+    } else if (properties.is_object()) {
+      topic->properties = properties;
+    } else {
+      WARNING("ignoring non-object properties when publishing '{}'",
+              topic->name);
+      topic->properties = wpi::json::object();
+    }
+
+    if (topic->properties.empty()) {
+      NotifyTopic(topic, NT_EVENT_PUBLISH);
+    } else {
+      PropertiesUpdated(topic, topic->properties, NT_EVENT_PUBLISH, false);
+    }
+  } else {
+    // only need to update just this publisher
+    publisher->UpdateActive();
+    if (!publisher->active) {
+      // warn on type mismatch
+      INFO(
+          "local publish to '{}' disabled due to type mismatch (wanted '{}', "
+          "currently '{}')",
+          topic->name, config.typeStr, topic->typeStr);
+    }
+  }
+
+  if (publisher->active && m_network) {
+    m_network->Publish(publisher->handle, topic->handle, topic->name,
+                       topic->typeStr, topic->properties, config);
+  }
+  return publisher;
+}
+
+std::unique_ptr<PublisherData> LSImpl::RemoveLocalPublisher(
+    NT_Publisher pubHandle) {
+  auto publisher = m_publishers.Remove(pubHandle);
+  if (publisher) {
+    auto topic = publisher->topic;
+    bool didExist = topic->Exists();
+    topic->localPublishers.Remove(publisher.get());
+    if (didExist && !topic->Exists()) {
+      CheckReset(topic);
+      NotifyTopic(topic, NT_EVENT_UNPUBLISH);
+    }
+
+    if (publisher->active && m_network) {
+      m_network->Unpublish(publisher->handle, topic->handle);
+    }
+
+    if (publisher->active && !topic->localPublishers.empty()) {
+      // some other publisher still exists; if it has a different type, refresh
+      // and publish it over the network
+      auto& nextPub = topic->localPublishers.front();
+      if (nextPub->config.type != topic->type ||
+          nextPub->config.typeStr != topic->typeStr) {
+        topic->type = nextPub->config.type;
+        topic->typeStr = nextPub->config.typeStr;
+        RefreshPubSubActive(topic, false);
+        if (nextPub->active && m_network) {
+          m_network->Publish(nextPub->handle, topic->handle, topic->name,
+                             topic->typeStr, topic->properties,
+                             nextPub->config);
+        }
+      }
+    }
+  }
+  return publisher;
+}
+
+SubscriberData* LSImpl::AddLocalSubscriber(TopicData* topic,
+                                           const PubSubConfig& config) {
+  DEBUG4("AddLocalSubscriber({})", topic->name);
+  auto subscriber = m_subscribers.Add(m_inst, topic, config);
+  topic->localSubscribers.Add(subscriber);
+  // set subscriber to active if the type matches
+  subscriber->UpdateActive();
+  if (topic->Exists() && !subscriber->active) {
+    // warn on type mismatch
+    INFO(
+        "local subscribe to '{}' disabled due to type mismatch (wanted '{}', "
+        "published as '{}')",
+        topic->name, config.typeStr, topic->typeStr);
+  }
+  if (m_network) {
+    DEBUG4("-> NetworkSubscribe({})", topic->name);
+    m_network->Subscribe(subscriber->handle, {{topic->name}}, config);
+  }
+  return subscriber;
+}
+
+std::unique_ptr<SubscriberData> LSImpl::RemoveLocalSubscriber(
+    NT_Subscriber subHandle) {
+  auto subscriber = m_subscribers.Remove(subHandle);
+  if (subscriber) {
+    auto topic = subscriber->topic;
+    topic->localSubscribers.Remove(subscriber.get());
+    for (auto&& listener : m_listeners) {
+      if (listener.getSecond()->subscriber == subscriber.get()) {
+        listener.getSecond()->subscriber = nullptr;
+      }
+    }
+    if (m_network) {
+      m_network->Unsubscribe(subscriber->handle);
+    }
+  }
+  return subscriber;
+}
+
+EntryData* LSImpl::AddEntry(SubscriberData* subscriber) {
+  auto entry = m_entries.Add(m_inst, subscriber);
+  subscriber->topic->entries.Add(entry);
+  return entry;
+}
+
+std::unique_ptr<EntryData> LSImpl::RemoveEntry(NT_Entry entryHandle) {
+  auto entry = m_entries.Remove(entryHandle);
+  if (entry) {
+    entry->topic->entries.Remove(entry.get());
+  }
+  return entry;
+}
+
+MultiSubscriberData* LSImpl::AddMultiSubscriber(
+    std::span<const std::string_view> prefixes, const PubSubOptions& options) {
+  auto subscriber = m_multiSubscribers.Add(m_inst, prefixes, options);
+  // subscribe to any already existing topics
+  for (auto&& topic : m_topics) {
+    for (auto&& prefix : prefixes) {
+      if (PrefixMatch(topic->name, prefix, topic->special)) {
+        topic->multiSubscribers.Add(subscriber);
+        break;
+      }
+    }
+  }
+  if (m_network) {
+    m_network->Subscribe(subscriber->handle, subscriber->prefixes,
+                         subscriber->options);
+  }
+  return subscriber;
+}
+
+std::unique_ptr<MultiSubscriberData> LSImpl::RemoveMultiSubscriber(
+    NT_MultiSubscriber subHandle) {
+  auto subscriber = m_multiSubscribers.Remove(subHandle);
+  if (subscriber) {
+    for (auto&& topic : m_topics) {
+      topic->multiSubscribers.Remove(subscriber.get());
+    }
+    for (auto&& listener : m_listeners) {
+      if (listener.getSecond()->multiSubscriber == subscriber.get()) {
+        listener.getSecond()->multiSubscriber = nullptr;
+      }
+    }
+    if (m_network) {
+      m_network->Unsubscribe(subscriber->handle);
+    }
+  }
+  return subscriber;
+}
+
+void LSImpl::AddListenerImpl(NT_Listener listenerHandle, TopicData* topic,
+                             unsigned int eventMask) {
+  if (topic->localSubscribers.size() >= kMaxSubscribers) {
+    ERROR(
+        "reached maximum number of subscribers to '{}', ignoring listener add",
+        topic->name);
+    return;
+  }
+  // subscribe to make sure topic updates are received
+  PubSubConfig config;
+  config.topicsOnly = (eventMask & NT_EVENT_VALUE_ALL) == 0;
+  auto sub = AddLocalSubscriber(topic, config);
+  AddListenerImpl(listenerHandle, sub, eventMask, sub->handle, true);
+}
+
+void LSImpl::AddListenerImpl(NT_Listener listenerHandle,
+                             SubscriberData* subscriber, unsigned int eventMask,
+                             NT_Handle subentryHandle, bool subscriberOwned) {
+  m_listeners.try_emplace(listenerHandle, std::make_unique<ListenerData>(
+                                              listenerHandle, subscriber,
+                                              eventMask, subscriberOwned));
+
+  auto topic = subscriber->topic;
+
+  if ((eventMask & NT_EVENT_TOPIC) != 0) {
+    if (topic->listeners.size() >= kMaxListeners) {
+      ERROR("reached maximum number of listeners to '{}', not adding listener",
+            topic->name);
+      return;
+    }
+
+    m_listenerStorage.Activate(
+        listenerHandle, eventMask & (NT_EVENT_TOPIC | NT_EVENT_IMMEDIATE));
+
+    topic->listeners.Add(listenerHandle);
+
+    // handle immediate publish
+    if ((eventMask & (NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE)) ==
+            (NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE) &&
+        topic->Exists()) {
+      m_listenerStorage.Notify({&listenerHandle, 1},
+                               NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE,
+                               topic->GetTopicInfo());
+    }
+  }
+
+  if ((eventMask & NT_EVENT_VALUE_ALL) != 0) {
+    if (subscriber->valueListeners.size() >= kMaxListeners) {
+      ERROR("reached maximum number of listeners to '{}', not adding listener",
+            topic->name);
+      return;
+    }
+    m_listenerStorage.Activate(
+        listenerHandle, eventMask & (NT_EVENT_VALUE_ALL | NT_EVENT_IMMEDIATE),
+        [subentryHandle](unsigned int mask, Event* event) {
+          if (auto valueData = event->GetValueEventData()) {
+            valueData->subentry = subentryHandle;
+          }
+          return true;
+        });
+
+    subscriber->valueListeners.Add(listenerHandle);
+
+    // handle immediate value
+    if ((eventMask & NT_EVENT_VALUE_ALL) != 0 &&
+        (eventMask & NT_EVENT_IMMEDIATE) != 0 && topic->lastValue) {
+      m_listenerStorage.Notify({&listenerHandle, 1},
+                               NT_EVENT_IMMEDIATE | NT_EVENT_VALUE_ALL,
+                               topic->handle, subentryHandle, topic->lastValue);
+    }
+  }
+}
+
+void LSImpl::AddListenerImpl(NT_Listener listenerHandle,
+                             MultiSubscriberData* subscriber,
+                             unsigned int eventMask, bool subscriberOwned) {
+  auto listener =
+      m_listeners
+          .try_emplace(listenerHandle, std::make_unique<ListenerData>(
+                                           listenerHandle, subscriber,
+                                           eventMask, subscriberOwned))
+          .first->getSecond()
+          .get();
+
+  // if we're doing anything immediate, get the list of matching topics
+  wpi::SmallVector<TopicData*, 32> topics;
+  if ((eventMask & NT_EVENT_IMMEDIATE) != 0 &&
+      (eventMask & (NT_EVENT_PUBLISH | NT_EVENT_VALUE_ALL)) != 0) {
+    for (auto&& topic : m_topics) {
+      if (topic->Exists() && subscriber->Matches(topic->name, topic->special)) {
+        topics.emplace_back(topic.get());
+      }
+    }
+  }
+
+  if ((eventMask & NT_EVENT_TOPIC) != 0) {
+    if (m_topicPrefixListeners.size() >= kMaxListeners) {
+      ERROR("reached maximum number of listeners, not adding listener");
+      return;
+    }
+
+    m_listenerStorage.Activate(
+        listenerHandle, eventMask & (NT_EVENT_TOPIC | NT_EVENT_IMMEDIATE));
+
+    m_topicPrefixListeners.Add(listener);
+
+    // handle immediate publish
+    if ((eventMask & (NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE)) ==
+        (NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE)) {
+      std::vector<TopicInfo> topicInfos;
+      for (auto&& topic : topics) {
+        topicInfos.emplace_back(topic->GetTopicInfo());
+      }
+      if (!topicInfos.empty()) {
+        m_listenerStorage.Notify({&listenerHandle, 1},
+                                 NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE,
+                                 topicInfos);
+      }
+    }
+  }
+
+  if ((eventMask & NT_EVENT_VALUE_ALL) != 0) {
+    if (subscriber->valueListeners.size() >= kMaxListeners) {
+      ERROR("reached maximum number of listeners, not adding listener");
+      return;
+    }
+
+    m_listenerStorage.Activate(
+        listenerHandle, eventMask & (NT_EVENT_VALUE_ALL | NT_EVENT_IMMEDIATE),
+        [subentryHandle = subscriber->handle.GetHandle()](unsigned int mask,
+                                                          Event* event) {
+          if (auto valueData = event->GetValueEventData()) {
+            valueData->subentry = subentryHandle;
+          }
+          return true;
+        });
+
+    subscriber->valueListeners.Add(listenerHandle);
+
+    // handle immediate value
+    if ((eventMask & NT_EVENT_VALUE_ALL) != 0 &&
+        (eventMask & NT_EVENT_IMMEDIATE) != 0) {
+      for (auto&& topic : topics) {
+        if (topic->lastValue) {
+          m_listenerStorage.Notify(
+              {&listenerHandle, 1}, NT_EVENT_VALUE_ALL | NT_EVENT_IMMEDIATE,
+              topic->handle, subscriber->handle, topic->lastValue);
+        }
+      }
+    }
+  }
+}
+
+void LSImpl::AddListener(NT_Listener listenerHandle,
+                         std::span<const std::string_view> prefixes,
+                         unsigned int eventMask) {
+  if (m_multiSubscribers.size() >= kMaxMultiSubscribers) {
+    ERROR("reached maximum number of multi-subscribers, not adding listener");
+    return;
+  }
+  // subscribe to make sure topic updates are received
+  auto sub = AddMultiSubscriber(
+      prefixes, {.topicsOnly = (eventMask & NT_EVENT_VALUE_ALL) == 0});
+  AddListenerImpl(listenerHandle, sub, eventMask, true);
+}
+
+void LSImpl::AddListener(NT_Listener listenerHandle, NT_Handle handle,
+                         unsigned int mask) {
+  if (auto topic = m_topics.Get(handle)) {
+    AddListenerImpl(listenerHandle, topic, mask);
+  } else if (auto sub = m_multiSubscribers.Get(handle)) {
+    AddListenerImpl(listenerHandle, sub, mask, false);
+  } else if (auto sub = m_subscribers.Get(handle)) {
+    AddListenerImpl(listenerHandle, sub, mask, sub->handle, false);
+  } else if (auto entry = m_entries.Get(handle)) {
+    AddListenerImpl(listenerHandle, entry->subscriber, mask, entry->handle,
+                    false);
+  }
+}
+
+void LSImpl::RemoveListener(NT_Listener listenerHandle, unsigned int mask) {
+  auto listenerIt = m_listeners.find(listenerHandle);
+  if (listenerIt == m_listeners.end()) {
+    return;
+  }
+  auto listener = std::move(listenerIt->getSecond());
+  m_listeners.erase(listenerIt);
+  if (!listener) {
+    return;
+  }
+
+  m_topicPrefixListeners.Remove(listener.get());
+  if (listener->subscriber) {
+    listener->subscriber->valueListeners.Remove(listenerHandle);
+    listener->subscriber->topic->listeners.Remove(listenerHandle);
+    if (listener->subscriberOwned) {
+      RemoveLocalSubscriber(listener->subscriber->handle);
+    }
+  }
+  if (listener->multiSubscriber) {
+    listener->multiSubscriber->valueListeners.Remove(listenerHandle);
+    if (listener->subscriberOwned) {
+      RemoveMultiSubscriber(listener->multiSubscriber->handle);
+    }
+  }
+}
+
+TopicData* LSImpl::GetOrCreateTopic(std::string_view name) {
+  auto& topic = m_nameTopics[name];
+  // create if it does not already exist
+  if (!topic) {
+    topic = m_topics.Add(m_inst, name);
+    // attach multi-subscribers
+    for (auto&& sub : m_multiSubscribers) {
+      if (sub->Matches(name, topic->special)) {
+        topic->multiSubscribers.Add(sub.get());
+      }
+    }
+  }
+  return topic;
+}
+
+TopicData* LSImpl::GetTopic(NT_Handle handle) {
+  switch (Handle{handle}.GetType()) {
+    case Handle::kEntry: {
+      if (auto entry = m_entries.Get(handle)) {
+        return entry->topic;
+      }
+      break;
+    }
+    case Handle::kSubscriber: {
+      if (auto subscriber = m_subscribers.Get(handle)) {
+        return subscriber->topic;
+      }
+      break;
+    }
+    case Handle::kPublisher: {
+      if (auto publisher = m_publishers.Get(handle)) {
+        return publisher->topic;
+      }
+      break;
+    }
+    case Handle::kTopic:
+      return m_topics.Get(handle);
+    default:
+      break;
+  }
+  return {};
+}
+
+SubscriberData* LSImpl::GetSubEntry(NT_Handle subentryHandle) {
+  Handle h{subentryHandle};
+  if (h.IsType(Handle::kSubscriber)) {
+    return m_subscribers.Get(subentryHandle);
+  } else if (h.IsType(Handle::kEntry)) {
+    auto entry = m_entries.Get(subentryHandle);
+    return entry ? entry->subscriber : nullptr;
+  } else {
+    return nullptr;
+  }
+}
+
+PublisherData* LSImpl::PublishEntry(EntryData* entry, NT_Type type) {
+  if (entry->publisher) {
+    return entry->publisher;
+  }
+  auto typeStr = TypeToString(type);
+  if (entry->subscriber->config.type == NT_UNASSIGNED) {
+    entry->subscriber->config.type = type;
+    entry->subscriber->config.typeStr = typeStr;
+  } else if (entry->subscriber->config.type != type ||
+             entry->subscriber->config.typeStr != typeStr) {
+    if (!IsNumericCompatible(type, entry->subscriber->config.type)) {
+      // don't allow dynamically changing the type of an entry
+      ERROR("cannot publish entry {} as type {}, previously subscribed as {}",
+            entry->topic->name, typeStr, entry->subscriber->config.typeStr);
+      return nullptr;
+    }
+  }
+  // create publisher
+  entry->publisher = AddLocalPublisher(entry->topic, wpi::json::object(),
+                                       entry->subscriber->config);
+  return entry->publisher;
+}
+
+Value* LSImpl::GetSubEntryValue(NT_Handle subentryHandle) {
+  if (auto subscriber = GetSubEntry(subentryHandle)) {
+    return &subscriber->topic->lastValue;
+  } else {
+    return nullptr;
+  }
+}
+
+bool LSImpl::PublishLocalValue(PublisherData* publisher, const Value& value,
+                               bool force) {
+  if (!value) {
+    return false;
+  }
+  if (publisher->topic->type != NT_UNASSIGNED &&
+      publisher->topic->type != value.type()) {
+    if (IsNumericCompatible(publisher->topic->type, value.type())) {
+      return PublishLocalValue(
+          publisher, ConvertNumericValue(value, publisher->topic->type));
+    }
+    return false;
+  }
+  if (publisher->active) {
+    bool isDuplicate, isNetworkDuplicate;
+    if (force || publisher->config.keepDuplicates) {
+      isDuplicate = false;
+      isNetworkDuplicate = false;
+    } else {
+      isDuplicate = (publisher->topic->lastValue == value);
+      isNetworkDuplicate = (publisher->topic->lastValueNetwork == value);
+    }
+    if (!isNetworkDuplicate && m_network) {
+      publisher->topic->lastValueNetwork = value;
+      m_network->SetValue(publisher->handle, value);
+    }
+    return SetValue(publisher->topic, value, NT_EVENT_VALUE_LOCAL, isDuplicate,
+                    publisher);
+  } else {
+    return false;
+  }
+}
+
+bool LSImpl::SetEntryValue(NT_Handle pubentryHandle, const Value& value) {
+  if (!value) {
+    return false;
+  }
+  auto publisher = m_publishers.Get(pubentryHandle);
+  if (!publisher) {
+    if (auto entry = m_entries.Get(pubentryHandle)) {
+      publisher = PublishEntry(entry, value.type());
+      if (entry->subscriber->config.excludeSelf) {
+        entry->subscriber->config.excludePublisher = publisher->handle;
+      }
+    }
+    if (!publisher) {
+      return false;
+    }
+  }
+  return PublishLocalValue(publisher, value);
+}
+
+bool LSImpl::SetDefaultEntryValue(NT_Handle pubsubentryHandle,
+                                  const Value& value) {
+  DEBUG4("SetDefaultEntryValue({}, {})", pubsubentryHandle,
+         static_cast<int>(value.type()));
+  if (!value) {
+    return false;
+  }
+  if (auto topic = GetTopic(pubsubentryHandle)) {
+    if (!topic->lastValue &&
+        (topic->type == NT_UNASSIGNED || topic->type == value.type() ||
+         IsNumericCompatible(topic->type, value.type()))) {
+      // publish if we haven't yet
+      auto publisher = m_publishers.Get(pubsubentryHandle);
+      if (!publisher) {
+        if (auto entry = m_entries.Get(pubsubentryHandle)) {
+          publisher = PublishEntry(entry, value.type());
+        }
+      }
+
+      // force value timestamps to 0
+      if (topic->type == NT_UNASSIGNED) {
+        topic->type = value.type();
+      }
+      if (topic->type == value.type()) {
+        topic->lastValue = value;
+      } else if (IsNumericCompatible(topic->type, value.type())) {
+        topic->lastValue = ConvertNumericValue(value, topic->type);
+      } else {
+        return true;
+      }
+      topic->lastValue.SetTime(0);
+      topic->lastValue.SetServerTime(0);
+      if (publisher) {
+        PublishLocalValue(publisher, topic->lastValue, true);
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+void LSImpl::RemoveSubEntry(NT_Handle subentryHandle) {
+  Handle h{subentryHandle};
+  if (h.IsType(Handle::kSubscriber)) {
+    RemoveLocalSubscriber(subentryHandle);
+  } else if (h.IsType(Handle::kMultiSubscriber)) {
+    RemoveMultiSubscriber(subentryHandle);
+  } else if (h.IsType(Handle::kEntry)) {
+    if (auto entry = RemoveEntry(subentryHandle)) {
+      RemoveLocalSubscriber(entry->subscriber->handle);
+      if (entry->publisher) {
+        RemoveLocalPublisher(entry->publisher->handle);
+      }
+    }
+  }
+}
+
+class LocalStorage::Impl : public LSImpl {
+ public:
+  Impl(int inst, IListenerStorage& listenerStorage, wpi::Logger& logger)
+      : LSImpl{inst, listenerStorage, logger} {}
+};
+
+LocalStorage::LocalStorage(int inst, IListenerStorage& listenerStorage,
+                           wpi::Logger& logger)
+    : m_impl{std::make_unique<Impl>(inst, listenerStorage, logger)} {}
+
+LocalStorage::~LocalStorage() = default;
+
+NT_Topic LocalStorage::NetworkAnnounce(std::string_view name,
+                                       std::string_view typeStr,
+                                       const wpi::json& properties,
+                                       NT_Publisher pubHandle) {
+  std::scoped_lock lock{m_mutex};
+  auto topic = m_impl->GetOrCreateTopic(name);
+  m_impl->NetworkAnnounce(topic, typeStr, properties, pubHandle);
+  return topic->handle;
+}
+
+void LocalStorage::NetworkUnannounce(std::string_view name) {
+  std::scoped_lock lock{m_mutex};
+  auto topic = m_impl->GetOrCreateTopic(name);
+  m_impl->RemoveNetworkPublisher(topic);
+}
+
+void LocalStorage::NetworkPropertiesUpdate(std::string_view name,
+                                           const wpi::json& update, bool ack) {
+  std::scoped_lock lock{m_mutex};
+  auto it = m_impl->m_nameTopics.find(name);
+  if (it != m_impl->m_nameTopics.end()) {
+    m_impl->NetworkPropertiesUpdate(it->second, update, ack);
+  }
+}
+
+void LocalStorage::NetworkSetValue(NT_Topic topicHandle, const Value& value) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    if (m_impl->SetValue(topic, value, NT_EVENT_VALUE_REMOTE,
+                         value == topic->lastValue, nullptr)) {
+      topic->lastValueNetwork = value;
+    }
+  }
+}
+
+void LocalStorage::StartNetwork(net::NetworkInterface* network) {
+  WPI_DEBUG4(m_impl->m_logger, "StartNetwork()");
+  std::scoped_lock lock{m_mutex};
+  m_impl->m_network = network;
+  // publish all active publishers to the network and send last values
+  // only send value once per topic
+  for (auto&& topic : m_impl->m_topics) {
+    PublisherData* anyPublisher = nullptr;
+    for (auto&& publisher : topic->localPublishers) {
+      if (publisher->active) {
+        network->Publish(publisher->handle, topic->handle, topic->name,
+                         topic->typeStr, topic->properties, publisher->config);
+        anyPublisher = publisher;
+      }
+    }
+    if (anyPublisher && topic->lastValue) {
+      network->SetValue(anyPublisher->handle, topic->lastValue);
+    }
+  }
+  for (auto&& subscriber : m_impl->m_subscribers) {
+    network->Subscribe(subscriber->handle, {{subscriber->topic->name}},
+                       subscriber->config);
+  }
+  for (auto&& subscriber : m_impl->m_multiSubscribers) {
+    network->Subscribe(subscriber->handle, subscriber->prefixes,
+                       subscriber->options);
+  }
+}
+
+void LocalStorage::ClearNetwork() {
+  WPI_DEBUG4(m_impl->m_logger, "ClearNetwork()");
+  std::scoped_lock lock{m_mutex};
+  m_impl->m_network = nullptr;
+  // treat as an unannounce all from the network side
+  for (auto&& topic : m_impl->m_topics) {
+    m_impl->RemoveNetworkPublisher(topic.get());
+  }
+}
+
+template <typename T, typename F>
+static void ForEachTopic(T& topics, std::string_view prefix, unsigned int types,
+                         F func) {
+  for (auto&& topic : topics) {
+    if (!topic->Exists()) {
+      continue;
+    }
+    if (!wpi::starts_with(topic->name, prefix)) {
+      continue;
+    }
+    if (types != 0 && (types & topic->type) == 0) {
+      continue;
+    }
+    func(*topic);
+  }
+}
+
+template <typename T, typename F>
+static void ForEachTopic(T& topics, std::string_view prefix,
+                         std::span<const std::string_view> types, F func) {
+  for (auto&& topic : topics) {
+    if (!topic->Exists()) {
+      continue;
+    }
+    if (!wpi::starts_with(topic->name, prefix)) {
+      continue;
+    }
+    if (!types.empty()) {
+      bool match = false;
+      for (auto&& type : types) {
+        if (topic->typeStr == type) {
+          match = true;
+          break;
+        }
+      }
+      if (!match) {
+        continue;
+      }
+    }
+    func(*topic);
+  }
+}
+
+std::vector<NT_Topic> LocalStorage::GetTopics(std::string_view prefix,
+                                              unsigned int types) {
+  std::scoped_lock lock(m_mutex);
+  std::vector<NT_Topic> rv;
+  ForEachTopic(m_impl->m_topics, prefix, types,
+               [&](TopicData& topic) { rv.push_back(topic.handle); });
+  return rv;
+}
+
+std::vector<NT_Topic> LocalStorage::GetTopics(
+    std::string_view prefix, std::span<const std::string_view> types) {
+  std::scoped_lock lock(m_mutex);
+  std::vector<NT_Topic> rv;
+  ForEachTopic(m_impl->m_topics, prefix, types,
+               [&](TopicData& topic) { rv.push_back(topic.handle); });
+  return rv;
+}
+
+std::vector<TopicInfo> LocalStorage::GetTopicInfo(std::string_view prefix,
+                                                  unsigned int types) {
+  std::scoped_lock lock(m_mutex);
+  std::vector<TopicInfo> rv;
+  ForEachTopic(m_impl->m_topics, prefix, types, [&](TopicData& topic) {
+    rv.emplace_back(topic.GetTopicInfo());
+  });
+  return rv;
+}
+
+std::vector<TopicInfo> LocalStorage::GetTopicInfo(
+    std::string_view prefix, std::span<const std::string_view> types) {
+  std::scoped_lock lock(m_mutex);
+  std::vector<TopicInfo> rv;
+  ForEachTopic(m_impl->m_topics, prefix, types, [&](TopicData& topic) {
+    rv.emplace_back(topic.GetTopicInfo());
+  });
+  return rv;
+}
+
+NT_Topic LocalStorage::GetTopic(std::string_view name) {
+  if (name.empty()) {
+    return {};
+  }
+  std::scoped_lock lock{m_mutex};
+  return m_impl->GetOrCreateTopic(name)->handle;
+}
+
+std::string LocalStorage::GetTopicName(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return topic->name;
+  } else {
+    return {};
+  }
+}
+
+NT_Type LocalStorage::GetTopicType(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return topic->type;
+  } else {
+    return {};
+  }
+}
+
+std::string LocalStorage::GetTopicTypeString(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return topic->typeStr;
+  } else {
+    return {};
+  }
+}
+
+void LocalStorage::SetTopicPersistent(NT_Topic topicHandle, bool value) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    m_impl->SetPersistent(topic, value);
+  }
+}
+
+bool LocalStorage::GetTopicPersistent(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return (topic->flags & NT_PERSISTENT) != 0;
+  } else {
+    return false;
+  }
+}
+
+void LocalStorage::SetTopicRetained(NT_Topic topicHandle, bool value) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    m_impl->SetRetained(topic, value);
+  }
+}
+
+bool LocalStorage::GetTopicRetained(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return (topic->flags & NT_RETAINED) != 0;
+  } else {
+    return false;
+  }
+}
+
+bool LocalStorage::GetTopicExists(NT_Handle handle) {
+  std::scoped_lock lock{m_mutex};
+  TopicData* topic = m_impl->GetTopic(handle);
+  return topic && topic->Exists();
+}
+
+wpi::json LocalStorage::GetTopicProperty(NT_Topic topicHandle,
+                                         std::string_view name) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return topic->properties.value(name, wpi::json{});
+  } else {
+    return {};
+  }
+}
+
+void LocalStorage::SetTopicProperty(NT_Topic topicHandle, std::string_view name,
+                                    const wpi::json& value) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    if (value.is_null()) {
+      topic->properties.erase(name);
+    } else {
+      topic->properties[name] = value;
+    }
+    wpi::json update = wpi::json::object();
+    update[name] = value;
+    m_impl->PropertiesUpdated(topic, update, NT_EVENT_NONE, true);
+  }
+}
+
+void LocalStorage::DeleteTopicProperty(NT_Topic topicHandle,
+                                       std::string_view name) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    topic->properties.erase(name);
+    wpi::json update = wpi::json::object();
+    update[name] = wpi::json();
+    m_impl->PropertiesUpdated(topic, update, NT_EVENT_NONE, true);
+  }
+}
+
+wpi::json LocalStorage::GetTopicProperties(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return topic->properties;
+  } else {
+    return wpi::json::object();
+  }
+}
+
+bool LocalStorage::SetTopicProperties(NT_Topic topicHandle,
+                                      const wpi::json& update) {
+  if (!update.is_object()) {
+    return false;
+  }
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    m_impl->SetProperties(topic, update, true);
+    return true;
+  } else {
+    return {};
+  }
+}
+
+TopicInfo LocalStorage::GetTopicInfo(NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->m_topics.Get(topicHandle)) {
+    return topic->GetTopicInfo();
+  } else {
+    return {};
+  }
+}
+
+NT_Subscriber LocalStorage::Subscribe(NT_Topic topicHandle, NT_Type type,
+                                      std::string_view typeStr,
+                                      const PubSubOptions& options) {
+  std::scoped_lock lock{m_mutex};
+
+  // Get the topic
+  auto* topic = m_impl->m_topics.Get(topicHandle);
+  if (!topic) {
+    return 0;
+  }
+
+  if (topic->localSubscribers.size() >= kMaxSubscribers) {
+    WPI_ERROR(m_impl->m_logger,
+              "reached maximum number of subscribers to '{}', not subscribing",
+              topic->name);
+    return 0;
+  }
+
+  // Create subscriber
+  return m_impl->AddLocalSubscriber(topic, PubSubConfig{type, typeStr, options})
+      ->handle;
+}
+
+void LocalStorage::Unsubscribe(NT_Subscriber subHandle) {
+  std::scoped_lock lock{m_mutex};
+  m_impl->RemoveSubEntry(subHandle);
+}
+
+NT_MultiSubscriber LocalStorage::SubscribeMultiple(
+    std::span<const std::string_view> prefixes, const PubSubOptions& options) {
+  std::scoped_lock lock{m_mutex};
+
+  if (m_impl->m_multiSubscribers.size() >= kMaxMultiSubscribers) {
+    WPI_ERROR(m_impl->m_logger,
+              "reached maximum number of multi-subscribers, not subscribing");
+    return 0;
+  }
+
+  return m_impl->AddMultiSubscriber(prefixes, options)->handle;
+}
+
+void LocalStorage::UnsubscribeMultiple(NT_MultiSubscriber subHandle) {
+  std::scoped_lock lock{m_mutex};
+  m_impl->RemoveMultiSubscriber(subHandle);
+}
+
+NT_Publisher LocalStorage::Publish(NT_Topic topicHandle, NT_Type type,
+                                   std::string_view typeStr,
+                                   const wpi::json& properties,
+                                   const PubSubOptions& options) {
+  std::scoped_lock lock{m_mutex};
+
+  // Get the topic
+  auto* topic = m_impl->m_topics.Get(topicHandle);
+  if (!topic) {
+    WPI_ERROR(m_impl->m_logger, "trying to publish invalid topic handle ({})",
+              topicHandle);
+    return 0;
+  }
+
+  if (type == NT_UNASSIGNED || typeStr.empty()) {
+    WPI_ERROR(
+        m_impl->m_logger,
+        "cannot publish '{}' with an unassigned type or empty type string",
+        topic->name);
+    return 0;
+  }
+
+  if (topic->localPublishers.size() >= kMaxPublishers) {
+    WPI_ERROR(m_impl->m_logger,
+              "reached maximum number of publishers to '{}', not publishing",
+              topic->name);
+    return 0;
+  }
+
+  return m_impl
+      ->AddLocalPublisher(topic, properties,
+                          PubSubConfig{type, typeStr, options})
+      ->handle;
+}
+
+void LocalStorage::Unpublish(NT_Handle pubentryHandle) {
+  std::scoped_lock lock{m_mutex};
+
+  if (Handle{pubentryHandle}.IsType(Handle::kPublisher)) {
+    m_impl->RemoveLocalPublisher(pubentryHandle);
+  } else if (auto entry = m_impl->m_entries.Get(pubentryHandle)) {
+    if (entry->publisher) {
+      m_impl->RemoveLocalPublisher(entry->publisher->handle);
+      entry->publisher = nullptr;
+    }
+  } else {
+    // TODO: report warning
+    return;
+  }
+}
+
+NT_Entry LocalStorage::GetEntry(NT_Topic topicHandle, NT_Type type,
+                                std::string_view typeStr,
+                                const PubSubOptions& options) {
+  std::scoped_lock lock{m_mutex};
+
+  // Get the topic
+  auto* topic = m_impl->m_topics.Get(topicHandle);
+  if (!topic) {
+    return 0;
+  }
+
+  if (topic->localSubscribers.size() >= kMaxSubscribers) {
+    WPI_ERROR(
+        m_impl->m_logger,
+        "reached maximum number of subscribers to '{}', not creating entry",
+        topic->name);
+    return 0;
+  }
+
+  // Create subscriber
+  auto subscriber =
+      m_impl->AddLocalSubscriber(topic, PubSubConfig{type, typeStr, options});
+
+  // Create entry
+  return m_impl->AddEntry(subscriber)->handle;
+}
+
+void LocalStorage::ReleaseEntry(NT_Entry entryHandle) {
+  std::scoped_lock lock{m_mutex};
+  m_impl->RemoveSubEntry(entryHandle);
+}
+
+void LocalStorage::Release(NT_Handle pubsubentryHandle) {
+  switch (Handle{pubsubentryHandle}.GetType()) {
+    case Handle::kEntry:
+      ReleaseEntry(pubsubentryHandle);
+      break;
+    case Handle::kPublisher:
+      Unpublish(pubsubentryHandle);
+      break;
+    case Handle::kSubscriber:
+      Unsubscribe(pubsubentryHandle);
+      break;
+    case Handle::kMultiSubscriber:
+      UnsubscribeMultiple(pubsubentryHandle);
+      break;
+    default:
+      break;
+  }
+}
+
+NT_Topic LocalStorage::GetTopicFromHandle(NT_Handle pubsubentryHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto topic = m_impl->GetTopic(pubsubentryHandle)) {
+    return topic->handle;
+  } else {
+    return {};
+  }
+}
+
+bool LocalStorage::SetEntryValue(NT_Handle pubentryHandle, const Value& value) {
+  std::scoped_lock lock{m_mutex};
+  return m_impl->SetEntryValue(pubentryHandle, value);
+}
+
+bool LocalStorage::SetDefaultEntryValue(NT_Handle pubsubentryHandle,
+                                        const Value& value) {
+  std::scoped_lock lock{m_mutex};
+  return m_impl->SetDefaultEntryValue(pubsubentryHandle, value);
+}
+
+TimestampedBoolean LocalStorage::GetAtomicBoolean(NT_Handle subentryHandle,
+                                                  bool defaultValue) {
+  std::scoped_lock lock{m_mutex};
+  Value* value = m_impl->GetSubEntryValue(subentryHandle);
+  if (value && value->type() == NT_BOOLEAN) {
+    return {value->time(), value->server_time(), value->GetBoolean()};
+  } else {
+    return {0, 0, defaultValue};
+  }
+}
+
+TimestampedString LocalStorage::GetAtomicString(NT_Handle subentryHandle,
+                                                std::string_view defaultValue) {
+  std::scoped_lock lock{m_mutex};
+  Value* value = m_impl->GetSubEntryValue(subentryHandle);
+  if (value && value->type() == NT_STRING) {
+    return {value->time(), value->server_time(),
+            std::string{value->GetString()}};
+  } else {
+    return {0, 0, std::string{defaultValue}};
+  }
+}
+
+TimestampedStringView LocalStorage::GetAtomicString(
+    NT_Handle subentryHandle, wpi::SmallVectorImpl<char>& buf,
+    std::string_view defaultValue) {
+  std::scoped_lock lock{m_mutex};
+  Value* value = m_impl->GetSubEntryValue(subentryHandle);
+  if (value && value->type() == NT_STRING) {
+    auto str = value->GetString();
+    buf.assign(str.begin(), str.end());
+    return {value->time(), value->server_time(), {buf.data(), buf.size()}};
+  } else {
+    return {0, 0, defaultValue};
+  }
+}
+
+template <typename T, typename U>
+static T GetAtomicNumber(Value* value, U defaultValue) {
+  if (value && value->type() == NT_INTEGER) {
+    return {value->time(), value->server_time(),
+            static_cast<U>(value->GetInteger())};
+  } else if (value && value->type() == NT_FLOAT) {
+    return {value->time(), value->server_time(),
+            static_cast<U>(value->GetFloat())};
+  } else if (value && value->type() == NT_DOUBLE) {
+    return {value->time(), value->server_time(),
+            static_cast<U>(value->GetDouble())};
+  } else {
+    return {0, 0, defaultValue};
+  }
+}
+
+template <typename T, typename U>
+static T GetAtomicNumberArray(Value* value, std::span<const U> defaultValue) {
+  if (value && value->type() == NT_INTEGER_ARRAY) {
+    auto arr = value->GetIntegerArray();
+    return {value->time(), value->server_time(), {arr.begin(), arr.end()}};
+  } else if (value && value->type() == NT_FLOAT_ARRAY) {
+    auto arr = value->GetFloatArray();
+    return {value->time(), value->server_time(), {arr.begin(), arr.end()}};
+  } else if (value && value->type() == NT_DOUBLE_ARRAY) {
+    auto arr = value->GetDoubleArray();
+    return {value->time(), value->server_time(), {arr.begin(), arr.end()}};
+  } else {
+    return {0, 0, {defaultValue.begin(), defaultValue.end()}};
+  }
+}
+
+template <typename T, typename U>
+static T GetAtomicNumberArray(Value* value, wpi::SmallVectorImpl<U>& buf,
+                              std::span<const U> defaultValue) {
+  if (value && value->type() == NT_INTEGER_ARRAY) {
+    auto str = value->GetIntegerArray();
+    buf.assign(str.begin(), str.end());
+    return {value->time(), value->server_time(), {buf.data(), buf.size()}};
+  } else if (value && value->type() == NT_FLOAT_ARRAY) {
+    auto str = value->GetFloatArray();
+    buf.assign(str.begin(), str.end());
+    return {value->time(), value->server_time(), {buf.data(), buf.size()}};
+  } else if (value && value->type() == NT_DOUBLE_ARRAY) {
+    auto str = value->GetDoubleArray();
+    buf.assign(str.begin(), str.end());
+    return {value->time(), value->server_time(), {buf.data(), buf.size()}};
+  } else {
+    buf.assign(defaultValue.begin(), defaultValue.end());
+    return {0, 0, {buf.data(), buf.size()}};
+  }
+}
+
+#define GET_ATOMIC_NUMBER(Name, dtype)                                  \
+  Timestamped##Name LocalStorage::GetAtomic##Name(NT_Handle subentry,   \
+                                                  dtype defaultValue) { \
+    std::scoped_lock lock{m_mutex};                                     \
+    return GetAtomicNumber<Timestamped##Name>(                          \
+        m_impl->GetSubEntryValue(subentry), defaultValue);              \
+  }                                                                     \
+                                                                        \
+  Timestamped##Name##Array LocalStorage::GetAtomic##Name##Array(        \
+      NT_Handle subentry, std::span<const dtype> defaultValue) {        \
+    std::scoped_lock lock{m_mutex};                                     \
+    return GetAtomicNumberArray<Timestamped##Name##Array>(              \
+        m_impl->GetSubEntryValue(subentry), defaultValue);              \
+  }                                                                     \
+                                                                        \
+  Timestamped##Name##ArrayView LocalStorage::GetAtomic##Name##Array(    \
+      NT_Handle subentry, wpi::SmallVectorImpl<dtype>& buf,             \
+      std::span<const dtype> defaultValue) {                            \
+    std::scoped_lock lock{m_mutex};                                     \
+    return GetAtomicNumberArray<Timestamped##Name##ArrayView>(          \
+        m_impl->GetSubEntryValue(subentry), buf, defaultValue);         \
+  }
+
+GET_ATOMIC_NUMBER(Integer, int64_t)
+GET_ATOMIC_NUMBER(Float, float)
+GET_ATOMIC_NUMBER(Double, double)
+
+#define GET_ATOMIC_ARRAY(Name, dtype)                                         \
+  Timestamped##Name LocalStorage::GetAtomic##Name(                            \
+      NT_Handle subentry, std::span<const dtype> defaultValue) {              \
+    std::scoped_lock lock{m_mutex};                                           \
+    Value* value = m_impl->GetSubEntryValue(subentry);                        \
+    if (value && value->Is##Name()) {                                         \
+      auto arr = value->Get##Name();                                          \
+      return {value->time(), value->server_time(), {arr.begin(), arr.end()}}; \
+    } else {                                                                  \
+      return {0, 0, {defaultValue.begin(), defaultValue.end()}};              \
+    }                                                                         \
+  }
+
+GET_ATOMIC_ARRAY(Raw, uint8_t)
+GET_ATOMIC_ARRAY(BooleanArray, int)
+GET_ATOMIC_ARRAY(StringArray, std::string)
+
+#define GET_ATOMIC_SMALL_ARRAY(Name, dtype)                                   \
+  Timestamped##Name##View LocalStorage::GetAtomic##Name(                      \
+      NT_Handle subentry, wpi::SmallVectorImpl<dtype>& buf,                   \
+      std::span<const dtype> defaultValue) {                                  \
+    std::scoped_lock lock{m_mutex};                                           \
+    Value* value = m_impl->GetSubEntryValue(subentry);                        \
+    if (value && value->Is##Name()) {                                         \
+      auto str = value->Get##Name();                                          \
+      buf.assign(str.begin(), str.end());                                     \
+      return {value->time(), value->server_time(), {buf.data(), buf.size()}}; \
+    } else {                                                                  \
+      buf.assign(defaultValue.begin(), defaultValue.end());                   \
+      return {0, 0, {buf.data(), buf.size()}};                                \
+    }                                                                         \
+  }
+
+GET_ATOMIC_SMALL_ARRAY(Raw, uint8_t)
+GET_ATOMIC_SMALL_ARRAY(BooleanArray, int)
+
+std::vector<Value> LocalStorage::ReadQueueValue(NT_Handle subentry) {
+  std::scoped_lock lock{m_mutex};
+  auto subscriber = m_impl->GetSubEntry(subentry);
+  if (!subscriber) {
+    return {};
+  }
+  std::vector<Value> rv;
+  rv.reserve(subscriber->pollStorage.size());
+  for (auto&& val : subscriber->pollStorage) {
+    rv.emplace_back(std::move(val));
+  }
+  subscriber->pollStorage.reset();
+  return rv;
+}
+
+std::vector<TimestampedBoolean> LocalStorage::ReadQueueBoolean(
+    NT_Handle subentry) {
+  std::scoped_lock lock{m_mutex};
+  auto subscriber = m_impl->GetSubEntry(subentry);
+  if (!subscriber) {
+    return {};
+  }
+  std::vector<TimestampedBoolean> rv;
+  rv.reserve(subscriber->pollStorage.size());
+  for (auto&& val : subscriber->pollStorage) {
+    if (val.IsBoolean()) {
+      rv.emplace_back(val.time(), val.server_time(), val.GetBoolean());
+    }
+  }
+  subscriber->pollStorage.reset();
+  return rv;
+}
+
+std::vector<TimestampedString> LocalStorage::ReadQueueString(
+    NT_Handle subentry) {
+  std::scoped_lock lock{m_mutex};
+  auto subscriber = m_impl->GetSubEntry(subentry);
+  if (!subscriber) {
+    return {};
+  }
+  std::vector<TimestampedString> rv;
+  rv.reserve(subscriber->pollStorage.size());
+  for (auto&& val : subscriber->pollStorage) {
+    if (val.IsString()) {
+      rv.emplace_back(val.time(), val.server_time(),
+                      std::string{val.GetString()});
+    }
+  }
+  subscriber->pollStorage.reset();
+  return rv;
+}
+
+#define READ_QUEUE_ARRAY(Name)                                         \
+  std::vector<Timestamped##Name> LocalStorage::ReadQueue##Name(        \
+      NT_Handle subentry) {                                            \
+    std::scoped_lock lock{m_mutex};                                    \
+    auto subscriber = m_impl->GetSubEntry(subentry);                   \
+    if (!subscriber) {                                                 \
+      return {};                                                       \
+    }                                                                  \
+    std::vector<Timestamped##Name> rv;                                 \
+    rv.reserve(subscriber->pollStorage.size());                        \
+    for (auto&& val : subscriber->pollStorage) {                       \
+      if (val.Is##Name()) {                                            \
+        auto arr = val.Get##Name();                                    \
+        rv.emplace_back(Timestamped##Name{                             \
+            val.time(), val.server_time(), {arr.begin(), arr.end()}}); \
+      }                                                                \
+    }                                                                  \
+    subscriber->pollStorage.reset();                                   \
+    return rv;                                                         \
+  }
+
+READ_QUEUE_ARRAY(Raw)
+READ_QUEUE_ARRAY(BooleanArray)
+READ_QUEUE_ARRAY(StringArray)
+
+template <typename T>
+static std::vector<T> ReadQueueNumber(SubscriberData* subscriber) {
+  if (!subscriber) {
+    return {};
+  }
+  std::vector<T> rv;
+  rv.reserve(subscriber->pollStorage.size());
+  for (auto&& val : subscriber->pollStorage) {
+    auto ts = val.time();
+    auto sts = val.server_time();
+    if (val.IsInteger()) {
+      rv.emplace_back(T(ts, sts, val.GetInteger()));
+    } else if (val.IsFloat()) {
+      rv.emplace_back(T(ts, sts, val.GetFloat()));
+    } else if (val.IsDouble()) {
+      rv.emplace_back(T(ts, sts, val.GetDouble()));
+    }
+  }
+  subscriber->pollStorage.reset();
+  return rv;
+}
+
+template <typename T>
+static std::vector<T> ReadQueueNumberArray(SubscriberData* subscriber) {
+  if (!subscriber) {
+    return {};
+  }
+  std::vector<T> rv;
+  rv.reserve(subscriber->pollStorage.size());
+  for (auto&& val : subscriber->pollStorage) {
+    auto ts = val.time();
+    auto sts = val.server_time();
+    if (val.IsIntegerArray()) {
+      auto arr = val.GetIntegerArray();
+      rv.emplace_back(T{ts, sts, {arr.begin(), arr.end()}});
+    } else if (val.IsFloatArray()) {
+      auto arr = val.GetFloatArray();
+      rv.emplace_back(T{ts, sts, {arr.begin(), arr.end()}});
+    } else if (val.IsDoubleArray()) {
+      auto arr = val.GetDoubleArray();
+      rv.emplace_back(T{ts, sts, {arr.begin(), arr.end()}});
+    }
+  }
+  subscriber->pollStorage.reset();
+  return rv;
+}
+
+#define READ_QUEUE_NUMBER(Name)                                               \
+  std::vector<Timestamped##Name> LocalStorage::ReadQueue##Name(               \
+      NT_Handle subentry) {                                                   \
+    std::scoped_lock lock{m_mutex};                                           \
+    return ReadQueueNumber<Timestamped##Name>(m_impl->GetSubEntry(subentry)); \
+  }                                                                           \
+                                                                              \
+  std::vector<Timestamped##Name##Array> LocalStorage::ReadQueue##Name##Array( \
+      NT_Handle subentry) {                                                   \
+    std::scoped_lock lock{m_mutex};                                           \
+    return ReadQueueNumberArray<Timestamped##Name##Array>(                    \
+        m_impl->GetSubEntry(subentry));                                       \
+  }
+
+READ_QUEUE_NUMBER(Integer)
+READ_QUEUE_NUMBER(Float)
+READ_QUEUE_NUMBER(Double)
+
+Value LocalStorage::GetEntryValue(NT_Handle subentryHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto subscriber = m_impl->GetSubEntry(subentryHandle)) {
+    if (subscriber->config.type == NT_UNASSIGNED ||
+        !subscriber->topic->lastValue ||
+        subscriber->config.type == subscriber->topic->lastValue.type()) {
+      return subscriber->topic->lastValue;
+    } else if (IsNumericCompatible(subscriber->config.type,
+                                   subscriber->topic->lastValue.type())) {
+      return ConvertNumericValue(subscriber->topic->lastValue,
+                                 subscriber->config.type);
+    }
+  }
+  return {};
+}
+
+void LocalStorage::SetEntryFlags(NT_Entry entryHandle, unsigned int flags) {
+  std::scoped_lock lock{m_mutex};
+  if (auto entry = m_impl->m_entries.Get(entryHandle)) {
+    m_impl->SetFlags(entry->subscriber->topic, flags);
+  }
+}
+
+unsigned int LocalStorage::GetEntryFlags(NT_Entry entryHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto entry = m_impl->m_entries.Get(entryHandle)) {
+    return entry->subscriber->topic->flags;
+  } else {
+    return 0;
+  }
+}
+
+NT_Entry LocalStorage::GetEntry(std::string_view name) {
+  if (name.empty()) {
+    return {};
+  }
+
+  std::scoped_lock lock{m_mutex};
+
+  // Get the topic data
+  auto* topic = m_impl->GetOrCreateTopic(name);
+
+  if (topic->entry == 0) {
+    if (topic->localSubscribers.size() >= kMaxSubscribers) {
+      WPI_ERROR(
+          m_impl->m_logger,
+          "reached maximum number of subscribers to '{}', not creating entry",
+          topic->name);
+      return 0;
+    }
+
+    // Create subscriber
+    auto* subscriber = m_impl->AddLocalSubscriber(topic, {});
+
+    // Create entry
+    topic->entry = m_impl->AddEntry(subscriber)->handle;
+  }
+
+  return topic->entry;
+}
+
+std::string LocalStorage::GetEntryName(NT_Handle subentryHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto subscriber = m_impl->GetSubEntry(subentryHandle)) {
+    return subscriber->topic->name;
+  } else {
+    return {};
+  }
+}
+
+NT_Type LocalStorage::GetEntryType(NT_Handle subentryHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto subscriber = m_impl->GetSubEntry(subentryHandle)) {
+    return subscriber->topic->type;
+  } else {
+    return {};
+  }
+}
+
+int64_t LocalStorage::GetEntryLastChange(NT_Handle subentryHandle) {
+  std::scoped_lock lock{m_mutex};
+  if (auto subscriber = m_impl->GetSubEntry(subentryHandle)) {
+    return subscriber->topic->lastValue.time();
+  } else {
+    return 0;
+  }
+}
+
+void LocalStorage::AddListener(NT_Listener listener,
+                               std::span<const std::string_view> prefixes,
+                               unsigned int mask) {
+  mask &= (NT_EVENT_TOPIC | NT_EVENT_VALUE_ALL | NT_EVENT_IMMEDIATE);
+  std::scoped_lock lock{m_mutex};
+  m_impl->AddListener(listener, prefixes, mask);
+}
+
+void LocalStorage::AddListener(NT_Listener listener, NT_Handle handle,
+                               unsigned int mask) {
+  mask &= (NT_EVENT_TOPIC | NT_EVENT_VALUE_ALL | NT_EVENT_IMMEDIATE);
+  std::scoped_lock lock{m_mutex};
+  m_impl->AddListener(listener, handle, mask);
+}
+
+void LocalStorage::RemoveListener(NT_Listener listener, unsigned int mask) {
+  std::scoped_lock lock{m_mutex};
+  m_impl->RemoveListener(listener, mask);
+}
+
+NT_DataLogger LocalStorage::StartDataLog(wpi::log::DataLog& log,
+                                         std::string_view prefix,
+                                         std::string_view logPrefix) {
+  std::scoped_lock lock{m_mutex};
+  auto datalogger =
+      m_impl->m_dataloggers.Add(m_impl->m_inst, log, prefix, logPrefix);
+
+  // start logging any matching topics
+  auto now = nt::Now();
+  for (auto&& topic : m_impl->m_topics) {
+    if (!wpi::starts_with(topic->name, prefix) ||
+        topic->type == NT_UNASSIGNED || topic->typeStr.empty()) {
+      continue;
+    }
+    topic->datalogs.emplace_back(log, datalogger->Start(topic.get(), now),
+                                 datalogger->handle);
+
+    // log current value, if any
+    if (!topic->lastValue) {
+      continue;
+    }
+    topic->datalogType = topic->type;
+    topic->datalogs.back().Append(topic->lastValue);
+  }
+
+  return datalogger->handle;
+}
+
+void LocalStorage::StopDataLog(NT_DataLogger logger) {
+  std::scoped_lock lock{m_mutex};
+  if (auto datalogger = m_impl->m_dataloggers.Remove(logger)) {
+    // finish any active entries
+    auto now = Now();
+    for (auto&& topic : m_impl->m_topics) {
+      auto it =
+          std::find_if(topic->datalogs.begin(), topic->datalogs.end(),
+                       [&](const auto& elem) { return elem.logger == logger; });
+      if (it != topic->datalogs.end()) {
+        it->log->Finish(it->entry, now);
+        topic->datalogs.erase(it);
+      }
+    }
+  }
+}
+
+void LocalStorage::Reset() {
+  std::scoped_lock lock{m_mutex};
+  m_impl = std::make_unique<Impl>(m_impl->m_inst, m_impl->m_listenerStorage,
+                                  m_impl->m_logger);
+}
diff --git a/ntcore/src/main/native/cpp/LocalStorage.h b/ntcore/src/main/native/cpp/LocalStorage.h
new file mode 100644
index 0000000..a93adb0
--- /dev/null
+++ b/ntcore/src/main/native/cpp/LocalStorage.h
@@ -0,0 +1,219 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include <wpi/mutex.h>
+
+#include "net/NetworkInterface.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt {
+
+class IListenerStorage;
+
+class LocalStorage final : public net::ILocalStorage {
+ public:
+  LocalStorage(int inst, IListenerStorage& listenerStorage,
+               wpi::Logger& logger);
+  LocalStorage(const LocalStorage&) = delete;
+  LocalStorage& operator=(const LocalStorage&) = delete;
+  ~LocalStorage() final;
+
+  // network interface functions
+  NT_Topic NetworkAnnounce(std::string_view name, std::string_view typeStr,
+                           const wpi::json& properties,
+                           NT_Publisher pubHandle) final;
+  void NetworkUnannounce(std::string_view name) final;
+  void NetworkPropertiesUpdate(std::string_view name, const wpi::json& update,
+                               bool ack) final;
+  void NetworkSetValue(NT_Topic topicHandle, const Value& value) final;
+
+  void StartNetwork(net::NetworkInterface* network) final;
+  void ClearNetwork() final;
+
+  // User functions.  These are the actual implementations of the corresponding
+  // user API functions in ntcore_cpp.
+
+  std::vector<NT_Topic> GetTopics(std::string_view prefix, unsigned int types);
+  std::vector<NT_Topic> GetTopics(std::string_view prefix,
+                                  std::span<const std::string_view> types);
+
+  std::vector<TopicInfo> GetTopicInfo(std::string_view prefix,
+                                      unsigned int types);
+  std::vector<TopicInfo> GetTopicInfo(std::string_view prefix,
+                                      std::span<const std::string_view> types);
+
+  NT_Topic GetTopic(std::string_view name);
+
+  std::string GetTopicName(NT_Topic topic);
+
+  NT_Type GetTopicType(NT_Topic topic);
+
+  std::string GetTopicTypeString(NT_Topic topic);
+
+  void SetTopicPersistent(NT_Topic topic, bool value);
+
+  bool GetTopicPersistent(NT_Topic topic);
+
+  void SetTopicRetained(NT_Topic topic, bool value);
+
+  bool GetTopicRetained(NT_Topic topic);
+
+  bool GetTopicExists(NT_Handle handle);
+
+  wpi::json GetTopicProperty(NT_Topic topic, std::string_view name);
+
+  void SetTopicProperty(NT_Topic topic, std::string_view name,
+                        const wpi::json& value);
+
+  void DeleteTopicProperty(NT_Topic topic, std::string_view name);
+
+  wpi::json GetTopicProperties(NT_Topic topic);
+
+  bool SetTopicProperties(NT_Topic topic, const wpi::json& update);
+
+  TopicInfo GetTopicInfo(NT_Topic topic);
+
+  NT_Subscriber Subscribe(NT_Topic topic, NT_Type type,
+                          std::string_view typeStr,
+                          const PubSubOptions& options);
+
+  void Unsubscribe(NT_Subscriber sub);
+
+  NT_MultiSubscriber SubscribeMultiple(
+      std::span<const std::string_view> prefixes, const PubSubOptions& options);
+
+  void UnsubscribeMultiple(NT_MultiSubscriber subHandle);
+
+  NT_Publisher Publish(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                       const wpi::json& properties,
+                       const PubSubOptions& options);
+
+  void Unpublish(NT_Handle pubentry);
+
+  NT_Entry GetEntry(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                    const PubSubOptions& options);
+
+  void ReleaseEntry(NT_Entry entry);
+
+  void Release(NT_Handle pubsubentry);
+
+  NT_Topic GetTopicFromHandle(NT_Handle pubsubentry);
+
+  bool SetEntryValue(NT_Handle pubentry, const Value& value);
+
+  bool SetDefaultEntryValue(NT_Handle pubsubentry, const Value& value);
+
+  TimestampedBoolean GetAtomicBoolean(NT_Handle subentry, bool defaultValue);
+  TimestampedInteger GetAtomicInteger(NT_Handle subentry, int64_t defaultValue);
+  TimestampedFloat GetAtomicFloat(NT_Handle subentry, float defaultValue);
+  TimestampedDouble GetAtomicDouble(NT_Handle subentry, double defaultValue);
+  TimestampedString GetAtomicString(NT_Handle subentry,
+                                    std::string_view defaultValue);
+  TimestampedRaw GetAtomicRaw(NT_Handle subentry,
+                              std::span<const uint8_t> defaultValue);
+  TimestampedBooleanArray GetAtomicBooleanArray(
+      NT_Handle subentry, std::span<const int> defaultValue);
+  TimestampedIntegerArray GetAtomicIntegerArray(
+      NT_Handle subentry, std::span<const int64_t> defaultValue);
+  TimestampedFloatArray GetAtomicFloatArray(
+      NT_Handle subentry, std::span<const float> defaultValue);
+  TimestampedDoubleArray GetAtomicDoubleArray(
+      NT_Handle subentry, std::span<const double> defaultValue);
+  TimestampedStringArray GetAtomicStringArray(
+      NT_Handle subentry, std::span<const std::string> defaultValue);
+
+  TimestampedStringView GetAtomicString(NT_Handle subentry,
+                                        wpi::SmallVectorImpl<char>& buf,
+                                        std::string_view defaultValue);
+  TimestampedRawView GetAtomicRaw(NT_Handle subentry,
+                                  wpi::SmallVectorImpl<uint8_t>& buf,
+                                  std::span<const uint8_t> defaultValue);
+  TimestampedBooleanArrayView GetAtomicBooleanArray(
+      NT_Handle subentry, wpi::SmallVectorImpl<int>& buf,
+      std::span<const int> defaultValue);
+  TimestampedIntegerArrayView GetAtomicIntegerArray(
+      NT_Handle subentry, wpi::SmallVectorImpl<int64_t>& buf,
+      std::span<const int64_t> defaultValue);
+  TimestampedFloatArrayView GetAtomicFloatArray(
+      NT_Handle subentry, wpi::SmallVectorImpl<float>& buf,
+      std::span<const float> defaultValue);
+  TimestampedDoubleArrayView GetAtomicDoubleArray(
+      NT_Handle subentry, wpi::SmallVectorImpl<double>& buf,
+      std::span<const double> defaultValue);
+
+  std::vector<Value> ReadQueueValue(NT_Handle subentry);
+
+  std::vector<TimestampedBoolean> ReadQueueBoolean(NT_Handle subentry);
+  std::vector<TimestampedInteger> ReadQueueInteger(NT_Handle subentry);
+  std::vector<TimestampedFloat> ReadQueueFloat(NT_Handle subentry);
+  std::vector<TimestampedDouble> ReadQueueDouble(NT_Handle subentry);
+  std::vector<TimestampedString> ReadQueueString(NT_Handle subentry);
+  std::vector<TimestampedRaw> ReadQueueRaw(NT_Handle subentry);
+  std::vector<TimestampedBooleanArray> ReadQueueBooleanArray(
+      NT_Handle subentry);
+  std::vector<TimestampedIntegerArray> ReadQueueIntegerArray(
+      NT_Handle subentry);
+  std::vector<TimestampedFloatArray> ReadQueueFloatArray(NT_Handle subentry);
+  std::vector<TimestampedDoubleArray> ReadQueueDoubleArray(NT_Handle subentry);
+  std::vector<TimestampedStringArray> ReadQueueStringArray(NT_Handle subentry);
+
+  //
+  // Backwards compatible user functions
+  //
+
+  Value GetEntryValue(NT_Handle subentry);
+  void SetEntryFlags(NT_Entry entry, unsigned int flags);
+  unsigned int GetEntryFlags(NT_Entry entry);
+
+  // Index-only
+  NT_Entry GetEntry(std::string_view name);
+
+  std::string GetEntryName(NT_Entry entry);
+  NT_Type GetEntryType(NT_Entry entry);
+  int64_t GetEntryLastChange(NT_Entry entry);
+
+  //
+  // Listener functions
+  //
+
+  void AddListener(NT_Listener listener,
+                   std::span<const std::string_view> prefixes,
+                   unsigned int mask);
+  void AddListener(NT_Listener listener, NT_Handle handle, unsigned int mask);
+
+  void RemoveListener(NT_Listener listener, unsigned int mask);
+
+  //
+  // Data log functions
+  //
+  NT_DataLogger StartDataLog(wpi::log::DataLog& log, std::string_view prefix,
+                             std::string_view logPrefix);
+  void StopDataLog(NT_DataLogger logger);
+
+  void Reset();
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+
+  wpi::mutex m_mutex;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/Log.h b/ntcore/src/main/native/cpp/Log.h
index d3066d7..7e052f9 100644
--- a/ntcore/src/main/native/cpp/Log.h
+++ b/ntcore/src/main/native/cpp/Log.h
@@ -2,22 +2,27 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_LOG_H_
-#define NTCORE_LOG_H_
+#pragma once
 
 #include <wpi/Logger.h>
 
-#define LOG(level, format, ...) WPI_LOG(m_logger, level, format, __VA_ARGS__)
+#define LOG(level, format, ...) \
+  WPI_LOG(m_logger, level, format __VA_OPT__(, ) __VA_ARGS__)
 
 #undef ERROR
-#define ERROR(format, ...) WPI_ERROR(m_logger, format, __VA_ARGS__)
-#define WARNING(format, ...) WPI_WARNING(m_logger, format, __VA_ARGS__)
-#define INFO(format, ...) WPI_INFO(m_logger, format, __VA_ARGS__)
+#define ERROR(format, ...) \
+  WPI_ERROR(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
+#define WARNING(format, ...) \
+  WPI_WARNING(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
+#define INFO(format, ...) WPI_INFO(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
 
-#define DEBUG0(format, ...) WPI_DEBUG(m_logger, format, __VA_ARGS__)
-#define DEBUG1(format, ...) WPI_DEBUG1(m_logger, format, __VA_ARGS__)
-#define DEBUG2(format, ...) WPI_DEBUG2(m_logger, format, __VA_ARGS__)
-#define DEBUG3(format, ...) WPI_DEBUG3(m_logger, format, __VA_ARGS__)
-#define DEBUG4(format, ...) WPI_DEBUG4(m_logger, format, __VA_ARGS__)
-
-#endif  // NTCORE_LOG_H_
+#define DEBUG0(format, ...) \
+  WPI_DEBUG(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
+#define DEBUG1(format, ...) \
+  WPI_DEBUG1(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
+#define DEBUG2(format, ...) \
+  WPI_DEBUG2(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
+#define DEBUG3(format, ...) \
+  WPI_DEBUG3(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
+#define DEBUG4(format, ...) \
+  WPI_DEBUG4(m_logger, format __VA_OPT__(, ) __VA_ARGS__)
diff --git a/ntcore/src/main/native/cpp/LoggerImpl.cpp b/ntcore/src/main/native/cpp/LoggerImpl.cpp
index fcb59d6..f5742d5 100644
--- a/ntcore/src/main/native/cpp/LoggerImpl.cpp
+++ b/ntcore/src/main/native/cpp/LoggerImpl.cpp
@@ -5,23 +5,27 @@
 #include "LoggerImpl.h"
 
 #include <fmt/format.h>
+#include <wpi/Logger.h>
+#include <wpi/SmallVector.h>
 #include <wpi/fs.h>
 
+#include "IListenerStorage.h"
+
 using namespace nt;
 
 static void DefaultLogger(unsigned int level, const char* file,
                           unsigned int line, const char* msg) {
-  if (level == 20) {
+  if (level == wpi::WPI_LOG_INFO) {
     fmt::print(stderr, "NT: {}\n", msg);
     return;
   }
 
   std::string_view levelmsg;
-  if (level >= 50) {
+  if (level >= wpi::WPI_LOG_CRITICAL) {
     levelmsg = "CRITICAL";
-  } else if (level >= 40) {
+  } else if (level >= wpi::WPI_LOG_ERROR) {
     levelmsg = "ERROR";
-  } else if (level >= 30) {
+  } else if (level >= wpi::WPI_LOG_WARNING) {
     levelmsg = "WARNING";
   } else {
     return;
@@ -29,34 +33,107 @@
   fmt::print(stderr, "NT: {}: {} ({}:{})\n", levelmsg, msg, file, line);
 }
 
-LoggerImpl::LoggerImpl(int inst) : m_inst(inst) {}
+static constexpr unsigned int kFlagCritical = 1u << 16;
+static constexpr unsigned int kFlagError = 1u << 17;
+static constexpr unsigned int kFlagWarning = 1u << 18;
+static constexpr unsigned int kFlagInfo = 1u << 19;
+static constexpr unsigned int kFlagDebug = 1u << 20;
+static constexpr unsigned int kFlagDebug1 = 1u << 21;
+static constexpr unsigned int kFlagDebug2 = 1u << 22;
+static constexpr unsigned int kFlagDebug3 = 1u << 23;
+static constexpr unsigned int kFlagDebug4 = 1u << 24;
 
-void LoggerImpl::Start() {
-  DoStart(m_inst);
+static unsigned int LevelToFlag(unsigned int level) {
+  if (level >= wpi::WPI_LOG_CRITICAL) {
+    return EventFlags::kLogMessage | kFlagCritical;
+  } else if (level >= wpi::WPI_LOG_ERROR) {
+    return EventFlags::kLogMessage | kFlagError;
+  } else if (level >= wpi::WPI_LOG_WARNING) {
+    return EventFlags::kLogMessage | kFlagWarning;
+  } else if (level >= wpi::WPI_LOG_INFO) {
+    return EventFlags::kLogMessage | kFlagInfo;
+  } else if (level >= wpi::WPI_LOG_DEBUG) {
+    return EventFlags::kLogMessage | kFlagDebug;
+  } else if (level >= wpi::WPI_LOG_DEBUG1) {
+    return EventFlags::kLogMessage | kFlagDebug1;
+  } else if (level >= wpi::WPI_LOG_DEBUG2) {
+    return EventFlags::kLogMessage | kFlagDebug2;
+  } else if (level >= wpi::WPI_LOG_DEBUG3) {
+    return EventFlags::kLogMessage | kFlagDebug3;
+  } else if (level >= wpi::WPI_LOG_DEBUG4) {
+    return EventFlags::kLogMessage | kFlagDebug4;
+  } else {
+    return EventFlags::kLogMessage;
+  }
 }
 
-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);
+static unsigned int LevelsToEventMask(unsigned int minLevel,
+                                      unsigned int maxLevel) {
+  unsigned int mask = 0;
+  if (minLevel <= wpi::WPI_LOG_CRITICAL && maxLevel >= wpi::WPI_LOG_CRITICAL) {
+    mask |= kFlagCritical;
+  }
+  if (minLevel <= wpi::WPI_LOG_ERROR && maxLevel >= wpi::WPI_LOG_ERROR) {
+    mask |= kFlagError;
+  }
+  if (minLevel <= wpi::WPI_LOG_WARNING && maxLevel >= wpi::WPI_LOG_WARNING) {
+    mask |= kFlagWarning;
+  }
+  if (minLevel <= wpi::WPI_LOG_INFO && maxLevel >= wpi::WPI_LOG_INFO) {
+    mask |= kFlagInfo;
+  }
+  if (minLevel <= wpi::WPI_LOG_DEBUG && maxLevel >= wpi::WPI_LOG_DEBUG) {
+    mask |= kFlagDebug;
+  }
+  if (minLevel <= wpi::WPI_LOG_DEBUG1 && maxLevel >= wpi::WPI_LOG_DEBUG1) {
+    mask |= kFlagDebug1;
+  }
+  if (minLevel <= wpi::WPI_LOG_DEBUG2 && maxLevel >= wpi::WPI_LOG_DEBUG2) {
+    mask |= kFlagDebug2;
+  }
+  if (minLevel <= wpi::WPI_LOG_DEBUG3 && maxLevel >= wpi::WPI_LOG_DEBUG3) {
+    mask |= kFlagDebug3;
+  }
+  if (minLevel <= wpi::WPI_LOG_DEBUG4 && maxLevel >= wpi::WPI_LOG_DEBUG4) {
+    mask |= kFlagDebug4;
+  }
+  if (mask == 0) {
+    mask = EventFlags::kLogMessage;
+  }
+  return mask;
 }
 
-unsigned int LoggerImpl::AddPolled(unsigned int poller_uid,
-                                   unsigned int min_level,
-                                   unsigned int max_level) {
-  return DoAdd(poller_uid, min_level, max_level);
+LoggerImpl::LoggerImpl(IListenerStorage& listenerStorage)
+    : m_listenerStorage{listenerStorage} {}
+
+LoggerImpl::~LoggerImpl() = default;
+
+void LoggerImpl::AddListener(NT_Listener listener, unsigned int minLevel,
+                             unsigned int maxLevel) {
+  ++m_listenerCount;
+  std::scoped_lock lock{m_mutex};
+  m_listenerLevels.emplace_back(listener, minLevel, maxLevel);
+  m_listenerStorage.Activate(listener, LevelsToEventMask(minLevel, maxLevel),
+                             [](unsigned int mask, Event* event) {
+                               event->flags = NT_EVENT_LOGMESSAGE;
+                               return true;
+                             });
+}
+
+void LoggerImpl::RemoveListener(NT_Listener listener) {
+  --m_listenerCount;
+  std::scoped_lock lock{m_mutex};
+  std::erase_if(m_listenerLevels,
+                [&](auto& v) { return v.listener == listener; });
 }
 
 unsigned int LoggerImpl::GetMinLevel() {
-  auto thr = GetThread();
-  if (!thr) {
-    return NT_LOG_INFO;
-  }
+  // return 0;
+  std::scoped_lock lock{m_mutex};
   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;
+  for (auto&& listenerLevel : m_listenerLevels) {
+    if (listenerLevel.minLevel < level) {
+      level = listenerLevel.minLevel;
     }
   }
   return level;
@@ -65,11 +142,10 @@
 void LoggerImpl::Log(unsigned int level, const char* file, unsigned int line,
                      const char* msg) {
   auto filename = fs::path{file}.filename();
-  {
-    auto thr = GetThread();
-    if (!thr || thr->m_listeners.empty()) {
-      DefaultLogger(level, filename.string().c_str(), line, msg);
-    }
+  if (m_listenerCount == 0) {
+    DefaultLogger(level, filename.string().c_str(), line, msg);
+  } else {
+    m_listenerStorage.Notify(LevelToFlag(level), level, filename.string(), line,
+                             msg);
   }
-  Send(UINT_MAX, 0, level, filename.string(), line, msg);
 }
diff --git a/ntcore/src/main/native/cpp/LoggerImpl.h b/ntcore/src/main/native/cpp/LoggerImpl.h
index 2b577c1..13a1b80 100644
--- a/ntcore/src/main/native/cpp/LoggerImpl.h
+++ b/ntcore/src/main/native/cpp/LoggerImpl.h
@@ -2,76 +2,31 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_LOGGERIMPL_H_
-#define NTCORE_LOGGERIMPL_H_
+#pragma once
 
-#include <utility>
+#include <atomic>
+#include <vector>
 
-#include <wpi/CallbackManager.h>
+#include <wpi/mutex.h>
 
-#include "Handle.h"
+#include "IListenerStorage.h"
+#include "ntcore_c.h"
 #include "ntcore_cpp.h"
 
 namespace nt {
 
-namespace impl {
+class IListenerStorage;
 
-struct LoggerListenerData : public wpi::CallbackListenerData<
-                                std::function<void(const LogMessage& msg)>> {
-  LoggerListenerData() = default;
-  LoggerListenerData(std::function<void(const LogMessage& msg)> callback_,
-                     unsigned int min_level_, unsigned int max_level_)
-      : CallbackListenerData(callback_),
-        min_level(min_level_),
-        max_level(max_level_) {}
-  LoggerListenerData(unsigned int poller_uid_, unsigned int min_level_,
-                     unsigned int max_level_)
-      : CallbackListenerData(poller_uid_),
-        min_level(min_level_),
-        max_level(max_level_) {}
-
-  unsigned int min_level;
-  unsigned int max_level;
-};
-
-class LoggerThread
-    : public wpi::CallbackThread<LoggerThread, LogMessage, LoggerListenerData> {
+class LoggerImpl {
  public:
-  LoggerThread(std::function<void()> on_start, std::function<void()> on_exit,
-               int inst)
-      : CallbackThread(std::move(on_start), std::move(on_exit)), m_inst(inst) {}
+  explicit LoggerImpl(IListenerStorage& listenerStorage);
+  LoggerImpl(const LoggerImpl&) = delete;
+  LoggerImpl& operator=(const LoggerImpl&) = delete;
+  ~LoggerImpl();
 
-  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 wpi::CallbackManager<LoggerImpl, impl::LoggerThread> {
-  friend class LoggerTest;
-  friend class wpi::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);
+  void AddListener(NT_Listener listener, unsigned int minLevel,
+                   unsigned int maxLevel);
+  void RemoveListener(NT_Listener listener);
 
   unsigned int GetMinLevel();
 
@@ -79,9 +34,20 @@
            const char* msg);
 
  private:
-  int m_inst;
+  IListenerStorage& m_listenerStorage;
+  std::atomic_int m_listenerCount{0};
+  wpi::mutex m_mutex;
+
+  struct ListenerLevels {
+    ListenerLevels(NT_Listener listener, unsigned int minLevel,
+                   unsigned int maxLevel)
+        : listener{listener}, minLevel{minLevel}, maxLevel{maxLevel} {}
+
+    NT_Listener listener;
+    unsigned int minLevel;
+    unsigned int maxLevel;
+  };
+  std::vector<ListenerLevels> m_listenerLevels;
 };
 
 }  // namespace nt
-
-#endif  // NTCORE_LOGGERIMPL_H_
diff --git a/ntcore/src/main/native/cpp/Message.cpp b/ntcore/src/main/native/cpp/Message.cpp
deleted file mode 100644
index 61efed1..0000000
--- a/ntcore/src/main/native/cpp/Message.cpp
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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.assign(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.assign(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(std::string_view 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,
-                                              std::string_view 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(std::string_view 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,
-                                             std::string_view 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,
-                                              std::string_view 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
deleted file mode 100644
index ec34a75..0000000
--- a/ntcore/src/main/native/cpp/Message.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_MESSAGE_H_
-#define NTCORE_MESSAGE_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-#include <string_view>
-
-#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
-  };
-  using GetEntryTypeFunc = std::function<NT_Type(unsigned int id)>;
-
-  Message() = default;
-  Message(MsgType type, const private_init&) : m_type(type) {}
-
-  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.
-  std::string_view 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(std::string_view self_id);
-  static std::shared_ptr<Message> ServerHello(unsigned int flags,
-                                              std::string_view self_id);
-  static std::shared_ptr<Message> EntryAssign(std::string_view 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,
-                                             std::string_view params);
-  static std::shared_ptr<Message> RpcResponse(unsigned int id, unsigned int uid,
-                                              std::string_view result);
-
-  Message(const Message&) = delete;
-  Message& operator=(const Message&) = delete;
-
- private:
-  MsgType m_type{kUnknown};
-
-  // Message data.  Use varies by message type.
-  std::string m_str;
-  std::shared_ptr<Value> m_value;
-  unsigned int m_id{0};  // also used for proto_rev
-  unsigned int m_flags{0};
-  unsigned int m_seq_num_uid{0};
-};
-
-}  // namespace nt
-
-#endif  // NTCORE_MESSAGE_H_
diff --git a/ntcore/src/main/native/cpp/NetworkClient.cpp b/ntcore/src/main/native/cpp/NetworkClient.cpp
new file mode 100644
index 0000000..a329fb9
--- /dev/null
+++ b/ntcore/src/main/native/cpp/NetworkClient.cpp
@@ -0,0 +1,557 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "NetworkClient.h"
+
+#include <stdint.h>
+
+#include <atomic>
+#include <memory>
+#include <vector>
+
+#include <fmt/format.h>
+#include <wpi/SmallString.h>
+#include <wpi/StringExtras.h>
+#include <wpinet/DsClient.h>
+#include <wpinet/EventLoopRunner.h>
+#include <wpinet/HttpUtil.h>
+#include <wpinet/ParallelTcpConnector.h>
+#include <wpinet/WebSocket.h>
+#include <wpinet/uv/Async.h>
+#include <wpinet/uv/Loop.h>
+#include <wpinet/uv/Tcp.h>
+#include <wpinet/uv/Timer.h>
+#include <wpinet/uv/util.h>
+
+#include "IConnectionList.h"
+#include "Log.h"
+#include "net/ClientImpl.h"
+#include "net/Message.h"
+#include "net/NetworkLoopQueue.h"
+#include "net/WebSocketConnection.h"
+#include "net3/ClientImpl3.h"
+#include "net3/UvStreamConnection3.h"
+
+using namespace nt;
+namespace uv = wpi::uv;
+
+static constexpr uv::Timer::Time kReconnectRate{1000};
+static constexpr uv::Timer::Time kWebsocketHandshakeTimeout{500};
+// use a larger max message size for websockets
+static constexpr size_t kMaxMessageSize = 2 * 1024 * 1024;
+
+namespace {
+
+class NCImpl {
+ public:
+  NCImpl(int inst, std::string_view id, net::ILocalStorage& localStorage,
+         IConnectionList& connList, wpi::Logger& logger);
+  virtual ~NCImpl() = default;
+
+  // user-facing functions
+  void SetServers(std::span<const std::pair<std::string, unsigned int>> servers,
+                  unsigned int defaultPort);
+  void StartDSClient(unsigned int port);
+  void StopDSClient();
+
+  virtual void TcpConnected(uv::Tcp& tcp) = 0;
+  virtual void Disconnect(std::string_view reason);
+
+  // invariants
+  int m_inst;
+  net::ILocalStorage& m_localStorage;
+  IConnectionList& m_connList;
+  wpi::Logger& m_logger;
+  std::string m_id;
+
+  // used only from loop
+  std::shared_ptr<wpi::ParallelTcpConnector> m_parallelConnect;
+  std::shared_ptr<uv::Timer> m_readLocalTimer;
+  std::shared_ptr<uv::Timer> m_sendValuesTimer;
+  std::shared_ptr<uv::Async<>> m_flushLocal;
+  std::shared_ptr<uv::Async<>> m_flush;
+
+  std::vector<net::ClientMessage> m_localMsgs;
+
+  std::vector<std::pair<std::string, unsigned int>> m_servers;
+
+  std::pair<std::string, unsigned int> m_dsClientServer{"", 0};
+  std::shared_ptr<wpi::DsClient> m_dsClient;
+
+  // shared with user
+  std::atomic<uv::Async<>*> m_flushLocalAtomic{nullptr};
+  std::atomic<uv::Async<>*> m_flushAtomic{nullptr};
+
+  net::NetworkLoopQueue m_localQueue;
+
+  int m_connHandle = 0;
+
+  wpi::EventLoopRunner m_loopRunner;
+  uv::Loop& m_loop;
+};
+
+class NCImpl3 : public NCImpl {
+ public:
+  NCImpl3(int inst, std::string_view id, net::ILocalStorage& localStorage,
+          IConnectionList& connList, wpi::Logger& logger);
+  ~NCImpl3() override;
+
+  void HandleLocal();
+  void TcpConnected(uv::Tcp& tcp) final;
+  void Disconnect(std::string_view reason) override;
+
+  std::shared_ptr<net3::UvStreamConnection3> m_wire;
+  std::shared_ptr<net3::ClientImpl3> m_clientImpl;
+};
+
+class NCImpl4 : public NCImpl {
+ public:
+  NCImpl4(
+      int inst, std::string_view id, net::ILocalStorage& localStorage,
+      IConnectionList& connList, wpi::Logger& logger,
+      std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+          timeSyncUpdated);
+  ~NCImpl4() override;
+
+  void HandleLocal();
+  void TcpConnected(uv::Tcp& tcp) final;
+  void WsConnected(wpi::WebSocket& ws, uv::Tcp& tcp);
+  void Disconnect(std::string_view reason) override;
+
+  std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+      m_timeSyncUpdated;
+  std::shared_ptr<net::WebSocketConnection> m_wire;
+  std::unique_ptr<net::ClientImpl> m_clientImpl;
+};
+
+}  // namespace
+
+NCImpl::NCImpl(int inst, std::string_view id, net::ILocalStorage& localStorage,
+               IConnectionList& connList, wpi::Logger& logger)
+    : m_inst{inst},
+      m_localStorage{localStorage},
+      m_connList{connList},
+      m_logger{logger},
+      m_id{id},
+      m_localQueue{logger},
+      m_loop{*m_loopRunner.GetLoop()} {
+  m_localMsgs.reserve(net::NetworkLoopQueue::kInitialQueueSize);
+
+  INFO("starting network client");
+}
+
+void NCImpl::SetServers(
+    std::span<const std::pair<std::string, unsigned int>> servers,
+    unsigned int defaultPort) {
+  std::vector<std::pair<std::string, unsigned int>> serversCopy;
+  serversCopy.reserve(servers.size());
+  for (auto&& server : servers) {
+    serversCopy.emplace_back(wpi::trim(server.first),
+                             server.second == 0 ? defaultPort : server.second);
+  }
+
+  m_loopRunner.ExecAsync(
+      [this, servers = std::move(serversCopy)](uv::Loop&) mutable {
+        m_servers = std::move(servers);
+        if (m_dsClientServer.first.empty()) {
+          m_parallelConnect->SetServers(m_servers);
+        }
+      });
+}
+
+void NCImpl::StartDSClient(unsigned int port) {
+  m_loopRunner.ExecAsync([=, this](uv::Loop& loop) {
+    if (m_dsClient) {
+      return;
+    }
+    m_dsClientServer.second = port == 0 ? NT_DEFAULT_PORT4 : port;
+    m_dsClient = wpi::DsClient::Create(m_loop, m_logger);
+    m_dsClient->setIp.connect([this](std::string_view ip) {
+      m_dsClientServer.first = ip;
+      m_parallelConnect->SetServers({{m_dsClientServer}});
+    });
+    m_dsClient->clearIp.connect([this] {
+      m_dsClientServer.first.clear();
+      m_parallelConnect->SetServers(m_servers);
+    });
+  });
+}
+
+void NCImpl::StopDSClient() {
+  m_loopRunner.ExecAsync([this](uv::Loop& loop) {
+    if (m_dsClient) {
+      m_dsClient->Close();
+      m_dsClient.reset();
+    }
+  });
+}
+
+void NCImpl::Disconnect(std::string_view reason) {
+  if (m_readLocalTimer) {
+    m_readLocalTimer->Stop();
+  }
+  m_sendValuesTimer->Stop();
+  m_localStorage.ClearNetwork();
+  m_localQueue.ClearQueue();
+  m_connList.RemoveConnection(m_connHandle);
+  m_connHandle = 0;
+
+  // start trying to connect again
+  uv::Timer::SingleShot(m_loop, kReconnectRate,
+                        [this] { m_parallelConnect->Disconnected(); });
+}
+
+NCImpl3::NCImpl3(int inst, std::string_view id,
+                 net::ILocalStorage& localStorage, IConnectionList& connList,
+                 wpi::Logger& logger)
+    : NCImpl{inst, id, localStorage, connList, logger} {
+  m_loopRunner.ExecAsync([this](uv::Loop& loop) {
+    m_parallelConnect = wpi::ParallelTcpConnector::Create(
+        loop, kReconnectRate, m_logger,
+        [this](uv::Tcp& tcp) { TcpConnected(tcp); });
+
+    m_sendValuesTimer = uv::Timer::Create(loop);
+    m_sendValuesTimer->timeout.connect([this] {
+      if (m_clientImpl) {
+        HandleLocal();
+        m_clientImpl->SendPeriodic(m_loop.Now().count());
+      }
+    });
+
+    // set up flush async
+    m_flush = uv::Async<>::Create(m_loop);
+    m_flush->wakeup.connect([this] {
+      if (m_clientImpl) {
+        HandleLocal();
+        m_clientImpl->SendPeriodic(m_loop.Now().count());
+      }
+    });
+    m_flushAtomic = m_flush.get();
+
+    m_flushLocal = uv::Async<>::Create(m_loop);
+    m_flushLocal->wakeup.connect([this] { HandleLocal(); });
+    m_flushLocalAtomic = m_flushLocal.get();
+  });
+}
+
+NCImpl3::~NCImpl3() {
+  // must explicitly destroy these on loop
+  m_loopRunner.ExecSync([&](auto&) {
+    m_clientImpl.reset();
+    m_wire.reset();
+  });
+  // shut down loop here to avoid race
+  m_loopRunner.Stop();
+}
+
+void NCImpl3::HandleLocal() {
+  m_localQueue.ReadQueue(&m_localMsgs);
+  if (m_clientImpl) {
+    m_clientImpl->HandleLocal(m_localMsgs);
+  }
+}
+
+void NCImpl3::TcpConnected(uv::Tcp& tcp) {
+  tcp.SetNoDelay(true);
+
+  // create as shared_ptr and capture in lambda because there may be multiple
+  // simultaneous attempts
+  auto wire = std::make_shared<net3::UvStreamConnection3>(tcp);
+  auto clientImpl = std::make_shared<net3::ClientImpl3>(
+      m_loop.Now().count(), m_inst, *wire, m_logger, [this](uint32_t repeatMs) {
+        DEBUG4("Setting periodic timer to {}", repeatMs);
+        m_sendValuesTimer->Start(uv::Timer::Time{repeatMs},
+                                 uv::Timer::Time{repeatMs});
+      });
+  clientImpl->Start(
+      m_id, [this, wire,
+             clientWeak = std::weak_ptr<net3::ClientImpl3>{clientImpl}, &tcp] {
+        auto clientImpl = clientWeak.lock();
+        if (!clientImpl) {
+          return;
+        }
+        if (m_connList.IsConnected()) {
+          tcp.Close();  // no longer needed
+          return;
+        }
+
+        m_parallelConnect->Succeeded(tcp);
+
+        m_wire = std::move(wire);
+        m_clientImpl = std::move(clientImpl);
+
+        ConnectionInfo connInfo;
+        uv::AddrToName(tcp.GetPeer(), &connInfo.remote_ip,
+                       &connInfo.remote_port);
+        connInfo.protocol_version = 0x0300;
+
+        INFO("CONNECTED NT3 to {} port {}", connInfo.remote_ip,
+             connInfo.remote_port);
+        m_connHandle = m_connList.AddConnection(connInfo);
+
+        tcp.error.connect([this, &tcp](uv::Error err) {
+          DEBUG3("NT3 TCP error {}", err.str());
+          if (!tcp.IsLoopClosing()) {
+            Disconnect(err.str());
+          }
+        });
+        tcp.end.connect([this, &tcp] {
+          DEBUG3("NT3 TCP read ended");
+          if (!tcp.IsLoopClosing()) {
+            Disconnect("remote end closed connection");
+          }
+        });
+        tcp.closed.connect([this, &tcp] {
+          DEBUG3("NT3 TCP connection closed");
+          if (!tcp.IsLoopClosing()) {
+            Disconnect(m_wire->GetDisconnectReason());
+          }
+        });
+
+        m_clientImpl->SetLocal(&m_localStorage);
+        m_localStorage.StartNetwork(&m_localQueue);
+        HandleLocal();
+      });
+
+  tcp.SetData(clientImpl);
+  tcp.data.connect(
+      [clientImpl = clientImpl.get()](uv::Buffer& buf, size_t len) {
+        clientImpl->ProcessIncoming(
+            {reinterpret_cast<const uint8_t*>(buf.base), len});
+      });
+  tcp.StartRead();
+}
+
+void NCImpl3::Disconnect(std::string_view reason) {
+  INFO("DISCONNECTED NT3 connection: {}", reason);
+  m_clientImpl.reset();
+  m_wire.reset();
+  NCImpl::Disconnect(reason);
+}
+
+NCImpl4::NCImpl4(
+    int inst, std::string_view id, net::ILocalStorage& localStorage,
+    IConnectionList& connList, wpi::Logger& logger,
+    std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+        timeSyncUpdated)
+    : NCImpl{inst, id, localStorage, connList, logger},
+      m_timeSyncUpdated{std::move(timeSyncUpdated)} {
+  m_loopRunner.ExecAsync([this](uv::Loop& loop) {
+    m_parallelConnect = wpi::ParallelTcpConnector::Create(
+        loop, kReconnectRate, m_logger,
+        [this](uv::Tcp& tcp) { TcpConnected(tcp); });
+
+    m_readLocalTimer = uv::Timer::Create(loop);
+    m_readLocalTimer->timeout.connect([this] {
+      if (m_clientImpl) {
+        HandleLocal();
+        m_clientImpl->SendControl(m_loop.Now().count());
+      }
+    });
+    m_readLocalTimer->Start(uv::Timer::Time{100}, uv::Timer::Time{100});
+
+    m_sendValuesTimer = uv::Timer::Create(loop);
+    m_sendValuesTimer->timeout.connect([this] {
+      if (m_clientImpl) {
+        HandleLocal();
+        m_clientImpl->SendValues(m_loop.Now().count());
+      }
+    });
+
+    // set up flush async
+    m_flush = uv::Async<>::Create(m_loop);
+    m_flush->wakeup.connect([this] {
+      if (m_clientImpl) {
+        HandleLocal();
+        m_clientImpl->SendValues(m_loop.Now().count());
+      }
+    });
+    m_flushAtomic = m_flush.get();
+
+    m_flushLocal = uv::Async<>::Create(m_loop);
+    m_flushLocal->wakeup.connect([this] { HandleLocal(); });
+    m_flushLocalAtomic = m_flushLocal.get();
+  });
+}
+
+NCImpl4::~NCImpl4() {
+  // must explicitly destroy these on loop
+  m_loopRunner.ExecSync([&](auto&) {
+    m_clientImpl.reset();
+    m_wire.reset();
+  });
+  // shut down loop here to avoid race
+  m_loopRunner.Stop();
+}
+
+void NCImpl4::HandleLocal() {
+  m_localQueue.ReadQueue(&m_localMsgs);
+  if (m_clientImpl) {
+    m_clientImpl->HandleLocal(std::move(m_localMsgs));
+  }
+}
+
+void NCImpl4::TcpConnected(uv::Tcp& tcp) {
+  tcp.SetNoDelay(true);
+  // Start the WS client
+  if (m_logger.min_level() >= wpi::WPI_LOG_DEBUG4) {
+    std::string ip;
+    unsigned int port = 0;
+    uv::AddrToName(tcp.GetPeer(), &ip, &port);
+    DEBUG4("Starting WebSocket client on {} port {}", ip, port);
+  }
+  wpi::WebSocket::ClientOptions options;
+  options.handshakeTimeout = kWebsocketHandshakeTimeout;
+  wpi::SmallString<128> idBuf;
+  auto ws = wpi::WebSocket::CreateClient(
+      tcp, fmt::format("/nt/{}", wpi::EscapeURI(m_id, idBuf)), "",
+      {{"networktables.first.wpi.edu"}}, options);
+  ws->SetMaxMessageSize(kMaxMessageSize);
+  ws->open.connect([this, &tcp, ws = ws.get()](std::string_view) {
+    if (m_connList.IsConnected()) {
+      ws->Terminate(1006, "no longer needed");
+      return;
+    }
+    WsConnected(*ws, tcp);
+  });
+}
+
+void NCImpl4::WsConnected(wpi::WebSocket& ws, uv::Tcp& tcp) {
+  m_parallelConnect->Succeeded(tcp);
+
+  ConnectionInfo connInfo;
+  uv::AddrToName(tcp.GetPeer(), &connInfo.remote_ip, &connInfo.remote_port);
+  connInfo.protocol_version = 0x0400;
+
+  INFO("CONNECTED NT4 to {} port {}", connInfo.remote_ip, connInfo.remote_port);
+  m_connHandle = m_connList.AddConnection(connInfo);
+
+  m_wire = std::make_shared<net::WebSocketConnection>(ws);
+  m_clientImpl = std::make_unique<net::ClientImpl>(
+      m_loop.Now().count(), m_inst, *m_wire, m_logger, m_timeSyncUpdated,
+      [this](uint32_t repeatMs) {
+        DEBUG4("Setting periodic timer to {}", repeatMs);
+        m_sendValuesTimer->Start(uv::Timer::Time{repeatMs},
+                                 uv::Timer::Time{repeatMs});
+      });
+  m_clientImpl->SetLocal(&m_localStorage);
+  m_localStorage.StartNetwork(&m_localQueue);
+  HandleLocal();
+  m_clientImpl->SendInitial();
+  ws.closed.connect([this, &ws](uint16_t, std::string_view reason) {
+    if (!ws.GetStream().IsLoopClosing()) {
+      Disconnect(reason);
+    }
+  });
+  ws.text.connect([this](std::string_view data, bool) {
+    if (m_clientImpl) {
+      m_clientImpl->ProcessIncomingText(data);
+    }
+  });
+  ws.binary.connect([this](std::span<const uint8_t> data, bool) {
+    if (m_clientImpl) {
+      m_clientImpl->ProcessIncomingBinary(data);
+    }
+  });
+}
+
+void NCImpl4::Disconnect(std::string_view reason) {
+  INFO("DISCONNECTED NT4 connection: {}", reason);
+  m_clientImpl.reset();
+  m_wire.reset();
+  NCImpl::Disconnect(reason);
+  m_timeSyncUpdated(0, 0, false);
+}
+
+class NetworkClient::Impl final : public NCImpl4 {
+ public:
+  Impl(int inst, std::string_view id, net::ILocalStorage& localStorage,
+       IConnectionList& connList, wpi::Logger& logger,
+       std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+           timeSyncUpdated)
+      : NCImpl4{inst,     id,     localStorage,
+                connList, logger, std::move(timeSyncUpdated)} {}
+};
+
+NetworkClient::NetworkClient(
+    int inst, std::string_view id, net::ILocalStorage& localStorage,
+    IConnectionList& connList, wpi::Logger& logger,
+    std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+        timeSyncUpdated)
+    : m_impl{std::make_unique<Impl>(inst, id, localStorage, connList, logger,
+                                    std::move(timeSyncUpdated))} {}
+
+NetworkClient::~NetworkClient() {
+  m_impl->m_localStorage.ClearNetwork();
+  m_impl->m_connList.ClearConnections();
+}
+
+void NetworkClient::SetServers(
+    std::span<const std::pair<std::string, unsigned int>> servers) {
+  m_impl->SetServers(servers, NT_DEFAULT_PORT4);
+}
+
+void NetworkClient::StartDSClient(unsigned int port) {
+  m_impl->StartDSClient(port);
+}
+
+void NetworkClient::StopDSClient() {
+  m_impl->StopDSClient();
+}
+
+void NetworkClient::FlushLocal() {
+  m_impl->m_loopRunner.ExecAsync([this](uv::Loop&) { m_impl->HandleLocal(); });
+}
+
+void NetworkClient::Flush() {
+  m_impl->m_loopRunner.ExecAsync([this](uv::Loop&) {
+    m_impl->HandleLocal();
+    if (m_impl->m_clientImpl) {
+      m_impl->m_clientImpl->SendValues(m_impl->m_loop.Now().count());
+    }
+  });
+}
+
+class NetworkClient3::Impl final : public NCImpl3 {
+ public:
+  Impl(int inst, std::string_view id, net::ILocalStorage& localStorage,
+       IConnectionList& connList, wpi::Logger& logger)
+      : NCImpl3{inst, id, localStorage, connList, logger} {}
+};
+
+NetworkClient3::NetworkClient3(int inst, std::string_view id,
+                               net::ILocalStorage& localStorage,
+                               IConnectionList& connList, wpi::Logger& logger)
+    : m_impl{std::make_unique<Impl>(inst, id, localStorage, connList, logger)} {
+}
+
+NetworkClient3::~NetworkClient3() {
+  m_impl->m_localStorage.ClearNetwork();
+  m_impl->m_connList.ClearConnections();
+}
+
+void NetworkClient3::SetServers(
+    std::span<const std::pair<std::string, unsigned int>> servers) {
+  m_impl->SetServers(servers, NT_DEFAULT_PORT3);
+}
+
+void NetworkClient3::StartDSClient(unsigned int port) {
+  m_impl->StartDSClient(port);
+}
+
+void NetworkClient3::StopDSClient() {
+  m_impl->StopDSClient();
+}
+
+void NetworkClient3::FlushLocal() {
+  if (auto async = m_impl->m_flushLocalAtomic.load(std::memory_order_relaxed)) {
+    async->UnsafeSend();
+  }
+}
+
+void NetworkClient3::Flush() {
+  if (auto async = m_impl->m_flushAtomic.load(std::memory_order_relaxed)) {
+    async->UnsafeSend();
+  }
+}
diff --git a/ntcore/src/main/native/cpp/NetworkClient.h b/ntcore/src/main/native/cpp/NetworkClient.h
new file mode 100644
index 0000000..34bf379
--- /dev/null
+++ b/ntcore/src/main/native/cpp/NetworkClient.h
@@ -0,0 +1,74 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+
+#include "INetworkClient.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt::net {
+class ILocalStorage;
+}  // namespace nt::net
+
+namespace nt {
+
+class IConnectionList;
+
+class NetworkClient final : public INetworkClient {
+ public:
+  NetworkClient(
+      int inst, std::string_view id, net::ILocalStorage& localStorage,
+      IConnectionList& connList, wpi::Logger& logger,
+      std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+          timeSyncUpdated);
+  ~NetworkClient() final;
+
+  void SetServers(
+      std::span<const std::pair<std::string, unsigned int>> servers) final;
+
+  void StartDSClient(unsigned int port) final;
+  void StopDSClient() final;
+
+  void FlushLocal() final;
+  void Flush() final;
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+class NetworkClient3 final : public INetworkClient {
+ public:
+  NetworkClient3(int inst, std::string_view id,
+                 net::ILocalStorage& localStorage, IConnectionList& connList,
+                 wpi::Logger& logger);
+  ~NetworkClient3() final;
+
+  void SetServers(
+      std::span<const std::pair<std::string, unsigned int>> servers) final;
+
+  void StartDSClient(unsigned int port) final;
+  void StopDSClient() final;
+
+  void FlushLocal() final;
+  void Flush() final;
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/NetworkConnection.cpp b/ntcore/src/main/native/cpp/NetworkConnection.cpp
deleted file mode 100644
index 838eecb..0000000
--- a/ntcore/src/main/native/cpp/NetworkConnection.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "NetworkConnection.h"
-
-#include <utility>
-
-#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(std::move(handshake)),
-      m_get_entry_type(std::move(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 ({})", fmt::ptr(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(), std::string{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(std::string_view 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;
-          },
-          [&](auto msgs) {
-            m_outgoing.emplace(std::vector<std::shared_ptr<Message>>(
-                msgs.begin(), msgs.end()));
-          })) {
-    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={} with str={} id={} seq_num={}", msg->type(),
-           msg->str(), msg->id(), msg->seq_num_uid());
-    m_last_update = Now();
-    m_process_incoming(std::move(msg), this);
-  }
-  DEBUG2("read thread died ({})", fmt::ptr(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 {} messages", msgs.size());
-    for (auto& msg : msgs) {
-      if (msg) {
-        DEBUG3("sending type={} with str={} id={} seq_num={}", msg->type(),
-               msg->str(), msg->id(), 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 {} bytes", encoder.size());
-  }
-  DEBUG2("write thread died ({})", fmt::ptr(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;
-}  // NOLINT
diff --git a/ntcore/src/main/native/cpp/NetworkConnection.h b/ntcore/src/main/native/cpp/NetworkConnection.h
deleted file mode 100644
index 59f18ff..0000000
--- a/ntcore/src/main/native/cpp/NetworkConnection.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_NETWORKCONNECTION_H_
-#define NTCORE_NETWORKCONNECTION_H_
-
-#include <stdint.h>
-
-#include <atomic>
-#include <chrono>
-#include <memory>
-#include <string>
-#include <string_view>
-#include <thread>
-#include <utility>
-#include <vector>
-
-#include <wpi/ConcurrentQueue.h>
-#include <wpi/condition_variable.h>
-#include <wpi/mutex.h>
-#include <wpi/span.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:
-  using HandshakeFunc = std::function<bool(
-      NetworkConnection& conn,
-      std::function<std::shared_ptr<Message>()> get_msg,
-      std::function<void(wpi::span<std::shared_ptr<Message>>)> send_msgs)>;
-  using ProcessIncomingFunc =
-      std::function<void(std::shared_ptr<Message>, NetworkConnection*)>;
-  using Outgoing = std::vector<std::shared_ptr<Message>>;
-  using OutgoingQueue = wpi::ConcurrentQueue<Outgoing>;
-
-  NetworkConnection(unsigned int uid,
-                    std::unique_ptr<wpi::NetworkStream> stream,
-                    IConnectionNotifier& notifier, wpi::Logger& logger,
-                    HandshakeFunc handshake,
-                    Message::GetEntryTypeFunc get_entry_type);
-  ~NetworkConnection() override;
-
-  // 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 final;
-
-  bool active() const { return m_active; }
-  wpi::NetworkStream& stream() { return *m_stream; }
-
-  void QueueOutgoing(std::shared_ptr<Message> msg) final;
-  void PostOutgoing(bool keep_alive) override;
-
-  unsigned int uid() const { return m_uid; }
-
-  unsigned int proto_rev() const final;
-  void set_proto_rev(unsigned int proto_rev) final;
-
-  State state() const final;
-  void set_state(State state) final;
-
-  std::string remote_id() const;
-  void set_remote_id(std::string_view 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/NetworkServer.cpp b/ntcore/src/main/native/cpp/NetworkServer.cpp
new file mode 100644
index 0000000..0086d24
--- /dev/null
+++ b/ntcore/src/main/native/cpp/NetworkServer.cpp
@@ -0,0 +1,571 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "NetworkServer.h"
+
+#include <stdint.h>
+
+#include <atomic>
+#include <span>
+#include <system_error>
+#include <vector>
+
+#include <wpi/SmallString.h>
+#include <wpi/StringExtras.h>
+#include <wpi/fs.h>
+#include <wpi/mutex.h>
+#include <wpi/raw_istream.h>
+#include <wpi/raw_ostream.h>
+#include <wpinet/EventLoopRunner.h>
+#include <wpinet/HttpUtil.h>
+#include <wpinet/HttpWebSocketServerConnection.h>
+#include <wpinet/UrlParser.h>
+#include <wpinet/uv/Async.h>
+#include <wpinet/uv/Tcp.h>
+#include <wpinet/uv/Work.h>
+#include <wpinet/uv/util.h>
+
+#include "IConnectionList.h"
+#include "InstanceImpl.h"
+#include "Log.h"
+#include "net/Message.h"
+#include "net/NetworkLoopQueue.h"
+#include "net/ServerImpl.h"
+#include "net/WebSocketConnection.h"
+#include "net3/UvStreamConnection3.h"
+
+using namespace nt;
+namespace uv = wpi::uv;
+
+// use a larger max message size for websockets
+static constexpr size_t kMaxMessageSize = 2 * 1024 * 1024;
+
+namespace {
+
+class NSImpl;
+
+class ServerConnection {
+ public:
+  ServerConnection(NSImpl& server, std::string_view addr, unsigned int port,
+                   wpi::Logger& logger)
+      : m_server{server},
+        m_connInfo{fmt::format("{}:{}", addr, port)},
+        m_logger{logger} {
+    m_info.remote_ip = addr;
+    m_info.remote_port = port;
+  }
+
+  int GetClientId() const { return m_clientId; }
+
+ protected:
+  void SetupPeriodicTimer();
+  void UpdatePeriodicTimer(uint32_t repeatMs);
+  void ConnectionClosed();
+
+  NSImpl& m_server;
+  ConnectionInfo m_info;
+  std::string m_connInfo;
+  wpi::Logger& m_logger;
+  int m_clientId;
+
+ private:
+  std::shared_ptr<uv::Timer> m_sendValuesTimer;
+};
+
+class ServerConnection4 final
+    : public ServerConnection,
+      public wpi::HttpWebSocketServerConnection<ServerConnection4> {
+ public:
+  ServerConnection4(std::shared_ptr<uv::Stream> stream, NSImpl& server,
+                    std::string_view addr, unsigned int port,
+                    wpi::Logger& logger)
+      : ServerConnection{server, addr, port, logger},
+        HttpWebSocketServerConnection(stream, {"networktables.first.wpi.edu"}) {
+    m_info.protocol_version = 0x0400;
+  }
+
+ private:
+  void ProcessRequest() final;
+  void ProcessWsUpgrade() final;
+
+  std::shared_ptr<net::WebSocketConnection> m_wire;
+};
+
+class ServerConnection3 : public ServerConnection {
+ public:
+  ServerConnection3(std::shared_ptr<uv::Stream> stream, NSImpl& server,
+                    std::string_view addr, unsigned int port,
+                    wpi::Logger& logger);
+
+ private:
+  std::shared_ptr<net3::UvStreamConnection3> m_wire;
+};
+
+class NSImpl {
+ public:
+  NSImpl(std::string_view persistFilename, std::string_view listenAddress,
+         unsigned int port3, unsigned int port4,
+         net::ILocalStorage& localStorage, IConnectionList& connList,
+         wpi::Logger& logger, std::function<void()> initDone);
+  ~NSImpl();
+
+  void HandleLocal();
+  void LoadPersistent();
+  void SavePersistent(std::string_view filename, std::string_view data);
+  void Init();
+  void AddConnection(ServerConnection* conn, const ConnectionInfo& info);
+  void RemoveConnection(ServerConnection* conn);
+
+  net::ILocalStorage& m_localStorage;
+  IConnectionList& m_connList;
+  wpi::Logger& m_logger;
+  std::function<void()> m_initDone;
+  std::string m_persistentData;
+  std::string m_persistentFilename;
+  std::string m_listenAddress;
+  unsigned int m_port3;
+  unsigned int m_port4;
+
+  // used only from loop
+  std::shared_ptr<uv::Timer> m_readLocalTimer;
+  std::shared_ptr<uv::Timer> m_savePersistentTimer;
+  std::shared_ptr<uv::Async<>> m_flushLocal;
+  std::shared_ptr<uv::Async<>> m_flush;
+  bool m_shutdown = false;
+
+  std::vector<net::ClientMessage> m_localMsgs;
+
+  net::ServerImpl m_serverImpl;
+
+  // shared with user (must be atomic or mutex-protected)
+  std::atomic<uv::Async<>*> m_flushLocalAtomic{nullptr};
+  std::atomic<uv::Async<>*> m_flushAtomic{nullptr};
+  mutable wpi::mutex m_mutex;
+  struct Connection {
+    ServerConnection* conn;
+    int connHandle;
+  };
+  std::vector<Connection> m_connections;
+
+  net::NetworkLoopQueue m_localQueue;
+
+  wpi::EventLoopRunner m_loopRunner;
+  wpi::uv::Loop& m_loop;
+};
+
+}  // namespace
+
+void ServerConnection::SetupPeriodicTimer() {
+  m_sendValuesTimer = uv::Timer::Create(m_server.m_loop);
+  m_sendValuesTimer->timeout.connect([this] {
+    m_server.HandleLocal();
+    m_server.m_serverImpl.SendValues(m_clientId, m_server.m_loop.Now().count());
+  });
+}
+
+void ServerConnection::UpdatePeriodicTimer(uint32_t repeatMs) {
+  if (repeatMs == UINT32_MAX) {
+    m_sendValuesTimer->Stop();
+  } else {
+    m_sendValuesTimer->Start(uv::Timer::Time{repeatMs},
+                             uv::Timer::Time{repeatMs});
+  }
+}
+
+void ServerConnection::ConnectionClosed() {
+  // don't call back into m_server if it's being destroyed
+  if (!m_sendValuesTimer->IsLoopClosing()) {
+    m_server.m_serverImpl.RemoveClient(m_clientId);
+    m_server.RemoveConnection(this);
+  }
+  m_sendValuesTimer->Close();
+}
+
+void ServerConnection4::ProcessRequest() {
+  DEBUG1("HTTP request: '{}'", m_request.GetUrl());
+  wpi::UrlParser url{m_request.GetUrl(),
+                     m_request.GetMethod() == wpi::HTTP_CONNECT};
+  if (!url.IsValid()) {
+    // failed to parse URL
+    SendError(400);
+    return;
+  }
+
+  std::string_view path;
+  if (url.HasPath()) {
+    path = url.GetPath();
+  }
+  DEBUG4("path: \"{}\"", path);
+
+  std::string_view query;
+  if (url.HasQuery()) {
+    query = url.GetQuery();
+  }
+  DEBUG4("query: \"{}\"\n", query);
+
+  const bool isGET = m_request.GetMethod() == wpi::HTTP_GET;
+  if (isGET && path == "/") {
+    // build HTML root page
+    SendResponse(200, "OK", "text/html",
+                 "<html><head><title>NetworkTables</title></head>"
+                 "<body><p>WebSockets must be used to access NetworkTables."
+                 "</body></html>");
+  } else if (isGET && path == "/nt/persistent.json") {
+    SendResponse(200, "OK", "application/json",
+                 m_server.m_serverImpl.DumpPersistent());
+  } else {
+    SendError(404, "Resource not found");
+  }
+}
+
+void ServerConnection4::ProcessWsUpgrade() {
+  // get name from URL
+  wpi::UrlParser url{m_request.GetUrl(), false};
+  std::string_view path;
+  if (url.HasPath()) {
+    path = url.GetPath();
+  }
+  DEBUG4("path: '{}'", path);
+
+  wpi::SmallString<128> nameBuf;
+  std::string_view name;
+  bool err = false;
+  if (wpi::starts_with(path, "/nt/")) {
+    name = wpi::UnescapeURI(wpi::drop_front(path, 4), nameBuf, &err);
+  }
+  if (err || name.empty()) {
+    INFO("invalid path '{}' (from {}), must match /nt/[clientId], closing",
+         path, m_connInfo);
+    m_websocket->Fail(
+        404, fmt::format("invalid path '{}', must match /nt/[clientId]", path));
+    return;
+  }
+
+  m_websocket->SetMaxMessageSize(kMaxMessageSize);
+
+  m_websocket->open.connect([this, name = std::string{name}](std::string_view) {
+    m_wire = std::make_shared<net::WebSocketConnection>(*m_websocket);
+    // TODO: set local flag appropriately
+    std::string dedupName;
+    std::tie(dedupName, m_clientId) = m_server.m_serverImpl.AddClient(
+        name, m_connInfo, false, *m_wire,
+        [this](uint32_t repeatMs) { UpdatePeriodicTimer(repeatMs); });
+    INFO("CONNECTED NT4 client '{}' (from {})", dedupName, m_connInfo);
+    m_info.remote_id = dedupName;
+    m_server.AddConnection(this, m_info);
+    m_websocket->closed.connect([this](uint16_t, std::string_view reason) {
+      INFO("DISCONNECTED NT4 client '{}' (from {}): {}", m_info.remote_id,
+           m_connInfo, reason);
+      ConnectionClosed();
+    });
+    m_websocket->text.connect([this](std::string_view data, bool) {
+      m_server.m_serverImpl.ProcessIncomingText(m_clientId, data);
+    });
+    m_websocket->binary.connect([this](std::span<const uint8_t> data, bool) {
+      m_server.m_serverImpl.ProcessIncomingBinary(m_clientId, data);
+    });
+
+    SetupPeriodicTimer();
+  });
+}
+
+ServerConnection3::ServerConnection3(std::shared_ptr<uv::Stream> stream,
+                                     NSImpl& server, std::string_view addr,
+                                     unsigned int port, wpi::Logger& logger)
+    : ServerConnection{server, addr, port, logger},
+      m_wire{std::make_shared<net3::UvStreamConnection3>(*stream)} {
+  m_info.remote_ip = addr;
+  m_info.remote_port = port;
+
+  // TODO: set local flag appropriately
+  m_clientId = m_server.m_serverImpl.AddClient3(
+      m_connInfo, false, *m_wire,
+      [this](std::string_view name, uint16_t proto) {
+        m_info.remote_id = name;
+        m_info.protocol_version = proto;
+        m_server.AddConnection(this, m_info);
+        INFO("CONNECTED NT3 client '{}' (from {})", name, m_connInfo);
+      },
+      [this](uint32_t repeatMs) { UpdatePeriodicTimer(repeatMs); });
+
+  stream->error.connect([this](uv::Error err) {
+    if (!m_wire->GetDisconnectReason().empty()) {
+      return;
+    }
+    m_wire->Disconnect(fmt::format("stream error: {}", err.name()));
+    m_wire->GetStream().Shutdown([this] { m_wire->GetStream().Close(); });
+  });
+  stream->end.connect([this] {
+    if (!m_wire->GetDisconnectReason().empty()) {
+      return;
+    }
+    m_wire->Disconnect("remote end closed connection");
+    m_wire->GetStream().Shutdown([this] { m_wire->GetStream().Close(); });
+  });
+  stream->closed.connect([this] {
+    INFO("DISCONNECTED NT3 client '{}' (from {}): {}", m_info.remote_id,
+         m_connInfo, m_wire->GetDisconnectReason());
+    ConnectionClosed();
+  });
+  stream->data.connect([this](uv::Buffer& buf, size_t size) {
+    m_server.m_serverImpl.ProcessIncomingBinary(
+        m_clientId, {reinterpret_cast<const uint8_t*>(buf.base), size});
+  });
+  stream->StartRead();
+
+  SetupPeriodicTimer();
+}
+
+NSImpl::NSImpl(std::string_view persistentFilename,
+               std::string_view listenAddress, unsigned int port3,
+               unsigned int port4, net::ILocalStorage& localStorage,
+               IConnectionList& connList, wpi::Logger& logger,
+               std::function<void()> initDone)
+    : m_localStorage{localStorage},
+      m_connList{connList},
+      m_logger{logger},
+      m_initDone{std::move(initDone)},
+      m_persistentFilename{persistentFilename},
+      m_listenAddress{wpi::trim(listenAddress)},
+      m_port3{port3},
+      m_port4{port4},
+      m_serverImpl{logger},
+      m_localQueue{logger},
+      m_loop(*m_loopRunner.GetLoop()) {
+  m_localMsgs.reserve(net::NetworkLoopQueue::kInitialQueueSize);
+  m_loopRunner.ExecAsync([=, this](uv::Loop& loop) {
+    // connect local storage to server
+    m_serverImpl.SetLocal(&m_localStorage);
+    m_localStorage.StartNetwork(&m_localQueue);
+    HandleLocal();
+
+    // load persistent file first, then initialize
+    uv::QueueWork(
+        m_loop, [this] { LoadPersistent(); }, [this] { Init(); });
+  });
+}
+
+NSImpl::~NSImpl() {
+  m_loopRunner.ExecAsync([this](uv::Loop&) { m_shutdown = true; });
+}
+
+void NSImpl::HandleLocal() {
+  m_localQueue.ReadQueue(&m_localMsgs);
+  m_serverImpl.HandleLocal(m_localMsgs);
+}
+
+void NSImpl::LoadPersistent() {
+  std::error_code ec;
+  auto size = fs::file_size(m_persistentFilename, ec);
+  wpi::raw_fd_istream is{m_persistentFilename, ec};
+  if (ec.value() != 0) {
+    INFO("could not open persistent file '{}': {}", m_persistentFilename,
+         ec.message());
+    return;
+  }
+  is.readinto(m_persistentData, size);
+  DEBUG4("read data: {}", m_persistentData);
+  if (is.has_error()) {
+    WARNING("error reading persistent file");
+    return;
+  }
+}
+
+void NSImpl::SavePersistent(std::string_view filename, std::string_view data) {
+  // write to temporary file
+  auto tmp = fmt::format("{}.tmp", filename);
+  std::error_code ec;
+  wpi::raw_fd_ostream os{tmp, ec, fs::F_Text};
+  if (ec.value() != 0) {
+    INFO("could not open persistent file '{}' for write: {}", tmp,
+         ec.message());
+    return;
+  }
+  os << data;
+  os.close();
+  if (os.has_error()) {
+    fs::remove(tmp);
+    return;
+  }
+
+  // move to real file
+  auto bak = fmt::format("{}.bck", filename);
+  fs::remove(bak, ec);
+  fs::rename(filename, bak, ec);
+  fs::rename(tmp, filename, ec);
+  if (ec.value() != 0) {
+    // attempt to restore backup
+    fs::rename(bak, filename, ec);
+  }
+}
+
+void NSImpl::Init() {
+  if (m_shutdown) {
+    return;
+  }
+  auto errs = m_serverImpl.LoadPersistent(m_persistentData);
+  if (!errs.empty()) {
+    WARNING("error reading persistent file: {}", errs);
+  }
+
+  // set up timers
+  m_readLocalTimer = uv::Timer::Create(m_loop);
+  m_readLocalTimer->timeout.connect([this] {
+    HandleLocal();
+    m_serverImpl.SendControl(m_loop.Now().count());
+  });
+  m_readLocalTimer->Start(uv::Timer::Time{100}, uv::Timer::Time{100});
+
+  m_savePersistentTimer = uv::Timer::Create(m_loop);
+  m_savePersistentTimer->timeout.connect([this] {
+    if (m_serverImpl.PersistentChanged()) {
+      uv::QueueWork(
+          m_loop,
+          [this, fn = m_persistentFilename,
+           data = m_serverImpl.DumpPersistent()] { SavePersistent(fn, data); },
+          nullptr);
+    }
+  });
+  m_savePersistentTimer->Start(uv::Timer::Time{1000}, uv::Timer::Time{1000});
+
+  // set up flush async
+  m_flush = uv::Async<>::Create(m_loop);
+  m_flush->wakeup.connect([this] {
+    HandleLocal();
+    for (auto&& conn : m_connections) {
+      m_serverImpl.SendValues(conn.conn->GetClientId(), m_loop.Now().count());
+    }
+  });
+  m_flushAtomic = m_flush.get();
+
+  m_flushLocal = uv::Async<>::Create(m_loop);
+  m_flushLocal->wakeup.connect([this] { HandleLocal(); });
+  m_flushLocalAtomic = m_flushLocal.get();
+
+  INFO("Listening on NT3 port {}, NT4 port {}", m_port3, m_port4);
+
+  if (m_port3 != 0) {
+    auto tcp3 = uv::Tcp::Create(m_loop);
+    tcp3->error.connect([logger = &m_logger](uv::Error err) {
+      WPI_INFO(*logger, "NT3 server socket error: {}", err.str());
+    });
+    tcp3->Bind(m_listenAddress, m_port3);
+
+    // when we get a NT3 connection, accept it and start reading
+    tcp3->connection.connect([this, srv = tcp3.get()] {
+      auto tcp = srv->Accept();
+      if (!tcp) {
+        return;
+      }
+      tcp->error.connect([logger = &m_logger](uv::Error err) {
+        WPI_INFO(*logger, "NT3 socket error: {}", err.str());
+      });
+      tcp->SetNoDelay(true);
+      std::string peerAddr;
+      unsigned int peerPort = 0;
+      if (uv::AddrToName(tcp->GetPeer(), &peerAddr, &peerPort) == 0) {
+        INFO("Got a NT3 connection from {} port {}", peerAddr, peerPort);
+      } else {
+        INFO("Got a NT3 connection from unknown");
+      }
+      auto conn = std::make_shared<ServerConnection3>(tcp, *this, peerAddr,
+                                                      peerPort, m_logger);
+      tcp->SetData(conn);
+    });
+
+    tcp3->Listen();
+  }
+
+  if (m_port4 != 0) {
+    auto tcp4 = uv::Tcp::Create(m_loop);
+    tcp4->error.connect([logger = &m_logger](uv::Error err) {
+      WPI_INFO(*logger, "NT4 server socket error: {}", err.str());
+    });
+    tcp4->Bind(m_listenAddress, m_port4);
+
+    // when we get a NT4 connection, accept it and start reading
+    tcp4->connection.connect([this, srv = tcp4.get()] {
+      auto tcp = srv->Accept();
+      if (!tcp) {
+        return;
+      }
+      tcp->error.connect([logger = &m_logger](uv::Error err) {
+        WPI_INFO(*logger, "NT4 socket error: {}", err.str());
+      });
+      tcp->SetNoDelay(true);
+      std::string peerAddr;
+      unsigned int peerPort = 0;
+      if (uv::AddrToName(tcp->GetPeer(), &peerAddr, &peerPort) == 0) {
+        INFO("Got a NT4 connection from {} port {}", peerAddr, peerPort);
+      } else {
+        INFO("Got a NT4 connection from unknown");
+      }
+      auto conn = std::make_shared<ServerConnection4>(tcp, *this, peerAddr,
+                                                      peerPort, m_logger);
+      tcp->SetData(conn);
+    });
+
+    tcp4->Listen();
+  }
+
+  if (m_initDone) {
+    DEBUG4("NetworkServer initDone()");
+    m_initDone();
+    m_initDone = nullptr;
+  }
+}
+
+void NSImpl::AddConnection(ServerConnection* conn, const ConnectionInfo& info) {
+  std::scoped_lock lock{m_mutex};
+  m_connections.emplace_back(Connection{conn, m_connList.AddConnection(info)});
+  m_serverImpl.ConnectionsChanged(m_connList.GetConnections());
+}
+
+void NSImpl::RemoveConnection(ServerConnection* conn) {
+  std::scoped_lock lock{m_mutex};
+  auto it = std::find_if(m_connections.begin(), m_connections.end(),
+                         [=](auto&& c) { return c.conn == conn; });
+  if (it != m_connections.end()) {
+    m_connList.RemoveConnection(it->connHandle);
+    m_connections.erase(it);
+    m_serverImpl.ConnectionsChanged(m_connList.GetConnections());
+  }
+}
+
+class NetworkServer::Impl final : public NSImpl {
+ public:
+  Impl(std::string_view persistFilename, std::string_view listenAddress,
+       unsigned int port3, unsigned int port4, net::ILocalStorage& localStorage,
+       IConnectionList& connList, wpi::Logger& logger,
+       std::function<void()> initDone)
+      : NSImpl{persistFilename, listenAddress, port3,  port4,
+               localStorage,    connList,      logger, std::move(initDone)} {}
+};
+
+NetworkServer::NetworkServer(std::string_view persistFilename,
+                             std::string_view listenAddress, unsigned int port3,
+                             unsigned int port4,
+                             net::ILocalStorage& localStorage,
+                             IConnectionList& connList, wpi::Logger& logger,
+                             std::function<void()> initDone)
+    : m_impl{std::make_unique<Impl>(persistFilename, listenAddress, port3,
+                                    port4, localStorage, connList, logger,
+                                    std::move(initDone))} {}
+
+NetworkServer::~NetworkServer() {
+  m_impl->m_localStorage.ClearNetwork();
+  m_impl->m_connList.ClearConnections();
+}
+
+void NetworkServer::FlushLocal() {
+  if (auto async = m_impl->m_flushLocalAtomic.load(std::memory_order_relaxed)) {
+    async->UnsafeSend();
+  }
+}
+
+void NetworkServer::Flush() {
+  if (auto async = m_impl->m_flushAtomic.load(std::memory_order_relaxed)) {
+    async->UnsafeSend();
+  }
+}
diff --git a/ntcore/src/main/native/cpp/NetworkServer.h b/ntcore/src/main/native/cpp/NetworkServer.h
new file mode 100644
index 0000000..b70c968
--- /dev/null
+++ b/ntcore/src/main/native/cpp/NetworkServer.h
@@ -0,0 +1,42 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <string_view>
+
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt::net {
+class ILocalStorage;
+}  // namespace nt::net
+
+namespace nt {
+
+class IConnectionList;
+
+class NetworkServer {
+ public:
+  NetworkServer(std::string_view persistentFilename,
+                std::string_view listenAddress, unsigned int port3,
+                unsigned int port4, net::ILocalStorage& localStorage,
+                IConnectionList& connList, wpi::Logger& logger,
+                std::function<void()> initDone);
+  ~NetworkServer();
+
+  void FlushLocal();
+  void Flush();
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/PubSubOptions.h b/ntcore/src/main/native/cpp/PubSubOptions.h
new file mode 100644
index 0000000..72ba2c3
--- /dev/null
+++ b/ntcore/src/main/native/cpp/PubSubOptions.h
@@ -0,0 +1,36 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+// internal helper class for PubSubOptions
+class PubSubOptionsImpl : public PubSubOptions {
+ public:
+  constexpr PubSubOptionsImpl() : PubSubOptionsImpl{kDefaultPubSubOptions} {}
+
+  /*implicit*/ constexpr PubSubOptionsImpl(  // NOLINT
+      const PubSubOptions& options)
+      : PubSubOptions{options} {
+    if (periodic == 0) {
+      periodic = kDefaultPeriodic;
+    }
+    periodicMs = static_cast<unsigned int>(periodic * 1000);
+    if (pollStorage == 0) {
+      if (sendAll) {
+        pollStorage = 20;
+      } else {
+        pollStorage = 1;
+      }
+    }
+  }
+
+  static constexpr unsigned int kDefaultPeriodicMs = 100;
+  unsigned int periodicMs = kDefaultPeriodicMs;
+};
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/RpcServer.cpp b/ntcore/src/main/native/cpp/RpcServer.cpp
deleted file mode 100644
index b4bf96a..0000000
--- a/ntcore/src/main/native/cpp/RpcServer.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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,
-                           std::string_view name, std::string_view 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,
-                                std::string_view 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
deleted file mode 100644
index b8ae6b7..0000000
--- a/ntcore/src/main/native/cpp/RpcServer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_RPCSERVER_H_
-#define NTCORE_RPCSERVER_H_
-
-#include <utility>
-
-#include <wpi/CallbackManager.h>
-#include <wpi/DenseMap.h>
-#include <wpi/mutex.h>
-
-#include "Handle.h"
-#include "IRpcServer.h"
-#include "Log.h"
-
-namespace nt {
-
-namespace impl {
-
-using RpcIdPair = std::pair<unsigned int, unsigned int>;
-
-struct RpcNotifierData : public RpcAnswer {
-  RpcNotifierData(NT_Entry entry_, NT_RpcCall call_, std::string_view name_,
-                  std::string_view params_, const ConnectionInfo& conn_,
-                  IRpcServer::SendResponseFunc send_response_)
-      : RpcAnswer{entry_, call_, name_, params_, conn_},
-        send_response{std::move(send_response_)} {}
-
-  IRpcServer::SendResponseFunc send_response;
-};
-
-using RpcListenerData =
-    wpi::CallbackListenerData<std::function<void(const RpcAnswer& answer)>>;
-
-class RpcServerThread
-    : public wpi::CallbackThread<RpcServerThread, RpcAnswer, RpcListenerData,
-                                 RpcNotifierData> {
- public:
-  RpcServerThread(std::function<void()> on_start, std::function<void()> on_exit,
-                  int inst, wpi::Logger& logger)
-      : CallbackThread(std::move(on_start), std::move(on_exit)),
-        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 wpi::CallbackManager<RpcServer, impl::RpcServerThread> {
-  friend class RpcServerTest;
-  friend class wpi::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,
-                  std::string_view name, std::string_view params,
-                  const ConnectionInfo& conn, SendResponseFunc send_response,
-                  unsigned int rpc_uid) override;
-
-  bool PostRpcResponse(unsigned int local_id, unsigned int call_uid,
-                       std::string_view 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
deleted file mode 100644
index e25e636..0000000
--- a/ntcore/src/main/native/cpp/SequenceNumber.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 719d85c..0000000
--- a/ntcore/src/main/native/cpp/SequenceNumber.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_SEQUENCENUMBER_H_
-#define NTCORE_SEQUENCENUMBER_H_
-
-namespace nt {
-
-/* A sequence number per RFC 1982 */
-class SequenceNumber {
- public:
-  SequenceNumber() = default;
-  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{0};
-};
-
-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
deleted file mode 100644
index dadc3f6..0000000
--- a/ntcore/src/main/native/cpp/Storage.cpp
+++ /dev/null
@@ -1,1286 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "Storage.h"
-
-#include <wpi/StringExtras.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();
-  std::string_view 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,
-      [=](std::string_view 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({RpcIdPair{entry->local_id, msg->seq_num_uid()},
-                        std::string{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::span<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());
-    std::string_view 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(std::string_view 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(std::string_view 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(std::string_view 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(std::string_view 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(std::string_view 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(std::string_view 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(std::string_view 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(std::string_view name) {
-  auto& entry = m_entries[name];
-  if (!entry) {
-    m_localmap.emplace_back(new Entry(name));
-    entry = m_localmap.back().get();
-    entry->local_id = m_localmap.size() - 1;
-  }
-  return entry;
-}
-
-unsigned int Storage::GetEntry(std::string_view name) {
-  if (name.empty()) {
-    return UINT_MAX;
-  }
-  std::unique_lock lock(m_mutex);
-  return GetOrNew(name)->local_id;
-}
-
-std::vector<unsigned int> Storage::GetEntries(std::string_view prefix,
-                                              unsigned int types) {
-  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 || !wpi::starts_with(i.getKey(), prefix)) {
-      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 {};
-  }
-  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, std::string_view prefix,
-                                             unsigned int types) {
-  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 || !wpi::starts_with(i.getKey(), prefix)) {
-      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(
-    std::string_view prefix,
-    std::function<void(const EntryNotification& event)> callback,
-    unsigned int flags) const {
-  std::scoped_lock lock(m_mutex);
-  unsigned int uid = m_notifier.Add(callback, prefix, 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 || !wpi::starts_with(i.getKey(), prefix)) {
-        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,
-                                        std::string_view prefix,
-                                        unsigned int flags) const {
-  std::scoped_lock lock(m_mutex);
-  unsigned int uid = m_notifier.AddPolled(poller, prefix, flags);
-  // perform immediate notifications
-  if ((flags & NT_NOTIFY_IMMEDIATE) != 0 && (flags & NT_NOTIFY_NEW) != 0) {
-    for (auto& i : m_entries) {
-      if (!wpi::starts_with(i.getKey(), prefix)) {
-        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(
-    std::string_view prefix,
-    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);
-    entries->reserve(m_entries.size());
-    for (auto& i : m_entries) {
-      Entry* entry = i.getValue();
-      // only write values with given prefix
-      if (!entry->value || !wpi::starts_with(i.getKey(), prefix)) {
-        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, std::string_view 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, std::string_view 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);
-  std::string_view 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,
-        [=](std::string_view result) {
-          std::scoped_lock lock(m_mutex);
-          m_rpc_results.insert(std::make_pair(RpcIdPair{local_id, call_uid},
-                                              std::string{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
deleted file mode 100644
index f49c071..0000000
--- a/ntcore/src/main/native/cpp/Storage.h
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_STORAGE_H_
-#define NTCORE_STORAGE_H_
-
-#include <stdint.h>
-
-#include <atomic>
-#include <cstddef>
-#include <functional>
-#include <memory>
-#include <string>
-#include <string_view>
-#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 <wpi/span.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() override;
-
-  // 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::span<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(std::string_view name) const;
-  std::shared_ptr<Value> GetEntryValue(unsigned int local_id) const;
-
-  bool SetDefaultEntryValue(std::string_view name,
-                            std::shared_ptr<Value> value);
-  bool SetDefaultEntryValue(unsigned int local_id,
-                            std::shared_ptr<Value> value);
-
-  bool SetEntryValue(std::string_view name, std::shared_ptr<Value> value);
-  bool SetEntryValue(unsigned int local_id, std::shared_ptr<Value> value);
-
-  void SetEntryTypeValue(std::string_view name, std::shared_ptr<Value> value);
-  void SetEntryTypeValue(unsigned int local_id, std::shared_ptr<Value> value);
-
-  void SetEntryFlags(std::string_view name, unsigned int flags);
-  void SetEntryFlags(unsigned int local_id, unsigned int flags);
-
-  unsigned int GetEntryFlags(std::string_view name) const;
-  unsigned int GetEntryFlags(unsigned int local_id) const;
-
-  void DeleteEntry(std::string_view name);
-  void DeleteEntry(unsigned int local_id);
-
-  void DeleteAllEntries();
-
-  std::vector<EntryInfo> GetEntryInfo(int inst, std::string_view prefix,
-                                      unsigned int types);
-
-  unsigned int AddListener(
-      std::string_view 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,
-                                 std::string_view 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(std::string_view name);
-  std::vector<unsigned int> GetEntries(std::string_view 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(std::string_view filename,
-                             bool periodic) const override;
-  const char* LoadPersistent(
-      std::string_view filename,
-      std::function<void(size_t line, const char* msg)> warn) override;
-
-  const char* SaveEntries(std::string_view filename,
-                          std::string_view prefix) const;
-  const char* LoadEntries(
-      std::string_view filename, std::string_view 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, std::string_view prefix,
-                   bool persistent,
-                   std::function<void(size_t line, const char* msg)> warn);
-
-  void SaveEntries(wpi::raw_ostream& os, std::string_view prefix) const;
-
-  // RPC configuration needs to come through here as RPC definitions are
-  // actually special Storage value types.
-  void CreateRpc(unsigned int local_id, std::string_view def,
-                 unsigned int rpc_uid);
-  unsigned int CallRpc(unsigned int local_id, std::string_view 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(std::string_view 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};
-  };
-
-  using EntriesMap = wpi::StringMap<Entry*>;
-  using IdMap = std::vector<Entry*>;
-  using LocalMap = std::vector<std::unique_ptr<Entry>>;
-  using RpcIdPair = std::pair<unsigned int, unsigned int>;
-  using RpcResultMap = wpi::DenseMap<RpcIdPair, std::string>;
-  using RpcBlockingCallSet = wpi::SmallSet<RpcIdPair, 12>;
-
-  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(std::string_view 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(std::string_view 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
deleted file mode 100644
index 98046e7..0000000
--- a/ntcore/src/main/native/cpp/Storage_load.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include <cctype>
-#include <string>
-#include <utility>
-
-#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:
-  using Entry = std::pair<std::string, std::shared_ptr<Value>>;
-  using WarnFunc = std::function<void(size_t, const char*)>;
-
-  LoadPersistentImpl(wpi::raw_istream& is, WarnFunc warn)
-      : m_is(is), m_warn(std::move(warn)) {}
-
-  bool Load(std::string_view prefix, std::vector<Entry>* entries);
-
- private:
-  bool ReadLine();
-  bool ReadHeader();
-  NT_Type ReadType();
-  std::string_view 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;
-
-  std::string_view 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<std::string_view, std::string_view> ReadStringToken(
-    std::string_view source) {
-  // Match opening quote
-  if (source.empty() || source.front() != '"') {
-    return {{}, 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 {wpi::slice(source, 0, pos), wpi::substr(source, 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 std::string_view UnescapeString(std::string_view 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 {buf.data(), buf.size()};
-}
-
-bool LoadPersistentImpl::Load(std::string_view 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;
-    std::string_view name = ReadName(buf);
-    if (name.empty() || !wpi::starts_with(name, prefix)) {
-      continue;
-    }
-
-    // =
-    m_line = wpi::ltrim(m_line, " \t");
-    if (m_line.empty() || m_line.front() != '=') {
-      Warn("expected = after name");
-      continue;
-    }
-    m_line.remove_prefix(1);
-    m_line = wpi::ltrim(m_line, " \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 = wpi::trim(m_is.getline(m_line_buf, INT_MAX));
-    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() {
-  std::string_view tok;
-  std::tie(tok, m_line) = wpi::split(m_line, ' ');
-  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") {
-    std::string_view array_tok;
-    std::tie(array_tok, m_line) = wpi::split(m_line, ' ');
-    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;
-}
-
-std::string_view LoadPersistentImpl::ReadName(wpi::SmallVectorImpl<char>& buf) {
-  std::string_view tok;
-  std::tie(tok, m_line) = ReadStringToken(m_line);
-  if (tok.empty()) {
-    Warn("missing name");
-    return {};
-  }
-  if (tok.back() != '"') {
-    Warn("unterminated name string");
-    return {};
-  }
-  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() {
-  std::string_view 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()) {
-    std::string_view tok;
-    std::tie(tok, m_line) = wpi::split(m_line, ',');
-    tok = wpi::trim(tok, " \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()) {
-    std::string_view tok;
-    std::tie(tok, m_line) = wpi::split(m_line, ',');
-    tok = wpi::trim(tok, " \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()) {
-    std::string_view 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.emplace_back(UnescapeString(tok, buf));
-
-    m_line = wpi::ltrim(m_line, " \t");
-    if (m_line.empty()) {
-      break;
-    }
-    if (m_line.front() != ',') {
-      Warn("expected comma between strings");
-      return nullptr;
-    }
-    m_line.remove_prefix(1);
-    m_line = wpi::ltrim(m_line, " \t");
-  }
-
-  return Value::MakeStringArray(std::move(m_buf_string_array));
-}
-
-bool Storage::LoadEntries(
-    wpi::raw_istream& is, std::string_view prefix, bool persistent,
-    std::function<void(size_t line, const char* msg)> warn) {
-  // entries to add
-  std::vector<LoadPersistentImpl::Entry> entries;
-
-  // load file
-  if (!LoadPersistentImpl(is, warn).Load(prefix, &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(
-    std::string_view 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(
-    std::string_view filename, std::string_view 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
deleted file mode 100644
index 6d5db9f..0000000
--- a/ntcore/src/main/native/cpp/Storage_save.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include <cctype>
-#include <string>
-
-#include <fmt/format.h>
-#include <wpi/Base64.h>
-#include <wpi/SmallString.h>
-#include <wpi/StringExtras.h>
-#include <wpi/fs.h>
-#include <wpi/raw_ostream.h>
-
-#include "Log.h"
-#include "Storage.h"
-
-using namespace nt;
-
-namespace {
-
-class SavePersistentImpl {
- public:
-  using Entry = std::pair<std::string, std::shared_ptr<Value>>;
-
-  explicit SavePersistentImpl(wpi::raw_ostream& os) : m_os(os) {}
-
-  void Save(wpi::span<const Entry> entries);
-
- private:
-  void WriteString(std::string_view str);
-  void WriteHeader();
-  void WriteEntries(wpi::span<const Entry> entries);
-  void WriteEntry(std::string_view 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(std::string_view 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::span<const Entry> entries) {
-  WriteHeader();
-  WriteEntries(entries);
-}
-
-void SavePersistentImpl::WriteHeader() {
-  m_os << "[NetworkTables Storage 3.0]\n";
-}
-
-void SavePersistentImpl::WriteEntries(wpi::span<const Entry> entries) {
-  for (auto& i : entries) {
-    if (!i.second) {
-      continue;
-    }
-    WriteEntry(i.first, *i.second);
-  }
-}
-
-void SavePersistentImpl::WriteEntry(std::string_view 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 << fmt::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 << fmt::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(std::string_view filename,
-                                    bool periodic) const {
-  std::string fn{filename};
-  auto tmp = fmt::format("{}.tmp", filename);
-  auto bak = fmt::format("{}.bak", filename);
-
-  // 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, 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, std::string_view prefix) const {
-  std::vector<SavePersistentImpl::Entry> entries;
-  if (!GetEntries(prefix, &entries)) {
-    return;
-  }
-  SavePersistentImpl(os).Save(entries);
-}
-
-const char* Storage::SaveEntries(std::string_view filename,
-                                 std::string_view prefix) const {
-  std::string fn{filename};
-  auto tmp = fmt::format("{}.tmp", filename);
-  auto bak = fmt::format("{}.bak", filename);
-
-  // 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, 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/Types_internal.cpp b/ntcore/src/main/native/cpp/Types_internal.cpp
new file mode 100644
index 0000000..d6de540
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Types_internal.cpp
@@ -0,0 +1,83 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "Types_internal.h"
+
+std::string_view nt::TypeToString(NT_Type type) {
+  switch (type) {
+    case NT_BOOLEAN:
+      return "boolean";
+    case NT_DOUBLE:
+      return "double";
+    case NT_STRING:
+      return "string";
+    case NT_BOOLEAN_ARRAY:
+      return "boolean[]";
+    case NT_DOUBLE_ARRAY:
+      return "double[]";
+    case NT_STRING_ARRAY:
+      return "string[]";
+    case NT_RPC:
+      return "rpc";
+    case NT_INTEGER:
+      return "int";
+    case NT_FLOAT:
+      return "float";
+    case NT_INTEGER_ARRAY:
+      return "int[]";
+    case NT_FLOAT_ARRAY:
+      return "float";
+    default:
+      return "raw";
+  }
+}
+
+NT_Type nt::StringToType(std::string_view typeStr) {
+  if (typeStr == "boolean") {
+    return NT_BOOLEAN;
+  } else if (typeStr == "double") {
+    return NT_DOUBLE;
+  } else if (typeStr == "string" || typeStr == "json") {
+    return NT_STRING;
+  } else if (typeStr == "boolean[]") {
+    return NT_BOOLEAN_ARRAY;
+  } else if (typeStr == "double[]") {
+    return NT_DOUBLE_ARRAY;
+  } else if (typeStr == "string[]") {
+    return NT_STRING_ARRAY;
+  } else if (typeStr == "rpc") {
+    return NT_RPC;
+  } else if (typeStr == "int") {
+    return NT_INTEGER;
+  } else if (typeStr == "float") {
+    return NT_FLOAT;
+  } else if (typeStr == "int[]") {
+    return NT_INTEGER_ARRAY;
+  } else if (typeStr == "float[]") {
+    return NT_FLOAT_ARRAY;
+  } else {
+    return NT_RAW;
+  }
+}
+
+NT_Type nt::StringToType3(std::string_view typeStr) {
+  if (typeStr == "boolean") {
+    return NT_BOOLEAN;
+  } else if (typeStr == "double" || typeStr == "int" || typeStr == "float") {
+    return NT_DOUBLE;
+  } else if (typeStr == "string" || typeStr == "json") {
+    return NT_STRING;
+  } else if (typeStr == "boolean[]") {
+    return NT_BOOLEAN_ARRAY;
+  } else if (typeStr == "double[]" || typeStr == "int[]" ||
+             typeStr == "float[]") {
+    return NT_DOUBLE_ARRAY;
+  } else if (typeStr == "string[]") {
+    return NT_STRING_ARRAY;
+  } else if (typeStr == "rpc") {
+    return NT_RPC;
+  } else {
+    return NT_RAW;
+  }
+}
diff --git a/ntcore/src/main/native/cpp/Types_internal.h b/ntcore/src/main/native/cpp/Types_internal.h
new file mode 100644
index 0000000..0919641
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Types_internal.h
@@ -0,0 +1,30 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <string_view>
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+std::string_view TypeToString(NT_Type type);
+NT_Type StringToType(std::string_view typeStr);
+NT_Type StringToType3(std::string_view typeStr);
+
+constexpr bool IsNumeric(NT_Type type) {
+  return (type & (NT_INTEGER | NT_FLOAT | NT_DOUBLE)) != 0;
+}
+
+constexpr bool IsNumericArray(NT_Type type) {
+  return (type & (NT_INTEGER_ARRAY | NT_FLOAT_ARRAY | NT_DOUBLE_ARRAY)) != 0;
+}
+
+constexpr bool IsNumericCompatible(NT_Type a, NT_Type b) {
+  return (IsNumeric(a) && IsNumeric(b)) ||
+         (IsNumericArray(a) && IsNumericArray(b));
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/Value.cpp b/ntcore/src/main/native/cpp/Value.cpp
index e0d65c9..240447f 100644
--- a/ntcore/src/main/native/cpp/Value.cpp
+++ b/ntcore/src/main/native/cpp/Value.cpp
@@ -5,29 +5,63 @@
 #include <stdint.h>
 
 #include <cstring>
+#include <span>
 
 #include <wpi/MemAlloc.h>
 #include <wpi/timestamp.h>
 
 #include "Value_internal.h"
 #include "networktables/NetworkTableValue.h"
+#include "ntcore_cpp.h"
 
 using namespace nt;
 
-Value::Value() {
-  m_val.type = NT_UNASSIGNED;
-  m_val.last_change = wpi::Now();
+namespace {
+struct StringArrayStorage {
+  explicit StringArrayStorage(std::span<const std::string> value)
+      : strings{value.begin(), value.end()} {
+    InitNtStrings();
+  }
+  explicit StringArrayStorage(std::vector<std::string>&& value)
+      : strings{std::move(value)} {
+    InitNtStrings();
+  }
+  void InitNtStrings();
+
+  std::vector<std::string> strings;
+  std::vector<NT_String> ntStrings;
+};
+}  // namespace
+
+void StringArrayStorage::InitNtStrings() {
+  // point NT_String's to the contents in the vector.
+  ntStrings.reserve(strings.size());
+  for (const auto& str : strings) {
+    ntStrings.emplace_back(
+        NT_String{const_cast<char*>(str.c_str()), str.size()});
+  }
 }
 
-Value::Value(NT_Type type, uint64_t time, const private_init&) {
+Value::Value() {
+  m_val.type = NT_UNASSIGNED;
+  m_val.last_change = 0;
+  m_val.server_time = 0;
+}
+
+Value::Value(NT_Type type, int64_t time, const private_init&)
+    : Value{type, time == 0 ? nt::Now() : time, 1, private_init{}} {}
+
+Value::Value(NT_Type type, int64_t time, int64_t serverTime,
+             const private_init&) {
   m_val.type = type;
-  if (time == 0) {
-    m_val.last_change = wpi::Now();
-  } else {
-    m_val.last_change = time;
-  }
+  m_val.last_change = time;
+  m_val.server_time = serverTime;
   if (m_val.type == NT_BOOLEAN_ARRAY) {
     m_val.data.arr_boolean.arr = nullptr;
+  } else if (m_val.type == NT_INTEGER_ARRAY) {
+    m_val.data.arr_int.arr = nullptr;
+  } else if (m_val.type == NT_FLOAT_ARRAY) {
+    m_val.data.arr_float.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) {
@@ -35,93 +69,121 @@
   }
 }
 
-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::span<const 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);
+Value Value::MakeBooleanArray(std::span<const bool> value, int64_t time) {
+  Value val{NT_BOOLEAN_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<int>>(value.begin(), value.end());
+  // data->reserve(value.size());
+  // std::copy(value.begin(), value.end(), *data);
+  val.m_val.data.arr_boolean.arr = data->data();
+  val.m_val.data.arr_boolean.size = data->size();
+  val.m_storage = std::move(data);
   return val;
 }
 
-std::shared_ptr<Value> Value::MakeBooleanArray(wpi::span<const 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);
+Value Value::MakeBooleanArray(std::span<const int> value, int64_t time) {
+  Value val{NT_BOOLEAN_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<int>>(value.begin(), value.end());
+  val.m_val.data.arr_boolean.arr = data->data();
+  val.m_val.data.arr_boolean.size = data->size();
+  val.m_storage = std::move(data);
   return val;
 }
 
-std::shared_ptr<Value> Value::MakeDoubleArray(wpi::span<const 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);
+Value Value::MakeBooleanArray(std::vector<int>&& value, int64_t time) {
+  Value val{NT_BOOLEAN_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<int>>(std::move(value));
+  val.m_val.data.arr_boolean.arr = data->data();
+  val.m_val.data.arr_boolean.size = data->size();
+  val.m_storage = std::move(data);
   return val;
 }
 
-std::shared_ptr<Value> Value::MakeStringArray(
-    wpi::span<const std::string> value, uint64_t time) {
-  auto val = std::make_shared<Value>(NT_STRING_ARRAY, time, private_init());
-  val->m_string_array.assign(value.begin(), value.end());
-  // 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();
-  }
+Value Value::MakeIntegerArray(std::span<const int64_t> value, int64_t time) {
+  Value val{NT_INTEGER_ARRAY, time, private_init{}};
+  auto data =
+      std::make_shared<std::vector<int64_t>>(value.begin(), value.end());
+  val.m_val.data.arr_int.arr = data->data();
+  val.m_val.data.arr_int.size = data->size();
+  val.m_storage = std::move(data);
   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();
-  }
+Value Value::MakeIntegerArray(std::vector<int64_t>&& value, int64_t time) {
+  Value val{NT_INTEGER_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<int64_t>>(std::move(value));
+  val.m_val.data.arr_int.arr = data->data();
+  val.m_val.data.arr_int.size = data->size();
+  val.m_storage = std::move(data);
+  return val;
+}
+
+Value Value::MakeFloatArray(std::span<const float> value, int64_t time) {
+  Value val{NT_FLOAT_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<float>>(value.begin(), value.end());
+  val.m_val.data.arr_float.arr = data->data();
+  val.m_val.data.arr_float.size = data->size();
+  val.m_storage = std::move(data);
+  return val;
+}
+
+Value Value::MakeFloatArray(std::vector<float>&& value, int64_t time) {
+  Value val{NT_FLOAT_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<float>>(std::move(value));
+  val.m_val.data.arr_float.arr = data->data();
+  val.m_val.data.arr_float.size = data->size();
+  val.m_storage = std::move(data);
+  return val;
+}
+
+Value Value::MakeDoubleArray(std::span<const double> value, int64_t time) {
+  Value val{NT_DOUBLE_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<double>>(value.begin(), value.end());
+  val.m_val.data.arr_double.arr = data->data();
+  val.m_val.data.arr_double.size = data->size();
+  val.m_storage = std::move(data);
+  return val;
+}
+
+Value Value::MakeDoubleArray(std::vector<double>&& value, int64_t time) {
+  Value val{NT_DOUBLE_ARRAY, time, private_init{}};
+  auto data = std::make_shared<std::vector<double>>(std::move(value));
+  val.m_val.data.arr_double.arr = data->data();
+  val.m_val.data.arr_double.size = data->size();
+  val.m_storage = std::move(data);
+  return val;
+}
+
+Value Value::MakeStringArray(std::span<const std::string> value, int64_t time) {
+  Value val{NT_STRING_ARRAY, time, private_init{}};
+  auto data = std::make_shared<StringArrayStorage>(value);
+  val.m_val.data.arr_string.arr = data->ntStrings.data();
+  val.m_val.data.arr_string.size = data->ntStrings.size();
+  val.m_storage = std::move(data);
+  return val;
+}
+
+Value Value::MakeStringArray(std::vector<std::string>&& value, int64_t time) {
+  Value val{NT_STRING_ARRAY, time, private_init{}};
+  auto data = std::make_shared<StringArrayStorage>(std::move(value));
+  val.m_val.data.arr_string.arr = data->ntStrings.data();
+  val.m_val.data.arr_string.size = data->ntStrings.size();
+  val.m_storage = std::move(data);
   return val;
 }
 
 void nt::ConvertToC(const Value& in, NT_Value* out) {
-  out->type = NT_UNASSIGNED;
+  *out = in.value();
   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);
+    case NT_RAW: {
+      auto v = in.GetRaw();
+      out->data.v_raw.data = static_cast<uint8_t*>(wpi::safe_malloc(v.size()));
+      out->data.v_raw.size = v.size();
+      std::memcpy(out->data.v_raw.data, v.data(), v.size());
       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 =
@@ -130,6 +192,22 @@
       std::copy(v.begin(), v.end(), out->data.arr_boolean.arr);
       break;
     }
+    case NT_INTEGER_ARRAY: {
+      auto v = in.GetIntegerArray();
+      out->data.arr_int.arr =
+          static_cast<int64_t*>(wpi::safe_malloc(v.size() * sizeof(int64_t)));
+      out->data.arr_int.size = v.size();
+      std::copy(v.begin(), v.end(), out->data.arr_int.arr);
+      break;
+    }
+    case NT_FLOAT_ARRAY: {
+      auto v = in.GetFloatArray();
+      out->data.arr_float.arr =
+          static_cast<float*>(wpi::safe_malloc(v.size() * sizeof(float)));
+      out->data.arr_float.size = v.size();
+      std::copy(v.begin(), v.end(), out->data.arr_float.arr);
+      break;
+    }
     case NT_DOUBLE_ARRAY: {
       auto v = in.GetDoubleArray();
       out->data.arr_double.arr =
@@ -143,16 +221,21 @@
       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]);
+        ConvertToC(std::string_view{v[i]}, &out->data.arr_string.arr[i]);
       }
       out->data.arr_string.size = v.size();
       break;
     }
     default:
-      // assert(false && "unknown value type");
-      return;
+      break;
   }
-  out->type = in.type();
+}
+
+size_t nt::ConvertToC(std::string_view in, char** out) {
+  *out = static_cast<char*>(wpi::safe_malloc(in.size() + 1));
+  std::memmove(*out, in.data(), in.size());  // NOLINT
+  (*out)[in.size()] = '\0';
+  return in.size();
 }
 
 void nt::ConvertToC(std::string_view in, NT_String* out) {
@@ -162,37 +245,48 @@
   out->str[in.size()] = '\0';
 }
 
-std::shared_ptr<Value> nt::ConvertFromC(const NT_Value& value) {
+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);
+      return Value::MakeBoolean(value.data.v_boolean != 0, value.last_change);
+    case NT_INTEGER:
+      return Value::MakeInteger(value.data.v_int, value.last_change);
+    case NT_FLOAT:
+      return Value::MakeFloat(value.data.v_float, value.last_change);
     case NT_DOUBLE:
-      return Value::MakeDouble(value.data.v_double);
+      return Value::MakeDouble(value.data.v_double, value.last_change);
     case NT_STRING:
-      return Value::MakeString(ConvertFromC(value.data.v_string));
+      return Value::MakeString(ConvertFromC(value.data.v_string),
+                               value.last_change);
     case NT_RAW:
-      return Value::MakeRaw(ConvertFromC(value.data.v_raw));
-    case NT_RPC:
-      return Value::MakeRpc(ConvertFromC(value.data.v_raw));
+      return Value::MakeRaw({value.data.v_raw.data, value.data.v_raw.size},
+                            value.last_change);
     case NT_BOOLEAN_ARRAY:
       return Value::MakeBooleanArray(
-          wpi::span(value.data.arr_boolean.arr, value.data.arr_boolean.size));
+          std::span(value.data.arr_boolean.arr, value.data.arr_boolean.size),
+          value.last_change);
+    case NT_INTEGER_ARRAY:
+      return Value::MakeIntegerArray(
+          std::span(value.data.arr_int.arr, value.data.arr_int.size),
+          value.last_change);
+    case NT_FLOAT_ARRAY:
+      return Value::MakeFloatArray(
+          std::span(value.data.arr_float.arr, value.data.arr_float.size),
+          value.last_change);
     case NT_DOUBLE_ARRAY:
       return Value::MakeDoubleArray(
-          wpi::span(value.data.arr_double.arr, value.data.arr_double.size));
+          std::span(value.data.arr_double.arr, value.data.arr_double.size),
+          value.last_change);
     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.emplace_back(ConvertFromC(value.data.arr_string.arr[i]));
       }
-      return Value::MakeStringArray(std::move(v));
+      return Value::MakeStringArray(std::move(v), value.last_change);
     }
     default:
-      // assert(false && "unknown value type");
-      return nullptr;
+      return {};
   }
 }
 
@@ -205,12 +299,20 @@
       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_INTEGER:
+      return lhs.m_val.data.v_int == rhs.m_val.data.v_int;
+    case NT_FLOAT:
+      return lhs.m_val.data.v_float == rhs.m_val.data.v_float;
     case NT_DOUBLE:
       return lhs.m_val.data.v_double == rhs.m_val.data.v_double;
     case NT_STRING:
+      return lhs.GetString() == rhs.GetString();
     case NT_RAW:
-    case NT_RPC:
-      return lhs.m_string == rhs.m_string;
+      if (lhs.m_val.data.v_raw.size != rhs.m_val.data.v_raw.size) {
+        return false;
+      }
+      return std::memcmp(lhs.m_val.data.v_raw.data, rhs.m_val.data.v_raw.data,
+                         lhs.m_val.data.v_raw.size) == 0;
     case NT_BOOLEAN_ARRAY:
       if (lhs.m_val.data.arr_boolean.size != rhs.m_val.data.arr_boolean.size) {
         return false;
@@ -219,6 +321,21 @@
                          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_INTEGER_ARRAY:
+      if (lhs.m_val.data.arr_int.size != rhs.m_val.data.arr_int.size) {
+        return false;
+      }
+      return std::memcmp(lhs.m_val.data.arr_int.arr, rhs.m_val.data.arr_int.arr,
+                         lhs.m_val.data.arr_int.size *
+                             sizeof(lhs.m_val.data.arr_int.arr[0])) == 0;
+    case NT_FLOAT_ARRAY:
+      if (lhs.m_val.data.arr_float.size != rhs.m_val.data.arr_float.size) {
+        return false;
+      }
+      return std::memcmp(lhs.m_val.data.arr_float.arr,
+                         rhs.m_val.data.arr_float.arr,
+                         lhs.m_val.data.arr_float.size *
+                             sizeof(lhs.m_val.data.arr_float.arr[0])) == 0;
     case NT_DOUBLE_ARRAY:
       if (lhs.m_val.data.arr_double.size != rhs.m_val.data.arr_double.size) {
         return false;
@@ -228,7 +345,8 @@
                          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;
+      return static_cast<StringArrayStorage*>(lhs.m_storage.get())->strings ==
+             static_cast<StringArrayStorage*>(rhs.m_storage.get())->strings;
     default:
       // assert(false && "unknown value type");
       return false;
diff --git a/ntcore/src/main/native/cpp/Value_internal.cpp b/ntcore/src/main/native/cpp/Value_internal.cpp
new file mode 100644
index 0000000..2003d31
--- /dev/null
+++ b/ntcore/src/main/native/cpp/Value_internal.cpp
@@ -0,0 +1,49 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "Value_internal.h"
+
+using namespace nt;
+
+Value nt::ConvertNumericValue(const Value& value, NT_Type type) {
+  switch (type) {
+    case NT_INTEGER: {
+      Value newval =
+          Value::MakeInteger(GetNumericAs<int64_t>(value), value.time());
+      newval.SetServerTime(value.server_time());
+      return newval;
+    }
+    case NT_FLOAT: {
+      Value newval = Value::MakeFloat(GetNumericAs<float>(value), value.time());
+      newval.SetServerTime(value.server_time());
+      return newval;
+    }
+    case NT_DOUBLE: {
+      Value newval =
+          Value::MakeDouble(GetNumericAs<double>(value), value.time());
+      newval.SetServerTime(value.server_time());
+      return newval;
+    }
+    case NT_INTEGER_ARRAY: {
+      Value newval = Value::MakeIntegerArray(GetNumericArrayAs<int64_t>(value),
+                                             value.time());
+      newval.SetServerTime(value.server_time());
+      return newval;
+    }
+    case NT_FLOAT_ARRAY: {
+      Value newval =
+          Value::MakeFloatArray(GetNumericArrayAs<float>(value), value.time());
+      newval.SetServerTime(value.server_time());
+      return newval;
+    }
+    case NT_DOUBLE_ARRAY: {
+      Value newval = Value::MakeDoubleArray(GetNumericArrayAs<double>(value),
+                                            value.time());
+      newval.SetServerTime(value.server_time());
+      return newval;
+    }
+    default:
+      return {};
+  }
+}
diff --git a/ntcore/src/main/native/cpp/Value_internal.h b/ntcore/src/main/native/cpp/Value_internal.h
index 54850ab..03532ac 100644
--- a/ntcore/src/main/native/cpp/Value_internal.h
+++ b/ntcore/src/main/native/cpp/Value_internal.h
@@ -2,26 +2,90 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_VALUE_INTERNAL_H_
-#define NTCORE_VALUE_INTERNAL_H_
+#pragma once
 
+#include <cstring>
 #include <memory>
 #include <string>
 #include <string_view>
+#include <vector>
 
+#include <wpi/MemAlloc.h>
+
+#include "networktables/NetworkTableValue.h"
 #include "ntcore_c.h"
 
 namespace nt {
 
 class Value;
 
+template <typename T>
+inline void ConvertToC(const T& in, T* out) {
+  *out = in;
+}
+
 void ConvertToC(const Value& in, NT_Value* out);
-std::shared_ptr<Value> ConvertFromC(const NT_Value& value);
+Value ConvertFromC(const NT_Value& value);
+size_t ConvertToC(std::string_view in, char** out);
 void ConvertToC(std::string_view in, NT_String* out);
 inline std::string_view ConvertFromC(const NT_String& str) {
   return {str.str, str.len};
 }
 
-}  // namespace nt
+template <typename O, typename I>
+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;
+}
 
-#endif  // NTCORE_VALUE_INTERNAL_H_
+template <typename O, typename I>
+O* ConvertToC(const std::basic_string<I>& in, size_t* out_len) {
+  char* out = static_cast<char*>(wpi::safe_malloc(in.size() + 1));
+  std::memmove(out, in.data(), in.size());  // NOLINT
+  out[in.size()] = '\0';
+  *out_len = in.size();
+  return out;
+}
+
+template <typename T>
+T GetNumericAs(const Value& value) {
+  if (value.IsInteger()) {
+    return static_cast<T>(value.GetInteger());
+  } else if (value.IsFloat()) {
+    return static_cast<T>(value.GetFloat());
+  } else if (value.IsDouble()) {
+    return static_cast<T>(value.GetDouble());
+  } else {
+    return {};
+  }
+}
+
+template <typename T>
+std::vector<T> GetNumericArrayAs(const Value& value) {
+  if (value.IsIntegerArray()) {
+    auto arr = value.GetIntegerArray();
+    return {arr.begin(), arr.end()};
+  } else if (value.IsFloatArray()) {
+    auto arr = value.GetFloatArray();
+    return {arr.begin(), arr.end()};
+  } else if (value.IsDoubleArray()) {
+    auto arr = value.GetDoubleArray();
+    return {arr.begin(), arr.end()};
+  } else {
+    return {};
+  }
+}
+
+Value ConvertNumericValue(const Value& value, NT_Type type);
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/cpp/WireDecoder.cpp b/ntcore/src/main/native/cpp/WireDecoder.cpp
deleted file mode 100644
index c0647dc..0000000
--- a/ntcore/src/main/native/cpp/WireDecoder.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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->assign(buf, len);
-  return true;
-}
diff --git a/ntcore/src/main/native/cpp/WireDecoder.h b/ntcore/src/main/native/cpp/WireDecoder.h
deleted file mode 100644
index 972be57..0000000
--- a/ntcore/src/main/native/cpp/WireDecoder.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index b35b780..0000000
--- a/ntcore/src/main/native/cpp/WireEncoder.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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(std::string_view 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(std::string_view 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
deleted file mode 100644
index 84edc39..0000000
--- a/ntcore/src/main/native/cpp/WireEncoder.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_WIREENCODER_H_
-#define NTCORE_WIREENCODER_H_
-
-#include <stdint.h>
-
-#include <cassert>
-#include <cstddef>
-#include <string_view>
-
-#include <wpi/SmallVector.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(); }
-
-  std::string_view ToStringView() const {
-    return {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(std::string_view 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(std::string_view 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
index 6c7ed82..b868604 100644
--- a/ntcore/src/main/native/cpp/jni/NetworkTablesJNI.cpp
+++ b/ntcore/src/main/native/cpp/jni/NetworkTablesJNI.cpp
@@ -9,9 +9,11 @@
 #include <fmt/format.h>
 #include <wpi/ConvertUTF.h>
 #include <wpi/jni_util.h>
+#include <wpi/json.h>
 
 #include "edu_wpi_first_networktables_NetworkTablesJNI.h"
 #include "ntcore.h"
+#include "ntcore_cpp.h"
 
 using namespace wpi::java;
 
@@ -19,6 +21,11 @@
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #endif
 
+namespace nt {
+bool JNI_LoadTypes(JNIEnv* env);
+void JNI_UnloadTypes(JNIEnv* env);
+}  // namespace nt
+
 //
 // Globals and load/unload
 //
@@ -27,35 +34,40 @@
 static JavaVM* jvm = nullptr;
 static JClass booleanCls;
 static JClass connectionInfoCls;
-static JClass connectionNotificationCls;
 static JClass doubleCls;
-static JClass entryInfoCls;
-static JClass entryNotificationCls;
+static JClass eventCls;
+static JClass floatCls;
 static JClass logMessageCls;
-static JClass rpcAnswerCls;
+static JClass longCls;
+static JClass optionalLongCls;
+static JClass pubSubOptionsCls;
+static JClass timeSyncEventDataCls;
+static JClass topicInfoCls;
 static JClass valueCls;
+static JClass valueEventDataCls;
 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/NetworkTableEvent", &eventCls},
+    {"java/lang/Float", &floatCls},
     {"edu/wpi/first/networktables/LogMessage", &logMessageCls},
-    {"edu/wpi/first/networktables/RpcAnswer", &rpcAnswerCls},
-    {"edu/wpi/first/networktables/NetworkTableValue", &valueCls}};
+    {"java/lang/Long", &longCls},
+    {"java/util/OptionalLong", &optionalLongCls},
+    {"edu/wpi/first/networktables/PubSubOptions", &pubSubOptionsCls},
+    {"edu/wpi/first/networktables/TimeSyncEventData", &timeSyncEventDataCls},
+    {"edu/wpi/first/networktables/TopicInfo", &topicInfoCls},
+    {"edu/wpi/first/networktables/NetworkTableValue", &valueCls},
+    {"edu/wpi/first/networktables/ValueEventData", &valueEventDataCls}};
 
 static const JExceptionInit exceptions[] = {
     {"java/lang/IllegalArgumentException", &illegalArgEx},
     {"java/lang/InterruptedException", &interruptedEx},
-    {"java/lang/NullPointerException", &nullPointerEx},
-    {"edu/wpi/first/networktables/PersistentException", &persistentEx}};
+    {"java/lang/NullPointerException", &nullPointerEx}};
 
 extern "C" {
 
@@ -82,6 +94,10 @@
     }
   }
 
+  if (!nt::JNI_LoadTypes(env)) {
+    return JNI_ERR;
+  }
+
   return JNI_VERSION_1_6;
 }
 
@@ -97,6 +113,7 @@
   for (auto& c : exceptions) {
     c.cls->free(env);
   }
+  nt::JNI_UnloadTypes(env);
   jvm = nullptr;
 }
 
@@ -106,92 +123,98 @@
 // 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;
+static nt::PubSubOptions FromJavaPubSubOptions(JNIEnv* env, jobject joptions) {
+  if (!joptions) {
+    return {};
   }
-  return nt::Value::MakeRaw(ref.str(), time);
-}
+#define FIELD(name, sig)                                         \
+  static jfieldID name##Field = nullptr;                         \
+  if (!name##Field) {                                            \
+    name##Field = env->GetFieldID(pubSubOptionsCls, #name, sig); \
+  }
 
-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);
-}
+  FIELD(pollStorage, "I");
+  FIELD(periodic, "D");
+  FIELD(excludePublisher, "I");
+  FIELD(sendAll, "Z");
+  FIELD(topicsOnly, "Z");
+  FIELD(keepDuplicates, "Z");
+  FIELD(prefixMatch, "Z");
+  FIELD(disableRemote, "Z");
+  FIELD(disableLocal, "Z");
+  FIELD(excludeSelf, "Z");
 
-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);
-}
+#undef FIELD
 
-std::shared_ptr<nt::Value> FromJavaBooleanArray(JNIEnv* env, jbooleanArray jarr,
-                                                jlong time) {
-  CriticalJBooleanArrayRef ref{env, jarr};
-  if (!ref) {
-    return nullptr;
-  }
-  wpi::span<const 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);
-}
+#define FIELD(ctype, jtype, name) \
+  .name = static_cast<ctype>(env->Get##jtype##Field(joptions, name##Field))
 
-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);
-}
+  return {FIELD(unsigned int, Int, pollStorage),
+          FIELD(double, Double, periodic),
+          FIELD(NT_Publisher, Int, excludePublisher),
+          FIELD(bool, Boolean, sendAll),
+          FIELD(bool, Boolean, topicsOnly),
+          FIELD(bool, Boolean, keepDuplicates),
+          FIELD(bool, Boolean, prefixMatch),
+          FIELD(bool, Boolean, disableRemote),
+          FIELD(bool, Boolean, disableLocal),
+          FIELD(bool, Boolean, excludeSelf)};
 
-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.emplace_back(JStringRef{env, elem}.str());
-  }
-  return nt::Value::MakeStringArray(std::move(arr), time);
+#undef GET
+#undef FIELD
 }
 
 //
 // Conversions from C++ to Java objects
 //
 
+static jobject MakeJObject(JNIEnv* env, std::optional<int64_t> value) {
+  static jmethodID emptyMethod = nullptr;
+  static jmethodID ofMethod = nullptr;
+  if (!emptyMethod) {
+    emptyMethod = env->GetStaticMethodID(optionalLongCls, "empty",
+                                         "()Ljava/util/OptionalLong;");
+  }
+  if (!ofMethod) {
+    ofMethod = env->GetStaticMethodID(optionalLongCls, "of",
+                                      "(J)Ljava/util/OptionalLong;");
+  }
+  if (value) {
+    return env->CallStaticObjectMethod(optionalLongCls, ofMethod,
+                                       static_cast<jlong>(*value));
+  } else {
+    return env->CallStaticObjectMethod(optionalLongCls, emptyMethod);
+  }
+}
+
 static jobject MakeJObject(JNIEnv* env, const nt::Value& value) {
   static jmethodID booleanConstructor = nullptr;
   static jmethodID doubleConstructor = nullptr;
+  static jmethodID floatConstructor = nullptr;
+  static jmethodID longConstructor = nullptr;
   if (!booleanConstructor) {
     booleanConstructor = env->GetMethodID(booleanCls, "<init>", "(Z)V");
   }
   if (!doubleConstructor) {
     doubleConstructor = env->GetMethodID(doubleCls, "<init>", "(D)V");
   }
+  if (!floatConstructor) {
+    floatConstructor = env->GetMethodID(floatCls, "<init>", "(F)V");
+  }
+  if (!longConstructor) {
+    longConstructor = env->GetMethodID(longCls, "<init>", "(J)V");
+  }
 
   switch (value.type()) {
     case NT_BOOLEAN:
       return env->NewObject(booleanCls, booleanConstructor,
                             static_cast<jboolean>(value.GetBoolean() ? 1 : 0));
+    case NT_INTEGER:
+      return env->NewObject(longCls, longConstructor,
+                            static_cast<jlong>(value.GetInteger()));
+    case NT_FLOAT:
+      return env->NewObject(floatCls, floatConstructor,
+                            static_cast<jfloat>(value.GetFloat()));
     case NT_DOUBLE:
       return env->NewObject(doubleCls, doubleConstructor,
                             static_cast<jdouble>(value.GetDouble()));
@@ -201,28 +224,31 @@
       return MakeJByteArray(env, value.GetRaw());
     case NT_BOOLEAN_ARRAY:
       return MakeJBooleanArray(env, value.GetBooleanArray());
+    case NT_INTEGER_ARRAY:
+      return MakeJLongArray(env, value.GetIntegerArray());
+    case NT_FLOAT_ARRAY:
+      return MakeJFloatArray(env, value.GetFloatArray());
     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 jobject MakeJValue(JNIEnv* env, const nt::Value& value) {
   static jmethodID constructor =
-      env->GetMethodID(valueCls, "<init>", "(ILjava/lang/Object;J)V");
+      env->GetMethodID(valueCls, "<init>", "(ILjava/lang/Object;JJ)V");
   if (!value) {
     return env->NewObject(valueCls, constructor,
                           static_cast<jint>(NT_UNASSIGNED), nullptr,
-                          static_cast<jlong>(0));
+                          static_cast<jlong>(0), static_cast<jlong>(0));
   }
-  return env->NewObject(valueCls, constructor, static_cast<jint>(value->type()),
-                        MakeJObject(env, *value),
-                        static_cast<jlong>(value->time()));
+  return env->NewObject(valueCls, constructor, static_cast<jint>(value.type()),
+                        MakeJObject(env, value),
+                        static_cast<jlong>(value.time()),
+                        static_cast<jlong>(value.server_time()));
 }
 
 static jobject MakeJObject(JNIEnv* env, const nt::ConnectionInfo& info) {
@@ -237,120 +263,96 @@
                         static_cast<jint>(info.protocol_version));
 }
 
-static jobject MakeJObject(JNIEnv* env, jobject inst,
-                           const nt::ConnectionNotification& notification) {
+static jobject MakeJObject(JNIEnv* env, const nt::LogMessage& msg) {
   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,
-                        static_cast<jint>(notification.listener),
-                        static_cast<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, static_cast<jint>(info.entry),
-      name.obj(), static_cast<jint>(info.type), static_cast<jint>(info.flags),
-      static_cast<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,
-                        static_cast<jint>(notification.listener),
-                        static_cast<jint>(notification.entry), name.obj(),
-                        value.obj(), static_cast<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");
+      logMessageCls, "<init>", "(ILjava/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,
-                        static_cast<jint>(msg.logger),
+  return env->NewObject(logMessageCls, constructor,
                         static_cast<jint>(msg.level), filename.obj(),
                         static_cast<jint>(msg.line), message.obj());
 }
 
 static jobject MakeJObject(JNIEnv* env, jobject inst,
-                           const nt::RpcAnswer& answer) {
+                           const nt::TopicInfo& info) {
+  static jmethodID constructor = env->GetMethodID(
+      topicInfoCls, "<init>",
+      "(Ledu/wpi/first/networktables/"
+      "NetworkTableInstance;ILjava/lang/String;ILjava/lang/String;)V");
+  JLocal<jstring> name{env, MakeJString(env, info.name)};
+  JLocal<jstring> typeStr{env, MakeJString(env, info.type_str)};
+  return env->NewObject(topicInfoCls, constructor, inst,
+                        static_cast<jint>(info.topic), name.obj(),
+                        static_cast<jint>(info.type), typeStr.obj());
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst,
+                           const nt::ValueEventData& data) {
   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)};
+      env->GetMethodID(valueEventDataCls, "<init>",
+                       "(Ledu/wpi/first/networktables/NetworkTableInstance;II"
+                       "Ledu/wpi/first/networktables/NetworkTableValue;)V");
+  JLocal<jobject> value{env, MakeJValue(env, data.value)};
+  return env->NewObject(valueEventDataCls, constructor, inst,
+                        static_cast<jint>(data.topic),
+                        static_cast<jint>(data.subentry), value.obj());
+}
+
+static jobject MakeJObject(JNIEnv* env, const nt::TimeSyncEventData& data) {
+  static jmethodID constructor =
+      env->GetMethodID(timeSyncEventDataCls, "<init>", "(JJZ)V");
+  return env->NewObject(timeSyncEventDataCls, constructor,
+                        static_cast<jlong>(data.serverTimeOffset),
+                        static_cast<jlong>(data.rtt2),
+                        static_cast<jboolean>(data.valid));
+}
+
+static jobject MakeJObject(JNIEnv* env, jobject inst, const nt::Event& event) {
+  static jmethodID constructor =
+      env->GetMethodID(eventCls, "<init>",
+                       "(Ledu/wpi/first/networktables/NetworkTableInstance;II"
+                       "Ledu/wpi/first/networktables/ConnectionInfo;"
+                       "Ledu/wpi/first/networktables/TopicInfo;"
+                       "Ledu/wpi/first/networktables/ValueEventData;"
+                       "Ledu/wpi/first/networktables/LogMessage;"
+                       "Ledu/wpi/first/networktables/TimeSyncEventData;)V");
+  JLocal<jobject> connInfo{env, nullptr};
+  JLocal<jobject> topicInfo{env, nullptr};
+  JLocal<jobject> valueData{env, nullptr};
+  JLocal<jobject> logMessage{env, nullptr};
+  JLocal<jobject> timeSyncData{env, nullptr};
+  if (auto v = event.GetConnectionInfo()) {
+    connInfo = JLocal<jobject>{env, MakeJObject(env, *v)};
+  } else if (auto v = event.GetTopicInfo()) {
+    topicInfo = JLocal<jobject>{env, MakeJObject(env, inst, *v)};
+  } else if (auto v = event.GetValueEventData()) {
+    valueData = JLocal<jobject>{env, MakeJObject(env, inst, *v)};
+  } else if (auto v = event.GetLogMessage()) {
+    logMessage = JLocal<jobject>{env, MakeJObject(env, *v)};
+  } else if (auto v = event.GetTimeSyncEventData()) {
+    timeSyncData = JLocal<jobject>{env, MakeJObject(env, *v)};
+  }
   return env->NewObject(
-      rpcAnswerCls, constructor, inst, static_cast<jint>(answer.entry),
-      static_cast<jint>(answer.call), name.obj(), params.obj(), conn.obj());
+      eventCls, constructor, inst, static_cast<jint>(event.listener),
+      static_cast<jint>(event.flags), connInfo.obj(), topicInfo.obj(),
+      valueData.obj(), logMessage.obj(), timeSyncData.obj());
 }
 
-static jobjectArray MakeJObject(
-    JNIEnv* env, jobject inst,
-    wpi::span<const nt::ConnectionNotification> arr) {
-  jobjectArray jarr =
-      env->NewObjectArray(arr.size(), connectionNotificationCls, nullptr);
+static jobjectArray MakeJObject(JNIEnv* env, std::span<const nt::Value> arr) {
+  jobjectArray jarr = env->NewObjectArray(arr.size(), valueCls, nullptr);
   if (!jarr) {
     return nullptr;
   }
   for (size_t i = 0; i < arr.size(); ++i) {
-    JLocal<jobject> elem{env, MakeJObject(env, inst, arr[i])};
+    JLocal<jobject> elem{env, MakeJValue(env, arr[i])};
     env->SetObjectArrayElement(jarr, i, elem.obj());
   }
   return jarr;
 }
 
 static jobjectArray MakeJObject(JNIEnv* env, jobject inst,
-                                wpi::span<const 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::span<const 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::span<const nt::RpcAnswer> arr) {
-  jobjectArray jarr = env->NewObjectArray(arr.size(), rpcAnswerCls, nullptr);
+                                std::span<const nt::Event> arr) {
+  jobjectArray jarr = env->NewObjectArray(arr.size(), eventCls, nullptr);
   if (!jarr) {
     return nullptr;
   }
@@ -424,24 +426,7 @@
     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));
+  return nt::GetEntry(inst, JStringRef{env, key});
 }
 
 /*
@@ -482,183 +467,504 @@
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setBoolean
- * Signature: (IJZZ)Z
+ * Method:    getTopics
+ * Signature: (ILjava/lang/String;I)[I
  */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setBoolean
-  (JNIEnv*, jclass, jint entry, jlong time, jboolean value, jboolean force)
+JNIEXPORT jintArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopics
+  (JNIEnv* env, jclass, jint inst, jstring prefix, jint types)
 {
-  if (force) {
-    nt::SetEntryTypeValue(entry,
-                          nt::Value::MakeBoolean(value != JNI_FALSE, time));
-    return JNI_TRUE;
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
   }
-  return nt::SetEntryValue(entry,
-                           nt::Value::MakeBoolean(value != JNI_FALSE, time));
+  auto arr = nt::GetTopics(inst, JStringRef{env, prefix}.str(), types);
+  return MakeJIntArray(env, arr);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setDouble
- * Signature: (IJDZ)Z
+ * Method:    getTopicsStr
+ * Signature: (ILjava/lang/String;[Ljava/lang/Object;)[I
  */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setDouble
-  (JNIEnv*, jclass, jint entry, jlong time, jdouble value, jboolean force)
+JNIEXPORT jintArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicsStr
+  (JNIEnv* env, jclass, jint inst, jstring prefix, jobjectArray types)
 {
-  if (force) {
-    nt::SetEntryTypeValue(entry, nt::Value::MakeDouble(value, time));
-    return JNI_TRUE;
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
   }
-  return nt::SetEntryValue(entry, nt::Value::MakeDouble(value, time));
+  if (!types) {
+    nullPointerEx.Throw(env, "types cannot be null");
+    return nullptr;
+  }
+
+  int len = env->GetArrayLength(types);
+  std::vector<std::string> typeStrData;
+  std::vector<std::string_view> typeStrs;
+  typeStrs.reserve(len);
+  for (int i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(types, i))};
+    if (!elem) {
+      nullPointerEx.Throw(env, "null string in types");
+      return nullptr;
+    }
+    typeStrData.emplace_back(JStringRef{env, elem}.str());
+    typeStrs.emplace_back(typeStrData.back());
+  }
+
+  auto arr = nt::GetTopics(inst, JStringRef{env, prefix}.str(), typeStrs);
+  return MakeJIntArray(env, arr);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setString
- * Signature: (IJLjava/lang/String;Z)Z
+ * Method:    getTopicInfos
+ * Signature: (Ljava/lang/Object;ILjava/lang/String;I)[Ljava/lang/Object;
  */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setString
-  (JNIEnv* env, jclass, jint entry, jlong time, jstring value, jboolean force)
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicInfos
+  (JNIEnv* env, jclass, jobject instObject, jint inst, jstring prefix,
+   jint types)
 {
-  if (!value) {
-    nullPointerEx.Throw(env, "value cannot be null");
-    return false;
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
   }
-  if (force) {
-    nt::SetEntryTypeValue(
-        entry, nt::Value::MakeString(JStringRef{env, value}.str(), time));
-    return JNI_TRUE;
+  auto arr = nt::GetTopicInfo(inst, JStringRef{env, prefix}.str(), types);
+  jobjectArray jarr = env->NewObjectArray(arr.size(), topicInfoCls, nullptr);
+  if (!jarr) {
+    return nullptr;
   }
-  return nt::SetEntryValue(
-      entry, nt::Value::MakeString(JStringRef{env, value}.str(), time));
+  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:    setRaw
- * Signature: (IJ[BZ)Z
+ * Method:    getTopicInfosStr
+ * Signature: (Ljava/lang/Object;ILjava/lang/String;[Ljava/lang/Object;)[Ljava/lang/Object;
  */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw__IJ_3BZ
-  (JNIEnv* env, jclass, jint entry, jlong time, jbyteArray value,
-   jboolean force)
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicInfosStr
+  (JNIEnv* env, jclass, jobject instObject, jint inst, jstring prefix,
+   jobjectArray types)
 {
-  if (!value) {
-    nullPointerEx.Throw(env, "value cannot be null");
-    return false;
+  if (!prefix) {
+    nullPointerEx.Throw(env, "prefix cannot be null");
+    return nullptr;
   }
-  auto v = FromJavaRaw(env, value, time);
-  if (!v) {
-    return false;
+  if (!types) {
+    nullPointerEx.Throw(env, "types cannot be null");
+    return nullptr;
   }
-  if (force) {
-    nt::SetEntryTypeValue(entry, v);
-    return JNI_TRUE;
+
+  int len = env->GetArrayLength(types);
+  std::vector<std::string> typeStrData;
+  std::vector<std::string_view> typeStrs;
+  typeStrs.reserve(len);
+  for (int i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(types, i))};
+    if (!elem) {
+      nullPointerEx.Throw(env, "null string in types");
+      return nullptr;
+    }
+    typeStrData.emplace_back(JStringRef{env, elem}.str());
+    typeStrs.emplace_back(typeStrData.back());
   }
-  return nt::SetEntryValue(entry, v);
+
+  auto arr = nt::GetTopicInfo(inst, JStringRef{env, prefix}.str(), typeStrs);
+  jobjectArray jarr = env->NewObjectArray(arr.size(), topicInfoCls, 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:    setRaw
- * Signature: (IJLjava/lang/Object;IZ)Z
+ * Method:    getTopic
+ * Signature: (ILjava/lang/String;)I
  */
-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)
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopic
+  (JNIEnv* env, jclass, jint inst, jstring name)
 {
-  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);
+  return nt::GetTopic(inst, JStringRef{env, name});
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setBooleanArray
- * Signature: (IJ[ZZ)Z
+ * Method:    getTopicName
+ * Signature: (I)Ljava/lang/String;
  */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setBooleanArray
-  (JNIEnv* env, jclass, jint entry, jlong time, jbooleanArray value,
-   jboolean force)
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicName
+  (JNIEnv* env, jclass, jint topic)
 {
-  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);
+  return MakeJString(env, nt::GetTopicName(topic));
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setDoubleArray
- * Signature: (IJ[DZ)Z
+ * Method:    getTopicType
+ * Signature: (I)I
  */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setDoubleArray
-  (JNIEnv* env, jclass, jint entry, jlong time, jdoubleArray value,
-   jboolean force)
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicType
+  (JNIEnv*, jclass, jint topic)
 {
-  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);
+  return nt::GetTopicType(topic);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setStringArray
- * Signature: (IJ[Ljava/lang/Object;Z)Z
+ * Method:    setTopicPersistent
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setTopicPersistent
+  (JNIEnv*, jclass, jint topic, jboolean value)
+{
+  nt::SetTopicPersistent(topic, value);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicPersistent
+ * Signature: (I)Z
  */
 JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setStringArray
-  (JNIEnv* env, jclass, jint entry, jlong time, jobjectArray value,
-   jboolean force)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicPersistent
+  (JNIEnv*, jclass, jint topic)
 {
-  if (!value) {
-    nullPointerEx.Throw(env, "value cannot be null");
-    return false;
+  return nt::GetTopicPersistent(topic);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setTopicRetained
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setTopicRetained
+  (JNIEnv*, jclass, jint topic, jboolean value)
+{
+  nt::SetTopicRetained(topic, value);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicRetained
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicRetained
+  (JNIEnv*, jclass, jint topic)
+{
+  return nt::GetTopicRetained(topic);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicTypeString
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicTypeString
+  (JNIEnv* env, jclass, jint topic)
+{
+  return MakeJString(env, nt::GetTopicTypeString(topic));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicExists
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicExists
+  (JNIEnv*, jclass, jint topic)
+{
+  return nt::GetTopicExists(topic);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicProperty
+ * Signature: (ILjava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicProperty
+  (JNIEnv* env, jclass, jint topic, jstring name)
+{
+  return MakeJString(env,
+                     nt::GetTopicProperty(topic, JStringRef{env, name}).dump());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setTopicProperty
+ * Signature: (ILjava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setTopicProperty
+  (JNIEnv* env, jclass, jint topic, jstring name, jstring value)
+{
+  wpi::json j;
+  try {
+    j = wpi::json::parse(JStringRef{env, value});
+  } catch (wpi::json::parse_error& err) {
+    illegalArgEx.Throw(
+        env, fmt::format("could not parse value JSON: {}", err.what()));
+    return;
   }
-  auto v = FromJavaStringArray(env, value, time);
-  if (!v) {
-    return false;
+  nt::SetTopicProperty(topic, JStringRef{env, name}, j);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    deleteTopicProperty
+ * Signature: (ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_deleteTopicProperty
+  (JNIEnv* env, jclass, jint topic, jstring name)
+{
+  nt::DeleteTopicProperty(topic, JStringRef{env, name});
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicProperties
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicProperties
+  (JNIEnv* env, jclass, jint topic)
+{
+  return MakeJString(env, nt::GetTopicProperties(topic).dump());
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    setTopicProperties
+ * Signature: (ILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_setTopicProperties
+  (JNIEnv* env, jclass, jint topic, jstring properties)
+{
+  wpi::json j;
+  try {
+    j = wpi::json::parse(JStringRef{env, properties});
+  } catch (wpi::json::parse_error& err) {
+    illegalArgEx.Throw(
+        env, fmt::format("could not parse properties JSON: {}", err.what()));
+    return;
   }
-  if (force) {
-    nt::SetEntryTypeValue(entry, v);
-    return JNI_TRUE;
+  if (!j.is_object()) {
+    illegalArgEx.Throw(env, "properties is not a JSON object");
+    return;
   }
-  return nt::SetEntryValue(entry, v);
+  nt::SetTopicProperties(topic, j);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    subscribe
+ * Signature: (IILjava/lang/String;Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_subscribe
+  (JNIEnv* env, jclass, jint topic, jint type, jstring typeStr, jobject options)
+{
+  return nt::Subscribe(topic, static_cast<NT_Type>(type),
+                       JStringRef{env, typeStr},
+                       FromJavaPubSubOptions(env, options));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    unsubscribe
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_unsubscribe
+  (JNIEnv*, jclass, jint sub)
+{
+  nt::Unsubscribe(sub);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    publish
+ * Signature: (IILjava/lang/String;Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_publish
+  (JNIEnv* env, jclass, jint topic, jint type, jstring typeStr, jobject options)
+{
+  return nt::Publish(topic, static_cast<NT_Type>(type),
+                     JStringRef{env, typeStr},
+                     FromJavaPubSubOptions(env, options));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    publishEx
+ * Signature: (IILjava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_publishEx
+  (JNIEnv* env, jclass, jint topic, jint type, jstring typeStr,
+   jstring properties, jobject options)
+{
+  wpi::json j;
+  try {
+    j = wpi::json::parse(JStringRef{env, properties});
+  } catch (wpi::json::parse_error& err) {
+    illegalArgEx.Throw(
+        env, fmt::format("could not parse properties JSON: {}", err.what()));
+    return 0;
+  }
+  if (!j.is_object()) {
+    illegalArgEx.Throw(env, "properties is not a JSON object");
+    return 0;
+  }
+  return nt::PublishEx(topic, static_cast<NT_Type>(type),
+                       JStringRef{env, typeStr}, j,
+                       FromJavaPubSubOptions(env, options));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    unpublish
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_unpublish
+  (JNIEnv*, jclass, jint pubentry)
+{
+  nt::Unpublish(pubentry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getEntryImpl
+ * Signature: (IILjava/lang/String;Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntryImpl
+  (JNIEnv* env, jclass, jint topic, jint type, jstring typeStr, jobject options)
+{
+  return nt::GetEntry(topic, static_cast<NT_Type>(type),
+                      JStringRef{env, typeStr},
+                      FromJavaPubSubOptions(env, options));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    releaseEntry
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_releaseEntry
+  (JNIEnv*, jclass, jint entry)
+{
+  nt::ReleaseEntry(entry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    release
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_release
+  (JNIEnv*, jclass, jint pubsubentry)
+{
+  nt::Release(pubsubentry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    getTopicFromHandle
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicFromHandle
+  (JNIEnv*, jclass, jint pubsubentry)
+{
+  return nt::GetTopicFromHandle(pubsubentry);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    subscribeMultiple
+ * Signature: (I[Ljava/lang/Object;Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_subscribeMultiple
+  (JNIEnv* env, jclass, jint inst, jobjectArray prefixes, jobject options)
+{
+  if (!prefixes) {
+    nullPointerEx.Throw(env, "prefixes cannot be null");
+    return {};
+  }
+  int len = env->GetArrayLength(prefixes);
+
+  std::vector<std::string> prefixStrings;
+  std::vector<std::string_view> prefixStringViews;
+  prefixStrings.reserve(len);
+  prefixStringViews.reserve(len);
+  for (int i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(prefixes, i))};
+    if (!elem) {
+      nullPointerEx.Throw(env, "null string in prefixes");
+      return {};
+    }
+    prefixStrings.emplace_back(JStringRef{env, elem}.str());
+    prefixStringViews.emplace_back(prefixStrings.back());
+  }
+
+  return nt::SubscribeMultiple(inst, prefixStringViews,
+                               FromJavaPubSubOptions(env, options));
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    unsubscribeMultiple
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_unsubscribeMultiple
+  (JNIEnv*, jclass, jint sub)
+{
+  nt::UnsubscribeMultiple(sub);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    readQueueValue
+ * Signature: (I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_readQueueValue
+  (JNIEnv* env, jclass, jint subentry)
+{
+  return MakeJObject(env, nt::ReadQueueValue(subentry));
 }
 
 /*
@@ -670,231 +976,7 @@
 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);
+  return MakeJValue(env, nt::GetEntryValue(entry));
 }
 
 /*
@@ -923,503 +1005,108 @@
 
 /*
  * 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
+ * Method:    getTopicInfo
  * 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)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getTopicInfo
+  (JNIEnv* env, jclass, jobject inst, jint topic)
 {
-  return MakeJObject(env, inst, nt::GetEntryInfo(entry));
+  return MakeJObject(env, inst, nt::GetTopicInfo(topic));
 }
 
 /*
  * 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
+ * Method:    createListenerPoller
  * Signature: (I)I
  */
 JNIEXPORT jint JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_createEntryListenerPoller
+Java_edu_wpi_first_networktables_NetworkTablesJNI_createListenerPoller
   (JNIEnv*, jclass, jint inst)
 {
-  return nt::CreateEntryListenerPoller(inst);
+  return nt::CreateListenerPoller(inst);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    destroyEntryListenerPoller
+ * Method:    destroyListenerPoller
  * Signature: (I)V
  */
 JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyEntryListenerPoller
+Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyListenerPoller
   (JNIEnv*, jclass, jint poller)
 {
-  nt::DestroyEntryListenerPoller(poller);
+  nt::DestroyListenerPoller(poller);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    addPolledEntryListener
- * Signature: (ILjava/lang/String;I)I
+ * Method:    addListener
+ * Signature: (I[Ljava/lang/Object;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)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addListener__I_3Ljava_lang_String_2I
+  (JNIEnv* env, jclass, jint poller, jobjectArray prefixes, jint flags)
 {
-  if (!prefix) {
-    nullPointerEx.Throw(env, "prefix cannot be null");
+  if (!prefixes) {
+    nullPointerEx.Throw(env, "prefixes cannot be null");
     return 0;
   }
-  return nt::AddPolledEntryListener(poller, JStringRef{env, prefix}.str(),
-                                    flags);
+
+  size_t len = env->GetArrayLength(prefixes);
+  std::vector<std::string> arr;
+  std::vector<std::string_view> arrview;
+  arr.reserve(len);
+  arrview.reserve(len);
+  for (size_t i = 0; i < len; ++i) {
+    JLocal<jstring> elem{
+        env, static_cast<jstring>(env->GetObjectArrayElement(prefixes, i))};
+    if (!elem) {
+      nullPointerEx.Throw(env, "prefixes cannot contain null");
+      return 0;
+    }
+    arr.emplace_back(JStringRef{env, elem}.str());
+    // this is safe because of the reserve (so arr elements won't move)
+    arrview.emplace_back(arr.back());
+  }
+
+  return nt::AddPolledListener(poller, arrview, flags);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    addPolledEntryListener
+ * Method:    addListener
  * Signature: (III)I
  */
 JNIEXPORT jint JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_addPolledEntryListener__III
-  (JNIEnv* env, jclass, jint poller, jint entry, jint flags)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addListener__III
+  (JNIEnv* env, jclass, jint poller, jint handle, jint flags)
 {
-  return nt::AddPolledEntryListener(poller, entry, flags);
+  return nt::AddPolledListener(poller, handle, flags);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    pollEntryListener
+ * Method:    readListenerQueue
  * Signature: (Ljava/lang/Object;I)[Ljava/lang/Object;
  */
 JNIEXPORT jobjectArray JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_pollEntryListener
+Java_edu_wpi_first_networktables_NetworkTablesJNI_readListenerQueue
   (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);
+  return MakeJObject(env, inst, nt::ReadListenerQueue(poller));
 }
 
 /*
  * 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
+ * Method:    removeListener
  * Signature: (I)V
  */
 JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_cancelPollEntryListener
-  (JNIEnv*, jclass, jint poller)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_removeListener
+  (JNIEnv*, jclass, jint topicListener)
 {
-  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}.str(), 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}.str());
-}
-
-/*
- * 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}.str());
-}
-
-/*
- * 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());
+  nt::RemoveListener(topicListener);
 }
 
 /*
@@ -1461,12 +1148,12 @@
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
  * Method:    startServer
- * Signature: (ILjava/lang/String;Ljava/lang/String;I)V
+ * Signature: (ILjava/lang/String;Ljava/lang/String;II)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_networktables_NetworkTablesJNI_startServer
   (JNIEnv* env, jclass, jint inst, jstring persistFilename,
-   jstring listenAddress, jint port)
+   jstring listenAddress, jint port3, jint port4)
 {
   if (!persistFilename) {
     nullPointerEx.Throw(env, "persistFilename cannot be null");
@@ -1477,7 +1164,7 @@
     return;
   }
   nt::StartServer(inst, JStringRef{env, persistFilename}.str(),
-                  JStringRef{env, listenAddress}.c_str(), port);
+                  JStringRef{env, listenAddress}.c_str(), port3, port4);
 }
 
 /*
@@ -1494,89 +1181,34 @@
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    startClient
- * Signature: (I)V
+ * Method:    startClient3
+ * Signature: (ILjava/lang/String;)V
  */
 JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient__I
-  (JNIEnv*, jclass, jint inst)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient3
+  (JNIEnv* env, jclass, jint inst, jstring identity)
 {
-  nt::StartClient(inst);
+  if (!identity) {
+    nullPointerEx.Throw(env, "identity cannot be null");
+    return;
+  }
+  nt::StartClient3(inst, JStringRef{env, identity}.str());
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    startClient
- * Signature: (ILjava/lang/String;I)V
+ * Method:    startClient4
+ * Signature: (ILjava/lang/String;)V
  */
 JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient__ILjava_lang_String_2I
-  (JNIEnv* env, jclass, jint inst, jstring serverName, jint port)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startClient4
+  (JNIEnv* env, jclass, jint inst, jstring identity)
 {
-  if (!serverName) {
-    nullPointerEx.Throw(env, "serverName cannot be null");
+  if (!identity) {
+    nullPointerEx.Throw(env, "identity 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<std::string_view, 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(std::string_view{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);
+  nt::StartClient4(inst, JStringRef{env, identity}.str());
 }
 
 /*
@@ -1692,14 +1324,14 @@
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    setUpdateRate
- * Signature: (ID)V
+ * Method:    flushLocal
+ * Signature: (I)V
  */
 JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_setUpdateRate
-  (JNIEnv*, jclass, jint inst, jdouble interval)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_flushLocal
+  (JNIEnv*, jclass, jint inst)
 {
-  nt::SetUpdateRate(inst, interval);
+  nt::FlushLocal(inst);
 }
 
 /*
@@ -1750,100 +1382,14 @@
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    savePersistent
- * Signature: (ILjava/lang/String;)V
+ * Method:    getServerTimeOffset
+ * Signature: (I)Ljava/lang/Object;
  */
-JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_savePersistent
-  (JNIEnv* env, jclass, jint inst, jstring filename)
+JNIEXPORT jobject JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_getServerTimeOffset
+  (JNIEnv* env, jclass, jint inst)
 {
-  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) {
-        warns.emplace_back(fmt::format("{}: {}", line, msg));
-      });
-  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) {
-        warns.emplace_back(fmt::format("{}: {}", line, msg));
-      });
-  if (err) {
-    persistentEx.Throw(env, err);
-    return nullptr;
-  }
-  return MakeJStringArray(env, warns);
+  return MakeJObject(env, nt::GetServerTimeOffset(inst));
 }
 
 /*
@@ -1860,109 +1406,65 @@
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    createLoggerPoller
- * Signature: (I)I
+ * Method:    startEntryDataLog
+ * Signature: (IJLjava/lang/String;Ljava/lang/String;)I
  */
 JNIEXPORT jint JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_createLoggerPoller
-  (JNIEnv*, jclass, jint inst)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startEntryDataLog
+  (JNIEnv* env, jclass, jint inst, jlong log, jstring prefix, jstring logPrefix)
 {
-  return nt::CreateLoggerPoller(inst);
+  return nt::StartEntryDataLog(inst, *reinterpret_cast<wpi::log::DataLog*>(log),
+                               JStringRef{env, prefix},
+                               JStringRef{env, logPrefix});
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    destroyLoggerPoller
+ * Method:    stopEntryDataLog
  * Signature: (I)V
  */
 JNIEXPORT void JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_destroyLoggerPoller
-  (JNIEnv*, jclass, jint poller)
+Java_edu_wpi_first_networktables_NetworkTablesJNI_stopEntryDataLog
+  (JNIEnv*, jclass, jint logger)
 {
-  nt::DestroyLoggerPoller(poller);
+  nt::StopEntryDataLog(logger);
 }
 
 /*
  * Class:     edu_wpi_first_networktables_NetworkTablesJNI
- * Method:    addPolledLogger
+ * Method:    startConnectionDataLog
+ * Signature: (IJLjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_startConnectionDataLog
+  (JNIEnv* env, jclass, jint inst, jlong log, jstring name)
+{
+  return nt::StartConnectionDataLog(
+      inst, *reinterpret_cast<wpi::log::DataLog*>(log), JStringRef{env, name});
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    stopConnectionDataLog
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_networktables_NetworkTablesJNI_stopConnectionDataLog
+  (JNIEnv*, jclass, jint logger)
+{
+  nt::StopConnectionDataLog(logger);
+}
+
+/*
+ * Class:     edu_wpi_first_networktables_NetworkTablesJNI
+ * Method:    addLogger
  * Signature: (III)I
  */
 JNIEXPORT jint JNICALL
-Java_edu_wpi_first_networktables_NetworkTablesJNI_addPolledLogger
+Java_edu_wpi_first_networktables_NetworkTablesJNI_addLogger
   (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/net/ClientImpl.cpp b/ntcore/src/main/native/cpp/net/ClientImpl.cpp
new file mode 100644
index 0000000..2efbb29
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/ClientImpl.cpp
@@ -0,0 +1,489 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ClientImpl.h"
+
+#include <numeric>
+#include <optional>
+#include <string>
+#include <variant>
+
+#include <fmt/format.h>
+#include <wpi/DenseMap.h>
+#include <wpi/Logger.h>
+#include <wpi/raw_ostream.h>
+#include <wpi/timestamp.h>
+
+#include "Handle.h"
+#include "Log.h"
+#include "Message.h"
+#include "NetworkInterface.h"
+#include "PubSubOptions.h"
+#include "WireConnection.h"
+#include "WireDecoder.h"
+#include "WireEncoder.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace nt;
+using namespace nt::net;
+
+static constexpr uint32_t kMinPeriodMs = 5;
+
+// maximum number of times the wire can be not ready to send another
+// transmission before we close the connection
+static constexpr int kWireMaxNotReady = 10;
+
+namespace {
+
+struct PublisherData {
+  NT_Publisher handle;
+  PubSubOptionsImpl options;
+  // in options as double, but copy here as integer; rounded to the nearest
+  // 10 ms
+  uint32_t periodMs;
+  uint64_t nextSendMs{0};
+  std::vector<Value> outValues;  // outgoing values
+};
+
+class CImpl : public ServerMessageHandler {
+ public:
+  CImpl(uint64_t curTimeMs, int inst, WireConnection& wire, wpi::Logger& logger,
+        std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+            timeSyncUpdated,
+        std::function<void(uint32_t repeatMs)> setPeriodic);
+
+  void ProcessIncomingBinary(std::span<const uint8_t> data);
+  void HandleLocal(std::vector<ClientMessage>&& msgs);
+  bool SendControl(uint64_t curTimeMs);
+  void SendValues(uint64_t curTimeMs);
+  void SendInitialValues();
+  bool CheckNetworkReady();
+
+  // ServerMessageHandler interface
+  void ServerAnnounce(std::string_view name, int64_t id,
+                      std::string_view typeStr, const wpi::json& properties,
+                      std::optional<int64_t> pubuid) final;
+  void ServerUnannounce(std::string_view name, int64_t id) final;
+  void ServerPropertiesUpdate(std::string_view name, const wpi::json& update,
+                              bool ack) final;
+
+  void Publish(NT_Publisher pubHandle, NT_Topic topicHandle,
+               std::string_view name, std::string_view typeStr,
+               const wpi::json& properties, const PubSubOptionsImpl& options);
+  bool Unpublish(NT_Publisher pubHandle, NT_Topic topicHandle);
+  void SetValue(NT_Publisher pubHandle, const Value& value);
+
+  int m_inst;
+  WireConnection& m_wire;
+  wpi::Logger& m_logger;
+  LocalInterface* m_local{nullptr};
+  std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+      m_timeSyncUpdated;
+  std::function<void(uint32_t repeatMs)> m_setPeriodic;
+
+  // indexed by publisher index
+  std::vector<std::unique_ptr<PublisherData>> m_publishers;
+
+  // indexed by server-provided topic id
+  wpi::DenseMap<int64_t, NT_Topic> m_topicMap;
+
+  // timestamp handling
+  static constexpr uint32_t kPingIntervalMs = 3000;
+  uint64_t m_nextPingTimeMs{0};
+  uint32_t m_rtt2Us{UINT32_MAX};
+  bool m_haveTimeOffset{false};
+  int64_t m_serverTimeOffsetUs{0};
+
+  // periodic sweep handling
+  uint32_t m_periodMs{kPingIntervalMs + 10};
+  uint64_t m_lastSendMs{0};
+  int m_notReadyCount{0};
+
+  // outgoing queue
+  std::vector<ClientMessage> m_outgoing;
+};
+
+}  // namespace
+
+CImpl::CImpl(
+    uint64_t curTimeMs, int inst, WireConnection& wire, wpi::Logger& logger,
+    std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+        timeSyncUpdated,
+    std::function<void(uint32_t repeatMs)> setPeriodic)
+    : m_inst{inst},
+      m_wire{wire},
+      m_logger{logger},
+      m_timeSyncUpdated{std::move(timeSyncUpdated)},
+      m_setPeriodic{std::move(setPeriodic)},
+      m_nextPingTimeMs{curTimeMs + kPingIntervalMs} {
+  // immediately send RTT ping
+  auto out = m_wire.SendBinary();
+  auto now = wpi::Now();
+  DEBUG4("Sending initial RTT ping {}", now);
+  WireEncodeBinary(out.Add(), -1, 0, Value::MakeInteger(now));
+  m_wire.Flush();
+  m_setPeriodic(m_periodMs);
+}
+
+void CImpl::ProcessIncomingBinary(std::span<const uint8_t> data) {
+  for (;;) {
+    if (data.empty()) {
+      break;
+    }
+
+    // decode message
+    int64_t id;
+    Value value;
+    std::string error;
+    if (!WireDecodeBinary(&data, &id, &value, &error, -m_serverTimeOffsetUs)) {
+      ERROR("binary decode error: {}", error);
+      break;  // FIXME
+    }
+    DEBUG4("BinaryMessage({})", id);
+
+    // handle RTT ping response
+    if (id == -1) {
+      if (!value.IsInteger()) {
+        WARNING("RTT ping response with non-integer type {}",
+                static_cast<int>(value.type()));
+        continue;
+      }
+      DEBUG4("RTT ping response time {} value {}", value.time(),
+             value.GetInteger());
+      int64_t now = wpi::Now();
+      int64_t rtt2 = (now - value.GetInteger()) / 2;
+      if (rtt2 < m_rtt2Us) {
+        m_rtt2Us = rtt2;
+        m_serverTimeOffsetUs = value.server_time() + rtt2 - now;
+        DEBUG3("Time offset: {}", m_serverTimeOffsetUs);
+        m_haveTimeOffset = true;
+        m_timeSyncUpdated(m_serverTimeOffsetUs, m_rtt2Us, true);
+      }
+      continue;
+    }
+
+    // otherwise it's a value message, get the local topic handle for it
+    auto topicIt = m_topicMap.find(id);
+    if (topicIt == m_topicMap.end()) {
+      WARNING("received unknown id {}", id);
+      continue;
+    }
+
+    // pass along to local handler
+    if (m_local) {
+      m_local->NetworkSetValue(topicIt->second, value);
+    }
+  }
+}
+
+void CImpl::HandleLocal(std::vector<ClientMessage>&& msgs) {
+  DEBUG4("HandleLocal()");
+  for (auto&& elem : msgs) {
+    // common case is value
+    if (auto msg = std::get_if<ClientValueMsg>(&elem.contents)) {
+      SetValue(msg->pubHandle, msg->value);
+      // setvalue puts on individual publish outgoing queues
+    } else if (auto msg = std::get_if<PublishMsg>(&elem.contents)) {
+      Publish(msg->pubHandle, msg->topicHandle, msg->name, msg->typeStr,
+              msg->properties, msg->options);
+      m_outgoing.emplace_back(std::move(elem));
+    } else if (auto msg = std::get_if<UnpublishMsg>(&elem.contents)) {
+      if (Unpublish(msg->pubHandle, msg->topicHandle)) {
+        m_outgoing.emplace_back(std::move(elem));
+      }
+    } else {
+      m_outgoing.emplace_back(std::move(elem));
+    }
+  }
+}
+
+bool CImpl::SendControl(uint64_t curTimeMs) {
+  DEBUG4("SendControl({})", curTimeMs);
+
+  // rate limit sends
+  if (curTimeMs < (m_lastSendMs + kMinPeriodMs)) {
+    return false;
+  }
+
+  // start a timestamp RTT ping if it's time to do one
+  if (curTimeMs >= m_nextPingTimeMs) {
+    if (!CheckNetworkReady()) {
+      return false;
+    }
+    auto now = wpi::Now();
+    DEBUG4("Sending RTT ping {}", now);
+    WireEncodeBinary(m_wire.SendBinary().Add(), -1, 0, Value::MakeInteger(now));
+    // drift isn't critical here, so just go from current time
+    m_nextPingTimeMs = curTimeMs + kPingIntervalMs;
+  }
+
+  if (!m_outgoing.empty()) {
+    if (!CheckNetworkReady()) {
+      return false;
+    }
+    auto writer = m_wire.SendText();
+    for (auto&& msg : m_outgoing) {
+      auto& stream = writer.Add();
+      if (!WireEncodeText(stream, msg)) {
+        // shouldn't happen, but just in case...
+        stream << "{}";
+      }
+    }
+    m_outgoing.resize(0);
+  }
+
+  m_lastSendMs = curTimeMs;
+  return true;
+}
+
+void CImpl::SendValues(uint64_t curTimeMs) {
+  DEBUG4("SendValues({})", curTimeMs);
+
+  // can't send value updates until we have a RTT
+  if (!m_haveTimeOffset) {
+    return;
+  }
+
+  // ensure all control messages are sent ahead of value updates
+  if (!SendControl(curTimeMs)) {
+    return;
+  }
+
+  // send any pending updates due to be sent
+  bool checkedNetwork = false;
+  auto writer = m_wire.SendBinary();
+  for (auto&& pub : m_publishers) {
+    if (pub && !pub->outValues.empty() && curTimeMs >= pub->nextSendMs) {
+      for (auto&& val : pub->outValues) {
+        if (!checkedNetwork) {
+          if (!CheckNetworkReady()) {
+            return;
+          }
+          checkedNetwork = true;
+        }
+        DEBUG4("Sending {} value time={} server_time={} st_off={}", pub->handle,
+               val.time(), val.server_time(), m_serverTimeOffsetUs);
+        int64_t time = val.time();
+        if (time != 0) {
+          time += m_serverTimeOffsetUs;
+        }
+        WireEncodeBinary(writer.Add(), Handle{pub->handle}.GetIndex(), time,
+                         val);
+      }
+      pub->outValues.resize(0);
+      pub->nextSendMs = curTimeMs + pub->periodMs;
+    }
+  }
+}
+
+void CImpl::SendInitialValues() {
+  DEBUG4("SendInitialValues()");
+
+  // ensure all control messages are sent ahead of value updates
+  if (!SendControl(0)) {
+    return;
+  }
+
+  // only send time=0 values (as we don't have a RTT yet)
+  auto writer = m_wire.SendBinary();
+  for (auto&& pub : m_publishers) {
+    if (pub && !pub->outValues.empty()) {
+      bool sent = false;
+      for (auto&& val : pub->outValues) {
+        if (val.server_time() == 0) {
+          DEBUG4("Sending {} value time={} server_time={}", pub->handle,
+                 val.time(), val.server_time());
+          WireEncodeBinary(writer.Add(), Handle{pub->handle}.GetIndex(), 0,
+                           val);
+          sent = true;
+        }
+      }
+      if (sent) {
+        std::erase_if(pub->outValues,
+                      [](const auto& v) { return v.server_time() == 0; });
+      }
+    }
+  }
+}
+
+bool CImpl::CheckNetworkReady() {
+  if (!m_wire.Ready()) {
+    ++m_notReadyCount;
+    if (m_notReadyCount > kWireMaxNotReady) {
+      m_wire.Disconnect("transmit stalled");
+    }
+    return false;
+  }
+  m_notReadyCount = 0;
+  return true;
+}
+
+void CImpl::Publish(NT_Publisher pubHandle, NT_Topic topicHandle,
+                    std::string_view name, std::string_view typeStr,
+                    const wpi::json& properties,
+                    const PubSubOptionsImpl& options) {
+  unsigned int index = Handle{pubHandle}.GetIndex();
+  if (index >= m_publishers.size()) {
+    m_publishers.resize(index + 1);
+  }
+  auto& publisher = m_publishers[index];
+  if (!publisher) {
+    publisher = std::make_unique<PublisherData>();
+  }
+  publisher->handle = pubHandle;
+  publisher->options = options;
+  publisher->periodMs = std::lround(options.periodicMs / 10.0) * 10;
+  if (publisher->periodMs < kMinPeriodMs) {
+    publisher->periodMs = kMinPeriodMs;
+  }
+
+  // update period
+  m_periodMs = std::gcd(m_periodMs, publisher->periodMs);
+  if (m_periodMs < kMinPeriodMs) {
+    m_periodMs = kMinPeriodMs;
+  }
+  m_setPeriodic(m_periodMs);
+}
+
+bool CImpl::Unpublish(NT_Publisher pubHandle, NT_Topic topicHandle) {
+  unsigned int index = Handle{pubHandle}.GetIndex();
+  if (index >= m_publishers.size()) {
+    return false;
+  }
+  bool doSend = true;
+  if (m_publishers[index]) {
+    // Look through outgoing queue to see if the publish hasn't been sent yet;
+    // if it hasn't, delete it and don't send the server a message.
+    // The outgoing queue doesn't contain values; those are deleted with the
+    // publisher object.
+    auto it = std::find_if(
+        m_outgoing.begin(), m_outgoing.end(), [&](const auto& elem) {
+          if (auto msg = std::get_if<PublishMsg>(&elem.contents)) {
+            return msg->pubHandle == pubHandle;
+          }
+          return false;
+        });
+    if (it != m_outgoing.end()) {
+      m_outgoing.erase(it);
+      doSend = false;
+    }
+  }
+  m_publishers[index].reset();
+
+  // loop over all publishers to update period
+  m_periodMs = kPingIntervalMs + 10;
+  for (auto&& pub : m_publishers) {
+    if (pub) {
+      m_periodMs = std::gcd(m_periodMs, pub->periodMs);
+    }
+  }
+  if (m_periodMs < kMinPeriodMs) {
+    m_periodMs = kMinPeriodMs;
+  }
+  m_setPeriodic(m_periodMs);
+
+  return doSend;
+}
+
+void CImpl::SetValue(NT_Publisher pubHandle, const Value& value) {
+  DEBUG4("SetValue({}, time={}, server_time={}, st_off={})", pubHandle,
+         value.time(), value.server_time(), m_serverTimeOffsetUs);
+  unsigned int index = Handle{pubHandle}.GetIndex();
+  if (index >= m_publishers.size() || !m_publishers[index]) {
+    return;
+  }
+  auto& publisher = *m_publishers[index];
+  if (publisher.outValues.empty() || publisher.options.sendAll) {
+    publisher.outValues.emplace_back(value);
+  } else {
+    publisher.outValues.back() = value;
+  }
+}
+
+void CImpl::ServerAnnounce(std::string_view name, int64_t id,
+                           std::string_view typeStr,
+                           const wpi::json& properties,
+                           std::optional<int64_t> pubuid) {
+  DEBUG4("ServerAnnounce({}, {}, {})", name, id, typeStr);
+  assert(m_local);
+  NT_Publisher pubHandle{0};
+  if (pubuid) {
+    pubHandle = Handle(m_inst, pubuid.value(), Handle::kPublisher);
+  }
+  m_topicMap[id] =
+      m_local->NetworkAnnounce(name, typeStr, properties, pubHandle);
+}
+
+void CImpl::ServerUnannounce(std::string_view name, int64_t id) {
+  DEBUG4("ServerUnannounce({}, {})", name, id);
+  assert(m_local);
+  m_local->NetworkUnannounce(name);
+  m_topicMap.erase(id);
+}
+
+void CImpl::ServerPropertiesUpdate(std::string_view name,
+                                   const wpi::json& update, bool ack) {
+  DEBUG4("ServerProperties({}, {}, {})", name, update.dump(), ack);
+  assert(m_local);
+  m_local->NetworkPropertiesUpdate(name, update, ack);
+}
+
+class ClientImpl::Impl final : public CImpl {
+ public:
+  Impl(uint64_t curTimeMs, int inst, WireConnection& wire, wpi::Logger& logger,
+       std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+           timeSyncUpdated,
+       std::function<void(uint32_t repeatMs)> setPeriodic)
+      : CImpl{curTimeMs,
+              inst,
+              wire,
+              logger,
+              std::move(timeSyncUpdated),
+              std::move(setPeriodic)} {}
+};
+
+ClientImpl::ClientImpl(
+    uint64_t curTimeMs, int inst, WireConnection& wire, wpi::Logger& logger,
+    std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+        timeSyncUpdated,
+    std::function<void(uint32_t repeatMs)> setPeriodic)
+    : m_impl{std::make_unique<Impl>(curTimeMs, inst, wire, logger,
+                                    std::move(timeSyncUpdated),
+                                    std::move(setPeriodic))} {}
+
+ClientImpl::~ClientImpl() = default;
+
+void ClientImpl::ProcessIncomingText(std::string_view data) {
+  if (!m_impl->m_local) {
+    return;
+  }
+  WireDecodeText(data, *m_impl, m_impl->m_logger);
+}
+
+void ClientImpl::ProcessIncomingBinary(std::span<const uint8_t> data) {
+  m_impl->ProcessIncomingBinary(data);
+}
+
+void ClientImpl::HandleLocal(std::vector<ClientMessage>&& msgs) {
+  m_impl->HandleLocal(std::move(msgs));
+}
+
+void ClientImpl::SendControl(uint64_t curTimeMs) {
+  m_impl->SendControl(curTimeMs);
+  m_impl->m_wire.Flush();
+}
+
+void ClientImpl::SendValues(uint64_t curTimeMs) {
+  m_impl->SendValues(curTimeMs);
+  m_impl->m_wire.Flush();
+}
+
+void ClientImpl::SetLocal(LocalInterface* local) {
+  m_impl->m_local = local;
+}
+
+void ClientImpl::SendInitial() {
+  m_impl->SendInitialValues();
+  m_impl->m_wire.Flush();
+}
diff --git a/ntcore/src/main/native/cpp/net/ClientImpl.h b/ntcore/src/main/native/cpp/net/ClientImpl.h
new file mode 100644
index 0000000..0e7fd4a
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/ClientImpl.h
@@ -0,0 +1,57 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "NetworkInterface.h"
+#include "WireConnection.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt {
+class PubSubOptionsImpl;
+class Value;
+}  // namespace nt
+
+namespace nt::net {
+
+struct ClientMessage;
+class WireConnection;
+
+class ClientImpl {
+ public:
+  ClientImpl(
+      uint64_t curTimeMs, int inst, WireConnection& wire, wpi::Logger& logger,
+      std::function<void(int64_t serverTimeOffset, int64_t rtt2, bool valid)>
+          timeSyncUpdated,
+      std::function<void(uint32_t repeatMs)> setPeriodic);
+  ~ClientImpl();
+
+  void ProcessIncomingText(std::string_view data);
+  void ProcessIncomingBinary(std::span<const uint8_t> data);
+  void HandleLocal(std::vector<ClientMessage>&& msgs);
+
+  void SendControl(uint64_t curTimeMs);
+  void SendValues(uint64_t curTimeMs);
+
+  void SetLocal(LocalInterface* local);
+  void SendInitial();
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/Message.h b/ntcore/src/main/native/cpp/net/Message.h
new file mode 100644
index 0000000..a95c5e8
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/Message.h
@@ -0,0 +1,100 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <optional>
+#include <string>
+#include <variant>
+#include <vector>
+
+#include <wpi/json.h>
+
+#include "PubSubOptions.h"
+#include "networktables/NetworkTableValue.h"
+#include "ntcore_c.h"
+
+namespace nt::net {
+
+struct PublishMsg {
+  static constexpr std::string_view kMethodStr = "publish";
+  NT_Publisher pubHandle{0};
+  NT_Topic topicHandle{0};  // will be 0 when coming from network
+  std::string name;
+  std::string typeStr;
+  wpi::json properties;
+  PubSubOptionsImpl options;  // will be empty when coming from network
+};
+
+struct UnpublishMsg {
+  static constexpr std::string_view kMethodStr = "unpublish";
+  NT_Publisher pubHandle{0};
+  NT_Topic topicHandle{0};  // will be 0 when coming from network
+};
+
+struct SetPropertiesMsg {
+  static constexpr std::string_view kMethodStr = "setproperties";
+  NT_Topic topicHandle{0};  // will be 0 when coming from network
+  std::string name;
+  wpi::json update;
+};
+
+struct SubscribeMsg {
+  static constexpr std::string_view kMethodStr = "subscribe";
+  NT_Subscriber subHandle{0};
+  std::vector<std::string> topicNames;
+  PubSubOptionsImpl options;
+};
+
+struct UnsubscribeMsg {
+  static constexpr std::string_view kMethodStr = "unsubscribe";
+  NT_Subscriber subHandle{0};
+};
+
+struct ClientValueMsg {
+  NT_Publisher pubHandle{0};
+  Value value;
+};
+
+struct ClientMessage {
+  using Contents =
+      std::variant<std::monostate, PublishMsg, UnpublishMsg, SetPropertiesMsg,
+                   SubscribeMsg, UnsubscribeMsg, ClientValueMsg>;
+  Contents contents;
+};
+
+struct AnnounceMsg {
+  static constexpr std::string_view kMethodStr = "announce";
+  std::string name;
+  int64_t id{0};
+  std::string typeStr;
+  std::optional<int64_t> pubuid;
+  wpi::json properties;
+};
+
+struct UnannounceMsg {
+  static constexpr std::string_view kMethodStr = "unannounce";
+  std::string name;
+  int64_t id{0};
+};
+
+struct PropertiesUpdateMsg {
+  static constexpr std::string_view kMethodStr = "properties";
+  std::string name;
+  wpi::json update;
+  bool ack;
+};
+
+struct ServerValueMsg {
+  NT_Topic topic{0};
+  Value value;
+};
+
+struct ServerMessage {
+  using Contents = std::variant<std::monostate, AnnounceMsg, UnannounceMsg,
+                                PropertiesUpdateMsg, ServerValueMsg>;
+  Contents contents;
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/NetworkInterface.h b/ntcore/src/main/native/cpp/net/NetworkInterface.h
new file mode 100644
index 0000000..3b2e7dd
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/NetworkInterface.h
@@ -0,0 +1,62 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string>
+#include <string_view>
+
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class json;
+}  // namespace wpi
+
+namespace nt {
+class PubSubOptionsImpl;
+class Value;
+}  // namespace nt
+
+namespace nt::net {
+
+class LocalInterface {
+ public:
+  virtual ~LocalInterface() = default;
+
+  virtual NT_Topic NetworkAnnounce(std::string_view name,
+                                   std::string_view typeStr,
+                                   const wpi::json& properties,
+                                   NT_Publisher pubHandle) = 0;
+  virtual void NetworkUnannounce(std::string_view name) = 0;
+  virtual void NetworkPropertiesUpdate(std::string_view name,
+                                       const wpi::json& update, bool ack) = 0;
+  virtual void NetworkSetValue(NT_Topic topicHandle, const Value& value) = 0;
+};
+
+class NetworkInterface {
+ public:
+  virtual ~NetworkInterface() = default;
+
+  virtual void Publish(NT_Publisher pubHandle, NT_Topic topicHandle,
+                       std::string_view name, std::string_view typeStr,
+                       const wpi::json& properties,
+                       const PubSubOptionsImpl& options) = 0;
+  virtual void Unpublish(NT_Publisher pubHandle, NT_Topic topicHandle) = 0;
+  virtual void SetProperties(NT_Topic topicHandle, std::string_view name,
+                             const wpi::json& update) = 0;
+  virtual void Subscribe(NT_Subscriber subHandle,
+                         std::span<const std::string> topicNames,
+                         const PubSubOptionsImpl& options) = 0;
+  virtual void Unsubscribe(NT_Subscriber subHandle) = 0;
+  virtual void SetValue(NT_Publisher pubHandle, const Value& value) = 0;
+};
+
+class ILocalStorage : public LocalInterface {
+ public:
+  virtual void StartNetwork(NetworkInterface* network) = 0;
+  virtual void ClearNetwork() = 0;
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/NetworkLoopQueue.cpp b/ntcore/src/main/native/cpp/net/NetworkLoopQueue.cpp
new file mode 100644
index 0000000..7c58c65
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/NetworkLoopQueue.cpp
@@ -0,0 +1,54 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "NetworkLoopQueue.h"
+
+#include <wpi/Logger.h>
+
+using namespace nt::net;
+
+static constexpr size_t kMaxSize = 2 * 1024 * 1024;
+
+void NetworkLoopQueue::SetValue(NT_Publisher pubHandle, const Value& value) {
+  std::scoped_lock lock{m_mutex};
+  switch (value.type()) {
+    case NT_STRING:
+      m_size += value.GetString().size();  // imperfect but good enough
+      break;
+    case NT_RAW:
+      m_size += value.GetRaw().size_bytes();
+      break;
+    case NT_BOOLEAN_ARRAY:
+      m_size += value.GetBooleanArray().size_bytes();
+      break;
+    case NT_INTEGER_ARRAY:
+      m_size += value.GetIntegerArray().size_bytes();
+      break;
+    case NT_FLOAT_ARRAY:
+      m_size += value.GetFloatArray().size_bytes();
+      break;
+    case NT_DOUBLE_ARRAY:
+      m_size += value.GetDoubleArray().size_bytes();
+      break;
+    case NT_STRING_ARRAY: {
+      auto arr = value.GetStringArray();
+      m_size += arr.size_bytes();
+      for (auto&& s : arr) {
+        m_size += s.capacity();
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  m_size += sizeof(ClientMessage);
+  if (m_size > kMaxSize) {
+    if (!m_sizeErrored) {
+      WPI_ERROR(m_logger, "NT: dropping value set due to memory limits");
+      m_sizeErrored = true;
+    }
+    return;  // avoid potential out of memory
+  }
+  m_queue.emplace_back(ClientMessage{ClientValueMsg{pubHandle, value}});
+}
diff --git a/ntcore/src/main/native/cpp/net/NetworkLoopQueue.h b/ntcore/src/main/native/cpp/net/NetworkLoopQueue.h
new file mode 100644
index 0000000..6ab68b6
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/NetworkLoopQueue.h
@@ -0,0 +1,57 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string>
+#include <vector>
+
+#include <wpi/mutex.h>
+
+#include "Message.h"
+#include "NetworkInterface.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt::net {
+
+class NetworkLoopQueue : public NetworkInterface {
+ public:
+  static constexpr size_t kInitialQueueSize = 2000;
+
+  explicit NetworkLoopQueue(wpi::Logger& logger) : m_logger{logger} {
+    m_queue.reserve(kInitialQueueSize);
+  }
+
+  void ReadQueue(std::vector<ClientMessage>* out);
+  void ClearQueue();
+
+  // NetworkInterface - calls to these append to the queue
+  void Publish(NT_Publisher pubHandle, NT_Topic topicHandle,
+               std::string_view name, std::string_view typeStr,
+               const wpi::json& properties,
+               const PubSubOptionsImpl& options) final;
+  void Unpublish(NT_Publisher pubHandle, NT_Topic topicHandle) final;
+  void SetProperties(NT_Topic topicHandle, std::string_view name,
+                     const wpi::json& update) final;
+  void Subscribe(NT_Subscriber subHandle,
+                 std::span<const std::string> topicNames,
+                 const PubSubOptionsImpl& options) final;
+  void Unsubscribe(NT_Subscriber subHandle) final;
+  void SetValue(NT_Publisher pubHandle, const Value& value) final;
+
+ private:
+  wpi::mutex m_mutex;
+  std::vector<ClientMessage> m_queue;
+  wpi::Logger& m_logger;
+  size_t m_size{0};
+  bool m_sizeErrored{false};
+};
+
+}  // namespace nt::net
+
+#include "NetworkLoopQueue.inc"
diff --git a/ntcore/src/main/native/cpp/net/NetworkLoopQueue.inc b/ntcore/src/main/native/cpp/net/NetworkLoopQueue.inc
new file mode 100644
index 0000000..a441780
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/NetworkLoopQueue.inc
@@ -0,0 +1,71 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string>
+#include <vector>
+
+#include "NetworkLoopQueue.h"
+#include "ntcore_c.h"
+
+namespace nt::net {
+
+inline void NetworkLoopQueue::ReadQueue(std::vector<ClientMessage>* out) {
+  std::scoped_lock lock{m_mutex};
+  out->swap(m_queue);
+  m_queue.resize(0);
+  m_queue.reserve(out->capacity());  // keep the same running capacity
+  m_size = 0;
+  m_sizeErrored = false;
+}
+
+inline void NetworkLoopQueue::ClearQueue() {
+  std::scoped_lock lock{m_mutex};
+  m_queue.resize(0);
+  m_size = 0;
+  m_sizeErrored = false;
+}
+
+inline void NetworkLoopQueue::Publish(NT_Publisher pubHandle,
+                                      NT_Topic topicHandle,
+                                      std::string_view name,
+                                      std::string_view typeStr,
+                                      const wpi::json& properties,
+                                      const PubSubOptionsImpl& options) {
+  std::scoped_lock lock{m_mutex};
+  m_queue.emplace_back(
+      ClientMessage{PublishMsg{pubHandle, topicHandle, std::string{name},
+                               std::string{typeStr}, properties, options}});
+}
+
+inline void NetworkLoopQueue::Unpublish(NT_Publisher pubHandle,
+                                        NT_Topic topicHandle) {
+  std::scoped_lock lock{m_mutex};
+  m_queue.emplace_back(ClientMessage{UnpublishMsg{pubHandle, topicHandle}});
+}
+
+inline void NetworkLoopQueue::SetProperties(NT_Topic topicHandle,
+                                            std::string_view name,
+                                            const wpi::json& update) {
+  std::scoped_lock lock{m_mutex};
+  m_queue.emplace_back(
+      ClientMessage{SetPropertiesMsg{topicHandle, std::string{name}, update}});
+}
+
+inline void NetworkLoopQueue::Subscribe(NT_Subscriber subHandle,
+                                        std::span<const std::string> topicNames,
+                                        const PubSubOptionsImpl& options) {
+  std::scoped_lock lock{m_mutex};
+  m_queue.emplace_back(ClientMessage{SubscribeMsg{
+      subHandle, {topicNames.begin(), topicNames.end()}, options}});
+}
+
+inline void NetworkLoopQueue::Unsubscribe(NT_Subscriber subHandle) {
+  std::scoped_lock lock{m_mutex};
+  m_queue.emplace_back(ClientMessage{UnsubscribeMsg{subHandle}});
+}
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/ServerImpl.cpp b/ntcore/src/main/native/cpp/net/ServerImpl.cpp
new file mode 100644
index 0000000..d9b1c0c
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/ServerImpl.cpp
@@ -0,0 +1,2363 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ServerImpl.h"
+
+#include <stdint.h>
+
+#include <algorithm>
+#include <cmath>
+#include <numeric>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <wpi/Base64.h>
+#include <wpi/DenseMap.h>
+#include <wpi/MessagePack.h>
+#include <wpi/SmallVector.h>
+#include <wpi/StringExtras.h>
+#include <wpi/StringMap.h>
+#include <wpi/UidVector.h>
+#include <wpi/json.h>
+#include <wpi/json_serializer.h>
+#include <wpi/raw_ostream.h>
+#include <wpi/timestamp.h>
+
+#include "IConnectionList.h"
+#include "Log.h"
+#include "Message.h"
+#include "NetworkInterface.h"
+#include "PubSubOptions.h"
+#include "Types_internal.h"
+#include "WireConnection.h"
+#include "WireDecoder.h"
+#include "WireEncoder.h"
+#include "net3/Message3.h"
+#include "net3/SequenceNumber.h"
+#include "net3/WireConnection3.h"
+#include "net3/WireDecoder3.h"
+#include "net3/WireEncoder3.h"
+#include "networktables/NetworkTableValue.h"
+#include "ntcore_c.h"
+
+using namespace nt;
+using namespace nt::net;
+using namespace mpack;
+
+static constexpr uint32_t kMinPeriodMs = 5;
+
+// maximum number of times the wire can be not ready to send another
+// transmission before we close the connection
+static constexpr int kWireMaxNotReady = 10;
+
+namespace {
+
+// Utility wrapper for making a set-like vector
+template <typename T>
+class VectorSet : public std::vector<T> {
+ public:
+  using iterator = typename std::vector<T>::iterator;
+  void Add(T value) { this->push_back(value); }
+  // returns true if element was present
+  bool Remove(T value) {
+    auto removeIt = std::remove(this->begin(), this->end(), value);
+    if (removeIt == this->end()) {
+      return false;
+    }
+    this->erase(removeIt, this->end());
+    return true;
+  }
+};
+
+struct PublisherData;
+struct SubscriberData;
+struct TopicData;
+class SImpl;
+
+class ClientData {
+ public:
+  ClientData(std::string_view originalName, std::string_view name,
+             std::string_view connInfo, bool local,
+             ServerImpl::SetPeriodicFunc setPeriodic, SImpl& server, int id,
+             wpi::Logger& logger)
+      : m_originalName{originalName},
+        m_name{name},
+        m_connInfo{connInfo},
+        m_local{local},
+        m_setPeriodic{std::move(setPeriodic)},
+        m_server{server},
+        m_id{id},
+        m_logger{logger} {}
+  virtual ~ClientData() = default;
+
+  virtual void ProcessIncomingText(std::string_view data) = 0;
+  virtual void ProcessIncomingBinary(std::span<const uint8_t> data) = 0;
+
+  enum SendMode { kSendDisabled = 0, kSendAll, kSendNormal, kSendImmNoFlush };
+
+  virtual void SendValue(TopicData* topic, const Value& value,
+                         SendMode mode) = 0;
+  virtual void SendAnnounce(TopicData* topic,
+                            std::optional<int64_t> pubuid) = 0;
+  virtual void SendUnannounce(TopicData* topic) = 0;
+  virtual void SendPropertiesUpdate(TopicData* topic, const wpi::json& update,
+                                    bool ack) = 0;
+  virtual void SendOutgoing(uint64_t curTimeMs) = 0;
+  virtual void Flush() = 0;
+
+  void UpdateMetaClientPub();
+  void UpdateMetaClientSub();
+
+  std::span<SubscriberData*> GetSubscribers(
+      std::string_view name, bool special,
+      wpi::SmallVectorImpl<SubscriberData*>& buf);
+
+  std::string_view GetOriginalName() const { return m_originalName; }
+  std::string_view GetName() const { return m_name; }
+  int GetId() const { return m_id; }
+
+ protected:
+  std::string m_originalName;
+  std::string m_name;
+  std::string m_connInfo;
+  bool m_local;  // local to machine
+  ServerImpl::SetPeriodicFunc m_setPeriodic;
+  // TODO: make this per-topic?
+  uint32_t m_periodMs{UINT32_MAX};
+  uint64_t m_lastSendMs{0};
+  SImpl& m_server;
+  int m_id;
+
+  wpi::Logger& m_logger;
+
+  wpi::DenseMap<int64_t, std::unique_ptr<PublisherData>> m_publishers;
+  wpi::DenseMap<int64_t, std::unique_ptr<SubscriberData>> m_subscribers;
+
+ public:
+  // meta topics
+  TopicData* m_metaPub = nullptr;
+  TopicData* m_metaSub = nullptr;
+};
+
+class ClientData4Base : public ClientData, protected ClientMessageHandler {
+ public:
+  ClientData4Base(std::string_view originalName, std::string_view name,
+                  std::string_view connInfo, bool local,
+                  ServerImpl::SetPeriodicFunc setPeriodic, SImpl& server,
+                  int id, wpi::Logger& logger)
+      : ClientData{originalName, name,   connInfo, local,
+                   setPeriodic,  server, id,       logger} {}
+
+ protected:
+  // ClientMessageHandler interface
+  void ClientPublish(int64_t pubuid, std::string_view name,
+                     std::string_view typeStr,
+                     const wpi::json& properties) final;
+  void ClientUnpublish(int64_t pubuid) final;
+  void ClientSetProperties(std::string_view name,
+                           const wpi::json& update) final;
+  void ClientSubscribe(int64_t subuid, std::span<const std::string> topicNames,
+                       const PubSubOptionsImpl& options) final;
+  void ClientUnsubscribe(int64_t subuid) final;
+
+  void ClientSetValue(int64_t pubuid, const Value& value);
+
+  wpi::DenseMap<TopicData*, bool> m_announceSent;
+};
+
+class ClientDataLocal final : public ClientData4Base {
+ public:
+  ClientDataLocal(SImpl& server, int id, wpi::Logger& logger)
+      : ClientData4Base{"", "", "", true, [](uint32_t) {}, server, id, logger} {
+  }
+
+  void ProcessIncomingText(std::string_view data) final {}
+  void ProcessIncomingBinary(std::span<const uint8_t> data) final {}
+
+  void SendValue(TopicData* topic, const Value& value, SendMode mode) final;
+  void SendAnnounce(TopicData* topic, std::optional<int64_t> pubuid) final;
+  void SendUnannounce(TopicData* topic) final;
+  void SendPropertiesUpdate(TopicData* topic, const wpi::json& update,
+                            bool ack) final;
+  void SendOutgoing(uint64_t curTimeMs) final {}
+  void Flush() final {}
+
+  void HandleLocal(std::span<const ClientMessage> msgs);
+};
+
+class ClientData4 final : public ClientData4Base {
+ public:
+  ClientData4(std::string_view originalName, std::string_view name,
+              std::string_view connInfo, bool local, WireConnection& wire,
+              ServerImpl::SetPeriodicFunc setPeriodic, SImpl& server, int id,
+              wpi::Logger& logger)
+      : ClientData4Base{originalName, name,   connInfo, local,
+                        setPeriodic,  server, id,       logger},
+        m_wire{wire} {}
+
+  void ProcessIncomingText(std::string_view data) final;
+  void ProcessIncomingBinary(std::span<const uint8_t> data) final;
+
+  void SendValue(TopicData* topic, const Value& value, SendMode mode) final;
+  void SendAnnounce(TopicData* topic, std::optional<int64_t> pubuid) final;
+  void SendUnannounce(TopicData* topic) final;
+  void SendPropertiesUpdate(TopicData* topic, const wpi::json& update,
+                            bool ack) final;
+  void SendOutgoing(uint64_t curTimeMs) final;
+
+  void Flush() final;
+
+ public:
+  WireConnection& m_wire;
+
+ private:
+  std::vector<ServerMessage> m_outgoing;
+  int m_notReadyCount{0};
+
+  bool WriteBinary(int64_t id, int64_t time, const Value& value) {
+    return WireEncodeBinary(SendBinary().Add(), id, time, value);
+  }
+
+  TextWriter& SendText() {
+    m_outBinary.reset();  // ensure proper interleaving of text and binary
+    if (!m_outText) {
+      m_outText = m_wire.SendText();
+    }
+    return *m_outText;
+  }
+
+  BinaryWriter& SendBinary() {
+    m_outText.reset();  // ensure proper interleaving of text and binary
+    if (!m_outBinary) {
+      m_outBinary = m_wire.SendBinary();
+    }
+    return *m_outBinary;
+  }
+
+  // valid when we are actively writing to this client
+  std::optional<TextWriter> m_outText;
+  std::optional<BinaryWriter> m_outBinary;
+};
+
+class ClientData3 final : public ClientData, private net3::MessageHandler3 {
+ public:
+  ClientData3(std::string_view connInfo, bool local,
+              net3::WireConnection3& wire, ServerImpl::Connected3Func connected,
+              ServerImpl::SetPeriodicFunc setPeriodic, SImpl& server, int id,
+              wpi::Logger& logger)
+      : ClientData{"", "", connInfo, local, setPeriodic, server, id, logger},
+        m_connected{std::move(connected)},
+        m_wire{wire},
+        m_decoder{*this} {}
+
+  void ProcessIncomingText(std::string_view data) final {}
+  void ProcessIncomingBinary(std::span<const uint8_t> data) final;
+
+  void SendValue(TopicData* topic, const Value& value, SendMode mode) final;
+  void SendAnnounce(TopicData* topic, std::optional<int64_t> pubuid) final;
+  void SendUnannounce(TopicData* topic) final;
+  void SendPropertiesUpdate(TopicData* topic, const wpi::json& update,
+                            bool ack) final;
+  void SendOutgoing(uint64_t curTimeMs) final;
+
+  void Flush() final { m_wire.Flush(); }
+
+ private:
+  // MessageHandler3 interface
+  void KeepAlive() final;
+  void ServerHelloDone() final;
+  void ClientHelloDone() final;
+  void ClearEntries() final;
+  void ProtoUnsup(unsigned int proto_rev) final;
+  void ClientHello(std::string_view self_id, unsigned int proto_rev) final;
+  void ServerHello(unsigned int flags, std::string_view self_id) final;
+  void EntryAssign(std::string_view name, unsigned int id, unsigned int seq_num,
+                   const Value& value, unsigned int flags) final;
+  void EntryUpdate(unsigned int id, unsigned int seq_num,
+                   const Value& value) final;
+  void FlagsUpdate(unsigned int id, unsigned int flags) final;
+  void EntryDelete(unsigned int id) final;
+  void ExecuteRpc(unsigned int id, unsigned int uid,
+                  std::span<const uint8_t> params) final {}
+  void RpcResponse(unsigned int id, unsigned int uid,
+                   std::span<const uint8_t> result) final {}
+
+  ServerImpl::Connected3Func m_connected;
+  net3::WireConnection3& m_wire;
+
+  enum State { kStateInitial, kStateServerHelloComplete, kStateRunning };
+  State m_state{kStateInitial};
+  net3::WireDecoder3 m_decoder;
+
+  std::vector<net3::Message3> m_outgoing;
+  int64_t m_nextPubUid{1};
+  int m_notReadyCount{0};
+
+  struct TopicData3 {
+    explicit TopicData3(TopicData* topic) { UpdateFlags(topic); }
+
+    unsigned int flags{0};
+    net3::SequenceNumber seqNum;
+    bool sentAssign{false};
+    bool published{false};
+    int64_t pubuid{0};
+
+    bool UpdateFlags(TopicData* topic);
+  };
+  wpi::DenseMap<TopicData*, TopicData3> m_topics3;
+  TopicData3* GetTopic3(TopicData* topic) {
+    return &m_topics3.try_emplace(topic, topic).first->second;
+  }
+};
+
+struct TopicData {
+  TopicData(std::string_view name, std::string_view typeStr)
+      : name{name}, typeStr{typeStr} {}
+  TopicData(std::string_view name, std::string_view typeStr,
+            wpi::json properties)
+      : name{name}, typeStr{typeStr}, properties(std::move(properties)) {
+    RefreshProperties();
+  }
+
+  bool IsPublished() const {
+    return persistent || retained || !publishers.empty();
+  }
+
+  // returns true if properties changed
+  bool SetProperties(const wpi::json& update);
+  void RefreshProperties();
+  bool SetFlags(unsigned int flags_);
+
+  std::string name;
+  unsigned int id;
+  Value lastValue;
+  ClientData* lastValueClient = nullptr;
+  std::string typeStr;
+  wpi::json properties = wpi::json::object();
+  bool persistent{false};
+  bool retained{false};
+  bool special{false};
+  NT_Topic localHandle{0};
+
+  VectorSet<PublisherData*> publishers;
+  VectorSet<SubscriberData*> subscribers;
+
+  // meta topics
+  TopicData* metaPub = nullptr;
+  TopicData* metaSub = nullptr;
+};
+
+struct PublisherData {
+  PublisherData(ClientData* client, TopicData* topic, int64_t pubuid)
+      : client{client}, topic{topic}, pubuid{pubuid} {}
+
+  ClientData* client;
+  TopicData* topic;
+  int64_t pubuid;
+};
+
+struct SubscriberData {
+  SubscriberData(ClientData* client, std::span<const std::string> topicNames,
+                 int64_t subuid, const PubSubOptionsImpl& options)
+      : client{client},
+        topicNames{topicNames.begin(), topicNames.end()},
+        subuid{subuid},
+        options{options},
+        periodMs(std::lround(options.periodicMs / 10.0) * 10) {
+    if (periodMs < kMinPeriodMs) {
+      periodMs = kMinPeriodMs;
+    }
+  }
+
+  void Update(std::span<const std::string> topicNames_,
+              const PubSubOptionsImpl& options_) {
+    topicNames = {topicNames_.begin(), topicNames_.end()};
+    options = options_;
+    periodMs = std::lround(options_.periodicMs / 10.0) * 10;
+    if (periodMs < kMinPeriodMs) {
+      periodMs = kMinPeriodMs;
+    }
+  }
+
+  bool Matches(std::string_view name, bool special);
+
+  ClientData* client;
+  std::vector<std::string> topicNames;
+  int64_t subuid;
+  PubSubOptionsImpl options;
+  // in options as double, but copy here as integer; rounded to the nearest
+  // 10 ms
+  uint32_t periodMs;
+};
+
+class SImpl {
+ public:
+  explicit SImpl(wpi::Logger& logger);
+
+  wpi::Logger& m_logger;
+  LocalInterface* m_local{nullptr};
+  bool m_controlReady{false};
+
+  ClientDataLocal* m_localClient;
+  std::vector<std::unique_ptr<ClientData>> m_clients;
+  wpi::UidVector<std::unique_ptr<TopicData>, 16> m_topics;
+  wpi::StringMap<TopicData*> m_nameTopics;
+  bool m_persistentChanged{false};
+
+  // global meta topics (other meta topics are linked to from the specific
+  // client or topic)
+  TopicData* m_metaClients;
+
+  // ServerImpl interface
+  std::pair<std::string, int> AddClient(
+      std::string_view name, std::string_view connInfo, bool local,
+      WireConnection& wire, ServerImpl::SetPeriodicFunc setPeriodic);
+  int AddClient3(std::string_view connInfo, bool local,
+                 net3::WireConnection3& wire,
+                 ServerImpl::Connected3Func connected,
+                 ServerImpl::SetPeriodicFunc setPeriodic);
+  void RemoveClient(int clientId);
+
+  bool PersistentChanged();
+  void DumpPersistent(wpi::raw_ostream& os);
+  std::string LoadPersistent(std::string_view in);
+
+  // helper functions
+  TopicData* CreateTopic(ClientData* client, std::string_view name,
+                         std::string_view typeStr, const wpi::json& properties,
+                         bool special = false);
+  TopicData* CreateMetaTopic(std::string_view name);
+  void DeleteTopic(TopicData* topic);
+  void SetProperties(ClientData* client, TopicData* topic,
+                     const wpi::json& update);
+  void SetFlags(ClientData* client, TopicData* topic, unsigned int flags);
+  void SetValue(ClientData* client, TopicData* topic, const Value& value);
+
+  // update meta topic values from data structures
+  void UpdateMetaClients(const std::vector<ConnectionInfo>& conns);
+  void UpdateMetaTopicPub(TopicData* topic);
+  void UpdateMetaTopicSub(TopicData* topic);
+
+ private:
+  void PropertiesChanged(ClientData* client, TopicData* topic,
+                         const wpi::json& update);
+};
+
+struct Writer : public mpack_writer_t {
+  Writer() {
+    mpack_writer_init(this, buf, sizeof(buf));
+    mpack_writer_set_context(this, &os);
+    mpack_writer_set_flush(
+        this, [](mpack_writer_t* w, const char* buffer, size_t count) {
+          static_cast<wpi::raw_ostream*>(w->context)->write(buffer, count);
+        });
+  }
+
+  std::vector<uint8_t> bytes;
+  wpi::raw_uvector_ostream os{bytes};
+  char buf[128];
+};
+}  // namespace
+
+static void WriteOptions(mpack_writer_t& w, const PubSubOptionsImpl& options) {
+  int size =
+      (options.sendAll ? 1 : 0) + (options.topicsOnly ? 1 : 0) +
+      (options.periodicMs != PubSubOptionsImpl::kDefaultPeriodicMs ? 1 : 0) +
+      (options.prefixMatch ? 1 : 0);
+  mpack_start_map(&w, size);
+  if (options.sendAll) {
+    mpack_write_str(&w, "all");
+    mpack_write_bool(&w, true);
+  }
+  if (options.topicsOnly) {
+    mpack_write_str(&w, "topicsonly");
+    mpack_write_bool(&w, true);
+  }
+  if (options.periodicMs != PubSubOptionsImpl::kDefaultPeriodicMs) {
+    mpack_write_str(&w, "periodic");
+    mpack_write_float(&w, options.periodicMs / 1000.0);
+  }
+  if (options.prefixMatch) {
+    mpack_write_str(&w, "prefix");
+    mpack_write_bool(&w, true);
+  }
+  mpack_finish_map(&w);
+}
+
+void ClientData::UpdateMetaClientPub() {
+  if (!m_metaPub) {
+    return;
+  }
+  Writer w;
+  mpack_start_array(&w, m_publishers.size());
+  for (auto&& pub : m_publishers) {
+    mpack_start_map(&w, 2);
+    mpack_write_str(&w, "uid");
+    mpack_write_int(&w, pub.first);
+    mpack_write_str(&w, "topic");
+    mpack_write_str(&w, pub.second->topic->name);
+    mpack_finish_map(&w);
+  }
+  mpack_finish_array(&w);
+  if (mpack_writer_destroy(&w) == mpack_ok) {
+    m_server.SetValue(nullptr, m_metaPub, Value::MakeRaw(std::move(w.bytes)));
+  }
+}
+
+void ClientData::UpdateMetaClientSub() {
+  if (!m_metaSub) {
+    return;
+  }
+  Writer w;
+  mpack_start_array(&w, m_subscribers.size());
+  for (auto&& sub : m_subscribers) {
+    mpack_start_map(&w, 3);
+    mpack_write_str(&w, "uid");
+    mpack_write_int(&w, sub.first);
+    mpack_write_str(&w, "topics");
+    mpack_start_array(&w, sub.second->topicNames.size());
+    for (auto&& name : sub.second->topicNames) {
+      mpack_write_str(&w, name);
+    }
+    mpack_finish_array(&w);
+    mpack_write_str(&w, "options");
+    WriteOptions(w, sub.second->options);
+    mpack_finish_map(&w);
+  }
+  mpack_finish_array(&w);
+  if (mpack_writer_destroy(&w) == mpack_ok) {
+    m_server.SetValue(nullptr, m_metaSub, Value::MakeRaw(std::move(w.bytes)));
+  }
+}
+
+std::span<SubscriberData*> ClientData::GetSubscribers(
+    std::string_view name, bool special,
+    wpi::SmallVectorImpl<SubscriberData*>& buf) {
+  buf.resize(0);
+  for (auto&& subPair : m_subscribers) {
+    SubscriberData* subscriber = subPair.getSecond().get();
+    if (subscriber->Matches(name, special)) {
+      buf.emplace_back(subscriber);
+    }
+  }
+  return {buf.data(), buf.size()};
+}
+
+void ClientData4Base::ClientPublish(int64_t pubuid, std::string_view name,
+                                    std::string_view typeStr,
+                                    const wpi::json& properties) {
+  DEBUG3("ClientPublish({}, {}, {}, {})", m_id, name, pubuid, typeStr);
+  auto topic = m_server.CreateTopic(this, name, typeStr, properties);
+
+  // create publisher
+  auto [publisherIt, isNew] = m_publishers.try_emplace(
+      pubuid, std::make_unique<PublisherData>(this, topic, pubuid));
+  if (!isNew) {
+    WARNING("client {} duplicate publish of pubuid {}", m_id, pubuid);
+  }
+
+  // add publisher to topic
+  topic->publishers.Add(publisherIt->getSecond().get());
+
+  // update meta data
+  m_server.UpdateMetaTopicPub(topic);
+  UpdateMetaClientPub();
+
+  // respond with announce with pubuid to client
+  DEBUG4("client {}: announce {} pubuid {}", m_id, topic->name, pubuid);
+  SendAnnounce(topic, pubuid);
+}
+
+void ClientData4Base::ClientUnpublish(int64_t pubuid) {
+  DEBUG3("ClientUnpublish({}, {})", m_id, pubuid);
+  auto publisherIt = m_publishers.find(pubuid);
+  if (publisherIt == m_publishers.end()) {
+    return;  // nothing to do
+  }
+  auto publisher = publisherIt->getSecond().get();
+  auto topic = publisher->topic;
+
+  // remove publisher from topic
+  topic->publishers.Remove(publisher);
+
+  // remove publisher from client
+  m_publishers.erase(publisherIt);
+
+  // update meta data
+  m_server.UpdateMetaTopicPub(topic);
+  UpdateMetaClientPub();
+
+  // delete topic if no longer published
+  if (!topic->IsPublished()) {
+    m_server.DeleteTopic(topic);
+  }
+}
+
+void ClientData4Base::ClientSetProperties(std::string_view name,
+                                          const wpi::json& update) {
+  DEBUG4("ClientSetProperties({}, {}, {})", m_id, name, update.dump());
+  auto topicIt = m_server.m_nameTopics.find(name);
+  if (topicIt == m_server.m_nameTopics.end() ||
+      !topicIt->second->IsPublished()) {
+    DEBUG3("ignored SetProperties from {} on non-existent topic '{}'", m_id,
+           name);
+    return;  // nothing to do
+  }
+  auto topic = topicIt->second;
+  if (topic->special) {
+    DEBUG3("ignored SetProperties from {} on meta topic '{}'", m_id, name);
+    return;  // nothing to do
+  }
+  m_server.SetProperties(nullptr, topic, update);
+}
+
+void ClientData4Base::ClientSubscribe(int64_t subuid,
+                                      std::span<const std::string> topicNames,
+                                      const PubSubOptionsImpl& options) {
+  DEBUG4("ClientSubscribe({}, ({}), {})", m_id, fmt::join(topicNames, ","),
+         subuid);
+  auto& sub = m_subscribers[subuid];
+  bool replace = false;
+  if (sub) {
+    // replace subscription
+    sub->Update(topicNames, options);
+    replace = true;
+  } else {
+    // create
+    sub = std::make_unique<SubscriberData>(this, topicNames, subuid, options);
+  }
+
+  // limit subscriber min period
+  if (sub->periodMs < kMinPeriodMs) {
+    sub->periodMs = kMinPeriodMs;
+  }
+
+  // update periodic sender (if not local)
+  if (!m_local) {
+    if (m_periodMs == UINT32_MAX) {
+      m_periodMs = sub->periodMs;
+    } else {
+      m_periodMs = std::gcd(m_periodMs, sub->periodMs);
+    }
+    if (m_periodMs < kMinPeriodMs) {
+      m_periodMs = kMinPeriodMs;
+    }
+    m_setPeriodic(m_periodMs);
+  }
+
+  // see if this immediately subscribes to any topics
+  for (auto&& topic : m_server.m_topics) {
+    bool removed = false;
+    if (replace) {
+      removed = topic->subscribers.Remove(sub.get());
+    }
+
+    // is client already subscribed?
+    bool wasSubscribed = false;
+    for (auto subscriber : topic->subscribers) {
+      if (subscriber->client == this) {
+        wasSubscribed = true;
+        break;
+      }
+    }
+
+    bool added = false;
+    if (sub->Matches(topic->name, topic->special)) {
+      topic->subscribers.Add(sub.get());
+      added = true;
+    }
+
+    if (added ^ removed) {
+      m_server.UpdateMetaTopicSub(topic.get());
+    }
+
+    if (!wasSubscribed && added && !removed) {
+      // announce topic to client
+      DEBUG4("client {}: announce {}", m_id, topic->name);
+      SendAnnounce(topic.get(), std::nullopt);
+
+      // send last value
+      if (!sub->options.topicsOnly && topic->lastValue) {
+        DEBUG4("send last value for {} to client {}", topic->name, m_id);
+        SendValue(topic.get(), topic->lastValue, kSendAll);
+      }
+    }
+  }
+
+  // update meta data
+  UpdateMetaClientSub();
+
+  Flush();
+}
+
+void ClientData4Base::ClientUnsubscribe(int64_t subuid) {
+  DEBUG3("ClientUnsubscribe({}, {})", m_id, subuid);
+  auto subIt = m_subscribers.find(subuid);
+  if (subIt == m_subscribers.end() || !subIt->getSecond()) {
+    return;  // nothing to do
+  }
+  auto sub = subIt->getSecond().get();
+
+  // remove from topics
+  for (auto&& topic : m_server.m_topics) {
+    if (topic->subscribers.Remove(sub)) {
+      m_server.UpdateMetaTopicSub(topic.get());
+    }
+  }
+
+  // delete it from client (future value sets will be ignored)
+  m_subscribers.erase(subIt);
+  UpdateMetaClientSub();
+
+  // loop over all publishers to update period
+  m_periodMs = UINT32_MAX;
+  for (auto&& sub : m_subscribers) {
+    if (m_periodMs == UINT32_MAX) {
+      m_periodMs = sub.getSecond()->periodMs;
+    } else {
+      m_periodMs = std::gcd(m_periodMs, sub.getSecond()->periodMs);
+    }
+  }
+  if (m_periodMs < kMinPeriodMs) {
+    m_periodMs = kMinPeriodMs;
+  }
+  m_setPeriodic(m_periodMs);
+}
+
+void ClientData4Base::ClientSetValue(int64_t pubuid, const Value& value) {
+  DEBUG4("ClientSetValue({}, {})", m_id, pubuid);
+  auto publisherIt = m_publishers.find(pubuid);
+  if (publisherIt == m_publishers.end()) {
+    WARNING("unrecognized client {} pubuid {}, ignoring set", m_id, pubuid);
+    return;  // ignore unrecognized pubuids
+  }
+  auto topic = publisherIt->getSecond().get()->topic;
+  m_server.SetValue(this, topic, value);
+}
+
+void ClientDataLocal::SendValue(TopicData* topic, const Value& value,
+                                SendMode mode) {
+  if (m_server.m_local) {
+    m_server.m_local->NetworkSetValue(topic->localHandle, value);
+  }
+}
+
+void ClientDataLocal::SendAnnounce(TopicData* topic,
+                                   std::optional<int64_t> pubuid) {
+  if (m_server.m_local) {
+    auto& sent = m_announceSent[topic];
+    if (sent) {
+      return;
+    }
+    sent = true;
+
+    topic->localHandle = m_server.m_local->NetworkAnnounce(
+        topic->name, topic->typeStr, topic->properties, pubuid.value_or(0));
+  }
+}
+
+void ClientDataLocal::SendUnannounce(TopicData* topic) {
+  if (m_server.m_local) {
+    auto& sent = m_announceSent[topic];
+    if (!sent) {
+      return;
+    }
+    sent = false;
+    m_server.m_local->NetworkUnannounce(topic->name);
+  }
+}
+
+void ClientDataLocal::SendPropertiesUpdate(TopicData* topic,
+                                           const wpi::json& update, bool ack) {
+  if (m_server.m_local) {
+    if (!m_announceSent.lookup(topic)) {
+      return;
+    }
+    m_server.m_local->NetworkPropertiesUpdate(topic->name, update, ack);
+  }
+}
+
+void ClientDataLocal::HandleLocal(std::span<const ClientMessage> msgs) {
+  DEBUG4("HandleLocal()");
+  // just map as a normal client into client=0 calls
+  for (const auto& elem : msgs) {  // NOLINT
+    // common case is value, so check that first
+    if (auto msg = std::get_if<ClientValueMsg>(&elem.contents)) {
+      ClientSetValue(msg->pubHandle, msg->value);
+    } else if (auto msg = std::get_if<PublishMsg>(&elem.contents)) {
+      ClientPublish(msg->pubHandle, msg->name, msg->typeStr, msg->properties);
+    } else if (auto msg = std::get_if<UnpublishMsg>(&elem.contents)) {
+      ClientUnpublish(msg->pubHandle);
+    } else if (auto msg = std::get_if<SetPropertiesMsg>(&elem.contents)) {
+      ClientSetProperties(msg->name, msg->update);
+    } else if (auto msg = std::get_if<SubscribeMsg>(&elem.contents)) {
+      ClientSubscribe(msg->subHandle, msg->topicNames, msg->options);
+    } else if (auto msg = std::get_if<UnsubscribeMsg>(&elem.contents)) {
+      ClientUnsubscribe(msg->subHandle);
+    }
+  }
+}
+
+void ClientData4::ProcessIncomingText(std::string_view data) {
+  WireDecodeText(data, *this, m_logger);
+}
+
+void ClientData4::ProcessIncomingBinary(std::span<const uint8_t> data) {
+  for (;;) {
+    if (data.empty()) {
+      break;
+    }
+
+    // decode message
+    int64_t pubuid;
+    Value value;
+    std::string error;
+    if (!WireDecodeBinary(&data, &pubuid, &value, &error, 0)) {
+      m_wire.Disconnect(fmt::format("binary decode error: {}", error));
+      break;
+    }
+
+    // respond to RTT ping
+    if (pubuid == -1) {
+      auto now = wpi::Now();
+      DEBUG4("RTT ping from {}, responding with time={}", m_id, now);
+      {
+        auto out = m_wire.SendBinary();
+        WireEncodeBinary(out.Add(), -1, now, value);
+      }
+      m_wire.Flush();
+      continue;
+    }
+
+    // handle value set
+    ClientSetValue(pubuid, value);
+  }
+}
+
+void ClientData4::SendValue(TopicData* topic, const Value& value,
+                            SendMode mode) {
+  if (m_local) {
+    mode = ClientData::kSendImmNoFlush;  // always send local immediately
+  }
+  switch (mode) {
+    case ClientData::kSendDisabled:  // do nothing
+      break;
+    case ClientData::kSendImmNoFlush:  // send immediately
+      WriteBinary(topic->id, value.time(), value);
+      if (m_local) {
+        Flush();
+      }
+      break;
+    case ClientData::kSendAll:  // append to outgoing
+      m_outgoing.emplace_back(ServerMessage{ServerValueMsg{topic->id, value}});
+      break;
+    case ClientData::kSendNormal: {
+      // scan outgoing and replace, or append if not present
+      bool found = false;
+      for (auto&& msg : m_outgoing) {
+        if (auto m = std::get_if<ServerValueMsg>(&msg.contents)) {
+          if (m->topic == topic->id) {
+            m->value = value;
+            found = true;
+            break;
+          }
+        }
+      }
+      if (!found) {
+        m_outgoing.emplace_back(
+            ServerMessage{ServerValueMsg{topic->id, value}});
+      }
+      break;
+    }
+  }
+}
+
+void ClientData4::SendAnnounce(TopicData* topic,
+                               std::optional<int64_t> pubuid) {
+  auto& sent = m_announceSent[topic];
+  if (sent) {
+    return;
+  }
+  sent = true;
+
+  if (m_local) {
+    WireEncodeAnnounce(SendText().Add(), topic->name, topic->id, topic->typeStr,
+                       topic->properties, pubuid);
+    Flush();
+  } else {
+    m_outgoing.emplace_back(ServerMessage{AnnounceMsg{
+        topic->name, topic->id, topic->typeStr, pubuid, topic->properties}});
+    m_server.m_controlReady = true;
+  }
+}
+
+void ClientData4::SendUnannounce(TopicData* topic) {
+  auto& sent = m_announceSent[topic];
+  if (!sent) {
+    return;
+  }
+  sent = false;
+
+  if (m_local) {
+    WireEncodeUnannounce(SendText().Add(), topic->name, topic->id);
+    Flush();
+  } else {
+    m_outgoing.emplace_back(
+        ServerMessage{UnannounceMsg{topic->name, topic->id}});
+    m_server.m_controlReady = true;
+  }
+}
+
+void ClientData4::SendPropertiesUpdate(TopicData* topic,
+                                       const wpi::json& update, bool ack) {
+  if (!m_announceSent.lookup(topic)) {
+    return;
+  }
+
+  if (m_local) {
+    WireEncodePropertiesUpdate(SendText().Add(), topic->name, update, ack);
+    Flush();
+  } else {
+    m_outgoing.emplace_back(
+        ServerMessage{PropertiesUpdateMsg{topic->name, update, ack}});
+    m_server.m_controlReady = true;
+  }
+}
+
+void ClientData4::SendOutgoing(uint64_t curTimeMs) {
+  if (m_outgoing.empty()) {
+    return;  // nothing to do
+  }
+
+  // rate limit frequency of transmissions
+  if (curTimeMs < (m_lastSendMs + kMinPeriodMs)) {
+    return;
+  }
+
+  if (!m_wire.Ready()) {
+    ++m_notReadyCount;
+    if (m_notReadyCount > kWireMaxNotReady) {
+      m_wire.Disconnect("transmit stalled");
+    }
+    return;
+  }
+  m_notReadyCount = 0;
+
+  for (auto&& msg : m_outgoing) {
+    if (auto m = std::get_if<ServerValueMsg>(&msg.contents)) {
+      WriteBinary(m->topic, m->value.time(), m->value);
+    } else {
+      WireEncodeText(SendText().Add(), msg);
+    }
+  }
+  m_outgoing.resize(0);
+  m_lastSendMs = curTimeMs;
+}
+
+void ClientData4::Flush() {
+  m_outText.reset();
+  m_outBinary.reset();
+  m_wire.Flush();
+}
+
+bool ClientData3::TopicData3::UpdateFlags(TopicData* topic) {
+  unsigned int newFlags = topic->persistent ? NT_PERSISTENT : 0;
+  bool updated = flags != newFlags;
+  flags = newFlags;
+  return updated;
+}
+
+void ClientData3::ProcessIncomingBinary(std::span<const uint8_t> data) {
+  if (!m_decoder.Execute(&data)) {
+    m_wire.Disconnect(m_decoder.GetError());
+  }
+}
+
+void ClientData3::SendValue(TopicData* topic, const Value& value,
+                            SendMode mode) {
+  if (m_state != kStateRunning) {
+    if (mode == kSendImmNoFlush) {
+      mode = kSendAll;
+    }
+  } else if (m_local) {
+    mode = ClientData::kSendImmNoFlush;  // always send local immediately
+  }
+  TopicData3* topic3 = GetTopic3(topic);
+
+  switch (mode) {
+    case ClientData::kSendDisabled:  // do nothing
+      break;
+    case ClientData::kSendImmNoFlush:  // send immediately and flush
+      ++topic3->seqNum;
+      if (topic3->sentAssign) {
+        net3::WireEncodeEntryUpdate(m_wire.Send().stream(), topic->id,
+                                    topic3->seqNum.value(), value);
+      } else {
+        net3::WireEncodeEntryAssign(m_wire.Send().stream(), topic->name,
+                                    topic->id, topic3->seqNum.value(), value,
+                                    topic3->flags);
+        topic3->sentAssign = true;
+      }
+      if (m_local) {
+        Flush();
+      }
+      break;
+    case ClientData::kSendNormal: {
+      // scan outgoing and replace, or append if not present
+      bool found = false;
+      for (auto&& msg : m_outgoing) {
+        if (msg.Is(net3::Message3::kEntryUpdate) ||
+            msg.Is(net3::Message3::kEntryAssign)) {
+          if (msg.id() == topic->id) {
+            msg.SetValue(value);
+            found = true;
+            break;
+          }
+        }
+      }
+      if (found) {
+        break;
+      }
+    }
+      // fallthrough
+    case ClientData::kSendAll:  // append to outgoing
+      ++topic3->seqNum;
+      if (topic3->sentAssign) {
+        m_outgoing.emplace_back(net3::Message3::EntryUpdate(
+            topic->id, topic3->seqNum.value(), value));
+      } else {
+        m_outgoing.emplace_back(net3::Message3::EntryAssign(
+            topic->name, topic->id, topic3->seqNum.value(), value,
+            topic3->flags));
+        topic3->sentAssign = true;
+      }
+      break;
+  }
+}
+
+void ClientData3::SendAnnounce(TopicData* topic,
+                               std::optional<int64_t> pubuid) {
+  // ignore if we've not yet built the subscriber
+  if (m_subscribers.empty()) {
+    return;
+  }
+
+  // subscribe to all non-special topics
+  if (!topic->special) {
+    topic->subscribers.Add(m_subscribers[0].get());
+    m_server.UpdateMetaTopicSub(topic);
+  }
+
+  // NT3 requires a value to send the assign message, so the assign message
+  // will get sent when the first value is sent (by SendValue).
+}
+
+void ClientData3::SendUnannounce(TopicData* topic) {
+  auto it = m_topics3.find(topic);
+  if (it == m_topics3.end()) {
+    return;  // never sent to client
+  }
+  bool sentAssign = it->second.sentAssign;
+  m_topics3.erase(it);
+  if (!sentAssign) {
+    return;  // never sent to client
+  }
+
+  // map to NT3 delete message
+  if (m_local && m_state == kStateRunning) {
+    net3::WireEncodeEntryDelete(m_wire.Send().stream(), topic->id);
+    Flush();
+  } else {
+    m_outgoing.emplace_back(net3::Message3::EntryDelete(topic->id));
+  }
+}
+
+void ClientData3::SendPropertiesUpdate(TopicData* topic,
+                                       const wpi::json& update, bool ack) {
+  if (ack) {
+    return;  // we don't ack in NT3
+  }
+  auto it = m_topics3.find(topic);
+  if (it == m_topics3.end()) {
+    return;  // never sent to client
+  }
+  TopicData3* topic3 = &it->second;
+  // Don't send flags update unless we've already sent an assign message.
+  // The assign message will contain the updated flags when we eventually
+  // send it.
+  if (topic3->UpdateFlags(topic) && topic3->sentAssign) {
+    if (m_local && m_state == kStateRunning) {
+      net3::WireEncodeFlagsUpdate(m_wire.Send().stream(), topic->id,
+                                  topic3->flags);
+      Flush();
+    } else {
+      m_outgoing.emplace_back(
+          net3::Message3::FlagsUpdate(topic->id, topic3->flags));
+    }
+  }
+}
+
+void ClientData3::SendOutgoing(uint64_t curTimeMs) {
+  if (m_outgoing.empty() || m_state != kStateRunning) {
+    return;  // nothing to do
+  }
+
+  // rate limit frequency of transmissions
+  if (curTimeMs < (m_lastSendMs + kMinPeriodMs)) {
+    return;
+  }
+
+  if (!m_wire.Ready()) {
+    ++m_notReadyCount;
+    if (m_notReadyCount > kWireMaxNotReady) {
+      m_wire.Disconnect("transmit stalled");
+    }
+    return;
+  }
+  m_notReadyCount = 0;
+
+  auto out = m_wire.Send();
+  for (auto&& msg : m_outgoing) {
+    net3::WireEncode(out.stream(), msg);
+  }
+  m_outgoing.resize(0);
+  m_lastSendMs = curTimeMs;
+}
+
+void ClientData3::KeepAlive() {
+  DEBUG4("KeepAlive({})", m_id);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received unexpected KeepAlive message");
+    return;
+  }
+  // ignore
+}
+
+void ClientData3::ServerHelloDone() {
+  DEBUG4("ServerHelloDone({})", m_id);
+  m_decoder.SetError("received unexpected ServerHelloDone message");
+}
+
+void ClientData3::ClientHelloDone() {
+  DEBUG4("ClientHelloDone({})", m_id);
+  if (m_state != kStateServerHelloComplete) {
+    m_decoder.SetError("received unexpected ClientHelloDone message");
+    return;
+  }
+  m_state = kStateRunning;
+}
+
+void ClientData3::ClearEntries() {
+  DEBUG4("ClearEntries({})", m_id);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received unexpected ClearEntries message");
+    return;
+  }
+
+  for (auto topic3it : m_topics3) {
+    TopicData* topic = topic3it.first;
+
+    // make sure we send assign the next time
+    topic3it.second.sentAssign = false;
+
+    // unpublish from this client (if it was previously published)
+    if (topic3it.second.published) {
+      topic3it.second.published = false;
+      auto publisherIt = m_publishers.find(topic3it.second.pubuid);
+      if (publisherIt != m_publishers.end()) {
+        // remove publisher from topic
+        topic->publishers.Remove(publisherIt->second.get());
+
+        // remove publisher from client
+        m_publishers.erase(publisherIt);
+
+        // update meta data
+        m_server.UpdateMetaTopicPub(topic);
+        UpdateMetaClientPub();
+      }
+    }
+
+    // set retained=false
+    m_server.SetProperties(this, topic, {{"retained", false}});
+  }
+}
+
+void ClientData3::ProtoUnsup(unsigned int proto_rev) {
+  DEBUG4("ProtoUnsup({})", m_id);
+  m_decoder.SetError("received unexpected ProtoUnsup message");
+}
+
+void ClientData3::ClientHello(std::string_view self_id,
+                              unsigned int proto_rev) {
+  DEBUG4("ClientHello({}, '{}', {:04x})", m_id, self_id, proto_rev);
+  if (m_state != kStateInitial) {
+    m_decoder.SetError("received unexpected ClientHello message");
+    return;
+  }
+  if (proto_rev != 0x0300) {
+    net3::WireEncodeProtoUnsup(m_wire.Send().stream(), 0x0300);
+    Flush();
+    m_decoder.SetError(
+        fmt::format("unsupported protocol version {:04x}", proto_rev));
+    return;
+  }
+  // create a unique name (just ignore provided client id)
+  m_name = fmt::format("NT3@{}", m_connInfo);
+  m_connected(m_name, 0x0300);
+  m_connected = nullptr;  // no longer required
+
+  // create client meta topics
+  m_metaPub = m_server.CreateMetaTopic(fmt::format("$clientpub${}", m_name));
+  m_metaSub = m_server.CreateMetaTopic(fmt::format("$clientsub${}", m_name));
+
+  // subscribe and send initial assignments
+  auto& sub = m_subscribers[0];
+  std::string prefix;
+  PubSubOptions options;
+  options.prefixMatch = true;
+  sub = std::make_unique<SubscriberData>(
+      this, std::span<const std::string>{{prefix}}, 0, options);
+  m_periodMs = std::gcd(m_periodMs, sub->periodMs);
+  if (m_periodMs < kMinPeriodMs) {
+    m_periodMs = kMinPeriodMs;
+  }
+  m_setPeriodic(m_periodMs);
+
+  {
+    auto out = m_wire.Send();
+    net3::WireEncodeServerHello(out.stream(), 0, "server");
+    for (auto&& topic : m_server.m_topics) {
+      if (topic && !topic->special && topic->IsPublished() &&
+          topic->lastValue) {
+        DEBUG4("client {}: initial announce of '{}' (id {})", m_id, topic->name,
+               topic->id);
+        topic->subscribers.Add(sub.get());
+        m_server.UpdateMetaTopicSub(topic.get());
+
+        TopicData3* topic3 = GetTopic3(topic.get());
+        ++topic3->seqNum;
+        net3::WireEncodeEntryAssign(out.stream(), topic->name, topic->id,
+                                    topic3->seqNum.value(), topic->lastValue,
+                                    topic3->flags);
+        topic3->sentAssign = true;
+      }
+    }
+    net3::WireEncodeServerHelloDone(out.stream());
+  }
+  Flush();
+  m_state = kStateServerHelloComplete;
+
+  // update meta topics
+  UpdateMetaClientPub();
+  UpdateMetaClientSub();
+}
+
+void ClientData3::ServerHello(unsigned int flags, std::string_view self_id) {
+  DEBUG4("ServerHello({}, {}, {})", m_id, flags, self_id);
+  m_decoder.SetError("received unexpected ServerHello message");
+}
+
+void ClientData3::EntryAssign(std::string_view name, unsigned int id,
+                              unsigned int seq_num, const Value& value,
+                              unsigned int flags) {
+  DEBUG4("EntryAssign({}, {}, {}, {}, {})", m_id, id, seq_num,
+         static_cast<int>(value.type()), flags);
+  if (id != 0xffff) {
+    DEBUG3("ignored EntryAssign from {} with non-0xffff id {}", m_id, id);
+    return;
+  }
+
+  // convert from NT3 info
+  auto typeStr = TypeToString(value.type());
+  wpi::json properties = wpi::json::object();
+  properties["retained"] = true;  // treat all NT3 published topics as retained
+  if ((flags & NT_PERSISTENT) != 0) {
+    properties["persistent"] = true;
+  }
+
+  // create topic
+  auto topic = m_server.CreateTopic(this, name, typeStr, properties);
+  TopicData3* topic3 = GetTopic3(topic);
+  if (topic3->published || topic3->sentAssign) {
+    WARNING("ignorning client {} duplicate publish of '{}'", m_id, name);
+    return;
+  }
+  ++topic3->seqNum;
+  topic3->published = true;
+  topic3->pubuid = m_nextPubUid++;
+  topic3->sentAssign = true;
+
+  // create publisher
+  auto [publisherIt, isNew] = m_publishers.try_emplace(
+      topic3->pubuid,
+      std::make_unique<PublisherData>(this, topic, topic3->pubuid));
+  if (!isNew) {
+    return;  // shouldn't happen, but just in case...
+  }
+
+  // add publisher to topic
+  topic->publishers.Add(publisherIt->getSecond().get());
+
+  // update meta data
+  m_server.UpdateMetaTopicPub(topic);
+  UpdateMetaClientPub();
+
+  // acts as an announce + data update
+  SendAnnounce(topic, topic3->pubuid);
+  m_server.SetValue(this, topic, value);
+
+  // respond with assign message with assigned topic ID
+  if (m_local && m_state == kStateRunning) {
+    net3::WireEncodeEntryAssign(m_wire.Send().stream(), topic->name, topic->id,
+                                topic3->seqNum.value(), value, topic3->flags);
+  } else {
+    m_outgoing.emplace_back(net3::Message3::EntryAssign(
+        topic->name, topic->id, topic3->seqNum.value(), value, topic3->flags));
+  }
+}
+
+void ClientData3::EntryUpdate(unsigned int id, unsigned int seq_num,
+                              const Value& value) {
+  DEBUG4("EntryUpdate({}, {}, {}, {})", m_id, id, seq_num,
+         static_cast<int>(value.type()));
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received unexpected EntryUpdate message");
+    return;
+  }
+
+  if (id >= m_server.m_topics.size()) {
+    DEBUG3("ignored EntryUpdate from {} on non-existent topic {}", m_id, id);
+    return;
+  }
+  TopicData* topic = m_server.m_topics[id].get();
+  if (!topic || !topic->IsPublished()) {
+    DEBUG3("ignored EntryUpdate from {} on non-existent topic {}", m_id, id);
+    return;
+  }
+
+  TopicData3* topic3 = GetTopic3(topic);
+  if (!topic3->published) {
+    topic3->published = true;
+    topic3->pubuid = m_nextPubUid++;
+
+    // create publisher
+    auto [publisherIt, isNew] = m_publishers.try_emplace(
+        topic3->pubuid,
+        std::make_unique<PublisherData>(this, topic, topic3->pubuid));
+    if (isNew) {
+      // add publisher to topic
+      topic->publishers.Add(publisherIt->getSecond().get());
+
+      // update meta data
+      m_server.UpdateMetaTopicPub(topic);
+      UpdateMetaClientPub();
+    }
+  }
+  topic3->seqNum = net3::SequenceNumber{seq_num};
+
+  m_server.SetValue(this, topic, value);
+}
+
+void ClientData3::FlagsUpdate(unsigned int id, unsigned int flags) {
+  DEBUG4("FlagsUpdate({}, {}, {})", m_id, id, flags);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received unexpected FlagsUpdate message");
+    return;
+  }
+  if (id >= m_server.m_topics.size()) {
+    DEBUG3("ignored FlagsUpdate from {} on non-existent topic {}", m_id, id);
+    return;
+  }
+  TopicData* topic = m_server.m_topics[id].get();
+  if (!topic || !topic->IsPublished()) {
+    DEBUG3("ignored FlagsUpdate from {} on non-existent topic {}", m_id, id);
+    return;
+  }
+  if (topic->special) {
+    DEBUG3("ignored FlagsUpdate from {} on special topic {}", m_id, id);
+    return;
+  }
+  m_server.SetFlags(this, topic, flags);
+}
+
+void ClientData3::EntryDelete(unsigned int id) {
+  DEBUG4("EntryDelete({}, {})", m_id, id);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received unexpected EntryDelete message");
+    return;
+  }
+  if (id >= m_server.m_topics.size()) {
+    DEBUG3("ignored EntryDelete from {} on non-existent topic {}", m_id, id);
+    return;
+  }
+  TopicData* topic = m_server.m_topics[id].get();
+  if (!topic || !topic->IsPublished()) {
+    DEBUG3("ignored EntryDelete from {} on non-existent topic {}", m_id, id);
+    return;
+  }
+  if (topic->special) {
+    DEBUG3("ignored EntryDelete from {} on special topic {}", m_id, id);
+    return;
+  }
+
+  auto topic3it = m_topics3.find(topic);
+  if (topic3it != m_topics3.end()) {
+    // make sure we send assign the next time
+    topic3it->second.sentAssign = false;
+
+    // unpublish from this client (if it was previously published)
+    if (topic3it->second.published) {
+      topic3it->second.published = false;
+      auto publisherIt = m_publishers.find(topic3it->second.pubuid);
+      if (publisherIt != m_publishers.end()) {
+        // remove publisher from topic
+        topic->publishers.Remove(publisherIt->second.get());
+
+        // remove publisher from client
+        m_publishers.erase(publisherIt);
+
+        // update meta data
+        m_server.UpdateMetaTopicPub(topic);
+        UpdateMetaClientPub();
+      }
+    }
+  }
+
+  // set retained=false
+  m_server.SetProperties(this, topic, {{"retained", false}});
+}
+
+bool TopicData::SetProperties(const wpi::json& update) {
+  if (!update.is_object()) {
+    return false;
+  }
+  bool updated = false;
+  for (auto&& elem : update.items()) {
+    if (elem.value().is_null()) {
+      properties.erase(elem.key());
+    } else {
+      properties[elem.key()] = elem.value();
+    }
+    updated = true;
+  }
+  if (updated) {
+    RefreshProperties();
+  }
+  return updated;
+}
+
+void TopicData::RefreshProperties() {
+  persistent = false;
+  retained = false;
+
+  auto persistentIt = properties.find("persistent");
+  if (persistentIt != properties.end()) {
+    if (auto val = persistentIt->get_ptr<bool*>()) {
+      persistent = *val;
+    }
+  }
+
+  auto retainedIt = properties.find("retained");
+  if (retainedIt != properties.end()) {
+    if (auto val = retainedIt->get_ptr<bool*>()) {
+      retained = *val;
+    }
+  }
+}
+
+bool TopicData::SetFlags(unsigned int flags_) {
+  bool updated;
+  if ((flags_ & NT_PERSISTENT) != 0) {
+    updated = !persistent;
+    persistent = true;
+    properties["persistent"] = true;
+  } else {
+    updated = persistent;
+    persistent = false;
+    properties.erase("persistent");
+  }
+  return updated;
+}
+
+bool SubscriberData::Matches(std::string_view name, bool special) {
+  for (auto&& topicName : topicNames) {
+    if ((!options.prefixMatch && name == topicName) ||
+        (options.prefixMatch && (!special || !topicName.empty()) &&
+         wpi::starts_with(name, topicName))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+SImpl::SImpl(wpi::Logger& logger) : m_logger{logger} {
+  // local is client 0
+  m_clients.emplace_back(std::make_unique<ClientDataLocal>(*this, 0, logger));
+  m_localClient = static_cast<ClientDataLocal*>(m_clients.back().get());
+}
+
+std::pair<std::string, int> SImpl::AddClient(
+    std::string_view name, std::string_view connInfo, bool local,
+    WireConnection& wire, ServerImpl::SetPeriodicFunc setPeriodic) {
+  // strip anything after @ in the name
+  name = wpi::split(name, '@').first;
+  if (name.empty()) {
+    name = "NT4";
+  }
+  size_t index = m_clients.size();
+  // find an empty slot and check for duplicates
+  // just do a linear search as number of clients is typically small (<10)
+  int duplicateName = 0;
+  for (size_t i = 0, end = index; i < end; ++i) {
+    auto& clientData = m_clients[i];
+    if (clientData && clientData->GetOriginalName() == name) {
+      ++duplicateName;
+    } else if (!clientData && index == end) {
+      index = i;
+    }
+  }
+  if (index == m_clients.size()) {
+    m_clients.emplace_back();
+  }
+
+  // if duplicate name, de-duplicate
+  std::string dedupName;
+  if (duplicateName > 0) {
+    dedupName = fmt::format("{}@{}", name, duplicateName);
+  } else {
+    dedupName = name;
+  }
+
+  auto& clientData = m_clients[index];
+  clientData = std::make_unique<ClientData4>(name, dedupName, connInfo, local,
+                                             wire, std::move(setPeriodic),
+                                             *this, index, m_logger);
+
+  // create client meta topics
+  clientData->m_metaPub =
+      CreateMetaTopic(fmt::format("$clientpub${}", dedupName));
+  clientData->m_metaSub =
+      CreateMetaTopic(fmt::format("$clientsub${}", dedupName));
+
+  // update meta topics
+  clientData->UpdateMetaClientPub();
+  clientData->UpdateMetaClientSub();
+
+  wire.Flush();
+
+  DEBUG3("AddClient('{}', '{}') -> {}", name, connInfo, index);
+  return {std::move(dedupName), index};
+}
+
+int SImpl::AddClient3(std::string_view connInfo, bool local,
+                      net3::WireConnection3& wire,
+                      ServerImpl::Connected3Func connected,
+                      ServerImpl::SetPeriodicFunc setPeriodic) {
+  size_t index = m_clients.size();
+  // find an empty slot; we can't check for duplicates until we get a hello.
+  // just do a linear search as number of clients is typically small (<10)
+  for (size_t i = 0, end = index; i < end; ++i) {
+    if (!m_clients[i]) {
+      index = i;
+      break;
+    }
+  }
+  if (index == m_clients.size()) {
+    m_clients.emplace_back();
+  }
+
+  m_clients[index] = std::make_unique<ClientData3>(
+      connInfo, local, wire, std::move(connected), std::move(setPeriodic),
+      *this, index, m_logger);
+
+  DEBUG3("AddClient3('{}') -> {}", connInfo, index);
+  return index;
+}
+
+void SImpl::RemoveClient(int clientId) {
+  DEBUG3("RemoveClient({})", clientId);
+  auto& client = m_clients[clientId];
+
+  // remove all publishers and subscribers for this client
+  wpi::SmallVector<TopicData*, 16> toDelete;
+  for (auto&& topic : m_topics) {
+    auto pubRemove =
+        std::remove_if(topic->publishers.begin(), topic->publishers.end(),
+                       [&](auto&& e) { return e->client == client.get(); });
+    bool pubChanged = pubRemove != topic->publishers.end();
+    topic->publishers.erase(pubRemove, topic->publishers.end());
+
+    auto subRemove =
+        std::remove_if(topic->subscribers.begin(), topic->subscribers.end(),
+                       [&](auto&& e) { return e->client == client.get(); });
+    bool subChanged = subRemove != topic->subscribers.end();
+    topic->subscribers.erase(subRemove, topic->subscribers.end());
+
+    if (!topic->IsPublished()) {
+      toDelete.push_back(topic.get());
+    } else {
+      if (pubChanged) {
+        UpdateMetaTopicPub(topic.get());
+      }
+      if (subChanged) {
+        UpdateMetaTopicSub(topic.get());
+      }
+    }
+  }
+
+  // delete unpublished topics
+  for (auto topic : toDelete) {
+    DeleteTopic(topic);
+  }
+  DeleteTopic(client->m_metaPub);
+  DeleteTopic(client->m_metaSub);
+
+  // delete the client
+  client.reset();
+}
+
+bool SImpl::PersistentChanged() {
+  bool rv = m_persistentChanged;
+  m_persistentChanged = false;
+  return rv;
+}
+
+static void DumpValue(wpi::raw_ostream& os, const Value& value,
+                      wpi::json::serializer& s) {
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      if (value.GetBoolean()) {
+        os << "true";
+      } else {
+        os << "false";
+      }
+      break;
+    case NT_DOUBLE:
+      s.dump_float(value.GetDouble());
+      break;
+    case NT_FLOAT:
+      s.dump_float(value.GetFloat());
+      break;
+    case NT_INTEGER:
+      s.dump_integer(value.GetInteger());
+      break;
+    case NT_STRING:
+      os << '"';
+      s.dump_escaped(value.GetString(), false);
+      os << '"';
+      break;
+    case NT_RAW:
+    case NT_RPC:
+      os << '"';
+      wpi::Base64Encode(os, value.GetRaw());
+      os << '"';
+      break;
+    case NT_BOOLEAN_ARRAY: {
+      os << '[';
+      bool first = true;
+      for (auto v : value.GetBooleanArray()) {
+        if (first) {
+          first = false;
+        } else {
+          os << ", ";
+        }
+        if (v) {
+          os << "true";
+        } else {
+          os << "false";
+        }
+      }
+      os << ']';
+      break;
+    }
+    case NT_DOUBLE_ARRAY: {
+      os << '[';
+      bool first = true;
+      for (auto v : value.GetDoubleArray()) {
+        if (first) {
+          first = false;
+        } else {
+          os << ", ";
+        }
+        s.dump_float(v);
+      }
+      os << ']';
+      break;
+    }
+    case NT_FLOAT_ARRAY: {
+      os << '[';
+      bool first = true;
+      for (auto v : value.GetFloatArray()) {
+        if (first) {
+          first = false;
+        } else {
+          os << ", ";
+        }
+        s.dump_float(v);
+      }
+      os << ']';
+      break;
+    }
+    case NT_INTEGER_ARRAY: {
+      os << '[';
+      bool first = true;
+      for (auto v : value.GetIntegerArray()) {
+        if (first) {
+          first = false;
+        } else {
+          os << ", ";
+        }
+        s.dump_integer(v);
+      }
+      os << ']';
+      break;
+    }
+    case NT_STRING_ARRAY: {
+      os << '[';
+      bool first = true;
+      for (auto&& v : value.GetStringArray()) {
+        if (first) {
+          first = false;
+        } else {
+          os << ", ";
+        }
+        os << '"';
+        s.dump_escaped(v, false);
+        os << '"';
+      }
+      os << ']';
+      break;
+    }
+    default:
+      os << "null";
+      break;
+  }
+}
+
+void SImpl::DumpPersistent(wpi::raw_ostream& os) {
+  wpi::json::serializer s{os, ' ', 16};
+  os << "[\n";
+  bool first = true;
+  for (const auto& topic : m_topics) {
+    if (!topic->persistent || !topic->lastValue) {
+      continue;
+    }
+    if (first) {
+      first = false;
+    } else {
+      os << ",\n";
+    }
+    os << "  {\n    \"name\": \"";
+    s.dump_escaped(topic->name, false);
+    os << "\",\n    \"type\": \"";
+    s.dump_escaped(topic->typeStr, false);
+    os << "\",\n    \"value\": ";
+    DumpValue(os, topic->lastValue, s);
+    os << ",\n    \"properties\": ";
+    s.dump(topic->properties, true, false, 2, 4);
+    os << "\n  }";
+  }
+  os << "\n]\n";
+}
+
+static std::string* ObjGetString(wpi::json::object_t& obj, std::string_view key,
+                                 std::string* error) {
+  auto it = obj.find(key);
+  if (it == obj.end()) {
+    *error = fmt::format("no {} key", key);
+    return nullptr;
+  }
+  auto val = it->second.get_ptr<std::string*>();
+  if (!val) {
+    *error = fmt::format("{} must be a string", key);
+  }
+  return val;
+}
+
+std::string SImpl::LoadPersistent(std::string_view in) {
+  if (in.empty()) {
+    return {};
+  }
+
+  wpi::json j;
+  try {
+    j = wpi::json::parse(in);
+  } catch (wpi::json::parse_error& err) {
+    return fmt::format("could not decode JSON: {}", err.what());
+  }
+
+  if (!j.is_array()) {
+    return "expected JSON array at top level";
+  }
+
+  bool persistentChanged = m_persistentChanged;
+
+  std::string allerrors;
+  int i = -1;
+  auto time = nt::Now();
+  for (auto&& jitem : j) {
+    ++i;
+    std::string error;
+    {
+      auto obj = jitem.get_ptr<wpi::json::object_t*>();
+      if (!obj) {
+        error = "expected item to be an object";
+        goto err;
+      }
+
+      // name
+      auto name = ObjGetString(*obj, "name", &error);
+      if (!name) {
+        goto err;
+      }
+
+      // type
+      auto typeStr = ObjGetString(*obj, "type", &error);
+      if (!typeStr) {
+        goto err;
+      }
+
+      // properties
+      auto propsIt = obj->find("properties");
+      if (propsIt == obj->end()) {
+        error = "no properties key";
+        goto err;
+      }
+      auto& props = propsIt->second;
+      if (!props.is_object()) {
+        error = "properties must be an object";
+        goto err;
+      }
+
+      // check to make sure persistent property is set
+      auto persistentIt = props.find("persistent");
+      if (persistentIt == props.end()) {
+        error = "no persistent property";
+        goto err;
+      }
+      if (auto v = persistentIt->get_ptr<bool*>()) {
+        if (!*v) {
+          error = "persistent property is false";
+          goto err;
+        }
+      } else {
+        error = "persistent property is not boolean";
+        goto err;
+      }
+
+      // value
+      auto valueIt = obj->find("value");
+      if (valueIt == obj->end()) {
+        error = "no value key";
+        goto err;
+      }
+      Value value;
+      if (*typeStr == "boolean") {
+        if (auto v = valueIt->second.get_ptr<bool*>()) {
+          value = Value::MakeBoolean(*v, time);
+        } else {
+          error = "value type mismatch, expected boolean";
+          goto err;
+        }
+      } else if (*typeStr == "int") {
+        if (auto v = valueIt->second.get_ptr<int64_t*>()) {
+          value = Value::MakeInteger(*v, time);
+        } else if (auto v = valueIt->second.get_ptr<uint64_t*>()) {
+          value = Value::MakeInteger(*v, time);
+        } else {
+          error = "value type mismatch, expected int";
+          goto err;
+        }
+      } else if (*typeStr == "float") {
+        if (auto v = valueIt->second.get_ptr<double*>()) {
+          value = Value::MakeFloat(*v, time);
+        } else {
+          error = "value type mismatch, expected float";
+          goto err;
+        }
+      } else if (*typeStr == "double") {
+        if (auto v = valueIt->second.get_ptr<double*>()) {
+          value = Value::MakeDouble(*v, time);
+        } else {
+          error = "value type mismatch, expected double";
+          goto err;
+        }
+      } else if (*typeStr == "string" || *typeStr == "json") {
+        if (auto v = valueIt->second.get_ptr<std::string*>()) {
+          value = Value::MakeString(*v, time);
+        } else {
+          error = "value type mismatch, expected string";
+          goto err;
+        }
+      } else if (*typeStr == "boolean[]") {
+        auto arr = valueIt->second.get_ptr<wpi::json::array_t*>();
+        if (!arr) {
+          error = "value type mismatch, expected array";
+          goto err;
+        }
+        std::vector<int> elems;
+        for (auto&& jelem : valueIt->second) {
+          if (auto v = jelem.get_ptr<bool*>()) {
+            elems.push_back(*v);
+          } else {
+            error = "value type mismatch, expected boolean";
+          }
+        }
+        value = Value::MakeBooleanArray(elems, time);
+      } else if (*typeStr == "int[]") {
+        auto arr = valueIt->second.get_ptr<wpi::json::array_t*>();
+        if (!arr) {
+          error = "value type mismatch, expected array";
+          goto err;
+        }
+        std::vector<int64_t> elems;
+        for (auto&& jelem : valueIt->second) {
+          if (auto v = jelem.get_ptr<int64_t*>()) {
+            elems.push_back(*v);
+          } else if (auto v = jelem.get_ptr<uint64_t*>()) {
+            elems.push_back(*v);
+          } else {
+            error = "value type mismatch, expected int";
+          }
+        }
+        value = Value::MakeIntegerArray(elems, time);
+      } else if (*typeStr == "double[]") {
+        auto arr = valueIt->second.get_ptr<wpi::json::array_t*>();
+        if (!arr) {
+          error = "value type mismatch, expected array";
+          goto err;
+        }
+        std::vector<double> elems;
+        for (auto&& jelem : valueIt->second) {
+          if (auto v = jelem.get_ptr<double*>()) {
+            elems.push_back(*v);
+          } else {
+            error = "value type mismatch, expected double";
+          }
+        }
+        value = Value::MakeDoubleArray(elems, time);
+      } else if (*typeStr == "float[]") {
+        auto arr = valueIt->second.get_ptr<wpi::json::array_t*>();
+        if (!arr) {
+          error = "value type mismatch, expected array";
+          goto err;
+        }
+        std::vector<float> elems;
+        for (auto&& jelem : valueIt->second) {
+          if (auto v = jelem.get_ptr<double*>()) {
+            elems.push_back(*v);
+          } else {
+            error = "value type mismatch, expected float";
+          }
+        }
+        value = Value::MakeFloatArray(elems, time);
+      } else if (*typeStr == "string[]") {
+        auto arr = valueIt->second.get_ptr<wpi::json::array_t*>();
+        if (!arr) {
+          error = "value type mismatch, expected array";
+          goto err;
+        }
+        std::vector<std::string> elems;
+        for (auto&& jelem : valueIt->second) {
+          if (auto v = jelem.get_ptr<std::string*>()) {
+            elems.emplace_back(*v);
+          } else {
+            error = "value type mismatch, expected string";
+          }
+        }
+        value = Value::MakeStringArray(std::move(elems), time);
+      } else {
+        // raw
+        if (auto v = valueIt->second.get_ptr<std::string*>()) {
+          std::vector<uint8_t> data;
+          wpi::Base64Decode(*v, &data);
+          value = Value::MakeRaw(std::move(data), time);
+        } else {
+          error = "value type mismatch, expected string";
+          goto err;
+        }
+      }
+
+      // create persistent topic
+      auto topic = CreateTopic(nullptr, *name, *typeStr, props);
+
+      // set value
+      SetValue(nullptr, topic, value);
+
+      continue;
+    }
+  err:
+    allerrors += fmt::format("{}: {}\n", i, error);
+  }
+
+  m_persistentChanged = persistentChanged;  // restore flag
+
+  return allerrors;
+}
+
+TopicData* SImpl::CreateTopic(ClientData* client, std::string_view name,
+                              std::string_view typeStr,
+                              const wpi::json& properties, bool special) {
+  auto& topic = m_nameTopics[name];
+  if (topic) {
+    if (typeStr != topic->typeStr) {
+      if (client) {
+        WARNING("client {} publish '{}' conflicting type '{}' (currently '{}')",
+                client->GetName(), name, typeStr, topic->typeStr);
+      }
+    }
+  } else {
+    // new topic
+    unsigned int id = m_topics.emplace_back(
+        std::make_unique<TopicData>(name, typeStr, properties));
+    topic = m_topics[id].get();
+    topic->id = id;
+    topic->special = special;
+
+    for (auto&& aClient : m_clients) {
+      if (!aClient) {
+        continue;
+      }
+
+      // look for subscriber matching prefixes
+      wpi::SmallVector<SubscriberData*, 16> subscribersBuf;
+      auto subscribers =
+          aClient->GetSubscribers(name, topic->special, subscribersBuf);
+      for (auto subscriber : subscribers) {
+        topic->subscribers.Add(subscriber);
+      }
+
+      // don't announce to this client if no subscribers
+      if (subscribers.empty()) {
+        continue;
+      }
+
+      if (aClient.get() == client) {
+        continue;  // don't announce to requesting client again
+      }
+
+      DEBUG4("client {}: announce {}", aClient->GetId(), topic->name);
+      aClient->SendAnnounce(topic, std::nullopt);
+    }
+
+    // create meta topics; don't create if topic is itself a meta topic
+    if (!special) {
+      topic->metaPub = CreateMetaTopic(fmt::format("$pub${}", name));
+      topic->metaSub = CreateMetaTopic(fmt::format("$sub${}", name));
+      UpdateMetaTopicPub(topic);
+      UpdateMetaTopicSub(topic);
+    }
+  }
+
+  return topic;
+}
+
+TopicData* SImpl::CreateMetaTopic(std::string_view name) {
+  return CreateTopic(nullptr, name, "msgpack", {{"retained", true}}, true);
+}
+
+void SImpl::DeleteTopic(TopicData* topic) {
+  if (!topic) {
+    return;
+  }
+
+  // delete meta topics
+  if (topic->metaPub) {
+    DeleteTopic(topic->metaPub);
+  }
+  if (topic->metaSub) {
+    DeleteTopic(topic->metaSub);
+  }
+
+  // unannounce to all subscribers
+  wpi::SmallVector<bool, 16> clients;
+  clients.resize(m_clients.size());
+  for (auto&& sub : topic->subscribers) {
+    clients[sub->client->GetId()] = true;
+  }
+  for (size_t i = 0, iend = clients.size(); i < iend; ++i) {
+    if (!clients[i]) {
+      continue;
+    }
+    if (auto aClient = m_clients[i].get()) {
+      aClient->SendUnannounce(topic);
+    }
+  }
+
+  // erase the topic
+  m_nameTopics.erase(topic->name);
+  m_topics.erase(topic->id);
+}
+
+void SImpl::SetProperties(ClientData* client, TopicData* topic,
+                          const wpi::json& update) {
+  DEBUG4("SetProperties({}, {}, {})", client ? client->GetId() : -1,
+         topic->name, update.dump());
+  bool wasPersistent = topic->persistent;
+  if (topic->SetProperties(update)) {
+    // update persistentChanged flag
+    if (topic->persistent != wasPersistent) {
+      m_persistentChanged = true;
+    }
+    PropertiesChanged(client, topic, update);
+  }
+}
+
+void SImpl::SetFlags(ClientData* client, TopicData* topic, unsigned int flags) {
+  bool wasPersistent = topic->persistent;
+  if (topic->SetFlags(flags)) {
+    // update persistentChanged flag
+    if (topic->persistent != wasPersistent) {
+      m_persistentChanged = true;
+      wpi::json update;
+      if (topic->persistent) {
+        update = {{"persistent", true}};
+      } else {
+        update = {{"persistent", wpi::json::object()}};
+      }
+      PropertiesChanged(client, topic, update);
+    }
+  }
+}
+
+void SImpl::SetValue(ClientData* client, TopicData* topic, const Value& value) {
+  // update retained value if from same client or timestamp newer
+  if (!topic->lastValue || topic->lastValueClient == client ||
+      value.time() >= topic->lastValue.time()) {
+    DEBUG4("updating '{}' last value (time was {} is {})", topic->name,
+           topic->lastValue.time(), value.time());
+    topic->lastValue = value;
+    topic->lastValueClient = client;
+
+    // if persistent, update flag
+    if (topic->persistent) {
+      m_persistentChanged = true;
+    }
+  }
+
+  // propagate to subscribers; as each client may have multiple subscribers,
+  // but we only want to send the value once, first map to clients and then
+  // take action based on union of subscriptions
+
+  // indexed by clientId
+  wpi::SmallVector<ClientData::SendMode, 16> toSend;
+  toSend.resize(m_clients.size());
+
+  for (auto&& subscriber : topic->subscribers) {
+    int id = subscriber->client->GetId();
+    if (subscriber->options.topicsOnly) {
+      continue;
+    } else if (subscriber->options.sendAll) {
+      toSend[id] = ClientData::kSendAll;
+    } else if (toSend[id] != ClientData::kSendAll) {
+      toSend[id] = ClientData::kSendNormal;
+    }
+  }
+
+  for (size_t i = 0, iend = toSend.size(); i < iend; ++i) {
+    auto aClient = m_clients[i].get();
+    if (!aClient || client == aClient) {
+      continue;  // don't echo back
+    }
+    if (toSend[i] != ClientData::kSendDisabled) {
+      aClient->SendValue(topic, value, toSend[i]);
+    }
+  }
+}
+
+void SImpl::UpdateMetaClients(const std::vector<ConnectionInfo>& conns) {
+  Writer w;
+  mpack_start_array(&w, conns.size());
+  for (auto&& conn : conns) {
+    mpack_start_map(&w, 3);
+    mpack_write_str(&w, "id");
+    mpack_write_str(&w, conn.remote_id);
+    mpack_write_str(&w, "conn");
+    mpack_write_str(&w, fmt::format("{}:{}", conn.remote_ip, conn.remote_port));
+    mpack_write_str(&w, "ver");
+    mpack_write_u16(&w, conn.protocol_version);
+    mpack_finish_map(&w);
+  }
+  mpack_finish_array(&w);
+  if (mpack_writer_destroy(&w) == mpack_ok) {
+    SetValue(nullptr, m_metaClients, Value::MakeRaw(std::move(w.bytes)));
+  } else {
+    DEBUG4("failed to encode $clients");
+  }
+}
+
+void SImpl::UpdateMetaTopicPub(TopicData* topic) {
+  if (!topic->metaPub) {
+    return;
+  }
+  Writer w;
+  mpack_start_array(&w, topic->publishers.size());
+  for (auto&& pub : topic->publishers) {
+    mpack_start_map(&w, 2);
+    mpack_write_str(&w, "client");
+    if (pub->client) {
+      mpack_write_str(&w, pub->client->GetName());
+    } else {
+      mpack_write_str(&w, "");
+    }
+    mpack_write_str(&w, "pubuid");
+    mpack_write_int(&w, pub->pubuid);
+    mpack_finish_map(&w);
+  }
+  mpack_finish_array(&w);
+  if (mpack_writer_destroy(&w) == mpack_ok) {
+    SetValue(nullptr, topic->metaPub, Value::MakeRaw(std::move(w.bytes)));
+  }
+}
+
+void SImpl::UpdateMetaTopicSub(TopicData* topic) {
+  if (!topic->metaSub) {
+    return;
+  }
+  Writer w;
+  mpack_start_array(&w, topic->subscribers.size());
+  for (auto&& sub : topic->subscribers) {
+    mpack_start_map(&w, 3);
+    mpack_write_str(&w, "client");
+    if (sub->client) {
+      mpack_write_str(&w, sub->client->GetName());
+    } else {
+      mpack_write_str(&w, "");
+    }
+    mpack_write_str(&w, "subuid");
+    mpack_write_int(&w, sub->subuid);
+    mpack_write_str(&w, "options");
+    WriteOptions(w, sub->options);
+    mpack_finish_map(&w);
+  }
+  mpack_finish_array(&w);
+  if (mpack_writer_destroy(&w) == mpack_ok) {
+    SetValue(nullptr, topic->metaSub, Value::MakeRaw(std::move(w.bytes)));
+  }
+}
+
+void SImpl::PropertiesChanged(ClientData* client, TopicData* topic,
+                              const wpi::json& update) {
+  // removing some properties can result in the topic being unpublished
+  if (!topic->IsPublished()) {
+    DeleteTopic(topic);
+  } else {
+    // send updated announcement to all subscribers
+    wpi::SmallVector<bool, 16> clients;
+    clients.resize(m_clients.size());
+    for (auto&& sub : topic->subscribers) {
+      clients[sub->client->GetId()] = true;
+    }
+    for (size_t i = 0, iend = clients.size(); i < iend; ++i) {
+      if (!clients[i]) {
+        continue;
+      }
+      if (auto aClient = m_clients[i].get()) {
+        aClient->SendPropertiesUpdate(topic, update, aClient == client);
+      }
+    }
+  }
+}
+
+class ServerImpl::Impl final : public SImpl {
+ public:
+  explicit Impl(wpi::Logger& logger) : SImpl{logger} {}
+};
+
+ServerImpl::ServerImpl(wpi::Logger& logger)
+    : m_impl{std::make_unique<Impl>(logger)} {}
+
+ServerImpl::~ServerImpl() = default;
+
+void ServerImpl::SendControl(uint64_t curTimeMs) {
+  if (!m_impl->m_controlReady) {
+    return;
+  }
+  m_impl->m_controlReady = false;
+
+  for (auto&& client : m_impl->m_clients) {
+    if (client) {
+      // to ensure ordering, just send everything
+      client->SendOutgoing(curTimeMs);
+      client->Flush();
+    }
+  }
+}
+
+void ServerImpl::SendValues(int clientId, uint64_t curTimeMs) {
+  auto client = m_impl->m_clients[clientId].get();
+  client->SendOutgoing(curTimeMs);
+  client->Flush();
+}
+
+void ServerImpl::HandleLocal(std::span<const ClientMessage> msgs) {
+  // just map as a normal client into client=0 calls
+  m_impl->m_localClient->HandleLocal(msgs);
+}
+
+void ServerImpl::SetLocal(LocalInterface* local) {
+  WPI_DEBUG4(m_impl->m_logger, "SetLocal()");
+  m_impl->m_local = local;
+
+  // create server meta topics
+  m_impl->m_metaClients = m_impl->CreateMetaTopic("$clients");
+
+  // create local client meta topics
+  m_impl->m_localClient->m_metaPub = m_impl->CreateMetaTopic("$serverpub");
+  m_impl->m_localClient->m_metaSub = m_impl->CreateMetaTopic("$serversub");
+
+  // update meta topics
+  m_impl->m_localClient->UpdateMetaClientPub();
+  m_impl->m_localClient->UpdateMetaClientSub();
+}
+
+void ServerImpl::ProcessIncomingText(int clientId, std::string_view data) {
+  m_impl->m_clients[clientId]->ProcessIncomingText(data);
+}
+
+void ServerImpl::ProcessIncomingBinary(int clientId,
+                                       std::span<const uint8_t> data) {
+  m_impl->m_clients[clientId]->ProcessIncomingBinary(data);
+}
+
+std::pair<std::string, int> ServerImpl::AddClient(std::string_view name,
+                                                  std::string_view connInfo,
+                                                  bool local,
+                                                  WireConnection& wire,
+                                                  SetPeriodicFunc setPeriodic) {
+  return m_impl->AddClient(name, connInfo, local, wire, std::move(setPeriodic));
+}
+
+int ServerImpl::AddClient3(std::string_view connInfo, bool local,
+                           net3::WireConnection3& wire,
+                           Connected3Func connected,
+                           SetPeriodicFunc setPeriodic) {
+  return m_impl->AddClient3(connInfo, local, wire, std::move(connected),
+                            std::move(setPeriodic));
+}
+
+void ServerImpl::RemoveClient(int clientId) {
+  m_impl->RemoveClient(clientId);
+}
+
+void ServerImpl::ConnectionsChanged(const std::vector<ConnectionInfo>& conns) {
+  m_impl->UpdateMetaClients(conns);
+}
+
+bool ServerImpl::PersistentChanged() {
+  return m_impl->PersistentChanged();
+}
+
+std::string ServerImpl::DumpPersistent() {
+  std::string rv;
+  wpi::raw_string_ostream os{rv};
+  m_impl->DumpPersistent(os);
+  os.flush();
+  return rv;
+}
+
+std::string ServerImpl::LoadPersistent(std::string_view in) {
+  return m_impl->LoadPersistent(in);
+}
diff --git a/ntcore/src/main/native/cpp/net/ServerImpl.h b/ntcore/src/main/native/cpp/net/ServerImpl.h
new file mode 100644
index 0000000..86607e9
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/ServerImpl.h
@@ -0,0 +1,76 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "NetworkInterface.h"
+#include "net3/WireConnection3.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt::net3 {
+class WireConnection3;
+}  // namespace nt::net3
+
+namespace nt::net {
+
+struct ClientMessage;
+class LocalInterface;
+class WireConnection;
+
+class ServerImpl final {
+ public:
+  using SetPeriodicFunc = std::function<void(uint32_t repeatMs)>;
+  using Connected3Func =
+      std::function<void(std::string_view name, uint16_t proto)>;
+
+  explicit ServerImpl(wpi::Logger& logger);
+  ~ServerImpl();
+
+  void SendControl(uint64_t curTimeMs);
+  void SendValues(int clientId, uint64_t curTimeMs);
+
+  void HandleLocal(std::span<const ClientMessage> msgs);
+  void SetLocal(LocalInterface* local);
+
+  void ProcessIncomingText(int clientId, std::string_view data);
+  void ProcessIncomingBinary(int clientId, std::span<const uint8_t> data);
+
+  // Returns -1 if cannot add client (e.g. due to duplicate name).
+  // Caller must ensure WireConnection lifetime lasts until RemoveClient() call.
+  std::pair<std::string, int> AddClient(std::string_view name,
+                                        std::string_view connInfo, bool local,
+                                        WireConnection& wire,
+                                        SetPeriodicFunc setPeriodic);
+  int AddClient3(std::string_view connInfo, bool local,
+                 net3::WireConnection3& wire, Connected3Func connected,
+                 SetPeriodicFunc setPeriodic);
+  void RemoveClient(int clientId);
+
+  void ConnectionsChanged(const std::vector<ConnectionInfo>& conns);
+
+  // if any persistent values changed since the last call to this function
+  bool PersistentChanged();
+  std::string DumpPersistent();
+  // returns newline-separated errors
+  std::string LoadPersistent(std::string_view in);
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/WebSocketConnection.cpp b/ntcore/src/main/native/cpp/net/WebSocketConnection.cpp
new file mode 100644
index 0000000..d3d192f
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WebSocketConnection.cpp
@@ -0,0 +1,126 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "WebSocketConnection.h"
+
+#include <span>
+
+#include <wpi/SpanExtras.h>
+#include <wpinet/WebSocket.h>
+
+using namespace nt;
+using namespace nt::net;
+
+static constexpr size_t kAllocSize = 4096;
+static constexpr size_t kTextFrameRolloverSize = 4096;
+static constexpr size_t kBinaryFrameRolloverSize = 8192;
+
+WebSocketConnection::WebSocketConnection(wpi::WebSocket& ws)
+    : m_ws{ws},
+      m_text_os{m_text_buffers, [this] { return AllocBuf(); }},
+      m_binary_os{m_binary_buffers, [this] { return AllocBuf(); }} {}
+
+WebSocketConnection::~WebSocketConnection() {
+  for (auto&& buf : m_buf_pool) {
+    buf.Deallocate();
+  }
+}
+
+void WebSocketConnection::Flush() {
+  FinishSendText();
+  FinishSendBinary();
+  if (m_frames.empty()) {
+    return;
+  }
+
+  // convert internal frames into WS frames
+  m_ws_frames.clear();
+  m_ws_frames.reserve(m_frames.size());
+  for (auto&& frame : m_frames) {
+    m_ws_frames.emplace_back(frame.opcode,
+                             std::span{frame.bufs->begin() + frame.start,
+                                       frame.bufs->begin() + frame.end});
+  }
+
+  ++m_sendsActive;
+  m_ws.SendFrames(m_ws_frames, [selfweak = weak_from_this()](auto bufs, auto) {
+    if (auto self = selfweak.lock()) {
+      self->m_buf_pool.insert(self->m_buf_pool.end(), bufs.begin(), bufs.end());
+      if (self->m_sendsActive > 0) {
+        --self->m_sendsActive;
+      }
+    }
+  });
+  m_frames.clear();
+  m_text_buffers.clear();
+  m_binary_buffers.clear();
+  m_text_pos = 0;
+  m_binary_pos = 0;
+}
+
+void WebSocketConnection::Disconnect(std::string_view reason) {
+  m_ws.Close(1005, reason);
+}
+
+void WebSocketConnection::StartSendText() {
+  // limit amount per single frame
+  size_t total = 0;
+  for (size_t i = m_text_pos; i < m_text_buffers.size(); ++i) {
+    total += m_text_buffers[i].len;
+  }
+  if (total >= kTextFrameRolloverSize) {
+    FinishSendText();
+  }
+
+  if (m_in_text) {
+    m_text_os << ',';
+  } else {
+    m_text_os << '[';
+    m_in_text = true;
+  }
+}
+
+void WebSocketConnection::FinishSendText() {
+  if (m_in_text) {
+    m_text_os << ']';
+    m_in_text = false;
+  }
+  if (m_text_pos >= m_text_buffers.size()) {
+    return;
+  }
+  m_frames.emplace_back(wpi::WebSocket::Frame::kText, &m_text_buffers,
+                        m_text_pos, m_text_buffers.size());
+  m_text_pos = m_text_buffers.size();
+  m_text_os.reset();
+}
+
+void WebSocketConnection::StartSendBinary() {
+  // limit amount per single frame
+  size_t total = 0;
+  for (size_t i = m_binary_pos; i < m_binary_buffers.size(); ++i) {
+    total += m_binary_buffers[i].len;
+  }
+  if (total >= kBinaryFrameRolloverSize) {
+    FinishSendBinary();
+  }
+}
+
+void WebSocketConnection::FinishSendBinary() {
+  if (m_binary_pos >= m_binary_buffers.size()) {
+    return;
+  }
+  m_frames.emplace_back(wpi::WebSocket::Frame::kBinary, &m_binary_buffers,
+                        m_binary_pos, m_binary_buffers.size());
+  m_binary_pos = m_binary_buffers.size();
+  m_binary_os.reset();
+}
+
+wpi::uv::Buffer WebSocketConnection::AllocBuf() {
+  if (!m_buf_pool.empty()) {
+    auto buf = m_buf_pool.back();
+    m_buf_pool.pop_back();
+    return buf;
+  }
+  return wpi::uv::Buffer::Allocate(kAllocSize);
+}
diff --git a/ntcore/src/main/native/cpp/net/WebSocketConnection.h b/ntcore/src/main/native/cpp/net/WebSocketConnection.h
new file mode 100644
index 0000000..ba15215
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WebSocketConnection.h
@@ -0,0 +1,69 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include <wpi/SmallVector.h>
+#include <wpinet/WebSocket.h>
+#include <wpinet/raw_uv_ostream.h>
+#include <wpinet/uv/Buffer.h>
+
+#include "WireConnection.h"
+
+namespace nt::net {
+
+class WebSocketConnection final
+    : public WireConnection,
+      public std::enable_shared_from_this<WebSocketConnection> {
+ public:
+  explicit WebSocketConnection(wpi::WebSocket& ws);
+  ~WebSocketConnection() override;
+  WebSocketConnection(const WebSocketConnection&) = delete;
+  WebSocketConnection& operator=(const WebSocketConnection&) = delete;
+
+  bool Ready() const final { return m_sendsActive == 0; }
+
+  TextWriter SendText() final { return {m_text_os, *this}; }
+  BinaryWriter SendBinary() final { return {m_binary_os, *this}; }
+
+  void Flush() final;
+
+  void Disconnect(std::string_view reason) final;
+
+ private:
+  void StartSendText() final;
+  void FinishSendText() final;
+  void StartSendBinary() final;
+  void FinishSendBinary() final;
+
+  wpi::uv::Buffer AllocBuf();
+
+  wpi::WebSocket& m_ws;
+  // Can't use WS frames directly as span could have dangling pointers
+  struct Frame {
+    Frame(uint8_t opcode, wpi::SmallVectorImpl<wpi::uv::Buffer>* bufs,
+          size_t start, size_t end)
+        : opcode{opcode}, bufs{bufs}, start{start}, end{end} {}
+    uint8_t opcode;
+    wpi::SmallVectorImpl<wpi::uv::Buffer>* bufs;
+    size_t start;
+    size_t end;
+  };
+  std::vector<Frame> m_frames;
+  std::vector<wpi::WebSocket::Frame> m_ws_frames;  // to reduce allocs
+  wpi::SmallVector<wpi::uv::Buffer, 4> m_text_buffers;
+  wpi::SmallVector<wpi::uv::Buffer, 4> m_binary_buffers;
+  std::vector<wpi::uv::Buffer> m_buf_pool;
+  wpi::raw_uv_ostream m_text_os;
+  wpi::raw_uv_ostream m_binary_os;
+  size_t m_text_pos = 0;
+  size_t m_binary_pos = 0;
+  bool m_in_text = false;
+  int m_sendsActive = 0;
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/WireConnection.h b/ntcore/src/main/native/cpp/net/WireConnection.h
new file mode 100644
index 0000000..2a79a12
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WireConnection.h
@@ -0,0 +1,110 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <string_view>
+
+#include <wpi/raw_ostream.h>
+
+namespace nt::net {
+
+class BinaryWriter;
+class TextWriter;
+
+class WireConnection {
+  friend class TextWriter;
+  friend class BinaryWriter;
+
+ public:
+  virtual ~WireConnection() = default;
+
+  virtual bool Ready() const = 0;
+
+  virtual TextWriter SendText() = 0;
+
+  virtual BinaryWriter SendBinary() = 0;
+
+  virtual void Flush() = 0;
+
+  virtual void Disconnect(std::string_view reason) = 0;
+
+ protected:
+  virtual void StartSendText() = 0;
+  virtual void FinishSendText() = 0;
+  virtual void StartSendBinary() = 0;
+  virtual void FinishSendBinary() = 0;
+};
+
+class TextWriter {
+ public:
+  TextWriter(wpi::raw_ostream& os, WireConnection& wire)
+      : m_os{&os}, m_wire{&wire} {}
+  TextWriter(const TextWriter&) = delete;
+  TextWriter(TextWriter&& rhs) : m_os{rhs.m_os}, m_wire{rhs.m_wire} {
+    rhs.m_os = nullptr;
+    rhs.m_wire = nullptr;
+  }
+  TextWriter& operator=(const TextWriter&) = delete;
+  TextWriter& operator=(TextWriter&& rhs) {
+    m_os = rhs.m_os;
+    m_wire = rhs.m_wire;
+    rhs.m_os = nullptr;
+    rhs.m_wire = nullptr;
+    return *this;
+  }
+  ~TextWriter() {
+    if (m_os) {
+      m_wire->FinishSendText();
+    }
+  }
+
+  wpi::raw_ostream& Add() {
+    m_wire->StartSendText();
+    return *m_os;
+  }
+  WireConnection& wire() { return *m_wire; }
+
+ private:
+  wpi::raw_ostream* m_os;
+  WireConnection* m_wire;
+};
+
+class BinaryWriter {
+ public:
+  BinaryWriter(wpi::raw_ostream& os, WireConnection& wire)
+      : m_os{&os}, m_wire{&wire} {}
+  BinaryWriter(const BinaryWriter&) = delete;
+  BinaryWriter(BinaryWriter&& rhs) : m_os{rhs.m_os}, m_wire{rhs.m_wire} {
+    rhs.m_os = nullptr;
+    rhs.m_wire = nullptr;
+  }
+  BinaryWriter& operator=(const BinaryWriter&) = delete;
+  BinaryWriter& operator=(BinaryWriter&& rhs) {
+    m_os = rhs.m_os;
+    m_wire = rhs.m_wire;
+    rhs.m_os = nullptr;
+    rhs.m_wire = nullptr;
+    return *this;
+  }
+  ~BinaryWriter() {
+    if (m_wire) {
+      m_wire->FinishSendBinary();
+    }
+  }
+
+  wpi::raw_ostream& Add() {
+    m_wire->StartSendBinary();
+    return *m_os;
+  }
+  WireConnection& wire() { return *m_wire; }
+
+ private:
+  wpi::raw_ostream* m_os;
+  WireConnection* m_wire;
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/WireDecoder.cpp b/ntcore/src/main/native/cpp/net/WireDecoder.cpp
new file mode 100644
index 0000000..e6474b2
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WireDecoder.cpp
@@ -0,0 +1,567 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "WireDecoder.h"
+
+#include <algorithm>
+
+#include <fmt/format.h>
+#include <wpi/Logger.h>
+#include <wpi/SpanExtras.h>
+#include <wpi/json.h>
+#include <wpi/mpack.h>
+
+#include "Message.h"
+
+using namespace nt;
+using namespace nt::net;
+using namespace mpack;
+
+static bool GetNumber(wpi::json& val, double* num) {
+  if (auto v = val.get_ptr<const int64_t*>()) {
+    *num = *v;
+  } else if (auto v = val.get_ptr<const uint64_t*>()) {
+    *num = *v;
+  } else if (auto v = val.get_ptr<const double*>()) {
+    *num = *v;
+  } else {
+    return false;
+  }
+  return true;
+}
+
+static bool GetNumber(wpi::json& val, int64_t* num) {
+  if (auto v = val.get_ptr<const int64_t*>()) {
+    *num = *v;
+  } else if (auto v = val.get_ptr<const uint64_t*>()) {
+    *num = *v;
+  } else {
+    return false;
+  }
+  return true;
+}
+
+static std::string* ObjGetString(wpi::json::object_t& obj, std::string_view key,
+                                 std::string* error) {
+  auto it = obj.find(key);
+  if (it == obj.end()) {
+    *error = fmt::format("no {} key", key);
+    return nullptr;
+  }
+  auto val = it->second.get_ptr<std::string*>();
+  if (!val) {
+    *error = fmt::format("{} must be a string", key);
+  }
+  return val;
+}
+
+static bool ObjGetNumber(wpi::json::object_t& obj, std::string_view key,
+                         std::string* error, int64_t* num) {
+  auto it = obj.find(key);
+  if (it == obj.end()) {
+    *error = fmt::format("no {} key", key);
+    return false;
+  }
+  if (!GetNumber(it->second, num)) {
+    *error = fmt::format("{} must be a number", key);
+    return false;
+  }
+  return true;
+}
+
+static bool ObjGetStringArray(wpi::json::object_t& obj, std::string_view key,
+                              std::string* error,
+                              std::vector<std::string>* out) {
+  // prefixes
+  auto it = obj.find(key);
+  if (it == obj.end()) {
+    *error = fmt::format("no {} key", key);
+    return false;
+  }
+  auto jarr = it->second.get_ptr<wpi::json::array_t*>();
+  if (!jarr) {
+    *error = fmt::format("{} must be an array", key);
+    return false;
+  }
+  out->resize(0);
+  out->reserve(jarr->size());
+  for (auto&& jval : *jarr) {
+    auto str = jval.get_ptr<std::string*>();
+    if (!str) {
+      *error = fmt::format("{}/{} must be a string", key, out->size());
+      return false;
+    }
+    out->emplace_back(std::move(*str));
+  }
+  return true;
+}
+
+// avoid a fmtlib "unused type alias 'char_type'" warning false positive
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-local-typedef"
+#endif
+
+template <typename T>
+static void WireDecodeTextImpl(std::string_view in, T& out,
+                               wpi::Logger& logger) {
+  static_assert(std::is_same_v<T, ClientMessageHandler> ||
+                    std::is_same_v<T, ServerMessageHandler>,
+                "T must be ClientMessageHandler or ServerMessageHandler");
+
+  wpi::json j;
+  try {
+    j = wpi::json::parse(in);
+  } catch (wpi::json::parse_error& err) {
+    WPI_WARNING(logger, "could not decode JSON message: {}", err.what());
+    return;
+  }
+
+  if (!j.is_array()) {
+    WPI_WARNING(logger, "expected JSON array at top level");
+    return;
+  }
+
+  int i = -1;
+  for (auto&& jmsg : j) {
+    ++i;
+    std::string error;
+    {
+      auto obj = jmsg.get_ptr<wpi::json::object_t*>();
+      if (!obj) {
+        error = "expected message to be an object";
+        goto err;
+      }
+
+      auto method = ObjGetString(*obj, "method", &error);
+      if (!method) {
+        goto err;
+      }
+
+      auto paramsIt = obj->find("params");
+      if (paramsIt == obj->end()) {
+        error = "no params key";
+        goto err;
+      }
+      auto params = paramsIt->second.get_ptr<wpi::json::object_t*>();
+      if (!params) {
+        error = "params must be an object";
+        goto err;
+      }
+
+      if constexpr (std::is_same_v<T, ClientMessageHandler>) {
+        if (*method == PublishMsg::kMethodStr) {
+          // name
+          auto name = ObjGetString(*params, "name", &error);
+          if (!name) {
+            goto err;
+          }
+
+          // type
+          auto typeStr = ObjGetString(*params, "type", &error);
+          if (!typeStr) {
+            goto err;
+          }
+
+          // pubuid
+          int64_t pubuid;
+          if (!ObjGetNumber(*params, "pubuid", &error, &pubuid)) {
+            goto err;
+          }
+
+          // properties; allow missing (treated as empty)
+          wpi::json* properties = nullptr;
+          auto propertiesIt = params->find("properties");
+          if (propertiesIt != params->end()) {
+            properties = &propertiesIt->second;
+            if (!properties->is_object()) {
+              error = "properties must be an object";
+              goto err;
+            }
+          }
+          wpi::json propertiesEmpty;
+          if (!properties) {
+            propertiesEmpty = wpi::json::object();
+            properties = &propertiesEmpty;
+          }
+
+          // complete
+          out.ClientPublish(pubuid, *name, *typeStr, *properties);
+        } else if (*method == UnpublishMsg::kMethodStr) {
+          // pubuid
+          int64_t pubuid;
+          if (!ObjGetNumber(*params, "pubuid", &error, &pubuid)) {
+            goto err;
+          }
+
+          // complete
+          out.ClientUnpublish(pubuid);
+        } else if (*method == SetPropertiesMsg::kMethodStr) {
+          // name
+          auto name = ObjGetString(*params, "name", &error);
+          if (!name) {
+            goto err;
+          }
+
+          // update
+          auto updateIt = params->find("update");
+          if (updateIt == params->end()) {
+            error = "no update key";
+            goto err;
+          }
+          auto update = &updateIt->second;
+          if (!update->is_object()) {
+            error = "update must be an object";
+            goto err;
+          }
+
+          // complete
+          out.ClientSetProperties(*name, *update);
+        } else if (*method == SubscribeMsg::kMethodStr) {
+          // subuid
+          int64_t subuid;
+          if (!ObjGetNumber(*params, "subuid", &error, &subuid)) {
+            goto err;
+          }
+
+          // options
+          PubSubOptionsImpl options;
+          auto optionsIt = params->find("options");
+          if (optionsIt != params->end()) {
+            auto joptions = optionsIt->second.get_ptr<wpi::json::object_t*>();
+            if (!joptions) {
+              error = "options must be an object";
+              goto err;
+            }
+
+            // periodic
+            auto periodicIt = joptions->find("periodic");
+            if (periodicIt != joptions->end()) {
+              double val;
+              if (!GetNumber(periodicIt->second, &val)) {
+                error = "periodic value must be a number";
+                goto err;
+              }
+              options.periodic = val;
+              options.periodicMs = val * 1000;
+            }
+
+            // send all changes
+            auto sendAllIt = joptions->find("all");
+            if (sendAllIt != joptions->end()) {
+              auto sendAll = sendAllIt->second.get_ptr<bool*>();
+              if (!sendAll) {
+                error = "all value must be a boolean";
+                goto err;
+              }
+              options.sendAll = *sendAll;
+            }
+
+            // topics only
+            auto topicsOnlyIt = joptions->find("topicsonly");
+            if (topicsOnlyIt != joptions->end()) {
+              auto topicsOnly = topicsOnlyIt->second.get_ptr<bool*>();
+              if (!topicsOnly) {
+                error = "topicsonly value must be a boolean";
+                goto err;
+              }
+              options.topicsOnly = *topicsOnly;
+            }
+
+            // prefix match
+            auto prefixMatchIt = joptions->find("prefix");
+            if (prefixMatchIt != joptions->end()) {
+              auto prefixMatch = prefixMatchIt->second.get_ptr<bool*>();
+              if (!prefixMatch) {
+                error = "prefix value must be a boolean";
+                goto err;
+              }
+              options.prefixMatch = *prefixMatch;
+            }
+          }
+
+          // topic names
+          std::vector<std::string> topicNames;
+          if (!ObjGetStringArray(*params, "topics", &error, &topicNames)) {
+            goto err;
+          }
+
+          // complete
+          out.ClientSubscribe(subuid, topicNames, options);
+        } else if (*method == UnsubscribeMsg::kMethodStr) {
+          // subuid
+          int64_t subuid;
+          if (!ObjGetNumber(*params, "subuid", &error, &subuid)) {
+            goto err;
+          }
+
+          // complete
+          out.ClientUnsubscribe(subuid);
+        } else {
+          error = fmt::format("unrecognized method '{}'", *method);
+          goto err;
+        }
+      } else if constexpr (std::is_same_v<T, ServerMessageHandler>) {
+        if (*method == AnnounceMsg::kMethodStr) {
+          // name
+          auto name = ObjGetString(*params, "name", &error);
+          if (!name) {
+            goto err;
+          }
+
+          // id
+          int64_t id;
+          if (!ObjGetNumber(*params, "id", &error, &id)) {
+            goto err;
+          }
+
+          // type
+          auto typeStr = ObjGetString(*params, "type", &error);
+          if (!typeStr) {
+            goto err;
+          }
+
+          // pubuid
+          std::optional<int64_t> pubuid;
+          auto pubuidIt = params->find("pubuid");
+          if (pubuidIt != params->end()) {
+            int64_t val;
+            if (!GetNumber(pubuidIt->second, &val)) {
+              error = "pubuid value must be a number";
+              goto err;
+            }
+            pubuid = val;
+          }
+
+          // properties
+          auto propertiesIt = params->find("properties");
+          if (propertiesIt == params->end()) {
+            error = "no properties key";
+            goto err;
+          }
+          auto properties = &propertiesIt->second;
+          if (!properties->is_object()) {
+            WPI_WARNING(logger, "{}: properties is not an object", *name);
+            *properties = wpi::json::object();
+          }
+
+          // complete
+          out.ServerAnnounce(*name, id, *typeStr, *properties, pubuid);
+        } else if (*method == UnannounceMsg::kMethodStr) {
+          // name
+          auto name = ObjGetString(*params, "name", &error);
+          if (!name) {
+            goto err;
+          }
+
+          // id
+          int64_t id;
+          if (!ObjGetNumber(*params, "id", &error, &id)) {
+            goto err;
+          }
+
+          // complete
+          out.ServerUnannounce(*name, id);
+        } else if (*method == PropertiesUpdateMsg::kMethodStr) {
+          // name
+          auto name = ObjGetString(*params, "name", &error);
+          if (!name) {
+            goto err;
+          }
+
+          // update
+          auto updateIt = params->find("update");
+          if (updateIt == params->end()) {
+            error = "no update key";
+            goto err;
+          }
+          auto update = &updateIt->second;
+          if (!update->is_object()) {
+            error = "update must be an object";
+            goto err;
+          }
+
+          bool ack = false;
+          auto ackIt = params->find("ack");
+          if (ackIt != params->end()) {
+            auto val = ackIt->second.get_ptr<bool*>();
+            if (!val) {
+              error = "ack must be a boolean";
+              goto err;
+            }
+            ack = *val;
+          }
+
+          // complete
+          out.ServerPropertiesUpdate(*name, *update, ack);
+        } else {
+          error = fmt::format("unrecognized method '{}'", *method);
+          goto err;
+        }
+      }
+      continue;
+    }
+  err:
+    WPI_WARNING(logger, "{}: {}", i, error);
+  }
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+void nt::net::WireDecodeText(std::string_view in, ClientMessageHandler& out,
+                             wpi::Logger& logger) {
+  ::WireDecodeTextImpl(in, out, logger);
+}
+
+void nt::net::WireDecodeText(std::string_view in, ServerMessageHandler& out,
+                             wpi::Logger& logger) {
+  ::WireDecodeTextImpl(in, out, logger);
+}
+
+bool nt::net::WireDecodeBinary(std::span<const uint8_t>* in, int64_t* outId,
+                               Value* outValue, std::string* error,
+                               int64_t localTimeOffset) {
+  mpack_reader_t reader;
+  mpack_reader_init_data(&reader, reinterpret_cast<const char*>(in->data()),
+                         in->size());
+  mpack_expect_array_match(&reader, 4);
+  *outId = mpack_expect_i64(&reader);
+  auto time = mpack_expect_i64(&reader);
+  int type = mpack_expect_int(&reader);
+  switch (type) {
+    case 0:  // boolean
+      *outValue = Value::MakeBoolean(mpack_expect_bool(&reader), 1);
+      break;
+    case 2:  // integer
+      *outValue = Value::MakeInteger(mpack_expect_i64(&reader), 1);
+      break;
+    case 3:  // float
+      *outValue = Value::MakeFloat(mpack_expect_float(&reader), 1);
+      break;
+    case 1:  // double
+      *outValue = Value::MakeDouble(mpack_expect_double(&reader), 1);
+      break;
+    case 4: {  // string
+      auto length = mpack_expect_str(&reader);
+      auto data = mpack_read_bytes_inplace(&reader, length);
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue = Value::MakeString({data, length}, 1);
+      }
+      mpack_done_str(&reader);
+      break;
+    }
+    case 5: {  // raw
+      auto length = mpack_expect_bin(&reader);
+      auto data = mpack_read_bytes_inplace(&reader, length);
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue =
+            Value::MakeRaw({reinterpret_cast<const uint8_t*>(data), length}, 1);
+      }
+      mpack_done_bin(&reader);
+      break;
+    }
+    case 16: {  // boolean array
+      auto length = mpack_expect_array(&reader);
+      std::vector<int> arr;
+      arr.reserve((std::min)(length, 1000u));
+      for (uint32_t i = 0; i < length; ++i) {
+        arr.emplace_back(mpack_expect_bool(&reader));
+        if (mpack_reader_error(&reader) != mpack_ok) {
+          break;
+        }
+      }
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue = Value::MakeBooleanArray(std::move(arr), 1);
+      }
+      mpack_done_array(&reader);
+      break;
+    }
+    case 18: {  // integer array
+      auto length = mpack_expect_array(&reader);
+      std::vector<int64_t> arr;
+      arr.reserve((std::min)(length, 1000u));
+      for (uint32_t i = 0; i < length; ++i) {
+        arr.emplace_back(mpack_expect_i64(&reader));
+        if (mpack_reader_error(&reader) != mpack_ok) {
+          break;
+        }
+      }
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue = Value::MakeIntegerArray(std::move(arr), 1);
+      }
+      mpack_done_array(&reader);
+      break;
+    }
+    case 19: {  // float array
+      auto length = mpack_expect_array(&reader);
+      std::vector<float> arr;
+      arr.reserve((std::min)(length, 1000u));
+      for (uint32_t i = 0; i < length; ++i) {
+        arr.emplace_back(mpack_expect_float(&reader));
+        if (mpack_reader_error(&reader) != mpack_ok) {
+          break;
+        }
+      }
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue = Value::MakeFloatArray(std::move(arr), 1);
+      }
+      mpack_done_array(&reader);
+      break;
+    }
+    case 17: {  // double array
+      auto length = mpack_expect_array(&reader);
+      std::vector<double> arr;
+      arr.reserve((std::min)(length, 1000u));
+      for (uint32_t i = 0; i < length; ++i) {
+        arr.emplace_back(mpack_expect_double(&reader));
+        if (mpack_reader_error(&reader) != mpack_ok) {
+          break;
+        }
+      }
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue = Value::MakeDoubleArray(std::move(arr), 1);
+      }
+      mpack_done_array(&reader);
+      break;
+    }
+    case 20: {  // string array
+      auto length = mpack_expect_array(&reader);
+      std::vector<std::string> arr;
+      arr.reserve((std::min)(length, 1000u));
+      for (uint32_t i = 0; i < length; ++i) {
+        auto length = mpack_expect_str(&reader);
+        auto data = mpack_read_bytes_inplace(&reader, length);
+        if (mpack_reader_error(&reader) == mpack_ok) {
+          arr.emplace_back(std::string{data, length});
+        } else {
+          break;
+        }
+        mpack_done_str(&reader);
+      }
+      if (mpack_reader_error(&reader) == mpack_ok) {
+        *outValue = Value::MakeStringArray(std::move(arr), 1);
+      }
+      mpack_done_array(&reader);
+      break;
+    }
+    default:
+      *error = fmt::format("unrecognized type {}", type);
+      return false;
+  }
+  mpack_done_array(&reader);
+  auto err = mpack_reader_destroy(&reader);
+  if (err != mpack_ok) {
+    *error = mpack_error_to_string(err);
+    return false;
+  }
+  // set time
+  outValue->SetServerTime(time);
+  outValue->SetTime(time == 0 ? 0 : time + localTimeOffset);
+  // update input range
+  *in = wpi::drop_front(*in,
+                        in->size() - mpack_reader_remaining(&reader, nullptr));
+  return true;
+}
diff --git a/ntcore/src/main/native/cpp/net/WireDecoder.h b/ntcore/src/main/native/cpp/net/WireDecoder.h
new file mode 100644
index 0000000..128dff2
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WireDecoder.h
@@ -0,0 +1,64 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+
+namespace wpi {
+class Logger;
+class json;
+}  // namespace wpi
+
+namespace nt {
+class PubSubOptionsImpl;
+class Value;
+}  // namespace nt
+
+namespace nt::net {
+
+class ClientMessageHandler {
+ public:
+  virtual ~ClientMessageHandler() = default;
+
+  virtual void ClientPublish(int64_t pubuid, std::string_view name,
+                             std::string_view typeStr,
+                             const wpi::json& properties) = 0;
+  virtual void ClientUnpublish(int64_t pubuid) = 0;
+  virtual void ClientSetProperties(std::string_view name,
+                                   const wpi::json& update) = 0;
+  virtual void ClientSubscribe(int64_t subuid,
+                               std::span<const std::string> topicNames,
+                               const PubSubOptionsImpl& options) = 0;
+  virtual void ClientUnsubscribe(int64_t subuid) = 0;
+};
+
+class ServerMessageHandler {
+ public:
+  virtual ~ServerMessageHandler() = default;
+  virtual void ServerAnnounce(std::string_view name, int64_t id,
+                              std::string_view typeStr,
+                              const wpi::json& properties,
+                              std::optional<int64_t> pubuid) = 0;
+  virtual void ServerUnannounce(std::string_view name, int64_t id) = 0;
+  virtual void ServerPropertiesUpdate(std::string_view name,
+                                      const wpi::json& update, bool ack) = 0;
+};
+
+void WireDecodeText(std::string_view in, ClientMessageHandler& out,
+                    wpi::Logger& logger);
+void WireDecodeText(std::string_view in, ServerMessageHandler& out,
+                    wpi::Logger& logger);
+
+// returns true if successfully decoded a message
+bool WireDecodeBinary(std::span<const uint8_t>* in, int64_t* outId,
+                      Value* outValue, std::string* error,
+                      int64_t localTimeOffset);
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net/WireEncoder.cpp b/ntcore/src/main/native/cpp/net/WireEncoder.cpp
new file mode 100644
index 0000000..143fe0d
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WireEncoder.cpp
@@ -0,0 +1,316 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "WireEncoder.h"
+
+#include <optional>
+
+#include <wpi/json_serializer.h>
+#include <wpi/mpack.h>
+#include <wpi/raw_ostream.h>
+
+#include "Handle.h"
+#include "Message.h"
+#include "PubSubOptions.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace nt;
+using namespace nt::net;
+using namespace mpack;
+
+void nt::net::WireEncodePublish(wpi::raw_ostream& os, int64_t pubuid,
+                                std::string_view name, std::string_view typeStr,
+                                const wpi::json& properties) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << PublishMsg::kMethodStr << "\",\"params\":{";
+  os << "\"name\":\"";
+  s.dump_escaped(name, false);
+  os << "\",\"properties\":";
+  s.dump(properties, false, false, 0, 0);
+  os << ",\"pubuid\":";
+  s.dump_integer(pubuid);
+  os << ",\"type\":\"";
+  s.dump_escaped(typeStr, false);
+  os << "\"}}";
+}
+
+void nt::net::WireEncodeUnpublish(wpi::raw_ostream& os, int64_t pubuid) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << UnpublishMsg::kMethodStr << "\",\"params\":{";
+  os << "\"pubuid\":";
+  s.dump_integer(pubuid);
+  os << "}}";
+}
+
+void nt::net::WireEncodeSetProperties(wpi::raw_ostream& os,
+                                      std::string_view name,
+                                      const wpi::json& update) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << SetPropertiesMsg::kMethodStr << "\",\"params\":{";
+  os << "\"name\":\"";
+  s.dump_escaped(name, false);
+  os << "\",\"update\":";
+  s.dump(update, false, false, 0, 0);
+  os << "}}";
+}
+
+template <typename T>
+static void EncodePrefixes(wpi::raw_ostream& os, std::span<const T> topicNames,
+                           wpi::json::serializer& s) {
+  os << '[';
+  bool first = true;
+  for (auto&& name : topicNames) {
+    if (first) {
+      first = false;
+    } else {
+      os << ',';
+    }
+    os << '"';
+    s.dump_escaped(name, false);
+    os << '"';
+  }
+  os << ']';
+}
+
+template <typename T>
+static void WireEncodeSubscribeImpl(wpi::raw_ostream& os, int64_t subuid,
+                                    std::span<const T> topicNames,
+                                    const PubSubOptionsImpl& options) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << SubscribeMsg::kMethodStr << "\",\"params\":{";
+  os << "\"options\":{";
+  bool first = true;
+  if (options.sendAll) {
+    os << "\"all\":true";
+    first = false;
+  }
+  if (options.topicsOnly) {
+    if (!first) {
+      os << ',';
+    }
+    os << "\"topicsonly\":true";
+    first = false;
+  }
+  if (options.prefixMatch) {
+    if (!first) {
+      os << ',';
+    }
+    os << "\"prefix\":true";
+    first = false;
+  }
+  if (options.periodicMs != PubSubOptionsImpl::kDefaultPeriodicMs) {
+    if (!first) {
+      os << ',';
+    }
+    os << "\"periodic\":";
+    s.dump_float(options.periodicMs / 1000.0);
+  }
+  os << "},\"topics\":";
+  EncodePrefixes(os, topicNames, s);
+  os << ",\"subuid\":";
+  s.dump_integer(subuid);
+  os << "}}";
+}
+
+void nt::net::WireEncodeSubscribe(wpi::raw_ostream& os, int64_t subuid,
+                                  std::span<const std::string_view> topicNames,
+                                  const PubSubOptionsImpl& options) {
+  WireEncodeSubscribeImpl(os, subuid, topicNames, options);
+}
+
+void nt::net::WireEncodeSubscribe(wpi::raw_ostream& os, int64_t subuid,
+                                  std::span<const std::string> topicNames,
+                                  const PubSubOptionsImpl& options) {
+  WireEncodeSubscribeImpl(os, subuid, topicNames, options);
+}
+
+void nt::net::WireEncodeUnsubscribe(wpi::raw_ostream& os, int64_t subHandle) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << UnsubscribeMsg::kMethodStr << "\",\"params\":{";
+  os << "\"subuid\":";
+  s.dump_integer(subHandle);
+  os << "}}";
+}
+
+bool nt::net::WireEncodeText(wpi::raw_ostream& os, const ClientMessage& msg) {
+  if (auto m = std::get_if<PublishMsg>(&msg.contents)) {
+    WireEncodePublish(os, Handle{m->pubHandle}.GetIndex(), m->name, m->typeStr,
+                      m->properties);
+  } else if (auto m = std::get_if<UnpublishMsg>(&msg.contents)) {
+    WireEncodeUnpublish(os, Handle{m->pubHandle}.GetIndex());
+  } else if (auto m = std::get_if<SetPropertiesMsg>(&msg.contents)) {
+    WireEncodeSetProperties(os, m->name, m->update);
+  } else if (auto m = std::get_if<SubscribeMsg>(&msg.contents)) {
+    WireEncodeSubscribe(os, Handle{m->subHandle}.GetIndex(), m->topicNames,
+                        m->options);
+  } else if (auto m = std::get_if<UnsubscribeMsg>(&msg.contents)) {
+    WireEncodeUnsubscribe(os, Handle{m->subHandle}.GetIndex());
+  } else {
+    return false;
+  }
+  return true;
+}
+
+void nt::net::WireEncodeAnnounce(wpi::raw_ostream& os, std::string_view name,
+                                 int64_t id, std::string_view typeStr,
+                                 const wpi::json& properties,
+                                 std::optional<int64_t> pubHandle) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << AnnounceMsg::kMethodStr << "\",\"params\":{";
+  os << "\"id\":";
+  s.dump_integer(id);
+  os << ",\"name\":\"";
+  s.dump_escaped(name, false);
+  os << "\",\"properties\":";
+  s.dump(properties, false, false, 0, 0);
+  if (pubHandle) {
+    os << ",\"pubuid\":";
+    s.dump_integer(*pubHandle);
+  }
+  os << ",\"type\":\"";
+  s.dump_escaped(typeStr, false);
+  os << "\"}}";
+}
+
+void nt::net::WireEncodeUnannounce(wpi::raw_ostream& os, std::string_view name,
+                                   int64_t id) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << UnannounceMsg::kMethodStr << "\",\"params\":{";
+  os << "\"id\":";
+  s.dump_integer(id);
+  os << ",\"name\":\"";
+  s.dump_escaped(name, false);
+  os << "\"}}";
+}
+
+void nt::net::WireEncodePropertiesUpdate(wpi::raw_ostream& os,
+                                         std::string_view name,
+                                         const wpi::json& update, bool ack) {
+  wpi::json::serializer s{os, ' ', 0};
+  os << "{\"method\":\"" << PropertiesUpdateMsg::kMethodStr
+     << "\",\"params\":{";
+  os << "\"name\":\"";
+  s.dump_escaped(name, false);
+  os << "\",\"update\":";
+  s.dump(update, false, false, 0, 0);
+  if (ack) {
+    os << ",\"ack\":true";
+  }
+  os << "}}";
+}
+
+bool nt::net::WireEncodeText(wpi::raw_ostream& os, const ServerMessage& msg) {
+  if (auto m = std::get_if<AnnounceMsg>(&msg.contents)) {
+    WireEncodeAnnounce(os, m->name, m->id, m->typeStr, m->properties,
+                       m->pubuid);
+  } else if (auto m = std::get_if<UnannounceMsg>(&msg.contents)) {
+    WireEncodeUnannounce(os, m->name, m->id);
+  } else if (auto m = std::get_if<PropertiesUpdateMsg>(&msg.contents)) {
+    WireEncodePropertiesUpdate(os, m->name, m->update, m->ack);
+  } else {
+    return false;
+  }
+  return true;
+}
+
+bool nt::net::WireEncodeBinary(wpi::raw_ostream& os, int64_t id, int64_t time,
+                               const Value& value) {
+  char buf[128];
+  mpack_writer_t writer;
+  mpack_writer_init(&writer, buf, sizeof(buf));
+  mpack_writer_set_context(&writer, &os);
+  mpack_writer_set_flush(
+      &writer, [](mpack_writer_t* writer, const char* buffer, size_t count) {
+        static_cast<wpi::raw_ostream*>(writer->context)->write(buffer, count);
+      });
+  mpack_start_array(&writer, 4);
+  mpack_write_int(&writer, id);
+  mpack_write_int(&writer, time);
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      mpack_write_u8(&writer, 0);
+      mpack_write_bool(&writer, value.GetBoolean());
+      break;
+    case NT_INTEGER:
+      mpack_write_u8(&writer, 2);
+      mpack_write_int(&writer, value.GetInteger());
+      break;
+    case NT_FLOAT:
+      mpack_write_u8(&writer, 3);
+      mpack_write_float(&writer, value.GetFloat());
+      break;
+    case NT_DOUBLE:
+      mpack_write_u8(&writer, 1);
+      mpack_write_double(&writer, value.GetDouble());
+      break;
+    case NT_STRING: {
+      auto v = value.GetString();
+      mpack_write_u8(&writer, 4);
+      mpack_write_str(&writer, v.data(), v.size());
+      break;
+    }
+    case NT_RPC:
+    case NT_RAW: {
+      auto v = value.GetRaw();
+      mpack_write_u8(&writer, 5);
+      mpack_write_bin(&writer, reinterpret_cast<const char*>(v.data()),
+                      v.size());
+      break;
+    }
+    case NT_BOOLEAN_ARRAY: {
+      auto v = value.GetBooleanArray();
+      mpack_write_u8(&writer, 16);
+      mpack_start_array(&writer, v.size());
+      for (auto val : v) {
+        mpack_write_bool(&writer, val);
+      }
+      mpack_finish_array(&writer);
+      break;
+    }
+    case NT_INTEGER_ARRAY: {
+      auto v = value.GetIntegerArray();
+      mpack_write_u8(&writer, 18);
+      mpack_start_array(&writer, v.size());
+      for (auto val : v) {
+        mpack_write_int(&writer, val);
+      }
+      mpack_finish_array(&writer);
+      break;
+    }
+    case NT_FLOAT_ARRAY: {
+      auto v = value.GetFloatArray();
+      mpack_write_u8(&writer, 19);
+      mpack_start_array(&writer, v.size());
+      for (auto val : v) {
+        mpack_write_float(&writer, val);
+      }
+      mpack_finish_array(&writer);
+      break;
+    }
+    case NT_DOUBLE_ARRAY: {
+      auto v = value.GetDoubleArray();
+      mpack_write_u8(&writer, 17);
+      mpack_start_array(&writer, v.size());
+      for (auto val : v) {
+        mpack_write_double(&writer, val);
+      }
+      mpack_finish_array(&writer);
+      break;
+    }
+    case NT_STRING_ARRAY: {
+      auto v = value.GetStringArray();
+      mpack_write_u8(&writer, 20);
+      mpack_start_array(&writer, v.size());
+      for (auto&& val : v) {
+        mpack_write_str(&writer, val.data(), val.size());
+      }
+      mpack_finish_array(&writer);
+      break;
+    }
+    default:
+      return false;
+  }
+  mpack_finish_array(&writer);
+  return mpack_writer_destroy(&writer) == mpack_ok;
+}
diff --git a/ntcore/src/main/native/cpp/net/WireEncoder.h b/ntcore/src/main/native/cpp/net/WireEncoder.h
new file mode 100644
index 0000000..d0a04cb
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net/WireEncoder.h
@@ -0,0 +1,61 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+
+namespace wpi {
+class json;
+class raw_ostream;
+}  // namespace wpi
+
+namespace nt {
+class PubSubOptionsImpl;
+class Value;
+}  // namespace nt
+
+namespace nt::net {
+
+struct ClientMessage;
+struct ServerMessage;
+
+// encoders for client text messages (avoids need to construct a Message struct)
+void WireEncodePublish(wpi::raw_ostream& os, int64_t pubuid,
+                       std::string_view name, std::string_view typeStr,
+                       const wpi::json& properties);
+void WireEncodeUnpublish(wpi::raw_ostream& os, int64_t pubuid);
+void WireEncodeSetProperties(wpi::raw_ostream& os, std::string_view name,
+                             const wpi::json& update);
+void WireEncodeSubscribe(wpi::raw_ostream& os, int64_t subuid,
+                         std::span<const std::string_view> topicNames,
+                         const PubSubOptionsImpl& options);
+void WireEncodeSubscribe(wpi::raw_ostream& os, int64_t subuid,
+                         std::span<const std::string> topicNames,
+                         const PubSubOptionsImpl& options);
+void WireEncodeUnsubscribe(wpi::raw_ostream& os, int64_t subuid);
+
+// encoders for server text messages (avoids need to construct a Message struct)
+void WireEncodeAnnounce(wpi::raw_ostream& os, std::string_view name, int64_t id,
+                        std::string_view typeStr, const wpi::json& properties,
+                        std::optional<int64_t> pubuid);
+void WireEncodeUnannounce(wpi::raw_ostream& os, std::string_view name,
+                          int64_t id);
+void WireEncodePropertiesUpdate(wpi::raw_ostream& os, std::string_view name,
+                                const wpi::json& update, bool ack);
+
+// Encode a single message; note text messages must be put into a
+// JSON array "[msg1, msg2]" for transmission.
+// Returns true if message was written
+bool WireEncodeText(wpi::raw_ostream& os, const ClientMessage& msg);
+bool WireEncodeText(wpi::raw_ostream& os, const ServerMessage& msg);
+
+// encoder for binary messages
+bool WireEncodeBinary(wpi::raw_ostream& os, int64_t id, int64_t time,
+                      const Value& value);
+
+}  // namespace nt::net
diff --git a/ntcore/src/main/native/cpp/net3/ClientImpl3.cpp b/ntcore/src/main/native/cpp/net3/ClientImpl3.cpp
new file mode 100644
index 0000000..0783865
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/ClientImpl3.cpp
@@ -0,0 +1,642 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "ClientImpl3.h"
+
+#include <algorithm>
+#include <numeric>
+#include <string>
+#include <vector>
+
+#include <fmt/format.h>
+#include <wpi/DenseMap.h>
+#include <wpi/StringMap.h>
+#include <wpi/json.h>
+
+#include "Handle.h"
+#include "Log.h"
+#include "Types_internal.h"
+#include "net/Message.h"
+#include "net/NetworkInterface.h"
+#include "net3/Message3.h"
+#include "net3/SequenceNumber.h"
+#include "net3/WireConnection3.h"
+#include "net3/WireDecoder3.h"
+#include "net3/WireEncoder3.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace nt;
+using namespace nt::net3;
+
+static constexpr uint32_t kMinPeriodMs = 5;
+
+// maximum number of times the wire can be not ready to send another
+// transmission before we close the connection
+static constexpr int kWireMaxNotReady = 10;
+
+namespace {
+
+struct Entry;
+
+struct PublisherData {
+  explicit PublisherData(Entry* entry) : entry{entry} {}
+
+  Entry* entry;
+  NT_Publisher handle;
+  PubSubOptionsImpl options;
+  // in options as double, but copy here as integer; rounded to the nearest
+  // 10 ms
+  uint32_t periodMs;
+  uint64_t nextSendMs{0};
+  std::vector<Value> outValues;  // outgoing values
+};
+
+// data for each entry
+struct Entry {
+  explicit Entry(std::string_view name_) : name(name_) {}
+  bool IsPersistent() const { return (flags & NT_PERSISTENT) != 0; }
+  wpi::json SetFlags(unsigned int flags_);
+
+  std::string name;
+
+  std::string typeStr;
+  NT_Type type{NT_UNASSIGNED};
+
+  wpi::json properties = wpi::json::object();
+
+  // The current value and flags
+  Value value;
+  unsigned int flags{0};
+
+  // Unique ID used in network messages; this is 0xffff until assigned
+  // by the server.
+  unsigned int id{0xffff};
+
+  // Sequence number for update resolution
+  SequenceNumber seqNum;
+
+  // Local topic handle
+  NT_Topic topic{0};
+
+  // Local publishers
+  std::vector<PublisherData*> publishers;
+};
+
+class CImpl : public MessageHandler3 {
+ public:
+  CImpl(uint64_t curTimeMs, int inst, WireConnection3& wire,
+        wpi::Logger& logger,
+        std::function<void(uint32_t repeatMs)> setPeriodic);
+
+  void ProcessIncoming(std::span<const uint8_t> data);
+  void HandleLocal(std::span<const net::ClientMessage> msgs);
+  void SendPeriodic(uint64_t curTimeMs, bool initial);
+  void SendValue(Writer& out, Entry* entry, const Value& value);
+  bool CheckNetworkReady();
+
+  // Outgoing handlers
+  void Publish(NT_Publisher pubHandle, NT_Topic topicHandle,
+               std::string_view name, std::string_view typeStr,
+               const wpi::json& properties, const PubSubOptionsImpl& options);
+  void Unpublish(NT_Publisher pubHandle, NT_Topic topicHandle);
+  void SetProperties(NT_Topic topicHandle, std::string_view name,
+                     const wpi::json& update);
+  void SetValue(NT_Publisher pubHandle, const Value& value);
+
+  // MessageHandler interface
+  void KeepAlive() final;
+  void ServerHelloDone() final;
+  void ClientHelloDone() final;
+  void ClearEntries() final;
+  void ProtoUnsup(unsigned int proto_rev) final;
+  void ClientHello(std::string_view self_id, unsigned int proto_rev) final;
+  void ServerHello(unsigned int flags, std::string_view self_id) final;
+  void EntryAssign(std::string_view name, unsigned int id, unsigned int seq_num,
+                   const Value& value, unsigned int flags) final;
+  void EntryUpdate(unsigned int id, unsigned int seq_num,
+                   const Value& value) final;
+  void FlagsUpdate(unsigned int id, unsigned int flags) final;
+  void EntryDelete(unsigned int id) final;
+  void ExecuteRpc(unsigned int id, unsigned int uid,
+                  std::span<const uint8_t> params) final {}
+  void RpcResponse(unsigned int id, unsigned int uid,
+                   std::span<const uint8_t> result) final {}
+
+  enum State {
+    kStateInitial,
+    kStateHelloSent,
+    kStateInitialAssignments,
+    kStateRunning
+  };
+
+  int m_inst;
+  WireConnection3& m_wire;
+  wpi::Logger& m_logger;
+  net::LocalInterface* m_local{nullptr};
+  std::function<void(uint32_t repeatMs)> m_setPeriodic;
+  uint64_t m_initTimeMs;
+
+  // periodic sweep handling
+  static constexpr uint32_t kKeepAliveIntervalMs = 1000;
+  uint32_t m_periodMs{kKeepAliveIntervalMs + 10};
+  uint64_t m_lastSendMs{0};
+  uint64_t m_nextKeepAliveTimeMs;
+  int m_notReadyCount{0};
+
+  // indexed by publisher index
+  std::vector<std::unique_ptr<PublisherData>> m_publishers;
+
+  State m_state{kStateInitial};
+  WireDecoder3 m_decoder;
+  std::string m_remoteId;
+  std::function<void()> m_handshakeSucceeded;
+
+  std::vector<std::pair<unsigned int, unsigned int>> m_outgoingFlags;
+
+  using NameMap = wpi::StringMap<std::unique_ptr<Entry>>;
+  using IdMap = std::vector<Entry*>;
+
+  NameMap m_nameMap;
+  IdMap m_idMap;
+
+  Entry* GetOrNewEntry(std::string_view name) {
+    auto& entry = m_nameMap[name];
+    if (!entry) {
+      entry = std::make_unique<Entry>(name);
+    }
+    return entry.get();
+  }
+  Entry* LookupId(unsigned int id) {
+    return id < m_idMap.size() ? m_idMap[id] : nullptr;
+  }
+};
+
+}  // namespace
+
+wpi::json Entry::SetFlags(unsigned int flags_) {
+  bool wasPersistent = IsPersistent();
+  flags = flags_;
+  bool isPersistent = IsPersistent();
+  if (isPersistent && !wasPersistent) {
+    properties["persistent"] = true;
+    return {{"persistent", true}};
+  } else if (!isPersistent && wasPersistent) {
+    properties.erase("persistent");
+    return {{"persistent", wpi::json()}};
+  } else {
+    return wpi::json::object();
+  }
+}
+
+CImpl::CImpl(uint64_t curTimeMs, int inst, WireConnection3& wire,
+             wpi::Logger& logger,
+             std::function<void(uint32_t repeatMs)> setPeriodic)
+    : m_inst{inst},
+      m_wire{wire},
+      m_logger{logger},
+      m_setPeriodic{std::move(setPeriodic)},
+      m_initTimeMs{curTimeMs},
+      m_nextKeepAliveTimeMs{curTimeMs + kKeepAliveIntervalMs},
+      m_decoder{*this} {}
+
+void CImpl::ProcessIncoming(std::span<const uint8_t> data) {
+  DEBUG4("received {} bytes", data.size());
+  if (!m_decoder.Execute(&data)) {
+    m_wire.Disconnect(m_decoder.GetError());
+  }
+}
+
+void CImpl::HandleLocal(std::span<const net::ClientMessage> msgs) {
+  for (const auto& elem : msgs) {  // NOLINT
+    // common case is value
+    if (auto msg = std::get_if<net::ClientValueMsg>(&elem.contents)) {
+      SetValue(msg->pubHandle, msg->value);
+    } else if (auto msg = std::get_if<net::PublishMsg>(&elem.contents)) {
+      Publish(msg->pubHandle, msg->topicHandle, msg->name, msg->typeStr,
+              msg->properties, msg->options);
+    } else if (auto msg = std::get_if<net::UnpublishMsg>(&elem.contents)) {
+      Unpublish(msg->pubHandle, msg->topicHandle);
+    } else if (auto msg = std::get_if<net::SetPropertiesMsg>(&elem.contents)) {
+      SetProperties(msg->topicHandle, msg->name, msg->update);
+    }
+  }
+}
+
+void CImpl::SendPeriodic(uint64_t curTimeMs, bool initial) {
+  DEBUG4("SendPeriodic({})", curTimeMs);
+
+  // rate limit sends
+  if (curTimeMs < (m_lastSendMs + kMinPeriodMs)) {
+    return;
+  }
+
+  auto out = m_wire.Send();
+
+  // send keep-alives
+  if (curTimeMs >= m_nextKeepAliveTimeMs) {
+    if (!CheckNetworkReady()) {
+      return;
+    }
+    DEBUG4("Sending keep alive");
+    WireEncodeKeepAlive(out.stream());
+    // drift isn't critical here, so just go from current time
+    m_nextKeepAliveTimeMs = curTimeMs + kKeepAliveIntervalMs;
+  }
+
+  // send any stored-up flags updates
+  if (!m_outgoingFlags.empty()) {
+    if (!CheckNetworkReady()) {
+      return;
+    }
+    for (auto&& p : m_outgoingFlags) {
+      WireEncodeFlagsUpdate(out.stream(), p.first, p.second);
+    }
+    m_outgoingFlags.resize(0);
+  }
+
+  // send any pending updates due to be sent
+  bool checkedNetwork = false;
+  for (auto&& pub : m_publishers) {
+    if (pub && !pub->outValues.empty() && curTimeMs >= pub->nextSendMs) {
+      if (!checkedNetwork) {
+        if (!CheckNetworkReady()) {
+          return;
+        }
+        checkedNetwork = true;
+      }
+      for (auto&& val : pub->outValues) {
+        SendValue(out, pub->entry, val);
+      }
+      pub->outValues.resize(0);
+      pub->nextSendMs = curTimeMs + pub->periodMs;
+    }
+  }
+
+  if (initial) {
+    DEBUG4("Sending ClientHelloDone");
+    WireEncodeClientHelloDone(out.stream());
+  }
+
+  m_wire.Flush();
+  m_lastSendMs = curTimeMs;
+}
+
+void CImpl::SendValue(Writer& out, Entry* entry, const Value& value) {
+  DEBUG4("sending value for '{}', seqnum {}", entry->name,
+         entry->seqNum.value());
+
+  // bump sequence number
+  ++entry->seqNum;
+
+  // only send assigns during initial handshake
+  if (entry->id == 0xffff || m_state == kStateInitialAssignments) {
+    // send assign
+    WireEncodeEntryAssign(out.stream(), entry->name, entry->id,
+                          entry->seqNum.value(), value, entry->flags);
+  } else {
+    // send update
+    WireEncodeEntryUpdate(out.stream(), entry->id, entry->seqNum.value(),
+                          value);
+  }
+}
+
+bool CImpl::CheckNetworkReady() {
+  if (!m_wire.Ready()) {
+    ++m_notReadyCount;
+    if (m_notReadyCount > kWireMaxNotReady) {
+      m_wire.Disconnect("transmit stalled");
+    }
+    return false;
+  }
+  m_notReadyCount = 0;
+  return true;
+}
+
+void CImpl::Publish(NT_Publisher pubHandle, NT_Topic topicHandle,
+                    std::string_view name, std::string_view typeStr,
+                    const wpi::json& properties,
+                    const PubSubOptionsImpl& options) {
+  DEBUG4("Publish('{}', '{}')", name, typeStr);
+  unsigned int index = Handle{pubHandle}.GetIndex();
+  if (index >= m_publishers.size()) {
+    m_publishers.resize(index + 1);
+  }
+  auto& publisher = m_publishers[index];
+  if (!publisher) {
+    publisher = std::make_unique<PublisherData>(GetOrNewEntry(name));
+    publisher->entry->typeStr = typeStr;
+    publisher->entry->type = StringToType3(typeStr);
+    publisher->entry->publishers.emplace_back(publisher.get());
+  }
+  publisher->handle = pubHandle;
+  publisher->options = options;
+  publisher->periodMs = std::lround(options.periodicMs / 10.0) * 10;
+  if (publisher->periodMs < 10) {
+    publisher->periodMs = 10;
+  }
+
+  // update period
+  m_periodMs = std::gcd(m_periodMs, publisher->periodMs);
+  m_setPeriodic(m_periodMs);
+}
+
+void CImpl::Unpublish(NT_Publisher pubHandle, NT_Topic topicHandle) {
+  DEBUG4("Unpublish({}, {})", pubHandle, topicHandle);
+  unsigned int index = Handle{pubHandle}.GetIndex();
+  if (index >= m_publishers.size()) {
+    return;
+  }
+  auto& publisher = m_publishers[index];
+  publisher->entry->publishers.erase(
+      std::remove(publisher->entry->publishers.begin(),
+                  publisher->entry->publishers.end(), publisher.get()),
+      publisher->entry->publishers.end());
+  publisher.reset();
+
+  // loop over all publishers to update period
+  m_periodMs = kKeepAliveIntervalMs + 10;
+  for (auto&& pub : m_publishers) {
+    if (pub) {
+      m_periodMs = std::gcd(m_periodMs, pub->periodMs);
+    }
+  }
+  m_setPeriodic(m_periodMs);
+}
+
+void CImpl::SetProperties(NT_Topic topicHandle, std::string_view name,
+                          const wpi::json& update) {
+  DEBUG4("SetProperties({}, {}, {})", topicHandle, name, update.dump());
+  auto entry = GetOrNewEntry(name);
+  bool updated = false;
+  for (auto&& elem : update.items()) {
+    entry->properties[elem.key()] = elem.value();
+    if (elem.key() == "persistent") {
+      if (auto val = elem.value().get_ptr<const bool*>()) {
+        if (*val) {
+          entry->flags |= NT_PERSISTENT;
+        } else {
+          entry->flags &= ~NT_PERSISTENT;
+        }
+        updated = true;
+      }
+    }
+  }
+  if (updated && entry->id == 0xffff) {
+    m_outgoingFlags.emplace_back(entry->id, entry->flags);
+  }
+}
+
+void CImpl::SetValue(NT_Publisher pubHandle, const Value& value) {
+  DEBUG4("SetValue({})", pubHandle);
+  unsigned int index = Handle{pubHandle}.GetIndex();
+  assert(index < m_publishers.size() && m_publishers[index]);
+  auto& publisher = *m_publishers[index];
+  if (value == publisher.entry->value) {
+    return;
+  }
+  publisher.entry->value = value;
+  if (publisher.outValues.empty() || publisher.options.sendAll) {
+    publisher.outValues.emplace_back(value);
+  } else {
+    publisher.outValues.back() = value;
+  }
+}
+
+void CImpl::KeepAlive() {
+  DEBUG4("KeepAlive()");
+  if (m_state != kStateRunning && m_state != kStateInitialAssignments) {
+    m_decoder.SetError("received unexpected KeepAlive message");
+    return;
+  }
+  // ignore
+}
+
+void CImpl::ServerHelloDone() {
+  DEBUG4("ServerHelloDone()");
+  if (m_state != kStateInitialAssignments) {
+    m_decoder.SetError("received unexpected ServerHelloDone message");
+    return;
+  }
+
+  // send initial assignments
+  SendPeriodic(m_initTimeMs, true);
+
+  m_state = kStateRunning;
+  m_setPeriodic(m_periodMs);
+}
+
+void CImpl::ClientHelloDone() {
+  DEBUG4("ClientHelloDone()");
+  m_decoder.SetError("received unexpected ClientHelloDone message");
+}
+
+void CImpl::ProtoUnsup(unsigned int proto_rev) {
+  DEBUG4("ProtoUnsup({})", proto_rev);
+  m_decoder.SetError(fmt::format("received ProtoUnsup(version={})", proto_rev));
+}
+
+void CImpl::ClientHello(std::string_view self_id, unsigned int proto_rev) {
+  DEBUG4("ClientHello({}, {})", self_id, proto_rev);
+  m_decoder.SetError("received unexpected ClientHello message");
+}
+
+void CImpl::ServerHello(unsigned int flags, std::string_view self_id) {
+  DEBUG4("ServerHello({}, {})", flags, self_id);
+  if (m_state != kStateHelloSent) {
+    m_decoder.SetError("received unexpected ServerHello message");
+    return;
+  }
+  m_state = kStateInitialAssignments;
+  m_remoteId = self_id;
+  m_handshakeSucceeded();
+  m_handshakeSucceeded = nullptr;  // no longer required
+}
+
+void CImpl::EntryAssign(std::string_view name, unsigned int id,
+                        unsigned int seq_num, const Value& value,
+                        unsigned int flags) {
+  DEBUG4("EntryAssign({}, {}, {}, value, {})", name, id, seq_num, flags);
+  if (m_state != kStateInitialAssignments && m_state != kStateRunning) {
+    m_decoder.SetError("received unexpected EntryAssign message");
+    return;
+  }
+  auto entry = GetOrNewEntry(name);
+  bool flagsChanged = entry->flags != flags;
+  bool typeChanged;
+  bool valueChanged;
+
+  // don't update value if we locally published a "strong" value
+  if (m_state == kStateInitialAssignments && entry->value &&
+      entry->value.server_time() != 0) {
+    typeChanged = false;
+    valueChanged = false;
+  } else {
+    typeChanged = entry->type != value.type();
+    valueChanged = entry->value != value;
+    if (m_state == kStateInitialAssignments) {
+      // remove outgoing during initial assignments so we don't get out of sync
+      for (auto publisher : entry->publishers) {
+        publisher->outValues.clear();
+      }
+    }
+  }
+
+  entry->id = id;
+  entry->seqNum = SequenceNumber{seq_num};
+  entry->SetFlags(flags);
+  if (typeChanged) {
+    entry->type = value.type();
+    entry->typeStr = TypeToString(value.type());
+  }
+  if (valueChanged) {
+    entry->value = value;
+  }
+
+  // add to id map
+  if (id >= m_idMap.size()) {
+    m_idMap.resize(id + 1);
+  }
+  m_idMap[id] = entry;
+
+  if (m_local) {
+    // XXX: need to handle type change specially? (e.g. with unannounce)
+    if (entry->topic == 0 || flagsChanged || typeChanged) {
+      DEBUG4("NetworkAnnounce({}, {})", name, entry->typeStr);
+      entry->topic =
+          m_local->NetworkAnnounce(name, entry->typeStr, entry->properties, 0);
+    }
+    if (valueChanged) {
+      m_local->NetworkSetValue(entry->topic, entry->value);
+    }
+  }
+}
+
+void CImpl::EntryUpdate(unsigned int id, unsigned int seq_num,
+                        const Value& value) {
+  DEBUG4("EntryUpdate({}, {}, value)", id, seq_num);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received EntryUpdate message before ServerHelloDone");
+    return;
+  }
+  if (auto entry = LookupId(id)) {
+    entry->value = value;
+    if (m_local && entry->topic != 0) {
+      m_local->NetworkSetValue(entry->topic, entry->value);
+    }
+  }
+}
+
+void CImpl::FlagsUpdate(unsigned int id, unsigned int flags) {
+  DEBUG4("FlagsUpdate({}, {})", id, flags);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received FlagsUpdate message before ServerHelloDone");
+    return;
+  }
+  if (auto entry = LookupId(id)) {
+    wpi::json update = entry->SetFlags(flags);
+    if (!update.empty() && m_local) {
+      m_local->NetworkPropertiesUpdate(entry->name, update, false);
+    }
+  }
+
+  // erase any outgoing flags updates
+  m_outgoingFlags.erase(
+      std::remove_if(m_outgoingFlags.begin(), m_outgoingFlags.end(),
+                     [&](const auto& p) { return p.first == id; }),
+      m_outgoingFlags.end());
+}
+
+void CImpl::EntryDelete(unsigned int id) {
+  DEBUG4("EntryDelete({})", id);
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received EntryDelete message before ServerHelloDone");
+    return;
+  }
+  if (auto entry = LookupId(id)) {
+    m_idMap[id] = nullptr;
+    // set id to 0xffff so any future local setvalue will result in assign
+    entry->id = 0xffff;
+    entry->value = Value{};
+
+    // if we have no local publishers, unannounce
+    if (entry->publishers.empty() && m_local) {
+      m_local->NetworkUnannounce(entry->name);
+    }
+  }
+
+  // erase any outgoing flags updates
+  m_outgoingFlags.erase(
+      std::remove_if(m_outgoingFlags.begin(), m_outgoingFlags.end(),
+                     [&](const auto& p) { return p.first == id; }),
+      m_outgoingFlags.end());
+}
+
+void CImpl::ClearEntries() {
+  DEBUG4("ClearEntries()");
+  if (m_state != kStateRunning) {
+    m_decoder.SetError("received ClearEntries message before ServerHelloDone");
+    return;
+  }
+  for (auto& entry : m_idMap) {
+    if (entry && entry->id != 0xffff && !entry->IsPersistent()) {
+      entry->id = 0xffff;
+      entry->value = Value{};
+
+      // if we have no local publishers, unannounce
+      if (entry->publishers.empty() && m_local) {
+        m_local->NetworkUnannounce(entry->name);
+      }
+
+      entry = nullptr;  // clear id mapping
+    }
+  }
+
+  // erase all outgoing flags updates
+  m_outgoingFlags.resize(0);
+}
+
+class ClientImpl3::Impl final : public CImpl {
+ public:
+  Impl(uint64_t curTimeMs, int inst, WireConnection3& wire, wpi::Logger& logger,
+       std::function<void(uint32_t repeatMs)> setPeriodic)
+      : CImpl{curTimeMs, inst, wire, logger, std::move(setPeriodic)} {}
+};
+
+ClientImpl3::ClientImpl3(uint64_t curTimeMs, int inst, WireConnection3& wire,
+                         wpi::Logger& logger,
+                         std::function<void(uint32_t repeatMs)> setPeriodic)
+    : m_impl{std::make_unique<Impl>(curTimeMs, inst, wire, logger,
+                                    std::move(setPeriodic))} {}
+
+ClientImpl3::~ClientImpl3() {
+  WPI_DEBUG4(m_impl->m_logger, "NT3 ClientImpl destroyed");
+}
+
+void ClientImpl3::Start(std::string_view selfId,
+                        std::function<void()> succeeded) {
+  if (m_impl->m_state != CImpl::kStateInitial) {
+    return;
+  }
+  m_impl->m_handshakeSucceeded = std::move(succeeded);
+  auto writer = m_impl->m_wire.Send();
+  WireEncodeClientHello(writer.stream(), selfId, 0x0300);
+  m_impl->m_wire.Flush();
+  m_impl->m_state = CImpl::kStateHelloSent;
+}
+
+void ClientImpl3::ProcessIncoming(std::span<const uint8_t> data) {
+  m_impl->ProcessIncoming(data);
+}
+
+void ClientImpl3::HandleLocal(std::span<const net::ClientMessage> msgs) {
+  m_impl->HandleLocal(msgs);
+}
+
+void ClientImpl3::SendPeriodic(uint64_t curTimeMs) {
+  m_impl->SendPeriodic(curTimeMs, false);
+}
+
+void ClientImpl3::SetLocal(net::LocalInterface* local) {
+  m_impl->m_local = local;
+}
diff --git a/ntcore/src/main/native/cpp/net3/ClientImpl3.h b/ntcore/src/main/native/cpp/net3/ClientImpl3.h
new file mode 100644
index 0000000..484ea3d
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/ClientImpl3.h
@@ -0,0 +1,50 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <span>
+#include <string>
+#include <string_view>
+
+#include "net/NetworkInterface.h"
+
+namespace wpi {
+class Logger;
+}  // namespace wpi
+
+namespace nt::net {
+struct ClientMessage;
+class LocalInterface;
+}  // namespace nt::net
+
+namespace nt::net3 {
+
+class WireConnection3;
+
+class ClientImpl3 {
+ public:
+  explicit ClientImpl3(uint64_t curTimeMs, int inst, WireConnection3& wire,
+                       wpi::Logger& logger,
+                       std::function<void(uint32_t repeatMs)> setPeriodic);
+  ~ClientImpl3();
+
+  void Start(std::string_view selfId, std::function<void()> succeeded);
+  void ProcessIncoming(std::span<const uint8_t> data);
+  void HandleLocal(std::span<const net::ClientMessage> msgs);
+
+  void SendPeriodic(uint64_t curTimeMs);
+
+  void SetLocal(net::LocalInterface* local);
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/net3/Message3.h b/ntcore/src/main/native/cpp/net3/Message3.h
new file mode 100644
index 0000000..ebac75f
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/Message3.h
@@ -0,0 +1,156 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <string>
+
+#include "networktables/NetworkTableValue.h"
+#include "ntcore_c.h"
+
+namespace nt::net3 {
+
+class WireDecoder3;
+
+class Message3 {
+  struct private_init {};
+  friend class WireDecoder3;
+
+ 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
+  };
+  enum DataType {
+    kBoolean = 0x00,
+    kDouble = 0x01,
+    kString = 0x02,
+    kRaw = 0x03,
+    kBooleanArray = 0x10,
+    kDoubleArray = 0x11,
+    kStringArray = 0x12,
+    kRpcDef = 0x20
+  };
+  static constexpr uint32_t kClearAllMagic = 0xD06CB27Aul;
+
+  Message3() = default;
+  Message3(MsgType type, const private_init&) : m_type(type) {}
+
+  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.
+  std::string_view str() const { return m_str; }
+  std::span<const uint8_t> bytes() const {
+    return {reinterpret_cast<const uint8_t*>(m_str.data()), m_str.size()};
+  }
+  const 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; }
+
+  void SetValue(const Value& value) { m_value = value; }
+
+  // Create messages without data
+  static Message3 KeepAlive() { return {kKeepAlive, {}}; }
+  static Message3 ServerHelloDone() { return {kServerHelloDone, {}}; }
+  static Message3 ClientHelloDone() { return {kClientHelloDone, {}}; }
+  static Message3 ClearEntries() { return {kClearEntries, {}}; }
+
+  // Create messages with data
+  static Message3 ProtoUnsup(unsigned int proto_rev = 0x0300u) {
+    Message3 msg{kProtoUnsup, {}};
+    msg.m_id = proto_rev;
+    return msg;
+  }
+  static Message3 ClientHello(std::string_view self_id,
+                              unsigned int proto_rev = 0x0300u) {
+    Message3 msg{kClientHello, {}};
+    msg.m_str = self_id;
+    msg.m_id = proto_rev;
+    return msg;
+  }
+  static Message3 ServerHello(unsigned int flags, std::string_view self_id) {
+    Message3 msg{kServerHello, {}};
+    msg.m_str = self_id;
+    msg.m_flags = flags;
+    return msg;
+  }
+  static Message3 EntryAssign(std::string_view name, unsigned int id,
+                              unsigned int seq_num, const Value& value,
+                              unsigned int flags) {
+    Message3 msg{kEntryAssign, {}};
+    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;
+  }
+  static Message3 EntryUpdate(unsigned int id, unsigned int seq_num,
+                              const Value& value) {
+    Message3 msg{kEntryUpdate, {}};
+    msg.m_value = value;
+    msg.m_id = id;
+    msg.m_seq_num_uid = seq_num;
+    return msg;
+  }
+  static Message3 FlagsUpdate(unsigned int id, unsigned int flags) {
+    Message3 msg{kFlagsUpdate, {}};
+    msg.m_id = id;
+    msg.m_flags = flags;
+    return msg;
+  }
+  static Message3 EntryDelete(unsigned int id) {
+    Message3 msg{kEntryDelete, {}};
+    msg.m_id = id;
+    return msg;
+  }
+  static Message3 ExecuteRpc(unsigned int id, unsigned int uid,
+                             std::span<const uint8_t> params) {
+    Message3 msg{kExecuteRpc, {}};
+    msg.m_str.assign(reinterpret_cast<const char*>(params.data()),
+                     params.size());
+    msg.m_id = id;
+    msg.m_seq_num_uid = uid;
+    return msg;
+  }
+  static Message3 RpcResponse(unsigned int id, unsigned int uid,
+                              std::span<const uint8_t> result) {
+    Message3 msg{kRpcResponse, {}};
+    msg.m_str.assign(reinterpret_cast<const char*>(result.data()),
+                     result.size());
+    msg.m_id = id;
+    msg.m_seq_num_uid = uid;
+    return msg;
+  }
+
+ private:
+  MsgType m_type{kUnknown};
+
+  // Message data.  Use varies by message type.
+  std::string m_str;
+  Value m_value;
+  unsigned int m_id{0};  // also used for proto_rev
+  unsigned int m_flags{0};
+  unsigned int m_seq_num_uid{0};
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/net3/SequenceNumber.h b/ntcore/src/main/native/cpp/net3/SequenceNumber.h
new file mode 100644
index 0000000..d8bf995
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/SequenceNumber.h
@@ -0,0 +1,38 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <compare>
+
+namespace nt::net3 {
+
+/* A sequence number per RFC 1982 */
+class SequenceNumber {
+ public:
+  SequenceNumber() = default;
+  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 auto operator<=>(const SequenceNumber& lhs,
+                          const SequenceNumber& rhs) = default;
+
+ private:
+  unsigned int m_value{0};
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/net3/UvStreamConnection3.cpp b/ntcore/src/main/native/cpp/net3/UvStreamConnection3.cpp
new file mode 100644
index 0000000..93af700
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/UvStreamConnection3.cpp
@@ -0,0 +1,52 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "UvStreamConnection3.h"
+
+#include <wpinet/uv/Stream.h>
+
+using namespace nt;
+using namespace nt::net3;
+
+UvStreamConnection3::UvStreamConnection3(wpi::uv::Stream& stream)
+    : m_stream{stream}, m_os{m_buffers, [this] { return AllocBuf(); }} {}
+
+UvStreamConnection3::~UvStreamConnection3() {
+  for (auto&& buf : m_buf_pool) {
+    buf.Deallocate();
+  }
+}
+
+void UvStreamConnection3::Flush() {
+  if (m_buffers.empty()) {
+    return;
+  }
+  ++m_sendsActive;
+  m_stream.Write(m_buffers, [selfweak = weak_from_this()](auto bufs, auto) {
+    if (auto self = selfweak.lock()) {
+      self->m_buf_pool.insert(self->m_buf_pool.end(), bufs.begin(), bufs.end());
+      if (self->m_sendsActive > 0) {
+        --self->m_sendsActive;
+      }
+    }
+  });
+  m_buffers.clear();
+  m_os.reset();
+}
+
+void UvStreamConnection3::Disconnect(std::string_view reason) {
+  m_reason = reason;
+  m_stream.Close();
+}
+
+void UvStreamConnection3::FinishSend() {}
+
+wpi::uv::Buffer UvStreamConnection3::AllocBuf() {
+  if (!m_buf_pool.empty()) {
+    auto buf = m_buf_pool.back();
+    m_buf_pool.pop_back();
+    return buf;
+  }
+  return wpi::uv::Buffer::Allocate(kAllocSize);
+}
diff --git a/ntcore/src/main/native/cpp/net3/UvStreamConnection3.h b/ntcore/src/main/native/cpp/net3/UvStreamConnection3.h
new file mode 100644
index 0000000..f94c4a3
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/UvStreamConnection3.h
@@ -0,0 +1,60 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include <wpi/SmallVector.h>
+#include <wpinet/raw_uv_ostream.h>
+#include <wpinet/uv/Buffer.h>
+
+#include "net3/WireConnection3.h"
+
+namespace wpi::uv {
+class Stream;
+}  // namespace wpi::uv
+
+namespace nt::net3 {
+
+class UvStreamConnection3 final
+    : public WireConnection3,
+      public std::enable_shared_from_this<UvStreamConnection3> {
+  static constexpr size_t kAllocSize = 4096;
+
+ public:
+  explicit UvStreamConnection3(wpi::uv::Stream& stream);
+  ~UvStreamConnection3() override;
+  UvStreamConnection3(const UvStreamConnection3&) = delete;
+  UvStreamConnection3& operator=(const UvStreamConnection3&) = delete;
+
+  bool Ready() const final { return m_sendsActive == 0; }
+
+  Writer Send() final { return {m_os, *this}; }
+
+  void Flush() final;
+
+  void Disconnect(std::string_view reason) final;
+
+  std::string_view GetDisconnectReason() const { return m_reason; }
+
+  wpi::uv::Stream& GetStream() { return m_stream; }
+
+ private:
+  void FinishSend() final;
+
+  wpi::uv::Buffer AllocBuf();
+
+  wpi::uv::Stream& m_stream;
+  wpi::SmallVector<wpi::uv::Buffer, 4> m_buffers;
+  std::vector<wpi::uv::Buffer> m_buf_pool;
+  wpi::raw_uv_ostream m_os;
+  std::string m_reason;
+  int m_sendsActive = 0;
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/net3/WireConnection3.h b/ntcore/src/main/native/cpp/net3/WireConnection3.h
new file mode 100644
index 0000000..85453d7
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/WireConnection3.h
@@ -0,0 +1,65 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <string_view>
+
+namespace wpi {
+class raw_ostream;
+}  // namespace wpi
+
+namespace nt::net3 {
+
+class Writer;
+
+class WireConnection3 {
+  friend class Writer;
+
+ public:
+  virtual ~WireConnection3() = default;
+
+  virtual bool Ready() const = 0;
+
+  virtual Writer Send() = 0;
+
+  virtual void Flush() = 0;
+
+  virtual void Disconnect(std::string_view reason) = 0;
+
+ protected:
+  virtual void FinishSend() = 0;
+};
+
+class Writer {
+ public:
+  Writer(wpi::raw_ostream& os, WireConnection3& wire)
+      : m_os{&os}, m_wire{&wire} {}
+  Writer(const Writer&) = delete;
+  Writer(Writer&& rhs) : m_os{rhs.m_os}, m_wire{rhs.m_wire} {
+    rhs.m_os = nullptr;
+    rhs.m_wire = nullptr;
+  }
+  ~Writer() {
+    if (m_wire) {
+      m_wire->FinishSend();
+    }
+  }
+  Writer& operator=(const Writer&) = delete;
+  Writer& operator=(Writer&& rhs) {
+    m_os = rhs.m_os;
+    m_wire = rhs.m_wire;
+    rhs.m_os = nullptr;
+    rhs.m_wire = nullptr;
+    return *this;
+  }
+
+  wpi::raw_ostream& stream() { return *m_os; }
+
+ private:
+  wpi::raw_ostream* m_os;
+  WireConnection3* m_wire;
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/net3/WireDecoder3.cpp b/ntcore/src/main/native/cpp/net3/WireDecoder3.cpp
new file mode 100644
index 0000000..ea08358
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/WireDecoder3.cpp
@@ -0,0 +1,600 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "WireDecoder3.h"
+
+#include <algorithm>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <fmt/format.h>
+#include <wpi/MathExtras.h>
+#include <wpi/SpanExtras.h>
+#include <wpi/leb128.h>
+
+#include "Message3.h"
+
+using namespace nt;
+using namespace nt::net3;
+
+namespace {
+
+class SimpleValueReader {
+ public:
+  std::optional<uint16_t> Read16(std::span<const uint8_t>* in);
+  std::optional<uint32_t> Read32(std::span<const uint8_t>* in);
+  std::optional<uint64_t> Read64(std::span<const uint8_t>* in);
+  std::optional<double> ReadDouble(std::span<const uint8_t>* in);
+
+ private:
+  uint64_t m_value = 0;
+  int m_count = 0;
+};
+
+struct StringReader {
+  void SetLen(uint64_t len_) {
+    len = len_;
+    buf.clear();
+  }
+
+  std::optional<uint64_t> len;
+  std::string buf;
+};
+
+struct RawReader {
+  void SetLen(uint64_t len_) {
+    len = len_;
+    buf.clear();
+  }
+
+  std::optional<uint64_t> len;
+  std::vector<uint8_t> buf;
+};
+
+struct ValueReader {
+  ValueReader() = default;
+  explicit ValueReader(NT_Type type_) : type{type_} {}
+
+  void SetSize(uint32_t size_) {
+    haveSize = true;
+    size = size_;
+    ints.clear();
+    doubles.clear();
+    strings.clear();
+  }
+
+  NT_Type type = NT_UNASSIGNED;
+  bool haveSize = false;
+  uint32_t size = 0;
+  std::vector<int> ints;
+  std::vector<double> doubles;
+  std::vector<std::string> strings;
+};
+
+struct WDImpl {
+  explicit WDImpl(MessageHandler3& out) : m_out{out} {}
+
+  MessageHandler3& m_out;
+
+  // primary (message) decode state
+  enum {
+    kStart,
+    kClientHello_1ProtoRev,
+    kClientHello_2Id,
+    kProtoUnsup_1ProtoRev,
+    kServerHello_1Flags,
+    kServerHello_2Id,
+    kEntryAssign_1Name,
+    kEntryAssign_2Type,
+    kEntryAssign_3Id,
+    kEntryAssign_4SeqNum,
+    kEntryAssign_5Flags,
+    kEntryAssign_6Value,
+    kEntryUpdate_1Id,
+    kEntryUpdate_2SeqNum,
+    kEntryUpdate_3Type,
+    kEntryUpdate_4Value,
+    kFlagsUpdate_1Id,
+    kFlagsUpdate_2Flags,
+    kEntryDelete_1Id,
+    kClearEntries_1Magic,
+    kExecuteRpc_1Id,
+    kExecuteRpc_2Uid,
+    kExecuteRpc_3Params,
+    kRpcResponse_1Id,
+    kRpcResponse_2Uid,
+    kRpcResponse_3Result,
+    kError
+  } m_state = kStart;
+
+  // detail decoders
+  wpi::Uleb128Reader m_ulebReader;
+  SimpleValueReader m_simpleReader;
+  StringReader m_stringReader;
+  RawReader m_rawReader;
+  ValueReader m_valueReader;
+
+  std::string m_error;
+
+  std::string m_str;
+  unsigned int m_id{0};  // also used for proto_rev
+  unsigned int m_flags{0};
+  unsigned int m_seq_num_uid{0};
+
+  void Execute(std::span<const uint8_t>* in);
+
+  std::nullopt_t EmitError(std::string_view msg) {
+    m_state = kError;
+    m_error = msg;
+    return std::nullopt;
+  }
+
+  std::optional<std::string> ReadString(std::span<const uint8_t>* in);
+  std::optional<std::vector<uint8_t>> ReadRaw(std::span<const uint8_t>* in);
+  std::optional<NT_Type> ReadType(std::span<const uint8_t>* in);
+  std::optional<Value> ReadValue(std::span<const uint8_t>* in);
+};
+
+}  // namespace
+
+static uint8_t Read8(std::span<const uint8_t>* in) {
+  uint8_t val = in->front();
+  *in = wpi::drop_front(*in);
+  return val;
+}
+
+std::optional<uint16_t> SimpleValueReader::Read16(
+    std::span<const uint8_t>* in) {
+  while (!in->empty()) {
+    m_value <<= 8;
+    m_value |= in->front() & 0xff;
+    *in = wpi::drop_front(*in);
+    if (++m_count >= 2) {
+      uint16_t val = static_cast<uint16_t>(m_value);
+      m_count = 0;
+      m_value = 0;
+      return val;
+    }
+  }
+  return std::nullopt;
+}
+
+std::optional<uint32_t> SimpleValueReader::Read32(
+    std::span<const uint8_t>* in) {
+  while (!in->empty()) {
+    m_value <<= 8;
+    m_value |= in->front() & 0xff;
+    *in = wpi::drop_front(*in);
+    if (++m_count >= 4) {
+      uint32_t val = static_cast<uint32_t>(m_value);
+      m_count = 0;
+      m_value = 0;
+      return val;
+    }
+  }
+  return std::nullopt;
+}
+
+std::optional<uint64_t> SimpleValueReader::Read64(
+    std::span<const uint8_t>* in) {
+  while (!in->empty()) {
+    m_value <<= 8;
+    m_value |= in->front() & 0xff;
+    *in = wpi::drop_front(*in);
+    if (++m_count >= 8) {
+      uint64_t val = m_value;
+      m_count = 0;
+      m_value = 0;
+      return val;
+    }
+  }
+  return std::nullopt;
+}
+
+std::optional<double> SimpleValueReader::ReadDouble(
+    std::span<const uint8_t>* in) {
+  if (auto val = Read64(in)) {
+    return wpi::BitsToDouble(val.value());
+  } else {
+    return std::nullopt;
+  }
+}
+
+void WDImpl::Execute(std::span<const uint8_t>* in) {
+  while (!in->empty()) {
+    switch (m_state) {
+      case kStart: {
+        uint8_t msgType = Read8(in);
+        switch (msgType) {
+          case Message3::kKeepAlive:
+            m_out.KeepAlive();
+            break;
+          case Message3::kClientHello:
+            m_state = kClientHello_1ProtoRev;
+            break;
+          case Message3::kProtoUnsup:
+            m_state = kProtoUnsup_1ProtoRev;
+            break;
+          case Message3::kServerHello:
+            m_state = kServerHello_1Flags;
+            break;
+          case Message3::kServerHelloDone:
+            m_out.ServerHelloDone();
+            break;
+          case Message3::kClientHelloDone:
+            m_out.ClientHelloDone();
+            break;
+          case Message3::kEntryAssign:
+            m_state = kEntryAssign_1Name;
+            break;
+          case Message3::kEntryUpdate:
+            m_state = kEntryUpdate_1Id;
+            break;
+          case Message3::kFlagsUpdate:
+            m_state = kFlagsUpdate_1Id;
+            break;
+          case Message3::kEntryDelete:
+            m_state = kEntryDelete_1Id;
+            break;
+          case Message3::kClearEntries:
+            m_state = kClearEntries_1Magic;
+            break;
+          case Message3::kExecuteRpc:
+            m_state = kExecuteRpc_1Id;
+            break;
+          case Message3::kRpcResponse:
+            m_state = kRpcResponse_1Id;
+            break;
+          default:
+            EmitError(fmt::format("unrecognized message type: {}",
+                                  static_cast<uint32_t>(msgType)));
+            return;
+        }
+        break;
+      }
+      case kClientHello_1ProtoRev:
+        if (auto val = m_simpleReader.Read16(in)) {
+          if (val < 0x0300u) {
+            m_state = kStart;
+            m_out.ClientHello("", val.value());
+          } else {
+            m_state = kClientHello_2Id;
+            m_id = val.value();
+          }
+        }
+        break;
+      case kClientHello_2Id:
+        if (auto val = ReadString(in)) {
+          m_state = kStart;
+          m_out.ClientHello(val.value(), m_id);
+        }
+        break;
+      case kProtoUnsup_1ProtoRev:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kStart;
+          m_out.ProtoUnsup(val.value());
+        }
+        break;
+      case kServerHello_1Flags: {
+        m_state = kServerHello_2Id;
+        m_flags = Read8(in);
+        break;
+      }
+      case kServerHello_2Id:
+        if (auto val = ReadString(in)) {
+          m_state = kStart;
+          m_out.ServerHello(m_flags, val.value());
+        }
+        break;
+      case kEntryAssign_1Name:
+        if (auto val = ReadString(in)) {
+          m_state = kEntryAssign_2Type;
+          m_str = std::move(val.value());
+        }
+        break;
+      case kEntryAssign_2Type:
+        if (auto val = ReadType(in)) {
+          m_state = kEntryAssign_3Id;
+          m_valueReader = ValueReader{val.value()};
+        }
+        break;
+      case kEntryAssign_3Id:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kEntryAssign_4SeqNum;
+          m_id = val.value();
+        }
+        break;
+      case kEntryAssign_4SeqNum:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kEntryAssign_5Flags;
+          m_seq_num_uid = val.value();
+        }
+        break;
+      case kEntryAssign_5Flags: {
+        m_state = kEntryAssign_6Value;
+        m_flags = Read8(in);
+        break;
+      }
+      case kEntryAssign_6Value:
+        if (auto val = ReadValue(in)) {
+          m_state = kStart;
+          m_out.EntryAssign(m_str, m_id, m_seq_num_uid, val.value(), m_flags);
+        }
+        break;
+      case kEntryUpdate_1Id:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kEntryUpdate_2SeqNum;
+          m_id = val.value();
+        }
+        break;
+      case kEntryUpdate_2SeqNum:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kEntryUpdate_3Type;
+          m_seq_num_uid = val.value();
+        }
+        break;
+      case kEntryUpdate_3Type:
+        if (auto val = ReadType(in)) {
+          m_state = kEntryUpdate_4Value;
+          m_valueReader = ValueReader{val.value()};
+        }
+        break;
+      case kEntryUpdate_4Value:
+        if (auto val = ReadValue(in)) {
+          m_state = kStart;
+          m_out.EntryUpdate(m_id, m_seq_num_uid, val.value());
+        }
+        break;
+      case kFlagsUpdate_1Id:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kFlagsUpdate_2Flags;
+          m_id = val.value();
+        }
+        break;
+      case kFlagsUpdate_2Flags: {
+        m_state = kStart;
+        m_out.FlagsUpdate(m_id, Read8(in));
+        break;
+      }
+      case kEntryDelete_1Id:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kStart;
+          m_out.EntryDelete(val.value());
+        }
+        break;
+      case kClearEntries_1Magic:
+        if (auto val = m_simpleReader.Read32(in)) {
+          m_state = kStart;
+          if (val.value() == Message3::kClearAllMagic) {
+            m_out.ClearEntries();
+          } else {
+            EmitError("received incorrect CLEAR_ENTRIES magic value");
+          }
+          break;
+        }
+        break;
+      case kExecuteRpc_1Id:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kExecuteRpc_2Uid;
+          m_id = val.value();
+        }
+        break;
+      case kExecuteRpc_2Uid:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kExecuteRpc_3Params;
+          m_seq_num_uid = val.value();
+        }
+        break;
+      case kExecuteRpc_3Params:
+        if (auto val = ReadRaw(in)) {
+          m_state = kStart;
+          m_out.ExecuteRpc(m_id, m_seq_num_uid, val.value());
+        }
+        break;
+      case kRpcResponse_1Id:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kRpcResponse_2Uid;
+          m_id = val.value();
+        }
+        break;
+      case kRpcResponse_2Uid:
+        if (auto val = m_simpleReader.Read16(in)) {
+          m_state = kRpcResponse_3Result;
+          m_seq_num_uid = val.value();
+        }
+        break;
+      case kRpcResponse_3Result:
+        if (auto val = ReadRaw(in)) {
+          m_state = kStart;
+          m_out.RpcResponse(m_id, m_seq_num_uid, val.value());
+        }
+        break;
+      case kError:
+        return;
+    }
+  }
+}
+
+std::optional<std::string> WDImpl::ReadString(std::span<const uint8_t>* in) {
+  // string length
+  if (!m_stringReader.len) {
+    if (auto val = m_ulebReader.ReadOne(in)) {
+      m_stringReader.SetLen(val.value());
+      m_stringReader.buf.clear();
+    } else {
+      return std::nullopt;
+    }
+  }
+
+  // string data; nolint to avoid clang-tidy false positive
+  size_t toCopy =
+      (std::min)(in->size(),
+                 static_cast<size_t>(m_stringReader.len.value() -
+                                     m_stringReader.buf.size()));  // NOLINT
+  m_stringReader.buf.append(reinterpret_cast<const char*>(in->data()), toCopy);
+  *in = wpi::drop_front(*in, toCopy);
+  if (m_stringReader.buf.size() >= m_stringReader.len) {
+    m_stringReader.len.reset();
+    return std::move(m_stringReader.buf);
+  }
+  return std::nullopt;
+}
+
+std::optional<std::vector<uint8_t>> WDImpl::ReadRaw(
+    std::span<const uint8_t>* in) {
+  // string length
+  if (!m_rawReader.len) {
+    if (auto val = m_ulebReader.ReadOne(in)) {
+      m_rawReader.SetLen(val.value());
+      m_rawReader.buf.clear();
+    } else {
+      return std::nullopt;
+    }
+  }
+
+  // string data
+  size_t toCopy = (std::min)(
+      static_cast<size_t>(in->size()),
+      static_cast<size_t>(m_rawReader.len.value() - m_rawReader.buf.size()));
+  m_rawReader.buf.insert(m_rawReader.buf.end(), in->begin(),
+                         in->begin() + toCopy);
+  *in = wpi::drop_front(*in, toCopy);
+  if (m_rawReader.buf.size() >= m_rawReader.len) {
+    m_rawReader.len.reset();
+    return std::move(m_rawReader.buf);
+  }
+  return std::nullopt;
+}
+
+std::optional<NT_Type> WDImpl::ReadType(std::span<const uint8_t>* in) {
+  // Convert from byte value to enum
+  switch (Read8(in)) {
+    case Message3::kBoolean:
+      return NT_BOOLEAN;
+    case Message3::kDouble:
+      return NT_DOUBLE;
+    case Message3::kString:
+      return NT_STRING;
+    case Message3::kRaw:
+      return NT_RAW;
+    case Message3::kBooleanArray:
+      return NT_BOOLEAN_ARRAY;
+    case Message3::kDoubleArray:
+      return NT_DOUBLE_ARRAY;
+    case Message3::kStringArray:
+      return NT_STRING_ARRAY;
+    case Message3::kRpcDef:
+      return NT_RPC;
+    default:
+      return EmitError("unrecognized value type");
+  }
+}
+
+std::optional<Value> WDImpl::ReadValue(std::span<const uint8_t>* in) {
+  while (!in->empty()) {
+    switch (m_valueReader.type) {
+      case NT_BOOLEAN:
+        return Value::MakeBoolean(Read8(in) != 0);
+      case NT_DOUBLE:
+        if (auto val = m_simpleReader.ReadDouble(in)) {
+          return Value::MakeDouble(val.value());
+        }
+        break;
+      case NT_STRING:
+        if (auto val = ReadString(in)) {
+          return Value::MakeString(std::move(val.value()));
+        }
+        break;
+      case NT_RAW:
+      case NT_RPC:
+        if (auto val = ReadRaw(in)) {
+          return Value::MakeRaw(std::move(val.value()));
+        }
+        break;
+#if 0
+      case NT_RPC:
+        if (auto val = ReadRaw(in)) {
+          return Value::MakeRpc(std::move(val.value()));
+        }
+        break;
+#endif
+      case NT_BOOLEAN_ARRAY:
+        // size
+        if (!m_valueReader.haveSize) {
+          m_valueReader.SetSize(Read8(in));
+          break;
+        }
+
+        // array values
+        while (!in->empty() && m_valueReader.ints.size() < m_valueReader.size) {
+          m_valueReader.ints.emplace_back(Read8(in) ? 1 : 0);
+        }
+        if (m_valueReader.ints.size() == m_valueReader.size) {
+          return Value::MakeBooleanArray(std::move(m_valueReader.ints));
+        }
+        break;
+      case NT_DOUBLE_ARRAY:
+        // size
+        if (!m_valueReader.haveSize) {
+          m_valueReader.SetSize(Read8(in));
+          break;
+        }
+
+        // array values
+        while (!in->empty() &&
+               m_valueReader.doubles.size() < m_valueReader.size) {
+          if (auto val = m_simpleReader.ReadDouble(in)) {
+            m_valueReader.doubles.emplace_back(std::move(val.value()));
+          }
+        }
+        if (m_valueReader.doubles.size() == m_valueReader.size) {
+          return Value::MakeDoubleArray(std::move(m_valueReader.doubles));
+        }
+        break;
+      case NT_STRING_ARRAY:
+        // size
+        if (!m_valueReader.haveSize) {
+          m_valueReader.SetSize(Read8(in));
+          break;
+        }
+
+        // array values
+        while (!in->empty() &&
+               m_valueReader.strings.size() < m_valueReader.size) {
+          if (auto val = ReadString(in)) {
+            m_valueReader.strings.emplace_back(std::move(val.value()));
+          }
+        }
+        if (m_valueReader.strings.size() == m_valueReader.size) {
+          return Value::MakeStringArray(std::move(m_valueReader.strings));
+        }
+        break;
+      default:
+        return EmitError("invalid type when trying to read value");
+    }
+  }
+  return std::nullopt;
+}
+
+struct WireDecoder3::Impl : public WDImpl {
+  explicit Impl(MessageHandler3& out) : WDImpl{out} {}
+};
+
+WireDecoder3::WireDecoder3(MessageHandler3& out) : m_impl{new Impl{out}} {}
+
+WireDecoder3::~WireDecoder3() = default;
+
+bool WireDecoder3::Execute(std::span<const uint8_t>* in) {
+  m_impl->Execute(in);
+  return m_impl->m_state != Impl::kError;
+}
+
+void WireDecoder3::SetError(std::string_view message) {
+  m_impl->EmitError(message);
+}
+
+std::string WireDecoder3::GetError() const {
+  return m_impl->m_error;
+}
diff --git a/ntcore/src/main/native/cpp/net3/WireDecoder3.h b/ntcore/src/main/native/cpp/net3/WireDecoder3.h
new file mode 100644
index 0000000..e877833
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/WireDecoder3.h
@@ -0,0 +1,64 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <memory>
+#include <span>
+#include <string>
+
+namespace nt {
+class Value;
+}  // namespace nt
+
+namespace nt::net3 {
+
+class MessageHandler3 {
+ public:
+  virtual void KeepAlive() = 0;
+  virtual void ServerHelloDone() = 0;
+  virtual void ClientHelloDone() = 0;
+  virtual void ClearEntries() = 0;
+  virtual void ProtoUnsup(unsigned int proto_rev) = 0;
+  virtual void ClientHello(std::string_view self_id,
+                           unsigned int proto_rev) = 0;
+  virtual void ServerHello(unsigned int flags, std::string_view self_id) = 0;
+  virtual void EntryAssign(std::string_view name, unsigned int id,
+                           unsigned int seq_num, const Value& value,
+                           unsigned int flags) = 0;
+  virtual void EntryUpdate(unsigned int id, unsigned int seq_num,
+                           const Value& value) = 0;
+  virtual void FlagsUpdate(unsigned int id, unsigned int flags) = 0;
+  virtual void EntryDelete(unsigned int id) = 0;
+  virtual void ExecuteRpc(unsigned int id, unsigned int uid,
+                          std::span<const uint8_t> params) = 0;
+  virtual void RpcResponse(unsigned int id, unsigned int uid,
+                           std::span<const uint8_t> result) = 0;
+};
+
+/* Decodes NT3 protocol into native representation. */
+class WireDecoder3 {
+ public:
+  explicit WireDecoder3(MessageHandler3& out);
+  ~WireDecoder3();
+
+  /**
+   * Executes the decoder.  All input data will be consumed unless an error
+   * occurs.
+   * @param in input data (updated during parse)
+   * @return false if error occurred
+   */
+  bool Execute(std::span<const uint8_t>* in);
+
+  void SetError(std::string_view message);
+  std::string GetError() const;
+
+ private:
+  struct Impl;
+  std::unique_ptr<Impl> m_impl;
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/net3/WireEncoder3.cpp b/ntcore/src/main/native/cpp/net3/WireEncoder3.cpp
new file mode 100644
index 0000000..6bf3435
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/WireEncoder3.cpp
@@ -0,0 +1,326 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "WireEncoder3.h"
+
+#include <wpi/MathExtras.h>
+#include <wpi/SmallVector.h>
+#include <wpi/leb128.h>
+#include <wpi/raw_ostream.h>
+
+#include "Message3.h"
+
+using namespace nt;
+using namespace nt::net3;
+
+static void Write8(wpi::raw_ostream& os, uint8_t val) {
+  os << val;
+}
+
+static void Write16(wpi::raw_ostream& os, uint16_t val) {
+  os << std::span<const uint8_t>{{static_cast<uint8_t>((val >> 8) & 0xff),
+                                  static_cast<uint8_t>(val & 0xff)}};
+}
+
+static void Write32(wpi::raw_ostream& os, uint32_t val) {
+  os << std::span<const uint8_t>{{static_cast<uint8_t>((val >> 24) & 0xff),
+                                  static_cast<uint8_t>((val >> 16) & 0xff),
+                                  static_cast<uint8_t>((val >> 8) & 0xff),
+                                  static_cast<uint8_t>(val & 0xff)}};
+}
+
+static void WriteDouble(wpi::raw_ostream& os, double val) {
+  // The highest performance way to do this, albeit non-portable.
+  uint64_t v = wpi::DoubleToBits(val);
+  os << std::span<const uint8_t>{{static_cast<uint8_t>((v >> 56) & 0xff),
+                                  static_cast<uint8_t>((v >> 48) & 0xff),
+                                  static_cast<uint8_t>((v >> 40) & 0xff),
+                                  static_cast<uint8_t>((v >> 32) & 0xff),
+                                  static_cast<uint8_t>((v >> 24) & 0xff),
+                                  static_cast<uint8_t>((v >> 16) & 0xff),
+                                  static_cast<uint8_t>((v >> 8) & 0xff),
+                                  static_cast<uint8_t>(v & 0xff)}};
+}
+
+static void WriteString(wpi::raw_ostream& os, std::string_view str) {
+  wpi::WriteUleb128(os, str.size());
+  os << str;
+}
+
+static void WriteRaw(wpi::raw_ostream& os, std::span<const uint8_t> str) {
+  wpi::WriteUleb128(os, str.size());
+  os << str;
+}
+
+static bool WriteType(wpi::raw_ostream& os, NT_Type type) {
+  char ch;
+  // Convert from enum to actual byte value.
+  switch (type) {
+    case NT_BOOLEAN:
+      ch = Message3::kBoolean;
+      break;
+    case NT_INTEGER:
+    case NT_FLOAT:
+    case NT_DOUBLE:
+      ch = Message3::kDouble;
+      break;
+    case NT_STRING:
+      ch = Message3::kString;
+      break;
+    case NT_RAW:
+      ch = Message3::kRaw;
+      break;
+    case NT_BOOLEAN_ARRAY:
+      ch = Message3::kBooleanArray;
+      break;
+    case NT_INTEGER_ARRAY:
+    case NT_FLOAT_ARRAY:
+    case NT_DOUBLE_ARRAY:
+      ch = Message3::kDoubleArray;
+      break;
+    case NT_STRING_ARRAY:
+      ch = Message3::kStringArray;
+      break;
+    case NT_RPC:
+      ch = Message3::kRpcDef;
+      break;
+    default:
+      return false;
+  }
+  os << ch;
+  return true;
+}
+
+static bool WriteValue(wpi::raw_ostream& os, const Value& value) {
+  switch (value.type()) {
+    case NT_BOOLEAN:
+      Write8(os, value.GetBoolean() ? 1 : 0);
+      break;
+    case NT_INTEGER:
+      WriteDouble(os, value.GetInteger());
+      break;
+    case NT_FLOAT:
+      WriteDouble(os, value.GetFloat());
+      break;
+    case NT_DOUBLE:
+      WriteDouble(os, value.GetDouble());
+      break;
+    case NT_STRING:
+      WriteString(os, value.GetString());
+      break;
+    case NT_RAW:
+      WriteRaw(os, value.GetRaw());
+      break;
+    case NT_RPC:
+      WriteRaw(os, value.GetRaw());
+      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(os, size);
+
+      for (size_t i = 0; i < size; ++i) {
+        Write8(os, v[i] ? 1 : 0);
+      }
+      break;
+    }
+    case NT_INTEGER_ARRAY: {
+      auto v = value.GetIntegerArray();
+      size_t size = v.size();
+      if (size > 0xff) {
+        size = 0xff;  // size is only 1 byte, truncate
+      }
+      Write8(os, size);
+
+      for (size_t i = 0; i < size; ++i) {
+        WriteDouble(os, v[i]);
+      }
+      break;
+    }
+    case NT_FLOAT_ARRAY: {
+      auto v = value.GetFloatArray();
+      size_t size = v.size();
+      if (size > 0xff) {
+        size = 0xff;  // size is only 1 byte, truncate
+      }
+      Write8(os, size);
+
+      for (size_t i = 0; i < size; ++i) {
+        WriteDouble(os, v[i]);
+      }
+      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(os, size);
+
+      for (size_t i = 0; i < size; ++i) {
+        WriteDouble(os, 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(os, size);
+
+      for (size_t i = 0; i < size; ++i) {
+        WriteString(os, v[i]);
+      }
+      break;
+    }
+    default:
+      return false;
+  }
+  return true;
+}
+
+void nt::net3::WireEncodeKeepAlive(wpi::raw_ostream& os) {
+  Write8(os, Message3::kKeepAlive);
+}
+
+void nt::net3::WireEncodeServerHelloDone(wpi::raw_ostream& os) {
+  Write8(os, Message3::kServerHelloDone);
+}
+
+void nt::net3::WireEncodeClientHelloDone(wpi::raw_ostream& os) {
+  Write8(os, Message3::kClientHelloDone);
+}
+
+void nt::net3::WireEncodeClearEntries(wpi::raw_ostream& os) {
+  Write8(os, Message3::kClearEntries);
+  Write32(os, Message3::kClearAllMagic);
+}
+
+void nt::net3::WireEncodeProtoUnsup(wpi::raw_ostream& os,
+                                    unsigned int proto_rev) {
+  Write8(os, Message3::kProtoUnsup);
+  Write16(os, proto_rev);
+}
+
+void nt::net3::WireEncodeClientHello(wpi::raw_ostream& os,
+                                     std::string_view self_id,
+                                     unsigned int proto_rev) {
+  Write8(os, Message3::kClientHello);
+  Write16(os, proto_rev);
+  WriteString(os, self_id);
+}
+
+void nt::net3::WireEncodeServerHello(wpi::raw_ostream& os, unsigned int flags,
+                                     std::string_view self_id) {
+  Write8(os, Message3::kServerHello);
+  Write8(os, flags);
+  WriteString(os, self_id);
+}
+
+bool nt::net3::WireEncodeEntryAssign(wpi::raw_ostream& os,
+                                     std::string_view name, unsigned int id,
+                                     unsigned int seq_num, const Value& value,
+                                     unsigned int flags) {
+  Write8(os, Message3::kEntryAssign);
+  WriteString(os, name);
+  WriteType(os, value.type());
+  Write16(os, id);
+  Write16(os, seq_num);
+  Write8(os, flags);
+  return WriteValue(os, value);
+}
+
+bool nt::net3::WireEncodeEntryUpdate(wpi::raw_ostream& os, unsigned int id,
+                                     unsigned int seq_num, const Value& value) {
+  Write8(os, Message3::kEntryUpdate);
+  Write16(os, id);
+  Write16(os, seq_num);
+  WriteType(os, value.type());
+  return WriteValue(os, value);
+}
+
+void nt::net3::WireEncodeFlagsUpdate(wpi::raw_ostream& os, unsigned int id,
+                                     unsigned int flags) {
+  Write8(os, Message3::kFlagsUpdate);
+  Write16(os, id);
+  Write8(os, flags);
+}
+
+void nt::net3::WireEncodeEntryDelete(wpi::raw_ostream& os, unsigned int id) {
+  Write8(os, Message3::kEntryDelete);
+  Write16(os, id);
+}
+
+void nt::net3::WireEncodeExecuteRpc(wpi::raw_ostream& os, unsigned int id,
+                                    unsigned int uid,
+                                    std::span<const uint8_t> params) {
+  Write8(os, Message3::kExecuteRpc);
+  Write16(os, id);
+  Write16(os, uid);
+  WriteRaw(os, params);
+}
+
+void nt::net3::WireEncodeRpcResponse(wpi::raw_ostream& os, unsigned int id,
+                                     unsigned int uid,
+                                     std::span<const uint8_t> result) {
+  Write8(os, Message3::kRpcResponse);
+  Write16(os, id);
+  Write16(os, uid);
+  WriteRaw(os, result);
+}
+
+bool nt::net3::WireEncode(wpi::raw_ostream& os, const Message3& msg) {
+  switch (msg.type()) {
+    case Message3::kKeepAlive:
+      WireEncodeKeepAlive(os);
+      break;
+    case Message3::kServerHelloDone:
+      WireEncodeServerHelloDone(os);
+      break;
+    case Message3::kClientHelloDone:
+      WireEncodeClientHelloDone(os);
+      break;
+    case Message3::kClientHello:
+      WireEncodeClientHello(os, msg.str(), msg.id());
+      break;
+    case Message3::kProtoUnsup:
+      WireEncodeProtoUnsup(os, msg.id());
+      break;
+    case Message3::kServerHello:
+      WireEncodeServerHello(os, msg.flags(), msg.str());
+      break;
+    case Message3::kEntryAssign:
+      return WireEncodeEntryAssign(os, msg.str(), msg.id(), msg.seq_num_uid(),
+                                   msg.value(), msg.flags());
+    case Message3::kEntryUpdate:
+      return WireEncodeEntryUpdate(os, msg.id(), msg.seq_num_uid(),
+                                   msg.value());
+    case Message3::kFlagsUpdate:
+      WireEncodeFlagsUpdate(os, msg.id(), msg.flags());
+      break;
+    case Message3::kEntryDelete:
+      WireEncodeEntryDelete(os, msg.id());
+      break;
+    case Message3::kClearEntries:
+      WireEncodeClearEntries(os);
+      break;
+    case Message3::kExecuteRpc:
+      WireEncodeExecuteRpc(os, msg.id(), msg.seq_num_uid(), msg.bytes());
+      break;
+    case Message3::kRpcResponse:
+      WireEncodeRpcResponse(os, msg.id(), msg.seq_num_uid(), msg.bytes());
+      break;
+    case Message3::kUnknown:
+      return true;  // ignore
+    default:
+      return false;
+  }
+  return true;
+}
diff --git a/ntcore/src/main/native/cpp/net3/WireEncoder3.h b/ntcore/src/main/native/cpp/net3/WireEncoder3.h
new file mode 100644
index 0000000..66be9ae
--- /dev/null
+++ b/ntcore/src/main/native/cpp/net3/WireEncoder3.h
@@ -0,0 +1,49 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <string_view>
+
+namespace wpi {
+class raw_ostream;
+}  // namespace wpi
+
+namespace nt {
+class Value;
+}  // namespace nt
+
+namespace nt::net3 {
+
+class Message3;
+
+// encoders for messages (avoids need to construct a Message struct)
+void WireEncodeKeepAlive(wpi::raw_ostream& os);
+void WireEncodeServerHelloDone(wpi::raw_ostream& os);
+void WireEncodeClientHelloDone(wpi::raw_ostream& os);
+void WireEncodeClearEntries(wpi::raw_ostream& os);
+void WireEncodeProtoUnsup(wpi::raw_ostream& os, unsigned int proto_rev);
+void WireEncodeClientHello(wpi::raw_ostream& os, std::string_view self_id,
+                           unsigned int proto_rev);
+void WireEncodeServerHello(wpi::raw_ostream& os, unsigned int flags,
+                           std::string_view self_id);
+bool WireEncodeEntryAssign(wpi::raw_ostream& os, std::string_view name,
+                           unsigned int id, unsigned int seq_num,
+                           const Value& value, unsigned int flags);
+bool WireEncodeEntryUpdate(wpi::raw_ostream& os, unsigned int id,
+                           unsigned int seq_num, const Value& value);
+void WireEncodeFlagsUpdate(wpi::raw_ostream& os, unsigned int id,
+                           unsigned int flags);
+void WireEncodeEntryDelete(wpi::raw_ostream& os, unsigned int id);
+void WireEncodeExecuteRpc(wpi::raw_ostream& os, unsigned int id,
+                          unsigned int uid, std::span<const uint8_t> params);
+void WireEncodeRpcResponse(wpi::raw_ostream& os, unsigned int id,
+                           unsigned int uid, std::span<const uint8_t> result);
+
+bool WireEncode(wpi::raw_ostream& os, const Message3& msg);
+
+}  // namespace nt::net3
diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp
index 0c28dd4..1f6a760 100644
--- a/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp
+++ b/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp
@@ -12,8 +12,20 @@
 #include <wpi/StringExtras.h>
 #include <wpi/StringMap.h>
 
+#include "networktables/BooleanArrayTopic.h"
+#include "networktables/BooleanTopic.h"
+#include "networktables/DoubleArrayTopic.h"
+#include "networktables/DoubleTopic.h"
+#include "networktables/FloatArrayTopic.h"
+#include "networktables/FloatTopic.h"
+#include "networktables/IntegerArrayTopic.h"
+#include "networktables/IntegerTopic.h"
 #include "networktables/NetworkTableInstance.h"
+#include "networktables/RawTopic.h"
+#include "networktables/StringArrayTopic.h"
+#include "networktables/StringTopic.h"
 #include "ntcore.h"
+#include "ntcore_cpp.h"
 
 using namespace nt;
 
@@ -78,11 +90,7 @@
                            const private_init&)
     : m_inst(inst), m_path(path) {}
 
-NetworkTable::~NetworkTable() {
-  for (auto i : m_listeners) {
-    RemoveEntryListener(i);
-  }
-}
+NetworkTable::~NetworkTable() = default;
 
 NetworkTableInstance NetworkTable::GetInstance() const {
   return NetworkTableInstance{m_inst};
@@ -99,78 +107,58 @@
   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, fmt::format("{}/", m_path),
-      [=](const EntryNotification& event) {
-        auto relative_key = wpi::substr(event.name, prefix_len);
-        if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) {
-          return;
-        }
-        listener(const_cast<NetworkTable*>(this), relative_key,
-                 NetworkTableEntry{event.entry}, event.value, event.flags);
-      },
-      flags);
+Topic NetworkTable::GetTopic(std::string_view name) const {
+  fmt::memory_buffer buf;
+  fmt::format_to(fmt::appender{buf}, "{}/{}", m_path, name);
+  return Topic{::nt::GetTopic(m_inst, {buf.data(), buf.size()})};
 }
 
-NT_EntryListener NetworkTable::AddEntryListener(std::string_view 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),
-                 wpi::substr(event.name, prefix_len), entry, event.value,
-                 event.flags);
-      },
-      flags);
+BooleanTopic NetworkTable::GetBooleanTopic(std::string_view name) const {
+  return BooleanTopic{GetTopic(name)};
 }
 
-void NetworkTable::RemoveEntryListener(NT_EntryListener listener) const {
-  nt::RemoveEntryListener(listener);
+IntegerTopic NetworkTable::GetIntegerTopic(std::string_view name) const {
+  return IntegerTopic{GetTopic(name)};
 }
 
-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, fmt::format("{}/", m_path),
-      [=](const EntryNotification& event) {
-        auto relative_key = wpi::substr(event.name, prefix_len);
-        auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
-        if (end_sub_table == std::string_view::npos) {
-          return;
-        }
-        auto sub_table_key = wpi::substr(relative_key, 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_listeners.emplace_back(id);
-  return id;
+FloatTopic NetworkTable::GetFloatTopic(std::string_view name) const {
+  return FloatTopic{GetTopic(name)};
 }
 
-void NetworkTable::RemoveTableListener(NT_EntryListener listener) {
-  nt::RemoveEntryListener(listener);
-  auto matches_begin =
-      std::remove(m_listeners.begin(), m_listeners.end(), listener);
-  m_listeners.erase(matches_begin, m_listeners.end());
+DoubleTopic NetworkTable::GetDoubleTopic(std::string_view name) const {
+  return DoubleTopic{GetTopic(name)};
+}
+
+StringTopic NetworkTable::GetStringTopic(std::string_view name) const {
+  return StringTopic{GetTopic(name)};
+}
+
+RawTopic NetworkTable::GetRawTopic(std::string_view name) const {
+  return RawTopic{GetTopic(name)};
+}
+
+BooleanArrayTopic NetworkTable::GetBooleanArrayTopic(
+    std::string_view name) const {
+  return BooleanArrayTopic{GetTopic(name)};
+}
+
+IntegerArrayTopic NetworkTable::GetIntegerArrayTopic(
+    std::string_view name) const {
+  return IntegerArrayTopic{GetTopic(name)};
+}
+
+FloatArrayTopic NetworkTable::GetFloatArrayTopic(std::string_view name) const {
+  return FloatArrayTopic{GetTopic(name)};
+}
+
+DoubleArrayTopic NetworkTable::GetDoubleArrayTopic(
+    std::string_view name) const {
+  return DoubleArrayTopic{GetTopic(name)};
+}
+
+StringArrayTopic NetworkTable::GetStringArrayTopic(
+    std::string_view name) const {
+  return StringArrayTopic{GetTopic(name)};
 }
 
 std::shared_ptr<NetworkTable> NetworkTable::GetSubTable(
@@ -183,25 +171,52 @@
   if (key.empty()) {
     return false;
   }
-  return GetEntry(key).Exists();
+  return GetTopic(key).Exists();
 }
 
 bool NetworkTable::ContainsSubTable(std::string_view key) const {
-  return !GetEntryInfo(m_inst, fmt::format("{}/{}/", m_path, key), 0).empty();
+  return !::nt::GetTopics(m_inst, fmt::format("{}/{}/", m_path, key), 0)
+              .empty();
+}
+
+std::vector<TopicInfo> NetworkTable::GetTopicInfo(int types) const {
+  std::vector<TopicInfo> infos;
+  size_t prefix_len = m_path.size() + 1;
+  for (auto&& info :
+       ::nt::GetTopicInfo(m_inst, fmt::format("{}/", m_path), types)) {
+    auto relative_key = wpi::substr(info.name, prefix_len);
+    if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) {
+      continue;
+    }
+    infos.emplace_back(std::move(info));
+  }
+  return infos;
+}
+
+std::vector<Topic> NetworkTable::GetTopics(int types) const {
+  std::vector<Topic> topics;
+  size_t prefix_len = m_path.size() + 1;
+  for (auto&& info :
+       ::nt::GetTopicInfo(m_inst, fmt::format("{}/", m_path), types)) {
+    auto relative_key = wpi::substr(info.name, prefix_len);
+    if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) {
+      continue;
+    }
+    topics.emplace_back(info.topic);
+  }
+  return topics;
 }
 
 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, fmt::format("{}/", m_path), types);
-  std::scoped_lock lock(m_mutex);
-  for (auto& info : infos) {
+  for (auto&& info :
+       ::nt::GetTopicInfo(m_inst, fmt::format("{}/", m_path), types)) {
     auto relative_key = wpi::substr(info.name, prefix_len);
     if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) {
       continue;
     }
     keys.emplace_back(relative_key);
-    m_entries[relative_key] = info.entry;
   }
   return keys;
 }
@@ -209,8 +224,9 @@
 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, fmt::format("{}/", m_path), 0)) {
-    auto relative_key = wpi::substr(entry.name, prefix_len);
+  for (auto&& topic :
+       ::nt::GetTopicInfo(m_inst, fmt::format("{}/", m_path), 0)) {
+    auto relative_key = wpi::substr(topic.name, prefix_len);
     size_t end_subtable = relative_key.find(PATH_SEPARATOR_CHAR);
     if (end_subtable == std::string_view::npos) {
       continue;
@@ -232,22 +248,6 @@
   return GetEntry(key).IsPersistent();
 }
 
-void NetworkTable::SetFlags(std::string_view key, unsigned int flags) {
-  GetEntry(key).SetFlags(flags);
-}
-
-void NetworkTable::ClearFlags(std::string_view key, unsigned int flags) {
-  GetEntry(key).ClearFlags(flags);
-}
-
-unsigned int NetworkTable::GetFlags(std::string_view key) const {
-  return GetEntry(key).GetFlags();
-}
-
-void NetworkTable::Delete(std::string_view key) {
-  GetEntry(key).Delete();
-}
-
 bool NetworkTable::PutNumber(std::string_view key, double value) {
   return GetEntry(key).SetDouble(value);
 }
@@ -288,75 +288,75 @@
 }
 
 bool NetworkTable::PutBooleanArray(std::string_view key,
-                                   wpi::span<const int> value) {
+                                   std::span<const int> value) {
   return GetEntry(key).SetBooleanArray(value);
 }
 
 bool NetworkTable::SetDefaultBooleanArray(std::string_view key,
-                                          wpi::span<const int> defaultValue) {
+                                          std::span<const int> defaultValue) {
   return GetEntry(key).SetDefaultBooleanArray(defaultValue);
 }
 
 std::vector<int> NetworkTable::GetBooleanArray(
-    std::string_view key, wpi::span<const int> defaultValue) const {
+    std::string_view key, std::span<const int> defaultValue) const {
   return GetEntry(key).GetBooleanArray(defaultValue);
 }
 
 bool NetworkTable::PutNumberArray(std::string_view key,
-                                  wpi::span<const double> value) {
+                                  std::span<const double> value) {
   return GetEntry(key).SetDoubleArray(value);
 }
 
 bool NetworkTable::SetDefaultNumberArray(std::string_view key,
-                                         wpi::span<const double> defaultValue) {
+                                         std::span<const double> defaultValue) {
   return GetEntry(key).SetDefaultDoubleArray(defaultValue);
 }
 
 std::vector<double> NetworkTable::GetNumberArray(
-    std::string_view key, wpi::span<const double> defaultValue) const {
+    std::string_view key, std::span<const double> defaultValue) const {
   return GetEntry(key).GetDoubleArray(defaultValue);
 }
 
 bool NetworkTable::PutStringArray(std::string_view key,
-                                  wpi::span<const std::string> value) {
+                                  std::span<const std::string> value) {
   return GetEntry(key).SetStringArray(value);
 }
 
 bool NetworkTable::SetDefaultStringArray(
-    std::string_view key, wpi::span<const std::string> defaultValue) {
+    std::string_view key, std::span<const std::string> defaultValue) {
   return GetEntry(key).SetDefaultStringArray(defaultValue);
 }
 
 std::vector<std::string> NetworkTable::GetStringArray(
-    std::string_view key, wpi::span<const std::string> defaultValue) const {
+    std::string_view key, std::span<const std::string> defaultValue) const {
   return GetEntry(key).GetStringArray(defaultValue);
 }
 
-bool NetworkTable::PutRaw(std::string_view key, std::string_view value) {
+bool NetworkTable::PutRaw(std::string_view key,
+                          std::span<const uint8_t> value) {
   return GetEntry(key).SetRaw(value);
 }
 
 bool NetworkTable::SetDefaultRaw(std::string_view key,
-                                 std::string_view defaultValue) {
+                                 std::span<const uint8_t> defaultValue) {
   return GetEntry(key).SetDefaultRaw(defaultValue);
 }
 
-std::string NetworkTable::GetRaw(std::string_view key,
-                                 std::string_view defaultValue) const {
+std::vector<uint8_t> NetworkTable::GetRaw(
+    std::string_view key, std::span<const uint8_t> defaultValue) const {
   return GetEntry(key).GetRaw(defaultValue);
 }
 
-bool NetworkTable::PutValue(std::string_view key,
-                            std::shared_ptr<Value> value) {
+bool NetworkTable::PutValue(std::string_view key, const Value& value) {
   return GetEntry(key).SetValue(value);
 }
 
 bool NetworkTable::SetDefaultValue(std::string_view key,
-                                   std::shared_ptr<Value> defaultValue) {
+                                   const Value& defaultValue) {
   return GetEntry(key).SetDefaultValue(defaultValue);
 }
 
-std::shared_ptr<Value> NetworkTable::GetValue(std::string_view key) const {
+Value NetworkTable::GetValue(std::string_view key) const {
   return GetEntry(key).GetValue();
 }
 
@@ -364,12 +364,63 @@
   return m_path;
 }
 
-const char* NetworkTable::SaveEntries(std::string_view filename) const {
-  return nt::SaveEntries(m_inst, filename, fmt::format("{}/", m_path));
+NT_Listener NetworkTable::AddListener(int eventMask,
+                                      TableEventListener listener) {
+  return NetworkTableInstance{m_inst}.AddListener(
+      {{fmt::format("{}/", m_path)}}, eventMask,
+      [this, cb = std::move(listener)](const Event& event) {
+        std::string topicNameStr;
+        std::string_view topicName;
+        if (auto topicInfo = event.GetTopicInfo()) {
+          topicName = topicInfo->name;
+        } else if (auto valueData = event.GetValueEventData()) {
+          topicNameStr = Topic{valueData->topic}.GetName();
+          topicName = topicNameStr;
+        } else {
+          return;
+        }
+        auto relative_key = wpi::substr(topicName, m_path.size() + 1);
+        if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) {
+          return;
+        }
+        cb(this, relative_key, event);
+      });
 }
 
-const char* NetworkTable::LoadEntries(
-    std::string_view filename,
-    std::function<void(size_t line, const char* msg)> warn) {
-  return nt::LoadEntries(m_inst, filename, fmt::format("{}/", m_path), warn);
+NT_Listener NetworkTable::AddListener(std::string_view key, int eventMask,
+                                      TableEventListener listener) {
+  return NetworkTableInstance{m_inst}.AddListener(
+      GetEntry(key), eventMask,
+      [this, cb = std::move(listener),
+       key = std::string{key}](const Event& event) { cb(this, key, event); });
+}
+
+NT_Listener NetworkTable::AddSubTableListener(SubTableListener listener) {
+  // 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>>();
+
+  return NetworkTableInstance{m_inst}.AddListener(
+      {{fmt::format("{}/", m_path)}}, NT_EVENT_PUBLISH | NT_EVENT_IMMEDIATE,
+      [this, cb = std::move(listener), notified_tables](const Event& event) {
+        auto topicInfo = event.GetTopicInfo();
+        if (!topicInfo) {
+          return;
+        }
+        auto relative_key = wpi::substr(topicInfo->name, m_path.size() + 1);
+        auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
+        if (end_sub_table == std::string_view::npos) {
+          return;
+        }
+        auto 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'));
+        cb(this, sub_table_key, this->GetSubTable(sub_table_key));
+      });
+}
+
+void NetworkTable::RemoveListener(NT_Listener listener) {
+  NetworkTableInstance{m_inst}.RemoveListener(listener);
 }
diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp
index abe64e5..12bb5d8 100644
--- a/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp
+++ b/ntcore/src/main/native/cpp/networktables/NetworkTableEntry.cpp
@@ -5,9 +5,14 @@
 #include "networktables/NetworkTableEntry.h"
 
 #include "networktables/NetworkTableInstance.h"
+#include "networktables/Topic.h"
 
 using namespace nt;
 
 NetworkTableInstance NetworkTableEntry::GetInstance() const {
   return NetworkTableInstance{GetInstanceFromHandle(m_handle)};
 }
+
+Topic NetworkTableEntry::GetTopic() const {
+  return Topic{::nt::GetTopicFromHandle(m_handle)};
+}
diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp
index 4566b30..251e211 100644
--- a/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp
+++ b/ntcore/src/main/native/cpp/networktables/NetworkTableInstance.cpp
@@ -7,8 +7,76 @@
 #include <fmt/format.h>
 #include <wpi/SmallVector.h>
 
+#include "networktables/BooleanArrayTopic.h"
+#include "networktables/BooleanTopic.h"
+#include "networktables/DoubleArrayTopic.h"
+#include "networktables/DoubleTopic.h"
+#include "networktables/FloatArrayTopic.h"
+#include "networktables/FloatTopic.h"
+#include "networktables/IntegerArrayTopic.h"
+#include "networktables/IntegerTopic.h"
+#include "networktables/MultiSubscriber.h"
+#include "networktables/RawTopic.h"
+#include "networktables/StringArrayTopic.h"
+#include "networktables/StringTopic.h"
+
 using namespace nt;
 
+Topic NetworkTableInstance::GetTopic(std::string_view name) const {
+  return Topic{::nt::GetTopic(m_handle, name)};
+}
+
+BooleanTopic NetworkTableInstance::GetBooleanTopic(
+    std::string_view name) const {
+  return BooleanTopic{GetTopic(name)};
+}
+
+IntegerTopic NetworkTableInstance::GetIntegerTopic(
+    std::string_view name) const {
+  return IntegerTopic{GetTopic(name)};
+}
+
+FloatTopic NetworkTableInstance::GetFloatTopic(std::string_view name) const {
+  return FloatTopic{GetTopic(name)};
+}
+
+DoubleTopic NetworkTableInstance::GetDoubleTopic(std::string_view name) const {
+  return DoubleTopic{GetTopic(name)};
+}
+
+StringTopic NetworkTableInstance::GetStringTopic(std::string_view name) const {
+  return StringTopic{GetTopic(name)};
+}
+
+RawTopic NetworkTableInstance::GetRawTopic(std::string_view name) const {
+  return RawTopic{GetTopic(name)};
+}
+
+BooleanArrayTopic NetworkTableInstance::GetBooleanArrayTopic(
+    std::string_view name) const {
+  return BooleanArrayTopic{GetTopic(name)};
+}
+
+IntegerArrayTopic NetworkTableInstance::GetIntegerArrayTopic(
+    std::string_view name) const {
+  return IntegerArrayTopic{GetTopic(name)};
+}
+
+FloatArrayTopic NetworkTableInstance::GetFloatArrayTopic(
+    std::string_view name) const {
+  return FloatArrayTopic{GetTopic(name)};
+}
+
+DoubleArrayTopic NetworkTableInstance::GetDoubleArrayTopic(
+    std::string_view name) const {
+  return DoubleArrayTopic{GetTopic(name)};
+}
+
+StringArrayTopic NetworkTableInstance::GetStringArrayTopic(
+    std::string_view name) const {
+  return StringArrayTopic{GetTopic(name)};
+}
+
 std::shared_ptr<NetworkTable> NetworkTableInstance::GetTable(
     std::string_view key) const {
   if (key.empty() || key == "/") {
@@ -23,33 +91,54 @@
   }
 }
 
-void NetworkTableInstance::StartClient(
-    wpi::span<const std::string_view> servers, unsigned int port) {
-  wpi::SmallVector<std::pair<std::string_view, 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(wpi::span<const std::string_view> servers,
+void NetworkTableInstance::SetServer(std::span<const std::string_view> servers,
                                      unsigned int port) {
-  wpi::SmallVector<std::pair<std::string_view, unsigned int>, 8> server_ports;
+  std::vector<std::pair<std::string_view, unsigned int>> serversArr;
+  serversArr.reserve(servers.size());
   for (const auto& server : servers) {
-    server_ports.emplace_back(std::make_pair(server, port));
+    serversArr.emplace_back(std::string{server}, port);
   }
-  SetServer(server_ports);
+  SetServer(serversArr);
 }
 
-NT_EntryListener NetworkTableInstance::AddEntryListener(
-    std::string_view prefix,
-    std::function<void(const EntryNotification& event)> callback,
-    unsigned int flags) const {
-  return ::nt::AddEntryListener(m_handle, prefix, callback, flags);
+NT_Listener NetworkTableInstance::AddListener(Topic topic,
+                                              unsigned int eventMask,
+                                              ListenerCallback listener) {
+  if (::nt::GetInstanceFromHandle(topic.GetHandle()) != m_handle) {
+    fmt::print(stderr, "AddListener: topic is not from this instance\n");
+    return 0;
+  }
+  return ::nt::AddListener(topic.GetHandle(), eventMask, std::move(listener));
 }
 
-NT_ConnectionListener NetworkTableInstance::AddConnectionListener(
-    std::function<void(const ConnectionNotification& event)> callback,
-    bool immediate_notify) const {
-  return ::nt::AddConnectionListener(m_handle, callback, immediate_notify);
+NT_Listener NetworkTableInstance::AddListener(Subscriber& subscriber,
+                                              unsigned int eventMask,
+                                              ListenerCallback listener) {
+  if (::nt::GetInstanceFromHandle(subscriber.GetHandle()) != m_handle) {
+    fmt::print(stderr, "AddListener: subscriber is not from this instance\n");
+    return 0;
+  }
+  return ::nt::AddListener(subscriber.GetHandle(), eventMask,
+                           std::move(listener));
+}
+
+NT_Listener NetworkTableInstance::AddListener(const NetworkTableEntry& entry,
+                                              int eventMask,
+                                              ListenerCallback listener) {
+  if (::nt::GetInstanceFromHandle(entry.GetHandle()) != m_handle) {
+    fmt::print(stderr, "AddListener: entry is not from this instance\n");
+    return 0;
+  }
+  return ::nt::AddListener(entry.GetHandle(), eventMask, std::move(listener));
+}
+
+NT_Listener NetworkTableInstance::AddListener(MultiSubscriber& subscriber,
+                                              int eventMask,
+                                              ListenerCallback listener) {
+  if (::nt::GetInstanceFromHandle(subscriber.GetHandle()) != m_handle) {
+    fmt::print(stderr, "AddListener: subscriber is not from this instance\n");
+    return 0;
+  }
+  return ::nt::AddListener(subscriber.GetHandle(), eventMask,
+                           std::move(listener));
 }
diff --git a/ntcore/src/main/native/cpp/networktables/RpcCall.cpp b/ntcore/src/main/native/cpp/networktables/RpcCall.cpp
deleted file mode 100644
index 2192a82..0000000
--- a/ntcore/src/main/native/cpp/networktables/RpcCall.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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/networktables/Topic.cpp b/ntcore/src/main/native/cpp/networktables/Topic.cpp
new file mode 100644
index 0000000..e3f6ac0
--- /dev/null
+++ b/ntcore/src/main/native/cpp/networktables/Topic.cpp
@@ -0,0 +1,57 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "networktables/Topic.h"
+
+#include <wpi/json.h>
+
+#include "networktables/GenericEntry.h"
+
+using namespace nt;
+
+wpi::json Topic::GetProperty(std::string_view name) const {
+  return ::nt::GetTopicProperty(m_handle, name);
+}
+
+void Topic::SetProperty(std::string_view name, const wpi::json& value) {
+  ::nt::SetTopicProperty(m_handle, name, value);
+}
+
+wpi::json Topic::GetProperties() const {
+  return ::nt::GetTopicProperties(m_handle);
+}
+
+GenericSubscriber Topic::GenericSubscribe(const PubSubOptions& options) {
+  return GenericSubscribe("", options);
+}
+
+GenericSubscriber Topic::GenericSubscribe(std::string_view typeString,
+                                          const PubSubOptions& options) {
+  return GenericSubscriber{::nt::Subscribe(
+      m_handle, ::nt::GetTypeFromString(typeString), typeString, options)};
+}
+
+GenericPublisher Topic::GenericPublish(std::string_view typeString,
+                                       const PubSubOptions& options) {
+  return GenericPublisher{::nt::Publish(
+      m_handle, ::nt::GetTypeFromString(typeString), typeString, options)};
+}
+
+GenericPublisher Topic::GenericPublishEx(std::string_view typeString,
+                                         const wpi::json& properties,
+                                         const PubSubOptions& options) {
+  return GenericPublisher{::nt::PublishEx(m_handle,
+                                          ::nt::GetTypeFromString(typeString),
+                                          typeString, properties, options)};
+}
+
+GenericEntry Topic::GetGenericEntry(const PubSubOptions& options) {
+  return GetGenericEntry("", options);
+}
+
+GenericEntry Topic::GetGenericEntry(std::string_view typeString,
+                                    const PubSubOptions& options) {
+  return GenericEntry{::nt::GetEntry(
+      m_handle, ::nt::GetTypeFromString(typeString), typeString, options)};
+}
diff --git a/ntcore/src/main/native/cpp/ntcore_c.cpp b/ntcore/src/main/native/cpp/ntcore_c.cpp
index d910892..151e0f1 100644
--- a/ntcore/src/main/native/cpp/ntcore_c.cpp
+++ b/ntcore/src/main/native/cpp/ntcore_c.cpp
@@ -2,6 +2,8 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
+#include "ntcore_c.h"
+
 #include <stdint.h>
 
 #include <cassert>
@@ -10,27 +12,24 @@
 #include <string_view>
 
 #include <wpi/MemAlloc.h>
+#include <wpi/SmallVector.h>
+#include <wpi/json.h>
 #include <wpi/timestamp.h>
 
 #include "Value_internal.h"
 #include "ntcore.h"
+#include "ntcore_cpp.h"
 
 using namespace nt;
 
 // Conversion helpers
 
-static void ConvertToC(std::string_view in, char** out) {
-  *out = static_cast<char*>(wpi::safe_malloc(in.size() + 1));
-  std::memmove(*out, in.data(), in.size());  // NOLINT
-  (*out)[in.size()] = '\0';
-}
-
-static void ConvertToC(const EntryInfo& in, NT_EntryInfo* out) {
-  out->entry = in.entry;
+static void ConvertToC(const TopicInfo& in, NT_TopicInfo* out) {
+  out->topic = in.topic;
   ConvertToC(in.name, &out->name);
   out->type = in.type;
-  out->flags = in.flags;
-  out->last_change = in.last_change;
+  ConvertToC(in.type_str, &out->type_str);
+  ConvertToC(in.properties, &out->properties);
 }
 
 static void ConvertToC(const ConnectionInfo& in, NT_ConnectionInfo* out) {
@@ -41,80 +40,50 @@
   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 ValueEventData& in, NT_ValueEventData* out) {
+  out->topic = in.topic;
+  out->subentry = in.subentry;
+  ConvertToC(in.value, &out->value);
 }
 
 static void ConvertToC(const LogMessage& in, NT_LogMessage* out) {
-  out->logger = in.logger;
   out->level = in.level;
   ConvertToC(in.filename, &out->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;
+static void ConvertToC(const TimeSyncEventData& in, NT_TimeSyncEventData* out) {
+  out->serverTimeOffset = in.serverTimeOffset;
+  out->rtt2 = in.rtt2;
+  out->valid = in.valid;
+}
+
+static void ConvertToC(const Event& in, NT_Event* out) {
+  out->listener = in.listener;
+  out->flags = in.flags;
+  if ((in.flags & NT_EVENT_VALUE_ALL) != 0) {
+    if (auto v = in.GetValueEventData()) {
+      return ConvertToC(*v, &out->data.valueData);
+    }
+  } else if ((in.flags & NT_EVENT_TOPIC) != 0) {
+    if (auto v = in.GetTopicInfo()) {
+      return ConvertToC(*v, &out->data.topicInfo);
+    }
+  } else if ((in.flags & NT_EVENT_CONNECTION) != 0) {
+    if (auto v = in.GetConnectionInfo()) {
+      return ConvertToC(*v, &out->data.connInfo);
+    }
+  } else if ((in.flags & NT_EVENT_LOGMESSAGE) != 0) {
+    if (auto v = in.GetLogMessage()) {
+      return ConvertToC(*v, &out->data.logMessage);
+    }
+  } else if ((in.flags & NT_EVENT_TIMESYNC) != 0) {
+    if (auto v = in.GetTimeSyncEventData()) {
+      return ConvertToC(*v, &out->data.timeSyncData);
+    }
   }
-  *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;
+  out->flags = NT_EVENT_NONE;  // sanity to make sure we don't dispose
 }
 
 static void DisposeConnectionInfo(NT_ConnectionInfo* info) {
@@ -122,48 +91,41 @@
   std::free(info->remote_ip.str);
 }
 
-static void DisposeEntryInfo(NT_EntryInfo* info) {
+static void DisposeTopicInfo(NT_TopicInfo* info) {
   std::free(info->name.str);
+  std::free(info->type_str.str);
+  std::free(info->properties.str);
 }
 
-static void DisposeEntryNotification(NT_EntryNotification* info) {
-  std::free(info->name.str);
-  NT_DisposeValue(&info->value);
+static void DisposeLogMessage(NT_LogMessage* msg) {
+  std::free(msg->filename);
+  std::free(msg->message);
 }
 
-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]));
+static void DisposeEvent(NT_Event* event) {
+  if ((event->flags & NT_EVENT_VALUE_ALL) != 0) {
+    NT_DisposeValue(&event->data.valueData.value);
+  } else if ((event->flags & NT_EVENT_TOPIC) != 0) {
+    DisposeTopicInfo(&event->data.topicInfo);
+  } else if ((event->flags & NT_EVENT_CONNECTION) != 0) {
+    DisposeConnectionInfo(&event->data.connInfo);
+  } else if ((event->flags & NT_EVENT_LOGMESSAGE) != 0) {
+    DisposeLogMessage(&event->data.logMessage);
   }
+}
 
-  out.results.reserve(in.num_results);
-  for (size_t i = 0; i < in.num_results; ++i) {
-    out.results.push_back(ConvertFromC(in.results[i]));
-  }
-
+static PubSubOptions ConvertToCpp(const NT_PubSubOptions* in) {
+  PubSubOptions out;
+  out.pollStorage = in->pollStorage;
+  out.periodic = in->periodic;
+  out.excludePublisher = in->excludePublisher;
+  out.sendAll = in->sendAll;
+  out.topicsOnly = in->topicsOnly;
+  out.prefixMatch = in->prefixMatch;
+  out.keepDuplicates = in->keepDuplicates;
+  out.disableRemote = in->disableRemote;
+  out.disableLocal = in->disableLocal;
+  out.excludeSelf = in->excludeSelf;
   return out;
 }
 
@@ -197,21 +159,6 @@
   return nt::GetEntry(inst, {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, {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);
@@ -233,7 +180,7 @@
   if (!v) {
     return;
   }
-  ConvertToC(*v, value);
+  ConvertToC(v, value);
 }
 
 int NT_SetDefaultEntryValue(NT_Entry entry,
@@ -245,10 +192,6 @@
   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);
 }
@@ -257,23 +200,50 @@
   return nt::GetEntryFlags(entry);
 }
 
-void NT_DeleteEntry(NT_Entry entry) {
-  nt::DeleteEntry(entry);
+struct NT_Value* NT_ReadQueueValue(NT_Handle subentry, size_t* count) {
+  return ConvertToC<NT_Value>(nt::ReadQueueValue(subentry), count);
 }
 
-void NT_DeleteAllEntries(NT_Inst inst) {
-  nt::DeleteAllEntries(inst);
+NT_Topic* NT_GetTopics(NT_Inst inst, const char* prefix, size_t prefix_len,
+                       unsigned int types, size_t* count) {
+  auto info_v = nt::GetTopics(inst, {prefix, prefix_len}, types);
+  return ConvertToC<NT_Topic>(info_v, count);
 }
 
-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, {prefix, prefix_len}, types);
-  return ConvertToC<NT_EntryInfo>(info_v, count);
+NT_Topic* NT_GetTopicsStr(NT_Inst inst, const char* prefix, size_t prefix_len,
+                          const char* const* types, size_t types_len,
+                          size_t* count) {
+  wpi::SmallVector<std::string_view, 4> typesCpp;
+  typesCpp.reserve(types_len);
+  for (size_t i = 0; i < types_len; ++i) {
+    typesCpp.emplace_back(types[i]);
+  }
+  auto info_v = nt::GetTopics(inst, {prefix, prefix_len}, typesCpp);
+  return ConvertToC<NT_Topic>(info_v, count);
 }
 
-NT_Bool NT_GetEntryInfoHandle(NT_Entry entry, struct NT_EntryInfo* info) {
-  auto info_v = nt::GetEntryInfo(entry);
+struct NT_TopicInfo* NT_GetTopicInfos(NT_Inst inst, const char* prefix,
+                                      size_t prefix_len, unsigned int types,
+                                      size_t* count) {
+  auto info_v = nt::GetTopicInfo(inst, {prefix, prefix_len}, types);
+  return ConvertToC<NT_TopicInfo>(info_v, count);
+}
+
+struct NT_TopicInfo* NT_GetTopicInfosStr(NT_Inst inst, const char* prefix,
+                                         size_t prefix_len,
+                                         const char* const* types,
+                                         size_t types_len, size_t* count) {
+  wpi::SmallVector<std::string_view, 4> typesCpp;
+  typesCpp.reserve(types_len);
+  for (size_t i = 0; i < types_len; ++i) {
+    typesCpp.emplace_back(types[i]);
+  }
+  auto info_v = nt::GetTopicInfo(inst, {prefix, prefix_len}, typesCpp);
+  return ConvertToC<NT_TopicInfo>(info_v, count);
+}
+
+NT_Bool NT_GetTopicInfo(NT_Topic topic, struct NT_TopicInfo* info) {
+  auto info_v = nt::GetTopicInfo(topic);
   if (info_v.name.empty()) {
     return false;
   }
@@ -281,299 +251,240 @@
   return true;
 }
 
+NT_Topic NT_GetTopic(NT_Inst inst, const char* name, size_t name_len) {
+  return nt::GetTopic(inst, std::string_view{name, name_len});
+}
+
+char* NT_GetTopicName(NT_Topic topic, size_t* name_len) {
+  auto name = nt::GetTopicName(topic);
+  if (name.empty()) {
+    *name_len = 0;
+    return nullptr;
+  }
+  struct NT_String v_name;
+  nt::ConvertToC(name, &v_name);
+  *name_len = v_name.len;
+  return v_name.str;
+}
+
+NT_Type NT_GetTopicType(NT_Topic topic) {
+  return nt::GetTopicType(topic);
+}
+
+char* NT_GetTopicTypeString(NT_Topic topic, size_t* type_len) {
+  auto type = nt::GetTopicTypeString(topic);
+  struct NT_String v_type;
+  nt::ConvertToC(type, &v_type);
+  *type_len = v_type.len;
+  return v_type.str;
+}
+
+void NT_SetTopicPersistent(NT_Topic topic, NT_Bool value) {
+  nt::SetTopicPersistent(topic, value);
+}
+
+NT_Bool NT_GetTopicPersistent(NT_Topic topic) {
+  return nt::GetTopicPersistent(topic);
+}
+
+void NT_SetTopicRetained(NT_Topic topic, NT_Bool value) {
+  nt::SetTopicRetained(topic, value);
+}
+
+NT_Bool NT_GetTopicRetained(NT_Topic topic) {
+  return nt::GetTopicRetained(topic);
+}
+
+NT_Bool NT_GetTopicExists(NT_Handle handle) {
+  return nt::GetTopicExists(handle);
+}
+
+char* NT_GetTopicProperty(NT_Topic topic, const char* name, size_t* len) {
+  wpi::json j = nt::GetTopicProperty(topic, name);
+  struct NT_String v;
+  nt::ConvertToC(j.dump(), &v);
+  *len = v.len;
+  return v.str;
+}
+
+NT_Bool NT_SetTopicProperty(NT_Topic topic, const char* name,
+                            const char* value) {
+  wpi::json j;
+  try {
+    j = wpi::json::parse(value);
+  } catch (wpi::json::parse_error&) {
+    return false;
+  }
+  nt::SetTopicProperty(topic, name, j);
+  return true;
+}
+
+void NT_DeleteTopicProperty(NT_Topic topic, const char* name) {
+  nt::DeleteTopicProperty(topic, name);
+}
+
+char* NT_GetTopicProperties(NT_Topic topic, size_t* len) {
+  wpi::json j = nt::GetTopicProperties(topic);
+  struct NT_String v;
+  nt::ConvertToC(j.dump(), &v);
+  *len = v.len;
+  return v.str;
+}
+
+NT_Bool NT_SetTopicProperties(NT_Topic topic, const char* properties) {
+  wpi::json j;
+  try {
+    j = wpi::json::parse(properties);
+  } catch (wpi::json::parse_error&) {
+    return false;
+  }
+  return nt::SetTopicProperties(topic, j);
+}
+
+NT_Subscriber NT_Subscribe(NT_Topic topic, NT_Type type, const char* typeStr,
+                           const struct NT_PubSubOptions* options) {
+  return nt::Subscribe(topic, type, typeStr, ConvertToCpp(options));
+}
+
+void NT_Unsubscribe(NT_Subscriber sub) {
+  return nt::Unsubscribe(sub);
+}
+
+NT_Publisher NT_Publish(NT_Topic topic, NT_Type type, const char* typeStr,
+                        const struct NT_PubSubOptions* options) {
+  return nt::Publish(topic, type, typeStr, ConvertToCpp(options));
+}
+
+NT_Publisher NT_PublishEx(NT_Topic topic, NT_Type type, const char* typeStr,
+                          const char* properties,
+                          const struct NT_PubSubOptions* options) {
+  wpi::json j;
+  if (properties[0] == '\0') {
+    // gracefully handle empty string
+    j = wpi::json::object();
+  } else {
+    try {
+      j = wpi::json::parse(properties);
+    } catch (wpi::json::parse_error&) {
+      return {};
+    }
+  }
+
+  return nt::PublishEx(topic, type, typeStr, j, ConvertToCpp(options));
+}
+
+void NT_Unpublish(NT_Handle pubentry) {
+  return nt::Unpublish(pubentry);
+}
+
+NT_Entry NT_GetEntryEx(NT_Topic topic, NT_Type type, const char* typeStr,
+                       const struct NT_PubSubOptions* options) {
+  return nt::GetEntry(topic, type, typeStr, ConvertToCpp(options));
+}
+
+void NT_ReleaseEntry(NT_Entry entry) {
+  nt::ReleaseEntry(entry);
+}
+
+void NT_Release(NT_Handle pubsubentry) {
+  nt::Release(pubsubentry);
+}
+
+NT_Topic NT_GetTopicFromHandle(NT_Handle pubsubentry) {
+  return nt::GetTopicFromHandle(pubsubentry);
+}
+
 /*
  * 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, {prefix, prefix_len},
-      [=](const EntryNotification& event) {
-        NT_EntryNotification c_event;
-        ConvertToC(event, &c_event);
-        callback(data, &c_event);
-        DisposeEntryNotification(&c_event);
-      },
-      flags);
+NT_ListenerPoller NT_CreateListenerPoller(NT_Inst inst) {
+  return nt::CreateListenerPoller(inst);
 }
 
-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);
+void NT_DestroyListenerPoller(NT_ListenerPoller poller) {
+  nt::DestroyListenerPoller(poller);
 }
 
-NT_EntryListenerPoller NT_CreateEntryListenerPoller(NT_Inst inst) {
-  return nt::CreateEntryListenerPoller(inst);
+struct NT_Event* NT_ReadListenerQueue(NT_ListenerPoller poller, size_t* len) {
+  auto arr_cpp = nt::ReadListenerQueue(poller);
+  return ConvertToC<NT_Event>(arr_cpp, len);
 }
 
-void NT_DestroyEntryListenerPoller(NT_EntryListenerPoller poller) {
-  nt::DestroyEntryListenerPoller(poller);
+void NT_RemoveListener(NT_Listener listener) {
+  nt::RemoveListener(listener);
 }
 
-NT_EntryListener NT_AddPolledEntryListener(NT_EntryListenerPoller poller,
-                                           const char* prefix,
-                                           size_t prefix_len,
-                                           unsigned int flags) {
-  return nt::AddPolledEntryListener(poller, {prefix, prefix_len}, flags);
+NT_Bool NT_WaitForListenerQueue(NT_Handle handle, double timeout) {
+  return nt::WaitForListenerQueue(handle, timeout);
 }
 
-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, {def, def_len}, [=](const RpcAnswer& answer) {
-    NT_RpcAnswer answer_c;
-    ConvertToC(answer, &answer_c);
-    callback(data, &answer_c);
-    NT_DisposeRpcAnswer(&answer_c);
+NT_Listener NT_AddListenerSingle(NT_Inst inst, const char* prefix,
+                                 size_t prefix_len, unsigned int mask,
+                                 void* data, NT_ListenerCallback callback) {
+  std::string_view p{prefix, prefix_len};
+  return nt::AddListener(inst, {{p}}, mask, [=](auto& event) {
+    NT_Event event_c;
+    ConvertToC(event, &event_c);
+    callback(data, &event_c);
+    DisposeEvent(&event_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, {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, {result, result_len});
-}
-
-NT_RpcCall NT_CallRpc(NT_Entry entry, const char* params, size_t params_len) {
-  return nt::CallRpc(entry, {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;
+NT_Listener NT_AddListenerMultiple(NT_Inst inst, const NT_String* prefixes,
+                                   size_t prefixes_len, unsigned int mask,
+                                   void* data, NT_ListenerCallback callback) {
+  wpi::SmallVector<std::string_view, 8> p;
+  p.reserve(prefixes_len);
+  for (size_t i = 0; i < prefixes_len; ++i) {
+    p.emplace_back(prefixes[i].str, prefixes[i].len);
   }
-
-  // convert result
-  *result_len = result.size();
-  char* result_cstr;
-  ConvertToC(result, &result_cstr);
-  return result_cstr;
+  return nt::AddListener(inst, p, mask, [=](auto& event) {
+    NT_Event event_c;
+    ConvertToC(event, &event_c);
+    callback(data, &event_c);
+    DisposeEvent(&event_c);
+  });
 }
 
-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;
+NT_Listener NT_AddListener(NT_Topic topic, unsigned int mask, void* data,
+                           NT_ListenerCallback callback) {
+  return nt::AddListener(topic, mask, [=](auto& event) {
+    NT_Event event_c;
+    ConvertToC(event, &event_c);
+    callback(data, &event_c);
+    DisposeEvent(&event_c);
+  });
+}
+
+NT_Listener NT_AddPolledListenerSingle(NT_ListenerPoller poller,
+                                       const char* prefix, size_t prefix_len,
+                                       unsigned int mask) {
+  std::string_view p{prefix, prefix_len};
+  return nt::AddPolledListener(poller, {{p}}, mask);
+}
+
+NT_Listener NT_AddPolledListenerMultiple(NT_ListenerPoller poller,
+                                         const NT_String* prefixes,
+                                         size_t prefixes_len,
+                                         unsigned int mask) {
+  wpi::SmallVector<std::string_view, 8> p;
+  p.reserve(prefixes_len);
+  for (size_t i = 0; i < prefixes_len; ++i) {
+    p.emplace_back(prefixes[i].str, prefixes[i].len);
   }
-
-  *timed_out = cpp_timed_out;
-  // convert result
-  *result_len = result.size();
-  char* result_cstr;
-  ConvertToC(result, &result_cstr);
-  return result_cstr;
+  return nt::AddPolledListener(poller, p, mask);
 }
 
-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({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({packed, packed_len}, {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*)));  // NOLINT
-  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;
+NT_Listener NT_AddPolledListener(NT_ListenerPoller poller, NT_Topic topic,
+                                 unsigned int mask) {
+  return nt::AddPolledListener(poller, topic, mask);
 }
 
 /*
  * Client/Server Functions
  */
 
-void NT_SetNetworkIdentity(NT_Inst inst, const char* name, size_t name_len) {
-  nt::SetNetworkIdentity(inst, {name, name_len});
-}
-
 unsigned int NT_GetNetworkMode(NT_Inst inst) {
   return nt::GetNetworkMode(inst);
 }
@@ -587,34 +498,21 @@
 }
 
 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);
+                    const char* listen_address, unsigned int port3,
+                    unsigned int port4) {
+  nt::StartServer(inst, persist_filename, listen_address, port3, port4);
 }
 
 void NT_StopServer(NT_Inst inst) {
   nt::StopServer(inst);
 }
 
-void NT_StartClientNone(NT_Inst inst) {
-  nt::StartClient(inst);
+void NT_StartClient3(NT_Inst inst, const char* identity) {
+  nt::StartClient3(inst, identity);
 }
 
-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<std::string_view, 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_StartClient4(NT_Inst inst, const char* identity) {
+  nt::StartClient4(inst, identity);
 }
 
 void NT_StopClient(NT_Inst inst) {
@@ -647,8 +545,8 @@
   nt::StopDSClient(inst);
 }
 
-void NT_SetUpdateRate(NT_Inst inst, double interval) {
-  nt::SetUpdateRate(inst, interval);
+void NT_FlushLocal(NT_Inst inst) {
+  nt::FlushLocal(inst);
 }
 
 void NT_Flush(NT_Inst inst) {
@@ -664,103 +562,67 @@
   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, {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, {prefix, prefix_len}, warn);
+int64_t NT_GetServerTimeOffset(NT_Inst inst, NT_Bool* valid) {
+  if (auto v = nt::GetServerTimeOffset(inst)) {
+    *valid = true;
+    return *v;
+  } else {
+    *valid = false;
+    return 0;
+  }
 }
 
 /*
  * Utility Functions
  */
 
-uint64_t NT_Now(void) {
-  return wpi::Now();
+int64_t NT_Now(void) {
+  return nt::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);
+void NT_SetNow(int64_t timestamp) {
+  nt::SetNow(timestamp);
 }
 
-NT_LoggerPoller NT_CreateLoggerPoller(NT_Inst inst) {
-  return nt::CreateLoggerPoller(inst);
+NT_Listener NT_AddLogger(NT_Inst inst, unsigned int min_level,
+                         unsigned int max_level, void* data,
+                         NT_ListenerCallback func) {
+  return nt::AddLogger(inst, min_level, max_level, [=](auto& event) {
+    NT_Event event_c;
+    ConvertToC(event, &event_c);
+    func(data, &event_c);
+    NT_DisposeEvent(&event_c);
+  });
 }
 
-void NT_DestroyLoggerPoller(NT_LoggerPoller poller) {
-  nt::DestroyLoggerPoller(poller);
-}
-
-NT_Logger NT_AddPolledLogger(NT_LoggerPoller poller, unsigned int min_level,
-                             unsigned int max_level) {
+NT_Listener NT_AddPolledLogger(NT_ListenerPoller 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_INTEGER:
+    case NT_FLOAT:
     case NT_DOUBLE:
       break;
     case NT_STRING:
-    case NT_RAW:
-    case NT_RPC:
       std::free(value->data.v_string.str);
       break;
+    case NT_RAW:
+      std::free(value->data.v_raw.data);
+      break;
     case NT_BOOLEAN_ARRAY:
       std::free(value->data.arr_boolean.arr);
       break;
+    case NT_INTEGER_ARRAY:
+      std::free(value->data.arr_int.arr);
+      break;
+    case NT_FLOAT_ARRAY:
+      std::free(value->data.arr_float.arr);
+      break;
     case NT_DOUBLE_ARRAY:
       std::free(value->data.arr_double.arr);
       break;
@@ -776,11 +638,13 @@
   }
   value->type = NT_UNASSIGNED;
   value->last_change = 0;
+  value->server_time = 0;
 }
 
 void NT_InitValue(NT_Value* value) {
   value->type = NT_UNASSIGNED;
   value->last_change = 0;
+  value->server_time = 0;
 }
 
 void NT_DisposeString(NT_String* str) {
@@ -794,7 +658,10 @@
   str->len = 0;
 }
 
-void NT_DisposeEntryArray(NT_Entry* arr, size_t /*count*/) {
+void NT_DisposeValueArray(struct NT_Value* arr, size_t count) {
+  for (size_t i = 0; i < count; ++i) {
+    NT_DisposeValue(&arr[i]);
+  }
   std::free(arr);
 }
 
@@ -805,108 +672,59 @@
   std::free(arr);
 }
 
-void NT_DisposeEntryInfoArray(NT_EntryInfo* arr, size_t count) {
+void NT_DisposeTopicInfoArray(NT_TopicInfo* arr, size_t count) {
   for (size_t i = 0; i < count; i++) {
-    DisposeEntryInfo(&arr[i]);
+    DisposeTopicInfo(&arr[i]);
   }
   std::free(arr);
 }
 
-void NT_DisposeEntryInfo(NT_EntryInfo* info) {
-  DisposeEntryInfo(info);
+void NT_DisposeTopicInfo(NT_TopicInfo* info) {
+  DisposeTopicInfo(info);
 }
 
-void NT_DisposeEntryNotificationArray(NT_EntryNotification* arr, size_t count) {
+void NT_DisposeEventArray(NT_Event* arr, size_t count) {
   for (size_t i = 0; i < count; i++) {
-    DisposeEntryNotification(&arr[i]);
+    DisposeEvent(&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->filename);
-  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);
+void NT_DisposeEvent(NT_Event* event) {
+  DisposeEvent(event);
 }
 
 /* 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. */
+int64_t* NT_AllocateIntegerArray(size_t size) {
+  int64_t* retVal =
+      static_cast<int64_t*>(wpi::safe_malloc(size * sizeof(int64_t)));
+  return retVal;
+}
+
+float* NT_AllocateFloatArray(size_t size) {
+  float* retVal = static_cast<float*>(wpi::safe_malloc(size * sizeof(float)));
+  return retVal;
+}
+
 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)));
@@ -916,99 +734,25 @@
 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_FreeIntegerArray(int64_t* v_int) {
+  std::free(v_int);
+}
+void NT_FreeFloatArray(float* v_float) {
+  std::free(v_float);
+}
+void NT_FreeDoubleArray(double* v_double) {
+  std::free(v_double);
+}
 void NT_FreeStringArray(struct NT_String* v_string, size_t arr_size) {
-  for (size_t i = 0; i < arr_size; i++) {
+  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({str, str_len}, time));
-    return 1;
-  } else {
-    return nt::SetEntryValue(entry, Value::MakeString({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({raw, raw_len}, time));
-    return 1;
-  } else {
-    return nt::SetEntryValue(entry, Value::MakeRaw({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::span(arr, size), time));
-    return 1;
-  } else {
-    return nt::SetEntryValue(
-        entry, Value::MakeBooleanArray(wpi::span(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({arr, size}, time));
-    return 1;
-  } else {
-    return nt::SetEntryValue(entry, Value::MakeDoubleArray({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.emplace_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;
@@ -1026,6 +770,26 @@
   return 1;
 }
 
+NT_Bool NT_GetValueInteger(const struct NT_Value* value, uint64_t* last_change,
+                           int64_t* v_int) {
+  if (!value || value->type != NT_Type::NT_INTEGER) {
+    return 0;
+  }
+  *last_change = value->last_change;
+  *v_int = value->data.v_int;
+  return 1;
+}
+
+NT_Bool NT_GetValueFloat(const struct NT_Value* value, uint64_t* last_change,
+                         float* v_float) {
+  if (!value || value->type != NT_Type::NT_FLOAT) {
+    return 0;
+  }
+  *last_change = value->last_change;
+  *v_float = value->data.v_float;
+  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) {
@@ -1049,16 +813,16 @@
   return str;
 }
 
-char* NT_GetValueRaw(const struct NT_Value* value, uint64_t* last_change,
-                     size_t* raw_len) {
+uint8_t* 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);
+  *raw_len = value->data.v_raw.size;
+  uint8_t* raw =
+      static_cast<uint8_t*>(wpi::safe_malloc(value->data.v_raw.size));
+  std::memcpy(raw, value->data.v_raw.data, value->data.v_raw.size);
   return raw;
 }
 
@@ -1076,6 +840,34 @@
   return arr;
 }
 
+int64_t* NT_GetValueIntegerArray(const struct NT_Value* value,
+                                 uint64_t* last_change, size_t* arr_size) {
+  if (!value || value->type != NT_Type::NT_INTEGER_ARRAY) {
+    return nullptr;
+  }
+  *last_change = value->last_change;
+  *arr_size = value->data.arr_int.size;
+  int64_t* arr = static_cast<int64_t*>(
+      wpi::safe_malloc(value->data.arr_int.size * sizeof(int64_t)));
+  std::memcpy(arr, value->data.arr_int.arr,
+              value->data.arr_int.size * sizeof(int64_t));
+  return arr;
+}
+
+float* NT_GetValueFloatArray(const struct NT_Value* value,
+                             uint64_t* last_change, size_t* arr_size) {
+  if (!value || value->type != NT_Type::NT_FLOAT_ARRAY) {
+    return nullptr;
+  }
+  *last_change = value->last_change;
+  *arr_size = value->data.arr_float.size;
+  float* arr = static_cast<float*>(
+      wpi::safe_malloc(value->data.arr_float.size * sizeof(float)));
+  std::memcpy(arr, value->data.arr_float.arr,
+              value->data.arr_float.size * sizeof(float));
+  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) {
@@ -1108,151 +900,4 @@
   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({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({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::span(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({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.emplace_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
index 8616aaf..cfb5af2 100644
--- a/ntcore/src/main/native/cpp/ntcore_cpp.cpp
+++ b/ntcore/src/main/native/cpp/ntcore_cpp.cpp
@@ -4,21 +4,35 @@
 
 #include <stdint.h>
 
+#include <atomic>
 #include <cassert>
 #include <cstdio>
 #include <cstdlib>
 
+#include <fmt/format.h>
+#include <wpi/json.h>
 #include <wpi/timestamp.h>
 
 #include "Handle.h"
 #include "InstanceImpl.h"
 #include "Log.h"
-#include "WireDecoder.h"
-#include "WireEncoder.h"
+#include "Types_internal.h"
 #include "ntcore.h"
+#include "ntcore_c.h"
+
+static std::atomic_bool gNowSet{false};
+static std::atomic<int64_t> gNowTime;
 
 namespace nt {
 
+wpi::json TopicInfo::GetProperties() const {
+  try {
+    return wpi::json::parse(properties);
+  } catch (wpi::json::parse_error&) {
+    return wpi::json::object();
+  }
+}
+
 /*
  * Instance Functions
  */
@@ -31,6 +45,12 @@
   return Handle{InstanceImpl::Alloc(), 0, Handle::kInstance};
 }
 
+void ResetInstance(NT_Inst inst) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->Reset();
+  }
+}
+
 void DestroyInstance(NT_Inst inst) {
   int i = Handle{inst}.GetTypedInst(Handle::kInstance);
   if (i < 0) {
@@ -42,7 +62,7 @@
 NT_Inst GetInstanceFromHandle(NT_Handle handle) {
   Handle h{handle};
   auto type = h.GetType();
-  if (type >= Handle::kConnectionListener && type <= Handle::kRpcCallPoller) {
+  if (type >= Handle::kListener && type < Handle::kTypeMax) {
     return Handle(h.GetInst(), 0, Handle::kInstance);
   }
 
@@ -54,1120 +74,704 @@
  */
 
 NT_Entry GetEntry(NT_Inst inst, std::string_view 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, std::string_view prefix,
-                                 unsigned int types) {
-  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
-  auto ii = InstanceImpl::Get(i);
-  if (!ii) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.GetEntry(name);
+  } else {
     return {};
   }
-
-  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) {
+  if (auto ii = InstanceImpl::GetHandle(entry)) {
+    return ii->localStorage.GetEntryName(entry);
+  } else {
     return {};
   }
-
-  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;
+  if (auto ii = InstanceImpl::GetHandle(entry)) {
+    return ii->localStorage.GetEntryType(entry);
+  } else {
+    return {};
   }
-
-  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;
+int64_t GetEntryLastChange(NT_Handle subentry) {
+  if (auto ii = InstanceImpl::GetHandle(subentry)) {
+    return ii->localStorage.GetEntryLastChange(subentry);
+  } else {
+    return {};
   }
-
-  return ii->storage.GetEntryLastChange(id);
 }
 
-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;
+Value GetEntryValue(NT_Handle subentry) {
+  if (auto ii = InstanceImpl::GetHandle(subentry)) {
+    return ii->localStorage.GetEntryValue(subentry);
+  } else {
+    return {};
   }
-
-  return ii->storage.GetEntryValue(id);
 }
 
-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;
+bool SetDefaultEntryValue(NT_Entry entry, const Value& value) {
+  if (auto ii = InstanceImpl::GetHandle(entry)) {
+    return ii->localStorage.SetDefaultEntryValue(entry, value);
+  } else {
+    return {};
   }
-
-  return ii->storage.SetDefaultEntryValue(id, 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;
+bool SetEntryValue(NT_Entry entry, const Value& value) {
+  if (auto ii = InstanceImpl::GetHandle(entry)) {
+    return ii->localStorage.SetEntryValue(entry, value);
+  } else {
+    return {};
   }
-
-  return ii->storage.SetEntryValue(id, 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(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;
+  if (auto ii = InstanceImpl::GetHandle(entry)) {
+    ii->localStorage.SetEntryFlags(entry, flags);
   }
-
-  ii->storage.SetEntryFlags(id, flags);
 }
 
 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(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(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(NT_Inst inst, std::string_view prefix,
-                                    unsigned int types) {
-  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
-  auto ii = InstanceImpl::Get(i);
-  if (!ii) {
+  if (auto ii = InstanceImpl::GetHandle(entry)) {
+    return ii->localStorage.GetEntryFlags(entry);
+  } else {
     return {};
   }
-
-  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;
+std::vector<Value> ReadQueueValue(NT_Handle subentry) {
+  if (auto ii = InstanceImpl::GetHandle(subentry)) {
+    return ii->localStorage.ReadQueueValue(subentry);
+  } else {
+    return {};
   }
+}
 
-  return ii->storage.GetEntryInfo(i, id);
+/*
+ * Topic Functions
+ */
+
+std::vector<NT_Topic> GetTopics(NT_Inst inst, std::string_view prefix,
+                                unsigned int types) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.GetTopics(prefix, types);
+  } else {
+    return {};
+  }
+}
+
+std::vector<NT_Topic> GetTopics(NT_Inst inst, std::string_view prefix,
+                                std::span<const std::string_view> types) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.GetTopics(prefix, types);
+  } else {
+    return {};
+  }
+}
+
+std::vector<TopicInfo> GetTopicInfo(NT_Inst inst, std::string_view prefix,
+                                    unsigned int types) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.GetTopicInfo(prefix, types);
+  } else {
+    return {};
+  }
+}
+
+std::vector<TopicInfo> GetTopicInfo(NT_Inst inst, std::string_view prefix,
+                                    std::span<const std::string_view> types) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.GetTopicInfo(prefix, types);
+  } else {
+    return {};
+  }
+}
+
+TopicInfo GetTopicInfo(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicInfo(topic);
+  } else {
+    return {};
+  }
+}
+
+NT_Topic GetTopic(NT_Inst inst, std::string_view name) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.GetTopic(name);
+  } else {
+    return {};
+  }
+}
+
+std::string GetTopicName(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicName(topic);
+  } else {
+    return {};
+  }
+}
+
+NT_Type GetTopicType(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicType(topic);
+  } else {
+    return {};
+  }
+}
+
+std::string GetTopicTypeString(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicTypeString(topic);
+  } else {
+    return {};
+  }
+}
+
+void SetTopicPersistent(NT_Topic topic, bool value) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    ii->localStorage.SetTopicPersistent(topic, value);
+  } else {
+    return;
+  }
+}
+
+bool GetTopicPersistent(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicPersistent(topic);
+  } else {
+    return {};
+  }
+}
+
+void SetTopicRetained(NT_Topic topic, bool value) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    ii->localStorage.SetTopicRetained(topic, value);
+  } else {
+    return;
+  }
+}
+
+bool GetTopicRetained(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicRetained(topic);
+  } else {
+    return {};
+  }
+}
+
+bool GetTopicExists(NT_Handle handle) {
+  if (auto ii = InstanceImpl::GetHandle(handle)) {
+    return ii->localStorage.GetTopicExists(handle);
+  }
+  return false;
+}
+
+wpi::json GetTopicProperty(NT_Topic topic, std::string_view name) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicProperty(topic, name);
+  } else {
+    return {};
+  }
+}
+
+void SetTopicProperty(NT_Topic topic, std::string_view name,
+                      const wpi::json& value) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    ii->localStorage.SetTopicProperty(topic, name, value);
+  } else {
+    return;
+  }
+}
+
+void DeleteTopicProperty(NT_Topic topic, std::string_view name) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    ii->localStorage.DeleteTopicProperty(topic, name);
+  }
+}
+
+wpi::json GetTopicProperties(NT_Topic topic) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetTopicProperties(topic);
+  } else {
+    return {};
+  }
+}
+
+bool SetTopicProperties(NT_Topic topic, const wpi::json& properties) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.SetTopicProperties(topic, properties);
+  } else {
+    return {};
+  }
+}
+
+NT_Subscriber Subscribe(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                        const PubSubOptions& options) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.Subscribe(topic, type, typeStr, options);
+  } else {
+    return {};
+  }
+}
+
+void Unsubscribe(NT_Subscriber sub) {
+  if (auto ii = InstanceImpl::GetTyped(sub, Handle::kSubscriber)) {
+    ii->localStorage.Unsubscribe(sub);
+  }
+}
+
+NT_Publisher Publish(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                     const PubSubOptions& options) {
+  return PublishEx(topic, type, typeStr, wpi::json::object(), options);
+}
+
+NT_Publisher PublishEx(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                       const wpi::json& properties,
+                       const PubSubOptions& options) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.Publish(topic, type, typeStr, properties, options);
+  } else {
+    return {};
+  }
+}
+
+void Unpublish(NT_Handle pubentry) {
+  if (auto ii = InstanceImpl::GetHandle(pubentry)) {
+    ii->localStorage.Unpublish(pubentry);
+  }
+}
+
+NT_Entry GetEntry(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                  const PubSubOptions& options) {
+  if (auto ii = InstanceImpl::GetTyped(topic, Handle::kTopic)) {
+    return ii->localStorage.GetEntry(topic, type, typeStr, options);
+  } else {
+    return {};
+  }
+}
+
+void ReleaseEntry(NT_Entry entry) {
+  if (auto ii = InstanceImpl::GetTyped(entry, Handle::kEntry)) {
+    ii->localStorage.ReleaseEntry(entry);
+  }
+}
+
+void Release(NT_Handle pubsubentry) {
+  if (auto ii = InstanceImpl::GetHandle(pubsubentry)) {
+    ii->localStorage.Release(pubsubentry);
+  }
+}
+
+NT_Topic GetTopicFromHandle(NT_Handle pubsubentry) {
+  if (auto ii = InstanceImpl::GetHandle(pubsubentry)) {
+    return ii->localStorage.GetTopicFromHandle(pubsubentry);
+  } else {
+    return {};
+  }
+}
+
+NT_MultiSubscriber SubscribeMultiple(NT_Inst inst,
+                                     std::span<const std::string_view> prefixes,
+                                     const PubSubOptions& options) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.SubscribeMultiple(prefixes, options);
+  } else {
+    return {};
+  }
+}
+
+void UnsubscribeMultiple(NT_MultiSubscriber sub) {
+  if (auto ii = InstanceImpl::GetTyped(sub, Handle::kMultiSubscriber)) {
+    ii->localStorage.UnsubscribeMultiple(sub);
+  }
 }
 
 /*
  * Callback Creation Functions
  */
 
-NT_EntryListener AddEntryListener(
-    NT_Inst inst, std::string_view 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;
+static void CleanupListeners(
+    InstanceImpl& ii,
+    std::span<const std::pair<NT_Listener, unsigned int>> listeners) {
+  bool updateMinLevel = false;
+  for (auto&& [listener, mask] : listeners) {
+    // connection doesn't need removal notification
+    if ((mask & (NT_EVENT_TOPIC | NT_EVENT_VALUE_ALL)) != 0) {
+      ii.localStorage.RemoveListener(listener, mask);
+    }
+    if ((mask & NT_EVENT_LOGMESSAGE) != 0) {
+      ii.logger_impl.RemoveListener(listener);
+      updateMinLevel = true;
+    }
   }
-
-  unsigned int uid = ii->storage.AddListener(prefix, callback, flags);
-  return Handle(i, uid, Handle::kEntryListener);
+  if (updateMinLevel) {
+    ii.logger.set_min_level(ii.logger_impl.GetMinLevel());
+  }
 }
 
-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;
+static void DoAddListener(InstanceImpl& ii, NT_Listener listener,
+                          NT_Handle handle, unsigned int mask) {
+  if (Handle{handle}.IsType(Handle::kInstance)) {
+    if ((mask & NT_EVENT_CONNECTION) != 0) {
+      ii.connectionList.AddListener(listener, mask);
+    }
+    if ((mask & NT_EVENT_LOGMESSAGE) != 0) {
+      ii.logger_impl.AddListener(listener, NT_LOG_INFO, UINT_MAX);
+    }
+    if ((mask & NT_EVENT_TIMESYNC) != 0) {
+      ii.AddTimeSyncListener(listener, mask);
+    }
+  } else if ((mask & (NT_EVENT_TOPIC | NT_EVENT_VALUE_ALL)) != 0) {
+    ii.localStorage.AddListener(listener, handle, mask);
   }
-
-  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,
-                                        std::string_view 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) {
+NT_ListenerPoller CreateListenerPoller(NT_Inst inst) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->listenerStorage.CreateListenerPoller();
+  } else {
     return {};
   }
-
-  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) {
+void DestroyListenerPoller(NT_ListenerPoller poller) {
+  if (auto ii = InstanceImpl::GetTyped(poller, Handle::kListenerPoller)) {
+    CleanupListeners(*ii, ii->listenerStorage.DestroyListenerPoller(poller));
+  }
+}
+
+std::vector<Event> ReadListenerQueue(NT_ListenerPoller poller) {
+  if (auto ii = InstanceImpl::GetTyped(poller, Handle::kListenerPoller)) {
+    return ii->listenerStorage.ReadListenerQueue(poller);
+  } else {
     return {};
   }
-
-  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;
+void RemoveListener(NT_Listener listener) {
+  if (auto ii = InstanceImpl::GetTyped(listener, Handle::kListener)) {
+    CleanupListeners(*ii, ii->listenerStorage.RemoveListener(listener));
   }
-
-  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(
-    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) {
+bool WaitForListenerQueue(NT_Handle handle, double timeout) {
+  if (auto ii = InstanceImpl::GetHandle(handle)) {
+    return ii->listenerStorage.WaitForListenerQueue(timeout);
+  } else {
     return {};
   }
-
-  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) {
+NT_Listener AddListener(NT_Inst inst,
+                        std::span<const std::string_view> prefixes,
+                        unsigned int mask, ListenerCallback callback) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    if ((mask & (NT_EVENT_TOPIC | NT_EVENT_VALUE_ALL)) != 0) {
+      auto listener = ii->listenerStorage.AddListener(std::move(callback));
+      ii->localStorage.AddListener(listener, prefixes, mask);
+      return listener;
+    }
+  }
+  return {};
+}
+
+NT_Listener AddListener(NT_Handle handle, unsigned int mask,
+                        ListenerCallback callback) {
+  if (auto ii = InstanceImpl::GetHandle(handle)) {
+    auto listener = ii->listenerStorage.AddListener(std::move(callback));
+    DoAddListener(*ii, listener, handle, mask);
+    return listener;
+  } else {
     return {};
   }
-
-  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;
+NT_Listener AddPolledListener(NT_ListenerPoller poller,
+                              std::span<const std::string_view> prefixes,
+                              unsigned int mask) {
+  if (auto ii = InstanceImpl::GetTyped(poller, Handle::kListenerPoller)) {
+    if ((mask & (NT_EVENT_TOPIC | NT_EVENT_VALUE_ALL)) != 0) {
+      auto listener = ii->listenerStorage.AddListener(poller);
+      ii->localStorage.AddListener(listener, prefixes, mask);
+      return listener;
+    }
   }
-
-  ii->connection_notifier.CancelPoll(id);
+  return {};
 }
 
-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;
+NT_Listener AddPolledListener(NT_ListenerPoller poller, NT_Handle handle,
+                              unsigned int mask) {
+  if (auto ii = InstanceImpl::GetTyped(poller, Handle::kListenerPoller)) {
+    if (Handle{handle}.GetInst() != Handle{poller}.GetInst()) {
+      WPI_ERROR(
+          ii->logger,
+          "AddPolledListener(): trying to listen to handle {} (instance {}) "
+          "with poller {} (instance {}), ignored due to different instance",
+          handle, Handle{handle}.GetInst(), poller, Handle{poller}.GetInst());
+      return {};
+    }
+    auto listener = ii->listenerStorage.AddListener(poller);
+    DoAddListener(*ii, listener, handle, mask);
+    return listener;
+  } else {
+    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;
+int64_t Now() {
+  if (gNowSet) {
+    return gNowTime;
   }
-  return ii->connection_notifier.WaitForQueue(timeout);
+  return wpi::Now();
+}
+
+void SetNow(int64_t timestamp) {
+  gNowTime = timestamp;
+  gNowSet = true;
+}
+
+NT_Type GetTypeFromString(std::string_view typeString) {
+  if (typeString.empty()) {
+    return NT_UNASSIGNED;
+  } else {
+    return StringToType(typeString);
+  }
+}
+
+std::string_view GetStringFromType(NT_Type type) {
+  if (type == NT_UNASSIGNED) {
+    return "";
+  } else {
+    return TypeToString(type);
+  }
 }
 
 /*
- * Remote Procedure Call Functions
+ * Data Logger Functions
  */
-
-void CreateRpc(NT_Entry entry, std::string_view 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) {
+NT_DataLogger StartEntryDataLog(NT_Inst inst, wpi::log::DataLog& log,
+                                std::string_view prefix,
+                                std::string_view logPrefix) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->localStorage.StartDataLog(log, prefix, logPrefix);
+  } else {
     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;
+void StopEntryDataLog(NT_DataLogger logger) {
+  if (auto ii = InstanceImpl::GetTyped(logger, Handle::kDataLogger)) {
+    ii->localStorage.StopDataLog(logger);
   }
-
-  ii->rpc_server.RemovePoller(id);
 }
 
-void CreatePolledRpc(NT_Entry entry, std::string_view 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 {};
-  }
-
-  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 {};
-  }
-
-  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, std::string_view 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, std::string_view params) {
-  Handle handle{entry};
-  int id = handle.GetTypedIndex(Handle::kEntry);
-  int i = handle.GetInst();
-  auto ii = InstanceImpl::Get(i);
-  if (id < 0 || !ii) {
+NT_ConnectionDataLogger StartConnectionDataLog(NT_Inst inst,
+                                               wpi::log::DataLog& log,
+                                               std::string_view name) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->connectionList.StartDataLog(log, name);
+  } else {
     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;
+void StopConnectionDataLog(NT_ConnectionDataLogger logger) {
+  if (auto ii = InstanceImpl::GetTyped(logger, Handle::kConnectionDataLogger)) {
+    ii->connectionList.StopDataLog(logger);
   }
-
-  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 std::string{enc.ToStringView()};
-}
-
-bool UnpackRpcDefinition(std::string_view 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(wpi::span<const std::shared_ptr<Value>> values) {
-  WireEncoder enc(0x0300);
-  for (auto& value : values) {
-    enc.WriteValue(*value);
-  }
-  return std::string{enc.ToStringView()};
-}
-
-std::vector<std::shared_ptr<Value>> UnpackRpcValues(
-    std::string_view packed, wpi::span<const 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(NT_Inst inst, std::string_view name) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
-  }
-
-  ii->dispatcher.SetIdentity(name);
-}
-
 unsigned int GetNetworkMode(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return 0;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->networkMode;
+  } else {
+    return {};
   }
-
-  return ii->dispatcher.GetNetworkMode();
 }
 
 void StartLocal(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StartLocal();
   }
-
-  ii->dispatcher.StartLocal();
 }
 
 void StopLocal(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StopLocal();
   }
-
-  ii->dispatcher.Stop();
 }
 
 void StartServer(NT_Inst inst, std::string_view persist_filename,
-                 const char* listen_address, unsigned int port) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+                 const char* listen_address, unsigned int port3,
+                 unsigned int port4) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StartServer(persist_filename, listen_address, port3, port4);
   }
-
-  ii->dispatcher.StartServer(persist_filename, listen_address, port);
 }
 
 void StopServer(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StopServer();
   }
-
-  ii->dispatcher.Stop();
 }
 
-void StartClient(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+void StartClient3(NT_Inst inst, std::string_view identity) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StartClient3(identity);
   }
-
-  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;
+void StartClient4(NT_Inst inst, std::string_view identity) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StartClient4(identity);
   }
-
-  ii->dispatcher.SetServer(server_name, port);
-  ii->dispatcher.StartClient();
-}
-
-void StartClient(
-    NT_Inst inst,
-    wpi::span<const std::pair<std::string_view, 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(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    ii->StopClient();
   }
-
-  ii->dispatcher.Stop();
 }
 
 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);
+  SetServer(inst, {{{server_name, port}}});
 }
 
 void SetServer(
     NT_Inst inst,
-    wpi::span<const std::pair<std::string_view, unsigned int>> servers) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+    std::span<const std::pair<std::string_view, unsigned int>> servers) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    std::vector<std::pair<std::string, unsigned int>> serversCopy;
+    serversCopy.reserve(servers.size());
+    for (auto&& server : servers) {
+      serversCopy.emplace_back(std::string{server.first}, server.second);
+    }
+    ii->SetServers(serversCopy);
   }
-
-  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;
-  }
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    std::vector<std::pair<std::string, unsigned int>> servers;
+    servers.reserve(5);
 
-  ii->dispatcher.SetServerTeam(team, port);
+    // 10.te.am.2
+    servers.emplace_back(fmt::format("10.{}.{}.2", static_cast<int>(team / 100),
+                                     static_cast<int>(team % 100)),
+                         port);
+
+    // 172.22.11.2
+    servers.emplace_back("172.22.11.2", port);
+
+    // roboRIO-<team>-FRC.local
+    servers.emplace_back(fmt::format("roboRIO-{}-FRC.local", team), port);
+
+    // roboRIO-<team>-FRC.lan
+    servers.emplace_back(fmt::format("roboRIO-{}-FRC.lan", team), port);
+
+    // roboRIO-<team>-FRC.frc-field.local
+    servers.emplace_back(fmt::format("roboRIO-{}-FRC.frc-field.local", team),
+                         port);
+
+    ii->SetServers(servers);
+  }
 }
 
 void StartDSClient(NT_Inst inst, unsigned int port) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    if (auto client = ii->GetClient()) {
+      client->StartDSClient(port);
+    }
   }
-
-  ii->ds_client.Start(port);
 }
 
 void StopDSClient(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    if (auto client = ii->GetClient()) {
+      client->StopDSClient();
+    }
   }
-
-  ii->ds_client.Stop();
 }
 
-void SetUpdateRate(NT_Inst inst, double interval) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+void FlushLocal(NT_Inst inst) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    if (auto client = ii->GetClient()) {
+      client->FlushLocal();
+    } else if (auto server = ii->GetServer()) {
+      server->FlushLocal();
+    }
   }
-
-  ii->dispatcher.SetUpdateRate(interval);
 }
 
 void Flush(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
-    return;
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    if (auto client = ii->GetClient()) {
+      client->Flush();
+    } else if (auto server = ii->GetServer()) {
+      server->Flush();
+    }
   }
-
-  ii->dispatcher.Flush();
 }
 
 std::vector<ConnectionInfo> GetConnections(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->connectionList.GetConnections();
+  } else {
     return {};
   }
-
-  return ii->dispatcher.GetConnections();
 }
 
 bool IsConnected(NT_Inst inst) {
-  auto ii = InstanceImpl::Get(Handle{inst}.GetTypedInst(Handle::kInstance));
-  if (!ii) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->networkMode == NT_NET_MODE_LOCAL ||
+           ii->connectionList.IsConnected();
+  } else {
     return false;
   }
-
-  return ii->dispatcher.IsConnected();
 }
 
-/*
- * Persistent Functions
- */
-
-const char* SavePersistent(NT_Inst inst, std::string_view 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(
-    NT_Inst inst, std::string_view 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, std::string_view filename,
-                        std::string_view 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, std::string_view filename, std::string_view 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);
-}
-
-NT_Logger AddLogger(NT_Inst inst,
-                    std::function<void(const LogMessage& msg)> func,
-                    unsigned int minLevel, unsigned int maxLevel) {
-  int i = Handle{inst}.GetTypedInst(Handle::kInstance);
-  auto ii = InstanceImpl::Get(i);
-  if (!ii) {
-    return 0;
-  }
-
-  if (minLevel < ii->logger.min_level()) {
-    ii->logger.set_min_level(minLevel);
-  }
-
-  return Handle(i, ii->logger_impl.Add(func, minLevel, maxLevel),
-                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) {
+std::optional<int64_t> GetServerTimeOffset(NT_Inst inst) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    return ii->GetServerTimeOffset();
+  } else {
     return {};
   }
-
-  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) {
+NT_Listener AddLogger(NT_Inst inst, unsigned int minLevel,
+                      unsigned int maxLevel, ListenerCallback func) {
+  if (auto ii = InstanceImpl::GetTyped(inst, Handle::kInstance)) {
+    if (minLevel < ii->logger.min_level()) {
+      ii->logger.set_min_level(minLevel);
+    }
+    auto listener = ii->listenerStorage.AddListener(std::move(func));
+    ii->logger_impl.AddListener(listener, minLevel, maxLevel);
+    return listener;
+  } else {
     return {};
   }
-
-  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;
+NT_Listener AddPolledLogger(NT_ListenerPoller poller, unsigned int minLevel,
+                            unsigned int maxLevel) {
+  if (auto ii = InstanceImpl::GetTyped(poller, Handle::kListenerPoller)) {
+    if (minLevel < ii->logger.min_level()) {
+      ii->logger.set_min_level(minLevel);
+    }
+    auto listener = ii->listenerStorage.AddListener(poller);
+    ii->logger_impl.AddListener(listener, minLevel, maxLevel);
+    return listener;
+  } else {
+    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_meta.cpp b/ntcore/src/main/native/cpp/ntcore_meta.cpp
new file mode 100644
index 0000000..05cb4b7
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ntcore_meta.cpp
@@ -0,0 +1,210 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <fmt/format.h>
+#include <wpi/MessagePack.h>
+#include <wpi/mpack.h>
+
+#include "ntcore_cpp.h"
+
+using namespace mpack;
+
+using namespace nt::meta;
+
+static SubscriberOptions DecodeSubscriberOptions(mpack_reader_t& r) {
+  SubscriberOptions options;
+  uint32_t numMapElem = mpack_expect_map(&r);
+  for (uint32_t j = 0; j < numMapElem; ++j) {
+    std::string key;
+    mpack_expect_str(&r, &key);
+    if (key == "topicsonly") {
+      options.topicsOnly = mpack_expect_bool(&r);
+    } else if (key == "all") {
+      options.sendAll = mpack_expect_bool(&r);
+    } else if (key == "periodic") {
+      options.periodic = mpack_expect_float(&r);
+    } else if (key == "prefix") {
+      options.prefixMatch = mpack_expect_bool(&r);
+    } else {
+      // TODO: Save other options
+      mpack_discard(&r);
+    }
+  }
+  mpack_done_map(&r);
+  return options;
+}
+
+std::optional<std::vector<ClientPublisher>> nt::meta::DecodeClientPublishers(
+    std::span<const uint8_t> data) {
+  mpack_reader_t r;
+  mpack_reader_init_data(&r, data);
+  uint32_t numPub = mpack_expect_array_max(&r, 1000);
+  std::vector<ClientPublisher> publishers;
+  publishers.reserve(numPub);
+  for (uint32_t i = 0; i < numPub; ++i) {
+    ClientPublisher pub;
+    uint32_t numMapElem = mpack_expect_map(&r);
+    for (uint32_t j = 0; j < numMapElem; ++j) {
+      std::string key;
+      mpack_expect_str(&r, &key);
+      if (key == "uid") {
+        pub.uid = mpack_expect_i64(&r);
+      } else if (key == "topic") {
+        mpack_expect_str(&r, &pub.topic);
+      } else {
+        mpack_discard(&r);
+      }
+    }
+    mpack_done_map(&r);
+    publishers.emplace_back(std::move(pub));
+  }
+  mpack_done_array(&r);
+  if (mpack_reader_destroy(&r) == mpack_ok) {
+    return {std::move(publishers)};
+  } else {
+    return {};
+  }
+}
+
+std::optional<std::vector<ClientSubscriber>> nt::meta::DecodeClientSubscribers(
+    std::span<const uint8_t> data) {
+  mpack_reader_t r;
+  mpack_reader_init_data(&r, data);
+  uint32_t numSub = mpack_expect_array_max(&r, 1000);
+  std::vector<ClientSubscriber> subscribers;
+  subscribers.reserve(numSub);
+  for (uint32_t i = 0; i < numSub; ++i) {
+    ClientSubscriber sub;
+    uint32_t numMapElem = mpack_expect_map(&r);
+    for (uint32_t j = 0; j < numMapElem; ++j) {
+      std::string key;
+      mpack_expect_str(&r, &key);
+      if (key == "uid") {
+        sub.uid = mpack_expect_i64(&r);
+      } else if (key == "topics") {
+        uint32_t numPrefix = mpack_expect_array_max(&r, 100);
+        sub.topics.reserve(numPrefix);
+        for (uint32_t k = 0; k < numPrefix; ++k) {
+          std::string val;
+          if (mpack_expect_str(&r, &val) == mpack_ok) {
+            sub.topics.emplace_back(std::move(val));
+          }
+        }
+        mpack_done_array(&r);
+      } else if (key == "options") {
+        sub.options = DecodeSubscriberOptions(r);
+      } else {
+        mpack_discard(&r);
+      }
+    }
+    mpack_done_map(&r);
+    subscribers.emplace_back(std::move(sub));
+  }
+  mpack_done_array(&r);
+  if (mpack_reader_destroy(&r) == mpack_ok) {
+    return {std::move(subscribers)};
+  } else {
+    return {};
+  }
+}
+
+std::optional<std::vector<TopicPublisher>> nt::meta::DecodeTopicPublishers(
+    std::span<const uint8_t> data) {
+  mpack_reader_t r;
+  mpack_reader_init_data(&r, data);
+  uint32_t numPub = mpack_expect_array_max(&r, 1000);
+  std::vector<TopicPublisher> publishers;
+  publishers.reserve(numPub);
+  for (uint32_t i = 0; i < numPub; ++i) {
+    TopicPublisher pub;
+    uint32_t numMapElem = mpack_expect_map(&r);
+    for (uint32_t j = 0; j < numMapElem; ++j) {
+      std::string key;
+      mpack_expect_str(&r, &key);
+      if (key == "pubuid") {
+        pub.pubuid = mpack_expect_i64(&r);
+      } else if (key == "client") {
+        mpack_expect_str(&r, &pub.client);
+      } else {
+        mpack_discard(&r);
+      }
+    }
+    mpack_done_map(&r);
+    publishers.emplace_back(std::move(pub));
+  }
+  mpack_done_array(&r);
+  if (mpack_reader_destroy(&r) == mpack_ok) {
+    return {std::move(publishers)};
+  } else {
+    return {};
+  }
+}
+
+std::optional<std::vector<TopicSubscriber>> nt::meta::DecodeTopicSubscribers(
+    std::span<const uint8_t> data) {
+  mpack_reader_t r;
+  mpack_reader_init_data(&r, data);
+  uint32_t numSub = mpack_expect_array_max(&r, 1000);
+  std::vector<TopicSubscriber> subscribers;
+  subscribers.reserve(numSub);
+  for (uint32_t i = 0; i < numSub; ++i) {
+    TopicSubscriber sub;
+    uint32_t numMapElem = mpack_expect_map(&r);
+    for (uint32_t j = 0; j < numMapElem; ++j) {
+      std::string key;
+      mpack_expect_str(&r, &key);
+      if (key == "subuid") {
+        sub.subuid = mpack_expect_i64(&r);
+      } else if (key == "client") {
+        mpack_expect_str(&r, &sub.client);
+      } else if (key == "options") {
+        sub.options = DecodeSubscriberOptions(r);
+      } else {
+        mpack_discard(&r);
+      }
+    }
+    mpack_done_map(&r);
+    subscribers.emplace_back(std::move(sub));
+  }
+  mpack_done_array(&r);
+  if (mpack_reader_destroy(&r) == mpack_ok) {
+    return {std::move(subscribers)};
+  } else {
+    return {};
+  }
+}
+
+std::optional<std::vector<Client>> nt::meta::DecodeClients(
+    std::span<const uint8_t> data) {
+  mpack_reader_t r;
+  mpack_reader_init_data(&r, data);
+  uint32_t numClients = mpack_expect_array_max(&r, 100);
+  std::vector<Client> clients;
+  clients.reserve(numClients);
+  for (uint32_t i = 0; i < numClients; ++i) {
+    Client client;
+    uint32_t numMapElem = mpack_expect_map(&r);
+    for (uint32_t j = 0; j < numMapElem; ++j) {
+      std::string key;
+      mpack_expect_str(&r, &key);
+      if (key == "id") {
+        mpack_expect_str(&r, &client.id);
+      } else if (key == "conn") {
+        mpack_expect_str(&r, &client.conn);
+      } else if (key == "ver") {
+        client.version = mpack_expect_u16(&r);
+      } else {
+        mpack_discard(&r);
+      }
+    }
+    mpack_done_map(&r);
+    clients.emplace_back(std::move(client));
+  }
+  mpack_done_array(&r);
+  if (mpack_reader_destroy(&r) == mpack_ok) {
+    return {std::move(clients)};
+  } else {
+    return {};
+  }
+}
diff --git a/ntcore/src/main/native/cpp/ntcore_meta_c.cpp b/ntcore/src/main/native/cpp/ntcore_meta_c.cpp
new file mode 100644
index 0000000..889254e
--- /dev/null
+++ b/ntcore/src/main/native/cpp/ntcore_meta_c.cpp
@@ -0,0 +1,138 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <optional>
+#include <vector>
+
+#include "Value_internal.h"
+#include "ntcore_cpp.h"
+
+using namespace nt;
+using namespace nt::meta;
+
+static void ConvertToC(const SubscriberOptions& in,
+                       NT_Meta_SubscriberOptions* out) {
+  out->periodic = in.periodic;
+  out->topicsOnly = in.topicsOnly;
+  out->sendAll = in.sendAll;
+  out->prefixMatch = in.prefixMatch;
+}
+
+static void ConvertToC(const TopicPublisher& in, NT_Meta_TopicPublisher* out) {
+  ConvertToC(in.client, &out->client);
+  out->pubuid = in.pubuid;
+}
+
+static void ConvertToC(const TopicSubscriber& in,
+                       NT_Meta_TopicSubscriber* out) {
+  ConvertToC(in.client, &out->client);
+  out->subuid = in.subuid;
+  ConvertToC(in.options, &out->options);
+}
+
+static void ConvertToC(const ClientPublisher& in,
+                       NT_Meta_ClientPublisher* out) {
+  out->uid = in.uid;
+  ConvertToC(in.topic, &out->topic);
+}
+
+static void ConvertToC(const ClientSubscriber& in,
+                       NT_Meta_ClientSubscriber* out) {
+  out->uid = in.uid;
+  out->topics = ConvertToC<NT_String>(in.topics, &out->topicsCount);
+  ConvertToC(in.options, &out->options);
+}
+
+static void ConvertToC(const Client& in, NT_Meta_Client* out) {
+  ConvertToC(in.id, &out->id);
+  ConvertToC(in.conn, &out->conn);
+  out->version = in.version;
+}
+
+template <typename O, typename I>
+static O* ConvertToC(const std::optional<std::vector<I>>& in, size_t* out_len) {
+  if (in) {
+    if (O* rv = ConvertToC<O>(*in, out_len)) {
+      return rv;
+    } else {
+      return static_cast<O*>(wpi::safe_malloc(0));  // return non-NULL
+    }
+  } else {
+    *out_len = 0;
+    return nullptr;
+  }
+}
+
+extern "C" {
+
+struct NT_Meta_TopicPublisher* NT_Meta_DecodeTopicPublishers(
+    const uint8_t* data, size_t size, size_t* count) {
+  return ConvertToC<NT_Meta_TopicPublisher>(DecodeTopicPublishers({data, size}),
+                                            count);
+}
+
+struct NT_Meta_TopicSubscriber* NT_Meta_DecodeTopicSubscribers(
+    const uint8_t* data, size_t size, size_t* count) {
+  return ConvertToC<NT_Meta_TopicSubscriber>(
+      DecodeTopicSubscribers({data, size}), count);
+}
+
+struct NT_Meta_ClientPublisher* NT_Meta_DecodeClientPublishers(
+    const uint8_t* data, size_t size, size_t* count) {
+  return ConvertToC<NT_Meta_ClientPublisher>(
+      DecodeClientPublishers({data, size}), count);
+}
+
+struct NT_Meta_ClientSubscriber* NT_Meta_DecodeClientSubscribers(
+    const uint8_t* data, size_t size, size_t* count) {
+  return ConvertToC<NT_Meta_ClientSubscriber>(
+      DecodeClientSubscribers({data, size}), count);
+}
+
+struct NT_Meta_Client* NT_Meta_DecodeClients(const uint8_t* data, size_t size,
+                                             size_t* count) {
+  return ConvertToC<NT_Meta_Client>(DecodeClients({data, size}), count);
+}
+
+void NT_Meta_FreeTopicPublishers(struct NT_Meta_TopicPublisher* arr,
+                                 size_t count) {
+  for (size_t i = 0; i < count; ++i) {
+    std::free(arr[i].client.str);
+  }
+  std::free(arr);
+}
+
+void NT_Meta_FreeTopicSubscribers(struct NT_Meta_TopicSubscriber* arr,
+                                  size_t count) {
+  for (size_t i = 0; i < count; ++i) {
+    std::free(arr[i].client.str);
+  }
+  std::free(arr);
+}
+
+void NT_Meta_FreeClientPublishers(struct NT_Meta_ClientPublisher* arr,
+                                  size_t count) {
+  for (size_t i = 0; i < count; ++i) {
+    std::free(arr[i].topic.str);
+  }
+  std::free(arr);
+}
+
+void NT_Meta_FreeClientSubscribers(struct NT_Meta_ClientSubscriber* arr,
+                                   size_t count) {
+  for (size_t i = 0; i < count; ++i) {
+    NT_FreeStringArray(arr[i].topics, arr[i].topicsCount);
+  }
+  std::free(arr);
+}
+
+void NT_Meta_FreeClients(struct NT_Meta_Client* arr, size_t count) {
+  for (size_t i = 0; i < count; ++i) {
+    std::free(arr[i].id.str);
+    std::free(arr[i].conn.str);
+  }
+  std::free(arr);
+}
+
+}  // extern "C"
diff --git a/ntcore/src/main/native/cpp/ntcore_test.cpp b/ntcore/src/main/native/cpp/ntcore_test.cpp
index 64bde68..2a07867 100644
--- a/ntcore/src/main/native/cpp/ntcore_test.cpp
+++ b/ntcore/src/main/native/cpp/ntcore_test.cpp
@@ -11,31 +11,30 @@
 #include "Value_internal.h"
 
 extern "C" {
-struct NT_String* NT_GetStringForTesting(const char* string, int* struct_size) {
-  struct NT_String* str =
+struct NT_String* NT_GetStringForTesting(const char* str, int* struct_size) {
+  struct NT_String* strout =
       static_cast<NT_String*>(wpi::safe_calloc(1, sizeof(NT_String)));
-  nt::ConvertToC(string, str);
+  nt::ConvertToC(str, strout);
   *struct_size = sizeof(NT_String);
-  return str;
+  return strout;
 }
 
-struct NT_EntryInfo* NT_GetEntryInfoForTesting(const char* name,
+struct NT_TopicInfo* NT_GetTopicInfoForTesting(const char* name,
                                                enum NT_Type type,
-                                               unsigned int flags,
-                                               uint64_t last_change,
+                                               const char* type_str,
                                                int* struct_size) {
-  struct NT_EntryInfo* entry_info =
-      static_cast<NT_EntryInfo*>(wpi::safe_calloc(1, sizeof(NT_EntryInfo)));
-  nt::ConvertToC(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;
+  struct NT_TopicInfo* topic_info =
+      static_cast<NT_TopicInfo*>(wpi::safe_calloc(1, sizeof(NT_TopicInfo)));
+  nt::ConvertToC(name, &topic_info->name);
+  topic_info->type = type;
+  nt::ConvertToC(type_str, &topic_info->type_str);
+  *struct_size = sizeof(NT_TopicInfo);
+  return topic_info;
 }
 
-void NT_FreeEntryInfoForTesting(struct NT_EntryInfo* info) {
+void NT_FreeTopicInfoForTesting(struct NT_TopicInfo* info) {
   std::free(info->name.str);
+  std::free(info->type_str.str);
   std::free(info);
 }
 
@@ -158,88 +157,4 @@
 }
 // 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({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(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(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(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(name, &info->name);
-  nt::ConvertToC({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/include/networktables/EntryListenerFlags.h b/ntcore/src/main/native/include/networktables/EntryListenerFlags.h
deleted file mode 100644
index bbf5e42..0000000
--- a/ntcore/src/main/native/include/networktables/EntryListenerFlags.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_NETWORKTABLES_ENTRYLISTENERFLAGS_H_
-#define NTCORE_NETWORKTABLES_ENTRYLISTENERFLAGS_H_
-
-#include "ntcore_c.h"
-
-/** Entry listener flags */
-namespace nt::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 nt::EntryListenerFlags
-
-#endif  // NTCORE_NETWORKTABLES_ENTRYLISTENERFLAGS_H_
diff --git a/ntcore/src/main/native/include/networktables/GenericEntry.h b/ntcore/src/main/native/include/networktables/GenericEntry.h
new file mode 100644
index 0000000..6c7fee4
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/GenericEntry.h
@@ -0,0 +1,483 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "networktables/Topic.h"
+
+namespace nt {
+
+class Value;
+
+/**
+ * NetworkTables generic subscriber.
+ */
+class GenericSubscriber : public Subscriber {
+ public:
+  using TopicType = Topic;
+  using ValueType = Value;
+  using ParamType = const Value&;
+  using TimestampedValueType = Value;
+
+  GenericSubscriber() = default;
+
+  /**
+   * Construct from a subscriber handle; recommended to use
+   * Topic::GenericSubscribe() instead.
+   *
+   * @param handle Native handle
+   */
+  explicit GenericSubscriber(NT_Subscriber handle);
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns a value with unassigned type.
+   *
+   * @return value
+   */
+  ValueType Get() 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 integer. 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
+   */
+  int64_t GetInteger(int64_t defaultValue) const;
+
+  /**
+   * Gets the entry's value as a float. 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
+   */
+  float GetFloat(float 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(std::string_view 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::vector<uint8_t> GetRaw(std::span<const uint8_t> 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::span<const int> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a integer 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<int64_t> GetIntegerArray(
+      std::span<const int64_t> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a float 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<float> GetFloatArray(std::span<const float> 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::span<const 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(
+      std::span<const std::string> defaultValue) const;
+
+  /**
+   * Get an array of all value changes since the last call to ReadQueue.
+   * Also provides a timestamp for each value.
+   *
+   * @note The "poll storage" subscribe option can be used to set the queue
+   *     depth.
+   *
+   * @return Array of timestamped values; empty array if no new changes have
+   *     been published since the previous call.
+   */
+  std::vector<TimestampedValueType> ReadQueue();
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+};
+
+/**
+ * NetworkTables generic publisher.
+ */
+class GenericPublisher : public Publisher {
+ public:
+  using TopicType = Topic;
+  using ValueType = Value;
+  using ParamType = const Value&;
+  using TimestampedValueType = Value;
+
+  GenericPublisher() = default;
+
+  /**
+   * Construct from a publisher handle; recommended to use
+   * Topic::GenericPublish() instead.
+   *
+   * @param handle Native handle
+   */
+  explicit GenericPublisher(NT_Publisher handle);
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   */
+  void Set(ParamType value);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetBoolean(bool value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetInteger(int64_t value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetFloat(float value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetDouble(double value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetString(std::string_view value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetRaw(std::span<const uint8_t> value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetBooleanArray(std::span<const bool> value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetBooleanArray(std::span<const int> value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetIntegerArray(std::span<const int64_t> value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetFloatArray(std::span<const float> value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetDoubleArray(std::span<const double> value, int64_t time = 0);
+
+  /**
+   * Sets the entry's value.
+   *
+   * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
+   * @return False if the entry exists with a different type
+   */
+  bool SetStringArray(std::span<const std::string> value, int64_t time = 0);
+
+  /**
+   * Publish a default value.
+   * On reconnect, a default value will never be used in preference to a
+   * published value.
+   *
+   * @param value value
+   */
+  void SetDefault(ParamType 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 SetDefaultInteger(int64_t 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 SetDefaultFloat(float 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(std::string_view 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(std::span<const uint8_t> 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::span<const 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 SetDefaultIntegerArray(std::span<const int64_t> 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 SetDefaultFloatArray(std::span<const float> 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::span<const 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(std::span<const std::string> defaultValue);
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+};
+
+/**
+ * NetworkTables generic entry.
+ *
+ * @note Unlike NetworkTableEntry, the entry goes away when this is destroyed.
+ */
+class GenericEntry final : public GenericSubscriber, public GenericPublisher {
+ public:
+  using SubscriberType = GenericSubscriber;
+  using PublisherType = GenericPublisher;
+  using TopicType = Topic;
+  using ValueType = Value;
+  using ParamType = const Value&;
+  using TimestampedValueType = Value;
+
+  GenericEntry() = default;
+
+  /**
+   * Construct from an entry handle; recommended to use
+   * RawTopic::GetEntry() instead.
+   *
+   * @param handle Native handle
+   */
+  explicit GenericEntry(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_subHandle != 0; }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  NT_Entry GetHandle() const { return m_subHandle; }
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+
+  /**
+   * Stops publishing the entry if it's published.
+   */
+  void Unpublish();
+};
+
+}  // namespace nt
+
+#include "networktables/GenericEntry.inc"
diff --git a/ntcore/src/main/native/include/networktables/GenericEntry.inc b/ntcore/src/main/native/include/networktables/GenericEntry.inc
new file mode 100644
index 0000000..f3d9967
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/GenericEntry.inc
@@ -0,0 +1,214 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "networktables/GenericEntry.h"
+#include "networktables/NetworkTableType.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+inline GenericSubscriber::GenericSubscriber(NT_Subscriber handle)
+    : Subscriber{handle} {}
+
+inline Value GenericSubscriber::Get() const {
+  return ::nt::GetEntryValue(m_subHandle);
+}
+
+inline bool GenericSubscriber::GetBoolean(bool defaultValue) const {
+  return ::nt::GetBoolean(m_subHandle, defaultValue);
+}
+
+inline int64_t GenericSubscriber::GetInteger(int64_t defaultValue) const {
+  return ::nt::GetInteger(m_subHandle, defaultValue);
+}
+
+inline float GenericSubscriber::GetFloat(float defaultValue) const {
+  return ::nt::GetFloat(m_subHandle, defaultValue);
+}
+
+inline double GenericSubscriber::GetDouble(double defaultValue) const {
+  return ::nt::GetDouble(m_subHandle, defaultValue);
+}
+
+inline std::string GenericSubscriber::GetString(
+    std::string_view defaultValue) const {
+  return ::nt::GetString(m_subHandle, defaultValue);
+}
+
+inline std::vector<uint8_t> GenericSubscriber::GetRaw(
+    std::span<const uint8_t> defaultValue) const {
+  return ::nt::GetRaw(m_subHandle, defaultValue);
+}
+
+inline std::vector<int> GenericSubscriber::GetBooleanArray(
+    std::span<const int> defaultValue) const {
+  return ::nt::GetBooleanArray(m_subHandle, defaultValue);
+}
+
+inline std::vector<int64_t> GenericSubscriber::GetIntegerArray(
+    std::span<const int64_t> defaultValue) const {
+  return ::nt::GetIntegerArray(m_subHandle, defaultValue);
+}
+
+inline std::vector<float> GenericSubscriber::GetFloatArray(
+    std::span<const float> defaultValue) const {
+  return ::nt::GetFloatArray(m_subHandle, defaultValue);
+}
+
+inline std::vector<double> GenericSubscriber::GetDoubleArray(
+    std::span<const double> defaultValue) const {
+  return ::nt::GetDoubleArray(m_subHandle, defaultValue);
+}
+
+inline std::vector<std::string> GenericSubscriber::GetStringArray(
+    std::span<const std::string> defaultValue) const {
+  return ::nt::GetStringArray(m_subHandle, defaultValue);
+}
+
+inline std::vector<Value> GenericSubscriber::ReadQueue() {
+  return ::nt::ReadQueueValue(m_subHandle);
+}
+
+inline Topic GenericSubscriber::GetTopic() const {
+  return Topic{::nt::GetTopicFromHandle(m_subHandle)};
+}
+
+inline GenericPublisher::GenericPublisher(NT_Publisher handle)
+    : Publisher{handle} {}
+
+inline void GenericPublisher::Set(const Value& value) {
+  ::nt::SetEntryValue(m_pubHandle, value);
+}
+
+inline bool GenericPublisher::SetBoolean(bool value, int64_t time) {
+  return nt::SetBoolean(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetInteger(int64_t value, int64_t time) {
+  return nt::SetInteger(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetFloat(float value, int64_t time) {
+  return nt::SetFloat(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetDouble(double value, int64_t time) {
+  return nt::SetDouble(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetString(std::string_view value, int64_t time) {
+  return nt::SetString(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetRaw(std::span<const uint8_t> value,
+                                     int64_t time) {
+  return nt::SetRaw(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetBooleanArray(std::span<const bool> value,
+                                              int64_t time) {
+  return SetEntryValue(m_pubHandle, Value::MakeBooleanArray(value, time));
+}
+
+inline bool GenericPublisher::SetBooleanArray(std::span<const int> value,
+                                              int64_t time) {
+  return nt::SetBooleanArray(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetIntegerArray(std::span<const int64_t> value,
+                                              int64_t time) {
+  return nt::SetIntegerArray(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetFloatArray(std::span<const float> value,
+                                            int64_t time) {
+  return nt::SetFloatArray(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetDoubleArray(std::span<const double> value,
+                                             int64_t time) {
+  return nt::SetDoubleArray(m_pubHandle, value, time);
+}
+
+inline bool GenericPublisher::SetStringArray(std::span<const std::string> value,
+                                             int64_t time) {
+  return nt::SetStringArray(m_pubHandle, value, time);
+}
+
+inline void GenericPublisher::SetDefault(const Value& value) {
+  ::nt::SetDefaultEntryValue(m_pubHandle, value);
+}
+
+inline bool GenericPublisher::SetDefaultBoolean(bool defaultValue) {
+  return nt::SetDefaultBoolean(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultInteger(int64_t defaultValue) {
+  return nt::SetDefaultInteger(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultFloat(float defaultValue) {
+  return nt::SetDefaultFloat(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultDouble(double defaultValue) {
+  return nt::SetDefaultDouble(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultString(std::string_view defaultValue) {
+  return nt::SetDefaultString(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultRaw(
+    std::span<const uint8_t> defaultValue) {
+  return nt::SetDefaultRaw(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultBooleanArray(
+    std::span<const int> defaultValue) {
+  return nt::SetDefaultBooleanArray(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultIntegerArray(
+    std::span<const int64_t> defaultValue) {
+  return nt::SetDefaultIntegerArray(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultFloatArray(
+    std::span<const float> defaultValue) {
+  return nt::SetDefaultFloatArray(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultDoubleArray(
+    std::span<const double> defaultValue) {
+  return nt::SetDefaultDoubleArray(m_pubHandle, defaultValue);
+}
+
+inline bool GenericPublisher::SetDefaultStringArray(
+    std::span<const std::string> defaultValue) {
+  return nt::SetDefaultStringArray(m_pubHandle, defaultValue);
+}
+
+inline Topic GenericPublisher::GetTopic() const {
+  return Topic{::nt::GetTopicFromHandle(m_pubHandle)};
+}
+
+inline GenericEntry::GenericEntry(NT_Entry handle)
+    : GenericSubscriber{handle}, GenericPublisher{handle} {}
+
+inline Topic GenericEntry::GetTopic() const {
+  return Topic{::nt::GetTopicFromHandle(m_subHandle)};
+}
+
+inline void GenericEntry::Unpublish() {
+  ::nt::Unpublish(m_pubHandle);
+}
+}  // namespace nt
diff --git a/ntcore/src/main/native/include/networktables/MultiSubscriber.h b/ntcore/src/main/native/include/networktables/MultiSubscriber.h
new file mode 100644
index 0000000..f146351
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/MultiSubscriber.h
@@ -0,0 +1,61 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string_view>
+
+#include "networktables/NetworkTableInstance.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+/**
+ * Subscribe to multiple topics based on one or more topic name prefixes. Can be
+ * used in combination with ValueListenerPoller to listen for value changes
+ * across all matching topics.
+ */
+class MultiSubscriber final {
+ public:
+  MultiSubscriber() = default;
+
+  /**
+   * Create a multiple subscriber.
+   *
+   * @param inst instance
+   * @param prefixes topic name prefixes
+   * @param options subscriber options
+   */
+  MultiSubscriber(NetworkTableInstance inst,
+                  std::span<const std::string_view> prefixes,
+                  const PubSubOptions& options = kDefaultPubSubOptions);
+
+  MultiSubscriber(const MultiSubscriber&) = delete;
+  MultiSubscriber& operator=(const MultiSubscriber&) = delete;
+  MultiSubscriber(MultiSubscriber&& rhs);
+  MultiSubscriber& operator=(MultiSubscriber&& rhs);
+  ~MultiSubscriber();
+
+  /**
+   * 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.
+   *
+   * @return Handle
+   */
+  NT_MultiSubscriber GetHandle() const { return m_handle; }
+
+ private:
+  NT_MultiSubscriber m_handle{0};
+};
+
+}  // namespace nt
+
+#include "MultiSubscriber.inc"
diff --git a/ntcore/src/main/native/include/networktables/MultiSubscriber.inc b/ntcore/src/main/native/include/networktables/MultiSubscriber.inc
new file mode 100644
index 0000000..c32c06a
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/MultiSubscriber.inc
@@ -0,0 +1,36 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include "networktables/MultiSubscriber.h"
+
+namespace nt {
+
+inline MultiSubscriber::MultiSubscriber(
+    NetworkTableInstance inst, std::span<const std::string_view> prefixes,
+    const PubSubOptions& options)
+    : m_handle{::nt::SubscribeMultiple(inst.GetHandle(), prefixes, options)} {}
+
+inline MultiSubscriber::MultiSubscriber(MultiSubscriber&& rhs)
+    : m_handle{rhs.m_handle} {
+  rhs.m_handle = 0;
+}
+
+inline MultiSubscriber& MultiSubscriber::operator=(MultiSubscriber&& rhs) {
+  if (m_handle != 0) {
+    ::nt::UnsubscribeMultiple(m_handle);
+  }
+  m_handle = rhs.m_handle;
+  rhs.m_handle = 0;
+  return *this;
+}
+
+inline MultiSubscriber::~MultiSubscriber() {
+  if (m_handle != 0) {
+    ::nt::UnsubscribeMultiple(m_handle);
+  }
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/include/networktables/NTSendableBuilder.h b/ntcore/src/main/native/include/networktables/NTSendableBuilder.h
index 8ff265b..01ce6cc 100644
--- a/ntcore/src/main/native/include/networktables/NTSendableBuilder.h
+++ b/ntcore/src/main/native/include/networktables/NTSendableBuilder.h
@@ -4,15 +4,14 @@
 
 #pragma once
 
-#include <functional>
 #include <memory>
 #include <string_view>
 
+#include <wpi/FunctionExtras.h>
 #include <wpi/sendable/SendableBuilder.h>
 
 #include "networktables/NetworkTable.h"
-#include "networktables/NetworkTableEntry.h"
-#include "networktables/NetworkTableValue.h"
+#include "networktables/Topic.h"
 
 namespace nt {
 
@@ -26,27 +25,16 @@
    *
    * @param func    function
    */
-  virtual void SetUpdateTable(std::function<void()> func) = 0;
+  virtual void SetUpdateTable(wpi::unique_function<void()> func) = 0;
 
   /**
    * Add a property without getters or setters.  This can be used to get
    * entry handles for the function called by SetUpdateTable().
    *
    * @param key   property name
-   * @return Network table entry
+   * @return Network table topic
    */
-  virtual NetworkTableEntry GetEntry(std::string_view key) = 0;
-
-  /**
-   * Add a NetworkTableValue property.
-   *
-   * @param key     property name
-   * @param getter  getter function (returns current value)
-   * @param setter  setter function (sets new value)
-   */
-  virtual void AddValueProperty(
-      std::string_view key, std::function<std::shared_ptr<Value>()> getter,
-      std::function<void(std::shared_ptr<Value>)> setter) = 0;
+  virtual Topic GetTopic(std::string_view key) = 0;
 
   /**
    * Get the network table.
diff --git a/ntcore/src/main/native/include/networktables/NetworkTable.h b/ntcore/src/main/native/include/networktables/NetworkTable.h
index 3a04e45..d34f54b 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTable.h
+++ b/ntcore/src/main/native/include/networktables/NetworkTable.h
@@ -2,11 +2,11 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLE_H_
-#define NTCORE_NETWORKTABLES_NETWORKTABLE_H_
+#pragma once
 
 #include <functional>
 #include <memory>
+#include <span>
 #include <string>
 #include <string_view>
 #include <utility>
@@ -14,16 +14,25 @@
 
 #include <wpi/StringMap.h>
 #include <wpi/mutex.h>
-#include <wpi/span.h>
 
 #include "networktables/NetworkTableEntry.h"
-#include "networktables/TableEntryListener.h"
-#include "networktables/TableListener.h"
 #include "ntcore_c.h"
 
 namespace nt {
 
+class BooleanArrayTopic;
+class BooleanTopic;
+class DoubleArrayTopic;
+class DoubleTopic;
+class FloatArrayTopic;
+class FloatTopic;
+class IntegerArrayTopic;
+class IntegerTopic;
 class NetworkTableInstance;
+class RawTopic;
+class StringArrayTopic;
+class StringTopic;
+class Topic;
 
 /**
  * @defgroup ntcore_cpp_api ntcore C++ object-oriented API
@@ -41,7 +50,6 @@
   std::string m_path;
   mutable wpi::mutex m_mutex;
   mutable wpi::StringMap<NT_Entry> m_entries;
-  std::vector<NT_EntryListener> m_listeners;
 
   struct private_init {};
   friend class NetworkTableInstance;
@@ -94,7 +102,7 @@
    * instead.
    */
   NetworkTable(NT_Inst inst, std::string_view path, const private_init&);
-  virtual ~NetworkTable();
+  ~NetworkTable();
 
   /**
    * Gets the instance for the table.
@@ -117,52 +125,100 @@
   NetworkTableEntry GetEntry(std::string_view key) const;
 
   /**
-   * Listen to keys only within this table.
+   * Get (generic) topic.
    *
-   * @param listener    listener to add
-   * @param flags       EntryListenerFlags bitmask
-   * @return Listener handle
+   * @param name topic name
+   * @return Topic
    */
-  NT_EntryListener AddEntryListener(TableEntryListener listener,
-                                    unsigned int flags) const;
+  Topic GetTopic(std::string_view name) const;
 
   /**
-   * Listen to a single key.
+   * Get boolean topic.
    *
-   * @param key         the key name
-   * @param listener    listener to add
-   * @param flags       EntryListenerFlags bitmask
-   * @return Listener handle
+   * @param name topic name
+   * @return BooleanTopic
    */
-  NT_EntryListener AddEntryListener(std::string_view key,
-                                    TableEntryListener listener,
-                                    unsigned int flags) const;
+  BooleanTopic GetBooleanTopic(std::string_view name) const;
 
   /**
-   * Remove an entry listener.
+   * Get integer topic.
    *
-   * @param listener    listener handle
+   * @param name topic name
+   * @return IntegerTopic
    */
-  void RemoveEntryListener(NT_EntryListener listener) const;
+  IntegerTopic GetIntegerTopic(std::string_view name) 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.
+   * Get float topic.
    *
-   * @param listener        listener to add
-   * @param localNotify     notify local changes as well as remote
-   * @return Listener handle
+   * @param name topic name
+   * @return FloatTopic
    */
-  NT_EntryListener AddSubTableListener(TableListener listener,
-                                       bool localNotify = false);
+  FloatTopic GetFloatTopic(std::string_view name) const;
 
   /**
-   * Remove a sub-table listener.
+   * Get double topic.
    *
-   * @param listener    listener handle
+   * @param name topic name
+   * @return DoubleTopic
    */
-  void RemoveTableListener(NT_EntryListener listener);
+  DoubleTopic GetDoubleTopic(std::string_view name) const;
+
+  /**
+   * Get String topic.
+   *
+   * @param name topic name
+   * @return StringTopic
+   */
+  StringTopic GetStringTopic(std::string_view name) const;
+
+  /**
+   * Get raw topic.
+   *
+   * @param name topic name
+   * @return BooleanArrayTopic
+   */
+  RawTopic GetRawTopic(std::string_view name) const;
+
+  /**
+   * Get boolean[] topic.
+   *
+   * @param name topic name
+   * @return BooleanArrayTopic
+   */
+  BooleanArrayTopic GetBooleanArrayTopic(std::string_view name) const;
+
+  /**
+   * Get integer[] topic.
+   *
+   * @param name topic name
+   * @return IntegerArrayTopic
+   */
+  IntegerArrayTopic GetIntegerArrayTopic(std::string_view name) const;
+
+  /**
+   * Get float[] topic.
+   *
+   * @param name topic name
+   * @return FloatArrayTopic
+   */
+  FloatArrayTopic GetFloatArrayTopic(std::string_view name) const;
+
+  /**
+   * Get double[] topic.
+   *
+   * @param name topic name
+   * @return DoubleArrayTopic
+   */
+  DoubleArrayTopic GetDoubleArrayTopic(std::string_view name) const;
+
+  /**
+   * Get String[] topic.
+   *
+   * @param name topic name
+   * @return StringArrayTopic
+   */
+  StringArrayTopic GetStringArrayTopic(std::string_view name) const;
 
   /**
    * Returns the table at the specified key. If there is no table at the
@@ -192,6 +248,23 @@
   bool ContainsSubTable(std::string_view key) const;
 
   /**
+   * Gets topic information for all keys in the table (not including
+   * sub-tables).
+   *
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return topic information for keys currently in the table
+   */
+  std::vector<TopicInfo> GetTopicInfo(int types = 0) const;
+
+  /**
+   * Gets all topics in the table (not including sub-tables).
+   *
+   * @param types bitmask of types; 0 is treated as a "don't care".
+   * @return topic for keys currently in the table
+   */
+  std::vector<Topic> GetTopics(int types = 0) const;
+
+  /**
    * Gets all keys in the table (not including sub-tables).
    *
    * @param types bitmask of types; 0 is treated as a "don't care".
@@ -230,39 +303,6 @@
   bool IsPersistent(std::string_view key) const;
 
   /**
-   * 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(std::string_view key, unsigned 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)
-   */
-  void ClearFlags(std::string_view key, unsigned 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
-   */
-  unsigned int GetFlags(std::string_view key) const;
-
-  /**
-   * Deletes the specified key in this table.
-   *
-   * @param key the key name
-   */
-  void Delete(std::string_view key);
-
-  /**
    * Put a number in the table
    *
    * @param key the key to be assigned to
@@ -360,7 +400,7 @@
    *       std::vector<bool> is special-cased in C++.  0 is false, any
    *       non-zero value is true.
    */
-  bool PutBooleanArray(std::string_view key, wpi::span<const int> value);
+  bool PutBooleanArray(std::string_view key, std::span<const int> value);
 
   /**
    * Gets the current value in the table, setting it if it does not exist.
@@ -370,7 +410,7 @@
    * @return False if the table key exists with a different type
    */
   bool SetDefaultBooleanArray(std::string_view key,
-                              wpi::span<const int> defaultValue);
+                              std::span<const int> defaultValue);
 
   /**
    * Returns the boolean array the key maps to. If the key does not exist or is
@@ -389,7 +429,7 @@
    *       non-zero value is true.
    */
   std::vector<int> GetBooleanArray(std::string_view key,
-                                   wpi::span<const int> defaultValue) const;
+                                   std::span<const int> defaultValue) const;
 
   /**
    * Put a number array in the table
@@ -398,7 +438,7 @@
    * @param value the value that will be assigned
    * @return False if the table key already exists with a different type
    */
-  bool PutNumberArray(std::string_view key, wpi::span<const double> value);
+  bool PutNumberArray(std::string_view key, std::span<const double> value);
 
   /**
    * Gets the current value in the table, setting it if it does not exist.
@@ -408,7 +448,7 @@
    * @returns False if the table key exists with a different type
    */
   bool SetDefaultNumberArray(std::string_view key,
-                             wpi::span<const double> defaultValue);
+                             std::span<const double> defaultValue);
 
   /**
    * Returns the number array the key maps to. If the key does not exist or is
@@ -423,7 +463,7 @@
    *       concern, use GetValue() instead.
    */
   std::vector<double> GetNumberArray(
-      std::string_view key, wpi::span<const double> defaultValue) const;
+      std::string_view key, std::span<const double> defaultValue) const;
 
   /**
    * Put a string array in the table
@@ -432,7 +472,7 @@
    * @param value the value that will be assigned
    * @return False if the table key already exists with a different type
    */
-  bool PutStringArray(std::string_view key, wpi::span<const std::string> value);
+  bool PutStringArray(std::string_view key, std::span<const std::string> value);
 
   /**
    * Gets the current value in the table, setting it if it does not exist.
@@ -442,7 +482,7 @@
    * @returns False if the table key exists with a different type
    */
   bool SetDefaultStringArray(std::string_view key,
-                             wpi::span<const std::string> defaultValue);
+                             std::span<const std::string> defaultValue);
 
   /**
    * Returns the string array the key maps to. If the key does not exist or is
@@ -457,7 +497,7 @@
    *       concern, use GetValue() instead.
    */
   std::vector<std::string> GetStringArray(
-      std::string_view key, wpi::span<const std::string> defaultValue) const;
+      std::string_view key, std::span<const std::string> defaultValue) const;
 
   /**
    * Put a raw value (byte array) in the table
@@ -466,7 +506,7 @@
    * @param value the value that will be assigned
    * @return False if the table key already exists with a different type
    */
-  bool PutRaw(std::string_view key, std::string_view value);
+  bool PutRaw(std::string_view key, std::span<const uint8_t> value);
 
   /**
    * Gets the current value in the table, setting it if it does not exist.
@@ -475,7 +515,8 @@
    * @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(std::string_view key, std::string_view defaultValue);
+  bool SetDefaultRaw(std::string_view key,
+                     std::span<const uint8_t> defaultValue);
 
   /**
    * Returns the raw value (byte array) the key maps to. If the key does not
@@ -489,7 +530,8 @@
    * @note This makes a copy of the raw contents.  If the overhead of this is a
    *       concern, use GetValue() instead.
    */
-  std::string GetRaw(std::string_view key, std::string_view defaultValue) const;
+  std::vector<uint8_t> GetRaw(std::string_view key,
+                              std::span<const uint8_t> defaultValue) const;
 
   /**
    * Put a value in the table
@@ -498,7 +540,7 @@
    * @param value the value that will be assigned
    * @return False if the table key already exists with a different type
    */
-  bool PutValue(std::string_view key, std::shared_ptr<Value> value);
+  bool PutValue(std::string_view key, const Value& value);
 
   /**
    * Gets the current value in the table, setting it if it does not exist.
@@ -507,8 +549,7 @@
    * @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(std::string_view key,
-                       std::shared_ptr<Value> defaultValue);
+  bool SetDefaultValue(std::string_view key, const Value& defaultValue);
 
   /**
    * Gets the value associated with a key as an object
@@ -517,7 +558,7 @@
    * @return the value associated with the given key, or nullptr if the key
    * does not exist
    */
-  std::shared_ptr<Value> GetValue(std::string_view key) const;
+  Value GetValue(std::string_view key) const;
 
   /**
    * Gets the full path of this table.  Does not include the trailing "/".
@@ -527,27 +568,62 @@
   std::string_view GetPath() const;
 
   /**
-   * Save table values to a file.  The file format used is identical to
-   * that used for SavePersistent.
+   * Called when an event occurs on a topic in a {@link NetworkTable}.
    *
-   * @param filename  filename
-   * @return error string, or nullptr if successful
+   * @param table the table the topic exists in
+   * @param key the key associated with the topic that changed
+   * @param event the event
    */
-  const char* SaveEntries(std::string_view filename) const;
+  using TableEventListener = std::function<void(
+      NetworkTable* table, std::string_view key, const Event& event)>;
 
   /**
-   * Load table values from a file.  The file format used is identical to
-   * that used for SavePersistent / LoadPersistent.
+   * Listen to topics only within this table.
    *
-   * @param filename  filename
-   * @param warn      callback function for warnings
-   * @return error string, or nullptr if successful
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener listener to add
+   * @return Listener handle
    */
-  const char* LoadEntries(
-      std::string_view filename,
-      std::function<void(size_t line, const char* msg)> warn);
+  NT_Listener AddListener(int eventMask, TableEventListener listener);
+
+  /**
+   * Listen to a single key.
+   *
+   * @param key the key name
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener listener to add
+   * @return Listener handle
+   */
+  NT_Listener AddListener(std::string_view key, int eventMask,
+                          TableEventListener listener);
+
+  /**
+   * Called when a new table is created within a NetworkTable.
+   *
+   * @param parent the parent of the table
+   * @param name the name of the new table
+   * @param table the new table
+   */
+  using SubTableListener =
+      std::function<void(NetworkTable* parent, std::string_view name,
+                         std::shared_ptr<NetworkTable> table)>;
+
+  /**
+   * 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
+   * @return Listener handle
+   */
+  NT_Listener AddSubTableListener(SubTableListener listener);
+
+  /**
+   * Remove a listener.
+   *
+   * @param listener listener handle
+   */
+  void RemoveListener(NT_Listener listener);
 };
 
 }  // namespace nt
-
-#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
index c6c9c86..b9d509a 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTableEntry.h
+++ b/ntcore/src/main/native/include/networktables/NetworkTableEntry.h
@@ -2,37 +2,42 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_H_
-#define NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_H_
+#pragma once
 
 #include <stdint.h>
 
 #include <initializer_list>
 #include <memory>
+#include <span>
 #include <string>
 #include <string_view>
 #include <vector>
 
-#include <wpi/span.h>
+#include <wpi/deprecated.h>
 
 #include "networktables/NetworkTableType.h"
 #include "networktables/NetworkTableValue.h"
-#include "networktables/RpcCall.h"
 #include "ntcore_c.h"
 #include "ntcore_cpp.h"
 
 namespace nt {
 
 class NetworkTableInstance;
+class Topic;
 
 /**
  * NetworkTables Entry
+ *
+ * @note For backwards compatibility, the NetworkTableEntry destructor does not
+ *       release the entry.
+ *
  * @ingroup ntcore_cpp_api
  */
 class NetworkTableEntry final {
  public:
   /**
    * Flag values (as returned by GetFlags()).
+   * @deprecated Use IsPersistent() instead.
    */
   enum Flags { kPersistent = NT_PERSISTENT };
 
@@ -94,7 +99,9 @@
    * Returns the flags.
    *
    * @return the flags (bitmask)
+   * @deprecated Use IsPersistent() or topic properties instead
    */
+  WPI_DEPRECATED("Use IsPersistent() or topic properties instead")
   unsigned int GetFlags() const;
 
   /**
@@ -102,21 +109,15 @@
    *
    * @return Entry last change time
    */
-  uint64_t GetLastChange() const;
+  int64_t GetLastChange() const;
 
   /**
-   * Gets combined information about the entry.
+   * Gets the entry's value. If the entry does not exist, returns an empty
+   * value.
    *
-   * @return Entry information
+   * @return the entry's value or an empty value if it does not exist.
    */
-  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;
+  Value GetValue() const;
 
   /**
    * Gets the entry's value as a boolean. If the entry does not exist or is of
@@ -128,6 +129,24 @@
   bool GetBoolean(bool defaultValue) const;
 
   /**
+   * Gets the entry's value as a integer. 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
+   */
+  int64_t GetInteger(int64_t defaultValue) const;
+
+  /**
+   * Gets the entry's value as a float. 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
+   */
+  float GetFloat(float 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.
    *
@@ -152,7 +171,7 @@
    * @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(std::string_view defaultValue) const;
+  std::vector<uint8_t> GetRaw(std::span<const uint8_t> defaultValue) const;
 
   /**
    * Gets the entry's value as a boolean array. If the entry does not exist
@@ -168,10 +187,10 @@
    *       because std::vector<bool> is special-cased in C++.  0 is false, any
    *       non-zero value is true.
    */
-  std::vector<int> GetBooleanArray(wpi::span<const int> defaultValue) const;
+  std::vector<int> GetBooleanArray(std::span<const int> defaultValue) const;
 
   /**
-   * Gets the entry's value as a boolean array. If the entry does not exist
+   * Gets the entry's value as a integer 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
@@ -179,13 +198,21 @@
    *
    * @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;
+  std::vector<int64_t> GetIntegerArray(
+      std::span<const int64_t> defaultValue) const;
+
+  /**
+   * Gets the entry's value as a float 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<float> GetFloatArray(std::span<const float> defaultValue) const;
 
   /**
    * Gets the entry's value as a double array. If the entry does not exist
@@ -198,20 +225,7 @@
    *       concern, use GetValue() instead.
    */
   std::vector<double> GetDoubleArray(
-      wpi::span<const 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;
+      std::span<const double> defaultValue) const;
 
   /**
    * Gets the entry's value as a string array. If the entry does not exist
@@ -224,28 +238,25 @@
    *       concern, use GetValue() instead.
    */
   std::vector<std::string> GetStringArray(
-      wpi::span<const std::string> defaultValue) const;
+      std::span<const 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.
+   * Get an array of all value changes since the last call to ReadQueue.
    *
-   * @param defaultValue the value to be returned if no value is found
-   * @return the entry's value or the given default value
+   * The "poll storage" subscribe option can be used to set the queue depth.
    *
-   * @note This makes a copy of the array.  If the overhead of this is a
-   *       concern, use GetValue() instead.
+   * @return Array of values; empty array if no new changes have been
+   *     published since the previous call.
    */
-  std::vector<std::string> GetStringArray(
-      std::initializer_list<std::string> defaultValue) const;
+  std::vector<NetworkTableValue> ReadQueue();
 
   /**
    * Sets the entry's value if it does not exist.
    *
-   * @param value the default value to set
+   * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultValue(std::shared_ptr<Value> value);
+  bool SetDefaultValue(const Value& defaultValue);
 
   /**
    * Sets the entry's value if it does not exist.
@@ -261,6 +272,22 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
+  bool SetDefaultInteger(int64_t 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 SetDefaultFloat(float 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);
 
   /**
@@ -277,7 +304,7 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultRaw(std::string_view defaultValue);
+  bool SetDefaultRaw(std::span<const uint8_t> defaultValue);
 
   /**
    * Sets the entry's value if it does not exist.
@@ -285,7 +312,7 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultBooleanArray(wpi::span<const int> defaultValue);
+  bool SetDefaultBooleanArray(std::span<const int> defaultValue);
 
   /**
    * Sets the entry's value if it does not exist.
@@ -293,7 +320,7 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultBooleanArray(std::initializer_list<int> defaultValue);
+  bool SetDefaultIntegerArray(std::span<const int64_t> defaultValue);
 
   /**
    * Sets the entry's value if it does not exist.
@@ -301,7 +328,7 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultDoubleArray(wpi::span<const double> defaultValue);
+  bool SetDefaultFloatArray(std::span<const float> defaultValue);
 
   /**
    * Sets the entry's value if it does not exist.
@@ -309,7 +336,7 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultDoubleArray(std::initializer_list<double> defaultValue);
+  bool SetDefaultDoubleArray(std::span<const double> defaultValue);
 
   /**
    * Sets the entry's value if it does not exist.
@@ -317,15 +344,7 @@
    * @param defaultValue the default value to set
    * @return False if the entry exists with a different type
    */
-  bool SetDefaultStringArray(wpi::span<const 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);
+  bool SetDefaultStringArray(std::span<const std::string> defaultValue);
 
   /**
    * Sets the entry's value.
@@ -333,220 +352,132 @@
    * @param value the value to set
    * @return False if the entry exists with a different type
    */
-  bool SetValue(std::shared_ptr<Value> value);
+  bool SetValue(const Value& value);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetBoolean(bool value);
+  bool SetBoolean(bool value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetDouble(double value);
+  bool SetInteger(int64_t value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetString(std::string_view value);
+  bool SetFloat(float value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetRaw(std::string_view value);
+  bool SetDouble(double value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetBooleanArray(wpi::span<const bool> value);
+  bool SetString(std::string_view value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetBooleanArray(std::initializer_list<bool> value);
+  bool SetRaw(std::span<const uint8_t> value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetBooleanArray(wpi::span<const int> value);
+  bool SetBooleanArray(std::span<const bool> value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetBooleanArray(std::initializer_list<int> value);
+  bool SetBooleanArray(std::span<const int> value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetDoubleArray(wpi::span<const double> value);
+  bool SetIntegerArray(std::span<const int64_t> value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetDoubleArray(std::initializer_list<double> value);
+  bool SetFloatArray(std::span<const float> value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @return False if the entry exists with a different type
    */
-  bool SetStringArray(wpi::span<const std::string> value);
+  bool SetDoubleArray(std::span<const double> value, int64_t time = 0);
 
   /**
    * Sets the entry's value.
    *
    * @param value the value to set
+   * @param time the timestamp to set (0 = nt::Now())
    * @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(std::string_view 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(std::string_view 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(wpi::span<const 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(wpi::span<const 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(wpi::span<const 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(wpi::span<const 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);
+  bool SetStringArray(std::span<const std::string> value, int64_t time = 0);
 
   /**
    * Sets flags.
    *
    * @param flags the flags to set (bitmask)
+   * @deprecated Use SetPersistent() or topic properties instead
    */
+  WPI_DEPRECATED("Use SetPersistent() or topic properties instead")
   void SetFlags(unsigned int flags);
 
   /**
    * Clears flags.
    *
    * @param flags the flags to clear (bitmask)
+   * @deprecated Use SetPersistent() or topic properties instead
    */
+  WPI_DEPRECATED("Use SetPersistent() or topic properties instead")
   void ClearFlags(unsigned int flags);
 
   /**
@@ -567,68 +498,29 @@
   bool IsPersistent() const;
 
   /**
-   * Deletes the entry.
+   * Stops publishing the entry if it's been published.
    */
+  void Unpublish();
+
+  /**
+   * Deletes the entry.
+   * @deprecated Use Unpublish() instead.
+   */
+  WPI_DEPRECATED("Use Unpublish() instead")
   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).
+   * Gets the entry's topic.
    *
-   * @param callback  callback function
+   * @return Topic
    */
-  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(std::string_view 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);
+  Topic GetTopic() const;
 
   /**
    * 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);
-  }
+  bool operator==(const NetworkTableEntry&) const = default;
 
  protected:
   /* Native handle */
@@ -638,5 +530,3 @@
 }  // namespace nt
 
 #include "networktables/NetworkTableEntry.inc"
-
-#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableEntry.inc b/ntcore/src/main/native/include/networktables/NetworkTableEntry.inc
index e7deb51..0b4f628 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTableEntry.inc
+++ b/ntcore/src/main/native/include/networktables/NetworkTableEntry.inc
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_INC_
-#define NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_INC_
+#pragma once
 
 #include <memory>
 #include <string>
@@ -11,6 +10,8 @@
 #include <vector>
 
 #include "networktables/NetworkTableEntry.h"
+#include "ntcore_cpp.h"
+#include "ntcore_cpp_types.h"
 
 namespace nt {
 
@@ -39,307 +40,208 @@
   return GetEntryFlags(m_handle);
 }
 
-inline uint64_t NetworkTableEntry::GetLastChange() const {
+inline int64_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 {
+inline 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();
+  return nt::GetBoolean(m_handle, defaultValue);
+}
+
+inline int64_t NetworkTableEntry::GetInteger(int64_t defaultValue) const {
+  return nt::GetInteger(m_handle, defaultValue);
+}
+
+inline float NetworkTableEntry::GetFloat(float defaultValue) const {
+  return nt::GetFloat(m_handle, defaultValue);
 }
 
 inline double NetworkTableEntry::GetDouble(double defaultValue) const {
-  auto value = GetEntryValue(m_handle);
-  if (!value || value->type() != NT_DOUBLE) {
-    return defaultValue;
-  }
-  return value->GetDouble();
+  return nt::GetDouble(m_handle, defaultValue);
 }
 
 inline std::string NetworkTableEntry::GetString(
     std::string_view defaultValue) const {
-  auto value = GetEntryValue(m_handle);
-  if (!value || value->type() != NT_STRING) {
-    return std::string{defaultValue};
-  }
-  return std::string{value->GetString()};
+  return nt::GetString(m_handle, defaultValue);
 }
 
-inline std::string NetworkTableEntry::GetRaw(
-    std::string_view defaultValue) const {
-  auto value = GetEntryValue(m_handle);
-  if (!value || value->type() != NT_RAW) {
-    return std::string{defaultValue};
-  }
-  return std::string{value->GetRaw()};
+inline std::vector<uint8_t> NetworkTableEntry::GetRaw(
+    std::span<const uint8_t> defaultValue) const {
+  return nt::GetRaw(m_handle, defaultValue);
 }
 
 inline std::vector<int> NetworkTableEntry::GetBooleanArray(
-    wpi::span<const int> defaultValue) const {
-  auto value = GetEntryValue(m_handle);
-  if (!value || value->type() != NT_BOOLEAN_ARRAY) {
-    return {defaultValue.begin(), defaultValue.end()};
-  }
-  auto arr = value->GetBooleanArray();
-  return {arr.begin(), arr.end()};
+    std::span<const int> defaultValue) const {
+  return nt::GetBooleanArray(m_handle, defaultValue);
 }
 
-inline std::vector<int> NetworkTableEntry::GetBooleanArray(
-    std::initializer_list<int> defaultValue) const {
-  return GetBooleanArray({defaultValue.begin(), defaultValue.end()});
+inline std::vector<int64_t> NetworkTableEntry::GetIntegerArray(
+    std::span<const int64_t> defaultValue) const {
+  return nt::GetIntegerArray(m_handle, defaultValue);
+}
+
+inline std::vector<float> NetworkTableEntry::GetFloatArray(
+    std::span<const float> defaultValue) const {
+  return nt::GetFloatArray(m_handle, defaultValue);
 }
 
 inline std::vector<double> NetworkTableEntry::GetDoubleArray(
-    wpi::span<const double> defaultValue) const {
-  auto value = GetEntryValue(m_handle);
-  if (!value || value->type() != NT_DOUBLE_ARRAY) {
-    return {defaultValue.begin(), defaultValue.end()};
-  }
-  auto arr = value->GetDoubleArray();
-  return {arr.begin(), arr.end()};
-}
-
-inline std::vector<double> NetworkTableEntry::GetDoubleArray(
-    std::initializer_list<double> defaultValue) const {
-  return GetDoubleArray({defaultValue.begin(), defaultValue.end()});
+    std::span<const double> defaultValue) const {
+  return nt::GetDoubleArray(m_handle, defaultValue);
 }
 
 inline std::vector<std::string> NetworkTableEntry::GetStringArray(
-    wpi::span<const std::string> defaultValue) const {
-  auto value = GetEntryValue(m_handle);
-  if (!value || value->type() != NT_STRING_ARRAY) {
-    return {defaultValue.begin(), defaultValue.end()};
-  }
-  auto arr = value->GetStringArray();
-  return {arr.begin(), arr.end()};
+    std::span<const std::string> defaultValue) const {
+  return nt::GetStringArray(m_handle, defaultValue);
 }
 
-inline std::vector<std::string> NetworkTableEntry::GetStringArray(
-    std::initializer_list<std::string> defaultValue) const {
-  return GetStringArray({defaultValue.begin(), defaultValue.end()});
+inline std::vector<NetworkTableValue> NetworkTableEntry::ReadQueue() {
+  return nt::ReadQueueValue(m_handle);
 }
 
-inline bool NetworkTableEntry::SetDefaultValue(std::shared_ptr<Value> value) {
-  return SetDefaultEntryValue(m_handle, value);
+inline bool NetworkTableEntry::SetDefaultValue(const Value& defaultValue) {
+  return SetDefaultEntryValue(m_handle, defaultValue);
 }
 
 inline bool NetworkTableEntry::SetDefaultBoolean(bool defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeBoolean(defaultValue));
+  return nt::SetDefaultBoolean(m_handle, defaultValue);
+}
+
+inline bool NetworkTableEntry::SetDefaultInteger(int64_t defaultValue) {
+  return nt::SetDefaultInteger(m_handle, defaultValue);
+}
+
+inline bool NetworkTableEntry::SetDefaultFloat(float defaultValue) {
+  return nt::SetDefaultFloat(m_handle, defaultValue);
 }
 
 inline bool NetworkTableEntry::SetDefaultDouble(double defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeDouble(defaultValue));
+  return nt::SetDefaultDouble(m_handle, defaultValue);
 }
 
 inline bool NetworkTableEntry::SetDefaultString(std::string_view defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeString(defaultValue));
+  return nt::SetDefaultString(m_handle, defaultValue);
 }
 
-inline bool NetworkTableEntry::SetDefaultRaw(std::string_view defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeRaw(defaultValue));
+inline bool NetworkTableEntry::SetDefaultRaw(
+    std::span<const uint8_t> defaultValue) {
+  return nt::SetDefaultRaw(m_handle, defaultValue);
 }
 
 inline bool NetworkTableEntry::SetDefaultBooleanArray(
-    wpi::span<const int> defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeBooleanArray(defaultValue));
+    std::span<const int> defaultValue) {
+  return nt::SetDefaultBooleanArray(m_handle, defaultValue);
 }
 
-inline bool NetworkTableEntry::SetDefaultBooleanArray(
-    std::initializer_list<int> defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeBooleanArray(defaultValue));
+inline bool NetworkTableEntry::SetDefaultIntegerArray(
+    std::span<const int64_t> defaultValue) {
+  return nt::SetDefaultIntegerArray(m_handle, defaultValue);
+}
+
+inline bool NetworkTableEntry::SetDefaultFloatArray(
+    std::span<const float> defaultValue) {
+  return nt::SetDefaultFloatArray(m_handle, defaultValue);
 }
 
 inline bool NetworkTableEntry::SetDefaultDoubleArray(
-    wpi::span<const double> defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeDoubleArray(defaultValue));
-}
-
-inline bool NetworkTableEntry::SetDefaultDoubleArray(
-    std::initializer_list<double> value) {
-  return SetDefaultEntryValue(m_handle, Value::MakeDoubleArray(value));
+    std::span<const double> defaultValue) {
+  return nt::SetDefaultDoubleArray(m_handle, defaultValue);
 }
 
 inline bool NetworkTableEntry::SetDefaultStringArray(
-    wpi::span<const std::string> defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeStringArray(defaultValue));
+    std::span<const std::string> defaultValue) {
+  return nt::SetDefaultStringArray(m_handle, defaultValue);
 }
 
-inline bool NetworkTableEntry::SetDefaultStringArray(
-    std::initializer_list<std::string> defaultValue) {
-  return SetDefaultEntryValue(m_handle, Value::MakeStringArray(defaultValue));
-}
-
-inline bool NetworkTableEntry::SetValue(std::shared_ptr<Value> value) {
+inline bool NetworkTableEntry::SetValue(const Value& value) {
   return SetEntryValue(m_handle, value);
 }
 
-inline bool NetworkTableEntry::SetBoolean(bool value) {
-  return SetEntryValue(m_handle, Value::MakeBoolean(value));
+inline bool NetworkTableEntry::SetBoolean(bool value, int64_t time) {
+  return nt::SetBoolean(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetDouble(double value) {
-  return SetEntryValue(m_handle, Value::MakeDouble(value));
+inline bool NetworkTableEntry::SetInteger(int64_t value, int64_t time) {
+  return nt::SetInteger(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetString(std::string_view value) {
-  return SetEntryValue(m_handle, Value::MakeString(value));
+inline bool NetworkTableEntry::SetFloat(float value, int64_t time) {
+  return nt::SetFloat(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetRaw(std::string_view value) {
-  return SetEntryValue(m_handle, Value::MakeRaw(value));
+inline bool NetworkTableEntry::SetDouble(double value, int64_t time) {
+  return nt::SetDouble(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetBooleanArray(wpi::span<const bool> value) {
-  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+inline bool NetworkTableEntry::SetString(std::string_view value, int64_t time) {
+  return nt::SetString(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetBooleanArray(
-    std::initializer_list<bool> value) {
-  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+inline bool NetworkTableEntry::SetRaw(std::span<const uint8_t> value,
+                                      int64_t time) {
+  return nt::SetRaw(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetBooleanArray(wpi::span<const int> value) {
-  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+inline bool NetworkTableEntry::SetBooleanArray(std::span<const bool> value,
+                                               int64_t time) {
+  return SetEntryValue(m_handle, Value::MakeBooleanArray(value, time));
 }
 
-inline bool NetworkTableEntry::SetBooleanArray(
-    std::initializer_list<int> value) {
-  return SetEntryValue(m_handle, Value::MakeBooleanArray(value));
+inline bool NetworkTableEntry::SetBooleanArray(std::span<const int> value,
+                                               int64_t time) {
+  return nt::SetBooleanArray(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetDoubleArray(wpi::span<const double> value) {
-  return SetEntryValue(m_handle, Value::MakeDoubleArray(value));
+inline bool NetworkTableEntry::SetIntegerArray(std::span<const int64_t> value,
+                                               int64_t time) {
+  return nt::SetIntegerArray(m_handle, value, time);
 }
 
-inline bool NetworkTableEntry::SetDoubleArray(
-    std::initializer_list<double> value) {
-  return SetEntryValue(m_handle, Value::MakeDoubleArray(value));
+inline bool NetworkTableEntry::SetFloatArray(std::span<const float> value,
+                                             int64_t time) {
+  return nt::SetFloatArray(m_handle, value, time);
+}
+
+inline bool NetworkTableEntry::SetDoubleArray(std::span<const double> value,
+                                              int64_t time) {
+  return nt::SetDoubleArray(m_handle, value, time);
 }
 
 inline bool NetworkTableEntry::SetStringArray(
-    wpi::span<const 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(std::string_view value) {
-  SetEntryTypeValue(m_handle, Value::MakeString(value));
-}
-
-inline void NetworkTableEntry::ForceSetRaw(std::string_view value) {
-  SetEntryTypeValue(m_handle, Value::MakeRaw(value));
-}
-
-inline void NetworkTableEntry::ForceSetBooleanArray(
-    wpi::span<const 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(
-    wpi::span<const 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(
-    wpi::span<const 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(
-    wpi::span<const 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));
+    std::span<const std::string> value, int64_t time) {
+  return nt::SetStringArray(m_handle, value, time);
 }
 
 inline void NetworkTableEntry::SetFlags(unsigned int flags) {
-  SetEntryFlags(m_handle, GetFlags() | flags);
+  SetEntryFlags(m_handle, GetEntryFlags(m_handle) | flags);
 }
 
 inline void NetworkTableEntry::ClearFlags(unsigned int flags) {
-  SetEntryFlags(m_handle, GetFlags() & ~flags);
+  SetEntryFlags(m_handle, GetEntryFlags(m_handle) & ~flags);
 }
 
 inline void NetworkTableEntry::SetPersistent() {
-  SetFlags(kPersistent);
+  nt::SetTopicPersistent(nt::GetTopicFromHandle(m_handle), true);
 }
 
 inline void NetworkTableEntry::ClearPersistent() {
-  ClearFlags(kPersistent);
+  nt::SetTopicPersistent(nt::GetTopicFromHandle(m_handle), false);
 }
 
 inline bool NetworkTableEntry::IsPersistent() const {
-  return (GetFlags() & kPersistent) != 0;
+  return nt::GetTopicPersistent(nt::GetTopicFromHandle(m_handle));
+}
+
+inline void NetworkTableEntry::Unpublish() {
+  return nt::Unpublish(m_handle);
 }
 
 inline void NetworkTableEntry::Delete() {
-  DeleteEntry(m_handle);
-}
-
-inline void NetworkTableEntry::CreateRpc(
-    std::function<void(const RpcAnswer& answer)> callback) {
-  ::nt::CreateRpc(m_handle, std::string_view("\0", 1), callback);
-}
-
-inline RpcCall NetworkTableEntry::CallRpc(std::string_view 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);
+  Unpublish();
 }
 
 }  // namespace nt
-
-#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEENTRY_INC_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableInstance.h b/ntcore/src/main/native/include/networktables/NetworkTableInstance.h
index 54b5324..fabc634 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTableInstance.h
+++ b/ntcore/src/main/native/include/networktables/NetworkTableInstance.h
@@ -2,18 +2,17 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_H_
-#define NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_H_
+#pragma once
 
 #include <functional>
 #include <memory>
+#include <optional>
+#include <span>
 #include <string>
 #include <string_view>
 #include <utility>
 #include <vector>
 
-#include <wpi/span.h>
-
 #include "networktables/NetworkTable.h"
 #include "networktables/NetworkTableEntry.h"
 #include "ntcore_c.h"
@@ -21,6 +20,21 @@
 
 namespace nt {
 
+class BooleanArrayTopic;
+class BooleanTopic;
+class DoubleArrayTopic;
+class DoubleTopic;
+class FloatArrayTopic;
+class FloatTopic;
+class IntegerArrayTopic;
+class IntegerTopic;
+class MultiSubscriber;
+class RawTopic;
+class StringArrayTopic;
+class StringTopic;
+class Subscriber;
+class Topic;
+
 /**
  * NetworkTables Instance.
  *
@@ -51,9 +65,8 @@
   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,
+    kNetModeClient3 = NT_NET_MODE_CLIENT3,
+    kNetModeClient4 = NT_NET_MODE_CLIENT4,
     kNetModeLocal = NT_NET_MODE_LOCAL
   };
 
@@ -73,9 +86,14 @@
   };
 
   /**
-   * The default port that network tables operates on.
+   * The default port that network tables operates on for NT3.
    */
-  enum { kDefaultPort = NT_DEFAULT_PORT };
+  static constexpr unsigned int kDefaultPort3 = NT_DEFAULT_PORT3;
+
+  /**
+   * The default port that network tables operates on for NT4.
+   */
+  static constexpr unsigned int kDefaultPort4 = NT_DEFAULT_PORT4;
 
   /**
    * Construct invalid instance.
@@ -115,7 +133,7 @@
    *
    * @param inst Instance
    */
-  static void Destroy(NetworkTableInstance inst);
+  static void Destroy(NetworkTableInstance& inst);
 
   /**
    * Gets the native handle for the entry.
@@ -125,6 +143,204 @@
   NT_Inst GetHandle() const;
 
   /**
+   * Gets a "generic" (untyped) topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  Topic GetTopic(std::string_view name) const;
+
+  /**
+   * Gets a boolean topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  BooleanTopic GetBooleanTopic(std::string_view name) const;
+
+  /**
+   * Gets an integer topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  IntegerTopic GetIntegerTopic(std::string_view name) const;
+
+  /**
+   * Gets a float topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  FloatTopic GetFloatTopic(std::string_view name) const;
+
+  /**
+   * Gets a double topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  DoubleTopic GetDoubleTopic(std::string_view name) const;
+
+  /**
+   * Gets a string topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  StringTopic GetStringTopic(std::string_view name) const;
+
+  /**
+   * Gets a raw topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  RawTopic GetRawTopic(std::string_view name) const;
+
+  /**
+   * Gets a boolean array topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  BooleanArrayTopic GetBooleanArrayTopic(std::string_view name) const;
+
+  /**
+   * Gets an integer array topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  IntegerArrayTopic GetIntegerArrayTopic(std::string_view name) const;
+
+  /**
+   * Gets a float array topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  FloatArrayTopic GetFloatArrayTopic(std::string_view name) const;
+
+  /**
+   * Gets a double array topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  DoubleArrayTopic GetDoubleArrayTopic(std::string_view name) const;
+
+  /**
+   * Gets a string array topic.
+   *
+   * @param name topic name
+   * @return Topic
+   */
+  StringArrayTopic GetStringArrayTopic(std::string_view name) const;
+
+  /**
+   * Get Published Topics.
+   *
+   * Returns an array of topics.
+   *
+   * @return Array of topics.
+   */
+  std::vector<Topic> GetTopics();
+
+  /**
+   * Get Published Topics.
+   *
+   * Returns an array of topics.  The results are filtered by
+   * string prefix to only return a subset of all topics.
+   *
+   * @param prefix  name required prefix; only topics whose name
+   *                starts with this string are returned
+   * @return Array of topics.
+   */
+  std::vector<Topic> GetTopics(std::string_view prefix);
+
+  /**
+   * Get Published Topics.
+   *
+   * Returns an array of topics.  The results are filtered by
+   * string prefix and type to only return a subset of all topics.
+   *
+   * @param prefix  name required prefix; only topics 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 topics.
+   */
+  std::vector<Topic> GetTopics(std::string_view prefix, unsigned int types);
+
+  /**
+   * Get Published Topics.
+   *
+   * Returns an array of topics.  The results are filtered by
+   * string prefix and type to only return a subset of all topics.
+   *
+   * @param prefix  name required prefix; only topics whose name
+   *                starts with this string are returned
+   * @param types   array of type strings
+   * @return Array of topic handles.
+   */
+  std::vector<Topic> GetTopics(std::string_view prefix,
+                               std::span<std::string_view> types);
+
+  /**
+   * Get Topic Information about multiple topics.
+   *
+   * Returns an array of topic information (handle, name, type, and properties).
+   *
+   * @return Array of topic information.
+   */
+  std::vector<TopicInfo> GetTopicInfo();
+
+  /**
+   * Get Topic Information about multiple topics.
+   *
+   * Returns an array of topic information (handle, name, type, and properties).
+   * The results are filtered by string prefix to only
+   * return a subset of all topics.
+   *
+   * @param prefix  name required prefix; only topics whose name
+   *                starts with this string are returned
+   * @return Array of topic information.
+   */
+  std::vector<TopicInfo> GetTopicInfo(std::string_view prefix);
+
+  /**
+   * Get Topic Information about multiple topics.
+   *
+   * Returns an array of topic information (handle, name, type, and properties).
+   * The results are filtered by string prefix and type to only
+   * return a subset of all topics.
+   *
+   * @param prefix  name required prefix; only topics 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 topic information.
+   */
+  std::vector<TopicInfo> GetTopicInfo(std::string_view prefix,
+                                      unsigned int types);
+
+  /**
+   * Get Topic Information about multiple topics.
+   *
+   * Returns an array of topic information (handle, name, type, and properties).
+   * The results are filtered by string prefix and type to only
+   * return a subset of all topics.
+   *
+   * @param prefix  name required prefix; only topics whose name
+   *                starts with this string are returned
+   * @param types   array of type strings
+   * @return Array of topic information.
+   */
+  std::vector<TopicInfo> GetTopicInfo(std::string_view prefix,
+                                      std::span<std::string_view> types);
+
+  /**
    * Gets the entry for a key.
    *
    * @param name Key
@@ -133,34 +349,6 @@
   NetworkTableEntry GetEntry(std::string_view 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(std::string_view 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(std::string_view prefix,
-                                      unsigned int types) const;
-
-  /**
    * Gets the table with the specified key.
    *
    * @param key the key name
@@ -169,103 +357,130 @@
   std::shared_ptr<NetworkTable> GetTable(std::string_view key) const;
 
   /**
-   * Deletes ALL keys in ALL subtables (except persistent values).
-   * Use with caution!
-   */
-  void DeleteAllEntries();
-
-  /**
    * @{
-   * @name Entry Listener Functions
+   * @name Listener Functions
    */
 
   /**
-   * Add a listener for all entries starting with a certain prefix.
+   * Remove a listener.
    *
-   * @param prefix            UTF-8 string prefix
-   * @param callback          listener to add
-   * @param flags             EntryListenerFlags bitmask
-   * @return Listener handle
+   * @param listener Listener handle to remove
    */
-  NT_EntryListener AddEntryListener(
-      std::string_view prefix,
-      std::function<void(const EntryNotification& event)> callback,
-      unsigned int flags) const;
+  static void RemoveListener(NT_Listener listener);
 
   /**
-   * 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
+   * Wait for the listener queue to be empty. This is primarily
+   * useful for deterministic testing. This blocks until either the
    * 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
+   * @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);
-
-  /** @} */
+  bool WaitForListenerQueue(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.
+   * Add a connection listener. The callback function is called asynchronously
+   * on a separate thread, so it's important to use synchronization or atomics
+   * when accessing any shared state from the callback function.
    *
-   * @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.
+   * @param immediate_notify  notify listener of all existing connections
+   * @param callback          listener to add
+   * @return Listener handle
    */
-  bool WaitForRpcCallQueue(double timeout);
+  NT_Listener AddConnectionListener(bool immediate_notify,
+                                    ListenerCallback callback) const;
+
+  /**
+   * Add a time synchronization listener. The callback function is called
+   * asynchronously on a separate thread, so it's important to use
+   * synchronization or atomics when accessing any shared state from the
+   * callback function.
+   *
+   * @param immediate_notify  notify listener of current time synchronization
+   *                          value
+   * @param callback          listener to add
+   * @return Listener handle
+   */
+  NT_Listener AddTimeSyncListener(bool immediate_notify,
+                                  ListenerCallback callback) const;
+
+  /**
+   * Add a listener for changes on a particular topic. The callback
+   * function is called asynchronously on a separate thread, so it's important
+   * to use synchronization or atomics when accessing any shared state from the
+   * callback function.
+   *
+   * This creates a corresponding internal subscriber with the lifetime of the
+   * listener.
+   *
+   * @param topic Topic
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  NT_Listener AddListener(Topic topic, unsigned int eventMask,
+                          ListenerCallback listener);
+
+  /**
+   * Add a listener for changes on a subscriber. The callback
+   * function is called asynchronously on a separate thread, so it's important
+   * to use synchronization or atomics when accessing any shared state from the
+   * callback function. This does NOT keep the subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  NT_Listener AddListener(Subscriber& subscriber, unsigned int eventMask,
+                          ListenerCallback listener);
+
+  /**
+   * Add a listener for changes on a subscriber. The callback
+   * function is called asynchronously on a separate thread, so it's important
+   * to use synchronization or atomics when accessing any shared state from the
+   * callback function. This does NOT keep the subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  NT_Listener AddListener(MultiSubscriber& subscriber, int eventMask,
+                          ListenerCallback listener);
+
+  /**
+   * Add a listener for changes on an entry. The callback function
+   * is called asynchronously on a separate thread, so it's important to use
+   * synchronization or atomics when accessing any shared state from the
+   * callback function.
+   *
+   * @param entry Entry
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  NT_Listener AddListener(const NetworkTableEntry& entry, int eventMask,
+                          ListenerCallback listener);
+
+  /**
+   * Add a listener for changes to topics with names that start with any
+   * of the given prefixes. The callback function is called asynchronously on a
+   * separate thread, so it's important to use synchronization or atomics when
+   * accessing any shared state from the callback function.
+   *
+   * This creates a corresponding internal subscriber with the lifetime of the
+   * listener.
+   *
+   * @param prefixes Topic name string prefixes
+   * @param eventMask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener handle
+   */
+  NT_Listener AddListener(std::span<const std::string_view> prefixes,
+                          int eventMask, ListenerCallback listener);
 
   /** @} */
 
@@ -275,16 +490,6 @@
    */
 
   /**
-   * 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(std::string_view name);
-
-  /**
    * Get the current network mode.
    *
    * @return Bitmask of NetworkMode.
@@ -311,11 +516,13 @@
    *                          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
+   * @param port3             port to communicate over (NT3)
+   * @param port4             port to communicate over (NT4)
    */
-  void StartServer(std::string_view persist_filename = "networktables.ini",
+  void StartServer(std::string_view persist_filename = "networktables.json",
                    const char* listen_address = "",
-                   unsigned int port = kDefaultPort);
+                   unsigned int port3 = kDefaultPort3,
+                   unsigned int port4 = kDefaultPort4);
 
   /**
    * Stops the server if it is running.
@@ -323,45 +530,20 @@
   void StopServer();
 
   /**
-   * Starts a client.  Use SetServer to set the server name and port.
+   * Starts a NT3 client.  Use SetServer or SetServerTeam to set the server name
+   * and port.
+   *
+   * @param identity  network identity to advertise (cannot be empty string)
    */
-  void StartClient();
+  void StartClient3(std::string_view identity);
 
   /**
-   * Starts a client using the specified server and port
+   * Starts a NT4 client.  Use SetServer or SetServerTeam to set the server name
+   * and port.
    *
-   * @param server_name server name (UTF-8 string, null terminated)
-   * @param port        port to communicate over
+   * @param identity  network identity to advertise (cannot be empty string)
    */
-  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(
-      wpi::span<const std::pair<std::string_view, 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(wpi::span<const std::string_view> 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);
+  void StartClient4(std::string_view identity);
 
   /**
    * Stops the client if it is running.
@@ -372,46 +554,46 @@
    * 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
+   * @param port        port to communicate over (0 = default)
    */
-  void SetServer(const char* server_name, unsigned int port = kDefaultPort);
+  void SetServer(const char* server_name, unsigned int port = 0);
 
   /**
    * 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
+   * @param servers   array of server address and port pairs
    */
   void SetServer(
-      wpi::span<const std::pair<std::string_view, unsigned int>> servers);
+      std::span<const std::pair<std::string_view, 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
+   * @param port      port to communicate over (0 = default)
    */
-  void SetServer(wpi::span<const std::string_view> servers,
-                 unsigned int port = kDefaultPort);
+  void SetServer(std::span<const std::string_view> servers,
+                 unsigned int port = 0);
 
   /**
    * 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
+   * @param port        port to communicate over (0 = default)
    */
-  void SetServerTeam(unsigned int team, unsigned int port = kDefaultPort);
+  void SetServerTeam(unsigned int team, unsigned int port = 0);
 
   /**
    * 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
+   * @param port server port to use in combination with IP from DS (0 = default)
    */
-  void StartDSClient(unsigned int port = kDefaultPort);
+  void StartDSClient(unsigned int port = 0);
 
   /**
    * Stops requesting server address from Driver Station.
@@ -419,12 +601,10 @@
   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)
+   * Flushes all updated values immediately to the local client/server. This
+   * does not flush to the network.
    */
-  void SetUpdateRate(double interval);
+  void FlushLocal() const;
 
   /**
    * Flushes all updated values immediately to the network.
@@ -449,59 +629,64 @@
    */
   bool IsConnected() const;
 
+  /**
+   * Get the time offset between server time and local time. Add this value to
+   * local time to get the estimated equivalent server time. In server mode,
+   * this always returns 0. In client mode, this returns the time offset only if
+   * the client and server are connected and have exchanged synchronization
+   * messages. Note the time offset may change over time as it is periodically
+   * updated; to receive updates as events, add a listener to the "time sync"
+   * event.
+   *
+   * @return Time offset in microseconds (optional)
+   */
+  std::optional<int64_t> GetServerTimeOffset() const;
+
   /** @} */
 
   /**
    * @{
-   * @name File Save/Load Functions
+   * @name Data Logger 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.
+   * Starts logging entry changes to a DataLog.
    *
-   * @param filename  filename
-   * @return error string, or nullptr if successful
+   * @param log data log object; lifetime must extend until StopEntryDataLog is
+   *            called or the instance is destroyed
+   * @param prefix only store entries with names that start with this prefix;
+   *               the prefix is not included in the data log entry name
+   * @param logPrefix prefix to add to data log entry names
+   * @return Data logger handle
    */
-  const char* SavePersistent(std::string_view filename) const;
+  NT_DataLogger StartEntryDataLog(wpi::log::DataLog& log,
+                                  std::string_view prefix,
+                                  std::string_view logPrefix);
 
   /**
-   * 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.
+   * Stops logging entry changes to a DataLog.
    *
-   * @param filename  filename
-   * @param warn      callback function for warnings
-   * @return error string, or nullptr if successful
+   * @param logger data logger handle
    */
-  const char* LoadPersistent(
-      std::string_view filename,
-      std::function<void(size_t line, const char* msg)> warn);
+  static void StopEntryDataLog(NT_DataLogger logger);
 
   /**
-   * Save table values to a file.  The file format used is identical to
-   * that used for SavePersistent.
+   * Starts logging connection changes to a DataLog.
    *
-   * @param filename  filename
-   * @param prefix    save only keys starting with this prefix
-   * @return error string, or nullptr if successful
+   * @param log data log object; lifetime must extend until
+   *            StopConnectionDataLog is called or the instance is destroyed
+   * @param name data log entry name
+   * @return Data logger handle
    */
-  const char* SaveEntries(std::string_view filename,
-                          std::string_view prefix) const;
+  NT_ConnectionDataLogger StartConnectionDataLog(wpi::log::DataLog& log,
+                                                 std::string_view name);
 
   /**
-   * Load table values from a file.  The file format used is identical to
-   * that used for SavePersistent / LoadPersistent.
+   * Stops logging connection changes to a DataLog.
    *
-   * @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
+   * @param logger data logger handle
    */
-  const char* LoadEntries(
-      std::string_view filename, std::string_view prefix,
-      std::function<void(size_t line, const char* msg)> warn);
+  static void StopConnectionDataLog(NT_ConnectionDataLogger logger);
 
   /** @} */
 
@@ -517,32 +702,13 @@
    * 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
+   * @param func        callback function
+   * @return Listener handle
    */
-  NT_Logger AddLogger(std::function<void(const LogMessage& msg)> func,
-                      unsigned int minLevel, unsigned int maxLevel);
-
-  /**
-   * 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);
+  NT_Listener AddLogger(unsigned int minLevel, unsigned int maxLevel,
+                        ListenerCallback func);
 
   /** @} */
 
@@ -550,14 +716,7 @@
    * 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);
-  }
+  bool operator==(const NetworkTableInstance&) const = default;
 
  private:
   /* Native handle */
@@ -567,5 +726,3 @@
 }  // namespace nt
 
 #include "networktables/NetworkTableInstance.inc"
-
-#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_H_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableInstance.inc b/ntcore/src/main/native/include/networktables/NetworkTableInstance.inc
index 5cb7be0..9b712eb 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTableInstance.inc
+++ b/ntcore/src/main/native/include/networktables/NetworkTableInstance.inc
@@ -2,14 +2,15 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_INC_
-#define NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_INC_
+#pragma once
 
 #include <string_view>
 #include <utility>
 #include <vector>
 
 #include "networktables/NetworkTableInstance.h"
+#include "networktables/Topic.h"
+#include "ntcore_c.h"
 
 namespace nt {
 
@@ -26,9 +27,10 @@
   return NetworkTableInstance{CreateInstance()};
 }
 
-inline void NetworkTableInstance::Destroy(NetworkTableInstance inst) {
+inline void NetworkTableInstance::Destroy(NetworkTableInstance& inst) {
   if (inst.m_handle != 0) {
     DestroyInstance(inst.m_handle);
+    inst.m_handle = 0;
   }
 }
 
@@ -36,53 +38,79 @@
   return m_handle;
 }
 
+inline std::vector<Topic> NetworkTableInstance::GetTopics() {
+  auto handles = ::nt::GetTopics(m_handle, "", 0);
+  return {handles.begin(), handles.end()};
+}
+
+inline std::vector<Topic> NetworkTableInstance::GetTopics(
+    std::string_view prefix) {
+  auto handles = ::nt::GetTopics(m_handle, prefix, 0);
+  return {handles.begin(), handles.end()};
+}
+
+inline std::vector<Topic> NetworkTableInstance::GetTopics(
+    std::string_view prefix, unsigned int types) {
+  auto handles = ::nt::GetTopics(m_handle, prefix, types);
+  return {handles.begin(), handles.end()};
+}
+
+inline std::vector<Topic> NetworkTableInstance::GetTopics(
+    std::string_view prefix, std::span<std::string_view> types) {
+  auto handles = ::nt::GetTopics(m_handle, prefix, types);
+  return {handles.begin(), handles.end()};
+}
+
+inline std::vector<TopicInfo> NetworkTableInstance::GetTopicInfo() {
+  return ::nt::GetTopicInfo(m_handle, "", 0);
+}
+
+inline std::vector<TopicInfo> NetworkTableInstance::GetTopicInfo(
+    std::string_view prefix) {
+  return ::nt::GetTopicInfo(m_handle, prefix, 0);
+}
+
+inline std::vector<TopicInfo> NetworkTableInstance::GetTopicInfo(
+    std::string_view prefix, unsigned int types) {
+  return ::nt::GetTopicInfo(m_handle, prefix, types);
+}
+
+inline std::vector<TopicInfo> NetworkTableInstance::GetTopicInfo(
+    std::string_view prefix, std::span<std::string_view> types) {
+  return ::nt::GetTopicInfo(m_handle, prefix, types);
+}
+
 inline NetworkTableEntry NetworkTableInstance::GetEntry(std::string_view name) {
   return NetworkTableEntry{::nt::GetEntry(m_handle, name)};
 }
 
-inline std::vector<NetworkTableEntry> NetworkTableInstance::GetEntries(
-    std::string_view prefix, unsigned int types) {
-  std::vector<NetworkTableEntry> entries;
-  for (auto entry : ::nt::GetEntries(m_handle, prefix, types)) {
-    entries.emplace_back(entry);
-  }
-  return entries;
+inline bool NetworkTableInstance::WaitForListenerQueue(double timeout) {
+  return ::nt::WaitForListenerQueue(m_handle, timeout);
 }
 
-inline std::vector<EntryInfo> NetworkTableInstance::GetEntryInfo(
-    std::string_view prefix, unsigned int types) const {
-  return ::nt::GetEntryInfo(m_handle, prefix, types);
+inline void NetworkTableInstance::RemoveListener(NT_Listener listener) {
+  ::nt::RemoveListener(listener);
 }
 
-inline void NetworkTableInstance::DeleteAllEntries() {
-  ::nt::DeleteAllEntries(m_handle);
+inline NT_Listener NetworkTableInstance::AddConnectionListener(
+    bool immediate_notify, ListenerCallback callback) const {
+  return ::nt::AddListener(
+      m_handle,
+      NT_EVENT_CONNECTION | (immediate_notify ? NT_EVENT_IMMEDIATE : 0),
+      std::move(callback));
 }
 
-inline void NetworkTableInstance::RemoveEntryListener(
-    NT_EntryListener entry_listener) {
-  ::nt::RemoveEntryListener(entry_listener);
+inline NT_Listener NetworkTableInstance::AddTimeSyncListener(
+    bool immediate_notify, ListenerCallback callback) const {
+  return ::nt::AddListener(
+      m_handle, NT_EVENT_TIMESYNC | (immediate_notify ? NT_EVENT_IMMEDIATE : 0),
+      std::move(callback));
 }
 
-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(std::string_view name) {
-  ::nt::SetNetworkIdentity(m_handle, name);
+inline NT_Listener NetworkTableInstance::AddListener(
+    std::span<const std::string_view> prefixes, int eventMask,
+    ListenerCallback listener) {
+  return ::nt::AddListener(m_handle, prefixes, eventMask, std::move(listener));
 }
 
 inline unsigned int NetworkTableInstance::GetNetworkMode() const {
@@ -99,31 +127,21 @@
 
 inline void NetworkTableInstance::StartServer(std::string_view persist_filename,
                                               const char* listen_address,
-                                              unsigned int port) {
-  ::nt::StartServer(m_handle, persist_filename, listen_address, port);
+                                              unsigned int port3,
+                                              unsigned int port4) {
+  ::nt::StartServer(m_handle, persist_filename, listen_address, port3, port4);
 }
 
 inline void NetworkTableInstance::StopServer() {
   ::nt::StopServer(m_handle);
 }
 
-inline void NetworkTableInstance::StartClient() {
-  ::nt::StartClient(m_handle);
+inline void NetworkTableInstance::StartClient3(std::string_view identity) {
+  ::nt::StartClient3(m_handle, identity);
 }
 
-inline void NetworkTableInstance::StartClient(const char* server_name,
-                                              unsigned int port) {
-  ::nt::StartClient(m_handle, server_name, port);
-}
-
-inline void NetworkTableInstance::StartClient(
-    wpi::span<const std::pair<std::string_view, 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::StartClient4(std::string_view identity) {
+  ::nt::StartClient4(m_handle, identity);
 }
 
 inline void NetworkTableInstance::StopClient() {
@@ -136,7 +154,7 @@
 }
 
 inline void NetworkTableInstance::SetServer(
-    wpi::span<const std::pair<std::string_view, unsigned int>> servers) {
+    std::span<const std::pair<std::string_view, unsigned int>> servers) {
   ::nt::SetServer(m_handle, servers);
 }
 
@@ -153,8 +171,8 @@
   ::nt::StopDSClient(m_handle);
 }
 
-inline void NetworkTableInstance::SetUpdateRate(double interval) {
-  ::nt::SetUpdateRate(m_handle, interval);
+inline void NetworkTableInstance::FlushLocal() const {
+  ::nt::FlushLocal(m_handle);
 }
 
 inline void NetworkTableInstance::Flush() const {
@@ -170,42 +188,35 @@
   return ::nt::IsConnected(m_handle);
 }
 
-inline const char* NetworkTableInstance::SavePersistent(
-    std::string_view filename) const {
-  return ::nt::SavePersistent(m_handle, filename);
+inline std::optional<int64_t> NetworkTableInstance::GetServerTimeOffset()
+    const {
+  return ::nt::GetServerTimeOffset(m_handle);
 }
 
-inline const char* NetworkTableInstance::LoadPersistent(
-    std::string_view filename,
-    std::function<void(size_t line, const char* msg)> warn) {
-  return ::nt::LoadPersistent(m_handle, filename, warn);
+inline NT_DataLogger NetworkTableInstance::StartEntryDataLog(
+    wpi::log::DataLog& log, std::string_view prefix,
+    std::string_view logPrefix) {
+  return ::nt::StartEntryDataLog(m_handle, log, prefix, logPrefix);
 }
 
-inline const char* NetworkTableInstance::SaveEntries(
-    std::string_view filename, std::string_view prefix) const {
-  return ::nt::SaveEntries(m_handle, filename, prefix);
+inline void NetworkTableInstance::StopEntryDataLog(NT_DataLogger logger) {
+  ::nt::StopEntryDataLog(logger);
 }
 
-inline const char* NetworkTableInstance::LoadEntries(
-    std::string_view filename, std::string_view prefix,
-    std::function<void(size_t line, const char* msg)> warn) {
-  return ::nt::LoadEntries(m_handle, filename, prefix, warn);
+inline NT_ConnectionDataLogger NetworkTableInstance::StartConnectionDataLog(
+    wpi::log::DataLog& log, std::string_view name) {
+  return ::nt::StartConnectionDataLog(m_handle, log, name);
 }
 
-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::StopConnectionDataLog(
+    NT_ConnectionDataLogger logger) {
+  ::nt::StopConnectionDataLog(logger);
 }
 
-inline void NetworkTableInstance::RemoveLogger(NT_Logger logger) {
-  ::nt::RemoveLogger(logger);
-}
-
-inline bool NetworkTableInstance::WaitForLoggerQueue(double timeout) {
-  return ::nt::WaitForLoggerQueue(m_handle, timeout);
+inline NT_Listener NetworkTableInstance::AddLogger(unsigned int min_level,
+                                                   unsigned int max_level,
+                                                   ListenerCallback func) {
+  return ::nt::AddLogger(m_handle, min_level, max_level, std::move(func));
 }
 
 }  // namespace nt
-
-#endif  // NTCORE_NETWORKTABLES_NETWORKTABLEINSTANCE_INC_
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableListener.h b/ntcore/src/main/native/include/networktables/NetworkTableListener.h
new file mode 100644
index 0000000..1a8cf1f
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableListener.h
@@ -0,0 +1,312 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <functional>
+#include <span>
+#include <string_view>
+#include <vector>
+
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class MultiSubscriber;
+class NetworkTableEntry;
+class NetworkTableInstance;
+class Subscriber;
+class Topic;
+
+/**
+ * Event listener. This calls back to a callback function when an event
+ * matching the specified mask occurs. The callback function is called
+ * asynchronously on a separate thread, so it's important to use synchronization
+ * or atomics when accessing any shared state from the callback function.
+ */
+class NetworkTableListener final {
+ public:
+  NetworkTableListener() = default;
+
+  /**
+   * Create a listener for changes to topics with names that start with any of
+   * the given prefixes. This creates a corresponding internal subscriber with
+   * the lifetime of the listener.
+   *
+   * @param inst Instance
+   * @param prefixes Topic name string prefixes
+   * @param mask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateListener(
+      NetworkTableInstance inst, std::span<const std::string_view> prefixes,
+      unsigned int mask, ListenerCallback listener);
+
+  /**
+   * Create a listener for changes on a particular topic. This creates a
+   * corresponding internal subscriber with the lifetime of the listener.
+   *
+   * @param topic Topic
+   * @param mask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateListener(Topic topic, unsigned int mask,
+                                             ListenerCallback listener);
+
+  /**
+   * Create a listener for topic changes on a subscriber. This does NOT keep the
+   * subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param mask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateListener(Subscriber& subscriber,
+                                             unsigned int mask,
+                                             ListenerCallback listener);
+
+  /**
+   * Create a listener for topic changes on a subscriber. This does NOT keep the
+   * subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param mask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateListener(MultiSubscriber& subscriber,
+                                             unsigned int mask,
+                                             ListenerCallback listener);
+
+  /**
+   * Create a listener for topic changes on an entry.
+   *
+   * @param entry Entry
+   * @param mask Bitmask of EventFlags values
+   * @param listener Listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateListener(NetworkTableEntry& entry,
+                                             unsigned int mask,
+                                             ListenerCallback listener);
+
+  /**
+   * Create a connection listener.
+   *
+   * @param inst              instance
+   * @param immediate_notify  notify listener of all existing connections
+   * @param listener          listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateConnectionListener(
+      NetworkTableInstance inst, bool immediate_notify,
+      ListenerCallback listener);
+
+  /**
+   * Create a time synchronization listener.
+   *
+   * @param inst              instance
+   * @param immediate_notify  notify listener of current time synchronization
+   *                          value
+   * @param listener          listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateTimeSyncListener(NetworkTableInstance inst,
+                                                     bool immediate_notify,
+                                                     ListenerCallback listener);
+
+  /**
+   * Create a listener for log messages.  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 inst        instance
+   * @param minLevel    minimum log level
+   * @param maxLevel    maximum log level
+   * @param listener    listener function
+   * @return Listener
+   */
+  static NetworkTableListener CreateLogger(NetworkTableInstance inst,
+                                           unsigned int minLevel,
+                                           unsigned int maxLevel,
+                                           ListenerCallback listener);
+
+  NetworkTableListener(const NetworkTableListener&) = delete;
+  NetworkTableListener& operator=(const NetworkTableListener&) = delete;
+  NetworkTableListener(NetworkTableListener&& rhs);
+  NetworkTableListener& operator=(NetworkTableListener&& rhs);
+  ~NetworkTableListener();
+
+  explicit operator bool() const { return m_handle != 0; }
+
+  /**
+   * Gets the native handle.
+   *
+   * @return Handle
+   */
+  NT_Listener GetHandle() const { return m_handle; }
+
+  /**
+   * Wait for the listener queue to be empty. This is primarily useful for
+   * deterministic testing. This blocks until either the 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 WaitForQueue(double timeout);
+
+ private:
+  explicit NetworkTableListener(NT_Listener handle) : m_handle{handle} {}
+
+  NT_Listener m_handle{0};
+};
+
+/**
+ * Event polled listener. This queues events matching the specified mask. Code
+ * using the listener must periodically call ReadQueue() to read the
+ * events.
+ */
+class NetworkTableListenerPoller final {
+ public:
+  NetworkTableListenerPoller() = default;
+
+  /**
+   * Construct a listener poller.
+   *
+   * @param inst Instance
+   */
+  explicit NetworkTableListenerPoller(NetworkTableInstance inst);
+
+  NetworkTableListenerPoller(const NetworkTableListenerPoller&) = delete;
+  NetworkTableListenerPoller& operator=(const NetworkTableListenerPoller&) =
+      delete;
+  NetworkTableListenerPoller(NetworkTableListenerPoller&& rhs);
+  NetworkTableListenerPoller& operator=(NetworkTableListenerPoller&& rhs);
+  ~NetworkTableListenerPoller();
+
+  explicit operator bool() const { return m_handle != 0; }
+
+  /**
+   * Gets the native handle.
+   *
+   * @return Handle
+   */
+  NT_ListenerPoller GetHandle() const { return m_handle; }
+
+  /**
+   * Start listening to topic changes for topics with names that start with any
+   * of the given prefixes. This creates a corresponding internal subscriber
+   * with the lifetime of the listener.
+   *
+   * @param prefixes Topic name string prefixes
+   * @param mask Bitmask of EventFlags values
+   * @return Listener handle
+   */
+  NT_Listener AddListener(std::span<const std::string_view> prefixes,
+                          unsigned int mask);
+
+  /**
+   * Start listening to changes to a particular topic. This creates a
+   * corresponding internal subscriber with the lifetime of the listener.
+   *
+   * @param topic Topic
+   * @param mask Bitmask of EventFlags values
+   * @return Listener handle
+   */
+  NT_Listener AddListener(Topic topic, unsigned int mask);
+
+  /**
+   * Start listening to topic changes on a subscriber. This does NOT keep the
+   * subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param mask Bitmask of EventFlags values
+   * @return Listener handle
+   */
+  NT_Listener AddListener(Subscriber& subscriber, unsigned int mask);
+
+  /**
+   * Start listening to topic changes on a subscriber. This does NOT keep the
+   * subscriber active.
+   *
+   * @param subscriber Subscriber
+   * @param mask Bitmask of EventFlags values
+   * @return Listener handle
+   */
+  NT_Listener AddListener(MultiSubscriber& subscriber, unsigned int mask);
+
+  /**
+   * Start listening to topic changes on an entry.
+   *
+   * @param entry Entry
+   * @param mask Bitmask of EventFlags values
+   * @return Listener handle
+   */
+  NT_Listener AddListener(NetworkTableEntry& entry, unsigned int mask);
+
+  /**
+   * Add a connection listener. The callback function is called asynchronously
+   * on a separate thread, so it's important to use synchronization or atomics
+   * when accessing any shared state from the callback function.
+   *
+   * @param immediate_notify  notify listener of all existing connections
+   * @return Listener handle
+   */
+  NT_Listener AddConnectionListener(bool immediate_notify);
+
+  /**
+   * Add a time synchronization listener. The callback function is called
+   * asynchronously on a separate thread, so it's important to use
+   * synchronization or atomics when accessing any shared state from the
+   * callback function.
+   *
+   * @param immediate_notify  notify listener of current time synchronization
+   *                          value
+   * @return Listener handle
+   */
+  NT_Listener AddTimeSyncListener(bool immediate_notify);
+
+  /**
+   * 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 minLevel    minimum log level
+   * @param maxLevel    maximum log level
+   * @return Listener handle
+   */
+  NT_Listener AddLogger(unsigned int minLevel, unsigned int maxLevel);
+
+  /**
+   * Remove a listener.
+   *
+   * @param listener Listener handle
+   */
+  void RemoveListener(NT_Listener listener);
+
+  /**
+   * Read events.
+   *
+   * @return Events since the previous call to ReadQueue()
+   */
+  std::vector<Event> ReadQueue();
+
+ private:
+  NT_ListenerPoller m_handle{0};
+};
+
+}  // namespace nt
+
+#include "NetworkTableListener.inc"
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableListener.inc b/ntcore/src/main/native/include/networktables/NetworkTableListener.inc
new file mode 100644
index 0000000..5453d87
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/NetworkTableListener.inc
@@ -0,0 +1,184 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <span>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "networktables/MultiSubscriber.h"
+#include "networktables/NetworkTableEntry.h"
+#include "networktables/NetworkTableInstance.h"
+#include "networktables/NetworkTableListener.h"
+#include "networktables/Topic.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+inline NetworkTableListener NetworkTableListener::CreateListener(
+    NetworkTableInstance inst, std::span<const std::string_view> prefixes,
+    unsigned int mask, ListenerCallback listener) {
+  return NetworkTableListener{
+      ::nt::AddListener(inst.GetHandle(), prefixes, mask, std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateListener(
+    Topic topic, unsigned int mask, ListenerCallback listener) {
+  return NetworkTableListener{
+      nt::AddListener(topic.GetHandle(), mask, std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateListener(
+    Subscriber& subscriber, unsigned int mask, ListenerCallback listener) {
+  return NetworkTableListener{
+      ::nt::AddListener(subscriber.GetHandle(), mask, std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateListener(
+    MultiSubscriber& subscriber, unsigned int mask, ListenerCallback listener) {
+  return NetworkTableListener{
+      ::nt::AddListener(subscriber.GetHandle(), mask, std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateListener(
+    NetworkTableEntry& entry, unsigned int mask, ListenerCallback listener) {
+  return NetworkTableListener{
+      ::nt::AddListener(entry.GetHandle(), mask, std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateConnectionListener(
+    NetworkTableInstance inst, bool immediate_notify,
+    ListenerCallback listener) {
+  return NetworkTableListener{::nt::AddListener(
+      inst.GetHandle(),
+      NT_EVENT_CONNECTION | (immediate_notify ? NT_EVENT_IMMEDIATE : 0),
+      std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateTimeSyncListener(
+    NetworkTableInstance inst, bool immediate_notify,
+    ListenerCallback listener) {
+  return NetworkTableListener{::nt::AddListener(
+      inst.GetHandle(),
+      NT_EVENT_TIMESYNC | (immediate_notify ? NT_EVENT_IMMEDIATE : 0),
+      std::move(listener))};
+}
+
+inline NetworkTableListener NetworkTableListener::CreateLogger(
+    NetworkTableInstance inst, unsigned int minLevel, unsigned int maxLevel,
+    ListenerCallback listener) {
+  return NetworkTableListener{::nt::AddLogger(inst.GetHandle(), minLevel,
+                                              maxLevel, std::move(listener))};
+}
+
+inline NetworkTableListener::NetworkTableListener(NetworkTableListener&& rhs)
+    : m_handle(rhs.m_handle) {
+  rhs.m_handle = 0;
+}
+
+inline NetworkTableListener& NetworkTableListener::operator=(
+    NetworkTableListener&& rhs) {
+  if (m_handle != 0) {
+    nt::RemoveListener(m_handle);
+  }
+  m_handle = rhs.m_handle;
+  rhs.m_handle = 0;
+  return *this;
+}
+
+inline NetworkTableListener::~NetworkTableListener() {
+  if (m_handle != 0) {
+    nt::RemoveListener(m_handle);
+  }
+}
+
+inline bool NetworkTableListener::WaitForQueue(double timeout) {
+  if (m_handle != 0) {
+    return nt::WaitForListenerQueue(m_handle, timeout);
+  } else {
+    return false;
+  }
+}
+
+inline NetworkTableListenerPoller::NetworkTableListenerPoller(
+    NetworkTableInstance inst)
+    : m_handle(nt::CreateListenerPoller(inst.GetHandle())) {}
+
+inline NetworkTableListenerPoller::NetworkTableListenerPoller(
+    NetworkTableListenerPoller&& rhs)
+    : m_handle(rhs.m_handle) {
+  rhs.m_handle = 0;
+}
+
+inline NetworkTableListenerPoller& NetworkTableListenerPoller::operator=(
+    NetworkTableListenerPoller&& rhs) {
+  if (m_handle != 0) {
+    nt::DestroyListenerPoller(m_handle);
+  }
+  m_handle = rhs.m_handle;
+  rhs.m_handle = 0;
+  return *this;
+}
+
+inline NetworkTableListenerPoller::~NetworkTableListenerPoller() {
+  if (m_handle != 0) {
+    nt::DestroyListenerPoller(m_handle);
+  }
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddListener(
+    std::span<const std::string_view> prefixes, unsigned int mask) {
+  return nt::AddPolledListener(m_handle, prefixes, mask);
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddListener(Topic topic,
+                                                           unsigned int mask) {
+  return ::nt::AddPolledListener(m_handle, topic.GetHandle(), mask);
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddListener(
+    Subscriber& subscriber, unsigned int mask) {
+  return ::nt::AddPolledListener(m_handle, subscriber.GetHandle(), mask);
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddListener(
+    MultiSubscriber& subscriber, unsigned int mask) {
+  return ::nt::AddPolledListener(m_handle, subscriber.GetHandle(), mask);
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddListener(
+    NetworkTableEntry& entry, unsigned int mask) {
+  return ::nt::AddPolledListener(m_handle, entry.GetHandle(), mask);
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddConnectionListener(
+    bool immediate_notify) {
+  return ::nt::AddPolledListener(
+      m_handle, ::nt::GetInstanceFromHandle(m_handle),
+      NT_EVENT_CONNECTION | (immediate_notify ? NT_EVENT_IMMEDIATE : 0));
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddTimeSyncListener(
+    bool immediate_notify) {
+  return ::nt::AddPolledListener(
+      m_handle, ::nt::GetInstanceFromHandle(m_handle),
+      NT_EVENT_TIMESYNC | (immediate_notify ? NT_EVENT_IMMEDIATE : 0));
+}
+
+inline NT_Listener NetworkTableListenerPoller::AddLogger(
+    unsigned int minLevel, unsigned int maxLevel) {
+  return ::nt::AddPolledLogger(m_handle, minLevel, maxLevel);
+}
+
+inline void NetworkTableListenerPoller::RemoveListener(NT_Listener listener) {
+  ::nt::RemoveListener(listener);
+}
+
+inline std::vector<Event> NetworkTableListenerPoller::ReadQueue() {
+  return ::nt::ReadListenerQueue(m_handle);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/include/networktables/NetworkTableType.h b/ntcore/src/main/native/include/networktables/NetworkTableType.h
index d7681f2..4b60454 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTableType.h
+++ b/ntcore/src/main/native/include/networktables/NetworkTableType.h
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLETYPE_H_
-#define NTCORE_NETWORKTABLES_NETWORKTABLETYPE_H_
+#pragma once
 
 #include "ntcore_c.h"
 
@@ -22,9 +21,10 @@
   kBooleanArray = NT_BOOLEAN_ARRAY,
   kDoubleArray = NT_DOUBLE_ARRAY,
   kStringArray = NT_STRING_ARRAY,
-  kRpc = NT_RPC
+  kInteger = NT_INTEGER,
+  kFloat = NT_FLOAT,
+  kIntegerArray = NT_INTEGER_ARRAY,
+  kFloatArray = NT_FLOAT_ARRAY
 };
 
 }  // 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
index fcb9cb5..673a833 100644
--- a/ntcore/src/main/native/include/networktables/NetworkTableValue.h
+++ b/ntcore/src/main/native/include/networktables/NetworkTableValue.h
@@ -2,22 +2,20 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NETWORKTABLES_NETWORKTABLEVALUE_H_
-#define NTCORE_NETWORKTABLES_NETWORKTABLEVALUE_H_
+#pragma once
 
 #include <stdint.h>
 
 #include <cassert>
 #include <initializer_list>
 #include <memory>
+#include <span>
 #include <string>
 #include <string_view>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
-#include <wpi/span.h>
-
 #include "ntcore_c.h"
 
 namespace nt {
@@ -31,8 +29,10 @@
 
  public:
   Value();
-  Value(NT_Type type, uint64_t time, const private_init&);
-  ~Value();
+  Value(NT_Type type, int64_t time, const private_init&);
+  Value(NT_Type type, int64_t time, int64_t serverTime, const private_init&);
+
+  explicit operator bool() const { return m_val.type != NT_UNASSIGNED; }
 
   /**
    * Get the data type.
@@ -49,18 +49,39 @@
   const NT_Value& value() const { return m_val; }
 
   /**
-   * Get the creation time of the value.
+   * Get the creation time of the value, in local time.
    *
    * @return The time, in the units returned by nt::Now().
    */
-  uint64_t last_change() const { return m_val.last_change; }
+  int64_t last_change() const { return m_val.last_change; }
 
   /**
-   * Get the creation time of the value.
+   * Get the creation time of the value, in local time.
    *
    * @return The time, in the units returned by nt::Now().
    */
-  uint64_t time() const { return m_val.last_change; }
+  int64_t time() const { return m_val.last_change; }
+
+  /**
+   * Set the local creation time of the value.
+   *
+   * @param time The time.
+   */
+  void SetTime(int64_t time) { m_val.last_change = time; }
+
+  /**
+   * Get the creation time of the value, in server time.
+   *
+   * @return The server time.
+   */
+  int64_t server_time() const { return m_val.server_time; }
+
+  /**
+   * Set the creation time of the value, in server time.
+   *
+   * @param time The server time.
+   */
+  void SetServerTime(int64_t time) { m_val.server_time = time; }
 
   /**
    * @{
@@ -82,6 +103,20 @@
   bool IsBoolean() const { return m_val.type == NT_BOOLEAN; }
 
   /**
+   * Determine if entry value contains an integer.
+   *
+   * @return True if the entry value is of integer type.
+   */
+  bool IsInteger() const { return m_val.type == NT_INTEGER; }
+
+  /**
+   * Determine if entry value contains a float.
+   *
+   * @return True if the entry value is of float type.
+   */
+  bool IsFloat() const { return m_val.type == NT_FLOAT; }
+
+  /**
    * Determine if entry value contains a double.
    *
    * @return True if the entry value is of double type.
@@ -103,13 +138,6 @@
   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.
@@ -117,6 +145,20 @@
   bool IsBooleanArray() const { return m_val.type == NT_BOOLEAN_ARRAY; }
 
   /**
+   * Determine if entry value contains an integer array.
+   *
+   * @return True if the entry value is of integer array type.
+   */
+  bool IsIntegerArray() const { return m_val.type == NT_INTEGER_ARRAY; }
+
+  /**
+   * Determine if entry value contains a float array.
+   *
+   * @return True if the entry value is of float array type.
+   */
+  bool IsFloatArray() const { return m_val.type == NT_FLOAT_ARRAY; }
+
+  /**
    * Determine if entry value contains a double array.
    *
    * @return True if the entry value is of double array type.
@@ -148,6 +190,26 @@
   }
 
   /**
+   * Get the entry's integer value.
+   *
+   * @return The integer value.
+   */
+  int64_t GetInteger() const {
+    assert(m_val.type == NT_INTEGER);
+    return m_val.data.v_int;
+  }
+
+  /**
+   * Get the entry's float value.
+   *
+   * @return The float value.
+   */
+  float GetFloat() const {
+    assert(m_val.type == NT_FLOAT);
+    return m_val.data.v_float;
+  }
+
+  /**
    * Get the entry's double value.
    *
    * @return The double value.
@@ -164,7 +226,7 @@
    */
   std::string_view GetString() const {
     assert(m_val.type == NT_STRING);
-    return m_string;
+    return {m_val.data.v_string.str, m_val.data.v_string.len};
   }
 
   /**
@@ -172,19 +234,9 @@
    *
    * @return The raw value.
    */
-  std::string_view GetRaw() const {
+  std::span<const uint8_t> GetRaw() const {
     assert(m_val.type == NT_RAW);
-    return m_string;
-  }
-
-  /**
-   * Get the entry's rpc definition value.
-   *
-   * @return The rpc definition value.
-   */
-  std::string_view GetRpc() const {
-    assert(m_val.type == NT_RPC);
-    return m_string;
+    return {m_val.data.v_raw.data, m_val.data.v_raw.size};
   }
 
   /**
@@ -192,17 +244,37 @@
    *
    * @return The boolean array value.
    */
-  wpi::span<const int> GetBooleanArray() const {
+  std::span<const int> GetBooleanArray() const {
     assert(m_val.type == NT_BOOLEAN_ARRAY);
     return {m_val.data.arr_boolean.arr, m_val.data.arr_boolean.size};
   }
 
   /**
+   * Get the entry's integer array value.
+   *
+   * @return The integer array value.
+   */
+  std::span<const int64_t> GetIntegerArray() const {
+    assert(m_val.type == NT_INTEGER_ARRAY);
+    return {m_val.data.arr_int.arr, m_val.data.arr_int.size};
+  }
+
+  /**
+   * Get the entry's float array value.
+   *
+   * @return The float array value.
+   */
+  std::span<const float> GetFloatArray() const {
+    assert(m_val.type == NT_FLOAT_ARRAY);
+    return {m_val.data.arr_float.arr, m_val.data.arr_float.size};
+  }
+
+  /**
    * Get the entry's double array value.
    *
    * @return The double array value.
    */
-  wpi::span<const double> GetDoubleArray() const {
+  std::span<const double> GetDoubleArray() const {
     assert(m_val.type == NT_DOUBLE_ARRAY);
     return {m_val.data.arr_double.arr, m_val.data.arr_double.size};
   }
@@ -212,9 +284,9 @@
    *
    * @return The string array value.
    */
-  wpi::span<const std::string> GetStringArray() const {
+  std::span<const std::string> GetStringArray() const {
     assert(m_val.type == NT_STRING_ARRAY);
-    return m_string_array;
+    return *static_cast<std::vector<std::string>*>(m_storage.get());
   }
 
   /** @} */
@@ -232,9 +304,37 @@
    *             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;
+  static Value MakeBoolean(bool value, int64_t time = 0) {
+    Value val{NT_BOOLEAN, time, private_init{}};
+    val.m_val.data.v_boolean = value;
+    return val;
+  }
+
+  /**
+   * Creates an integer 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 Value MakeInteger(int64_t value, int64_t time = 0) {
+    Value val{NT_INTEGER, time, private_init{}};
+    val.m_val.data.v_int = value;
+    return val;
+  }
+
+  /**
+   * Creates a float 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 Value MakeFloat(float value, int64_t time = 0) {
+    Value val{NT_FLOAT, time, private_init{}};
+    val.m_val.data.v_float = value;
     return val;
   }
 
@@ -246,9 +346,9 @@
    *             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;
+  static Value MakeDouble(double value, int64_t time = 0) {
+    Value val{NT_DOUBLE, time, private_init{}};
+    val.m_val.data.v_double = value;
     return val;
   }
 
@@ -260,12 +360,12 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeString(std::string_view value,
-                                           uint64_t time = 0) {
-    auto val = std::make_shared<Value>(NT_STRING, time, private_init());
-    val->m_string = 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();
+  static Value MakeString(std::string_view value, int64_t time = 0) {
+    Value val{NT_STRING, time, private_init{}};
+    auto data = std::make_shared<std::string>(value);
+    val.m_val.data.v_string.str = const_cast<char*>(data->c_str());
+    val.m_val.data.v_string.len = data->size();
+    val.m_storage = std::move(data);
     return val;
   }
 
@@ -279,11 +379,12 @@
    */
   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::forward<T>(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();
+  static Value MakeString(T&& value, int64_t time = 0) {
+    Value val{NT_STRING, time, private_init{}};
+    auto data = std::make_shared<std::string>(std::forward(value));
+    val.m_val.data.v_string.str = const_cast<char*>(data->c_str());
+    val.m_val.data.v_string.len = data->size();
+    val.m_storage = std::move(data);
     return val;
   }
 
@@ -295,12 +396,13 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeRaw(std::string_view 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();
+  static Value MakeRaw(std::span<const uint8_t> value, int64_t time = 0) {
+    Value val{NT_RAW, time, private_init{}};
+    auto data =
+        std::make_shared<std::vector<uint8_t>>(value.begin(), value.end());
+    val.m_val.data.v_raw.data = const_cast<uint8_t*>(data->data());
+    val.m_val.data.v_raw.size = data->size();
+    val.m_storage = std::move(data);
     return val;
   }
 
@@ -312,47 +414,14 @@
    *             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::forward<T>(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(std::string_view 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::forward<T>(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();
+  template <typename T, typename std::enable_if<
+                            std::is_same<T, std::vector<uint8_t>>::value>::type>
+  static Value MakeRaw(T&& value, int64_t time = 0) {
+    Value val{NT_RAW, time, private_init{}};
+    auto data = std::make_shared<std::vector<uint8_t>>(std::forward(value));
+    val.m_val.data.v_raw.data = const_cast<uint8_t*>(data->data());
+    val.m_val.data.v_raw.size = data->size();
+    val.m_storage = std::move(data);
     return val;
   }
 
@@ -364,8 +433,7 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeBooleanArray(wpi::span<const bool> value,
-                                                 uint64_t time = 0);
+  static Value MakeBooleanArray(std::span<const bool> value, int64_t time = 0);
 
   /**
    * Creates a boolean array entry value.
@@ -375,9 +443,9 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeBooleanArray(
-      std::initializer_list<bool> value, uint64_t time = 0) {
-    return MakeBooleanArray(wpi::span(value.begin(), value.end()), time);
+  static Value MakeBooleanArray(std::initializer_list<bool> value,
+                                int64_t time = 0) {
+    return MakeBooleanArray(std::span(value.begin(), value.end()), time);
   }
 
   /**
@@ -388,8 +456,7 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeBooleanArray(wpi::span<const int> value,
-                                                 uint64_t time = 0);
+  static Value MakeBooleanArray(std::span<const int> value, int64_t time = 0);
 
   /**
    * Creates a boolean array entry value.
@@ -399,12 +466,95 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeBooleanArray(
-      std::initializer_list<int> value, uint64_t time = 0) {
-    return MakeBooleanArray(wpi::span(value.begin(), value.end()), time);
+  static Value MakeBooleanArray(std::initializer_list<int> value,
+                                int64_t time = 0) {
+    return MakeBooleanArray(std::span(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
+   *
+   * @note This function moves the values out of the vector.
+   */
+  static Value MakeBooleanArray(std::vector<int>&& value, int64_t time = 0);
+
+  /**
+   * Creates an integer 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 Value MakeIntegerArray(std::span<const int64_t> value,
+                                int64_t time = 0);
+
+  /**
+   * Creates an integer 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 Value MakeIntegerArray(std::initializer_list<int64_t> value,
+                                int64_t time = 0) {
+    return MakeIntegerArray(std::span(value.begin(), value.end()), time);
+  }
+
+  /**
+   * Creates an integer 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 Value MakeIntegerArray(std::vector<int64_t>&& value, int64_t time = 0);
+
+  /**
+   * Creates a float 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 Value MakeFloatArray(std::span<const float> value, int64_t time = 0);
+
+  /**
+   * Creates a float 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 Value MakeFloatArray(std::initializer_list<float> value,
+                              int64_t time = 0) {
+    return MakeFloatArray(std::span(value.begin(), value.end()), time);
+  }
+
+  /**
+   * Creates a float 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 Value MakeFloatArray(std::vector<float>&& value, int64_t time = 0);
+
+  /**
    * Creates a double array entry value.
    *
    * @param value the value
@@ -412,8 +562,7 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeDoubleArray(wpi::span<const double> value,
-                                                uint64_t time = 0);
+  static Value MakeDoubleArray(std::span<const double> value, int64_t time = 0);
 
   /**
    * Creates a double array entry value.
@@ -423,21 +572,22 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeDoubleArray(
-      std::initializer_list<double> value, uint64_t time = 0) {
-    return MakeDoubleArray(wpi::span(value.begin(), value.end()), time);
+  static Value MakeDoubleArray(std::initializer_list<double> value,
+                               int64_t time = 0) {
+    return MakeDoubleArray(std::span(value.begin(), value.end()), time);
   }
 
   /**
-   * Creates a string array entry value.
+   * 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
+   *
+   * @note This function moves the values out of the vector.
    */
-  static std::shared_ptr<Value> MakeStringArray(
-      wpi::span<const std::string> value, uint64_t time = 0);
+  static Value MakeDoubleArray(std::vector<double>&& value, int64_t time = 0);
 
   /**
    * Creates a string array entry value.
@@ -447,9 +597,20 @@
    *             time)
    * @return The entry value
    */
-  static std::shared_ptr<Value> MakeStringArray(
-      std::initializer_list<std::string> value, uint64_t time = 0) {
-    return MakeStringArray(wpi::span(value.begin(), value.end()), time);
+  static Value MakeStringArray(std::span<const std::string> value,
+                               int64_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 Value MakeStringArray(std::initializer_list<std::string> value,
+                               int64_t time = 0) {
+    return MakeStringArray(std::span(value.begin(), value.end()), time);
   }
 
   /**
@@ -462,25 +623,19 @@
    *
    * @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);
+  static Value MakeStringArray(std::vector<std::string>&& value,
+                               int64_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;
+  std::shared_ptr<void> m_storage;
 };
 
 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.
@@ -489,5 +644,3 @@
 using NetworkTableValue = Value;
 
 }  // 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
deleted file mode 100644
index 9c6e9f9..0000000
--- a/ntcore/src/main/native/include/networktables/RpcCall.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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() = default;
-
-  /**
-   * 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{0};
-  NT_RpcCall m_call{0};
-};
-
-}  // namespace nt
-
-#include "networktables/RpcCall.inc"
-
-#endif  // NTCORE_NETWORKTABLES_RPCCALL_H_
diff --git a/ntcore/src/main/native/include/networktables/RpcCall.inc b/ntcore/src/main/native/include/networktables/RpcCall.inc
deleted file mode 100644
index 5e25b04..0000000
--- a/ntcore/src/main/native/include/networktables/RpcCall.inc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_NETWORKTABLES_RPCCALL_INC_
-#define NTCORE_NETWORKTABLES_RPCCALL_INC_
-
-#include <string>
-#include <utility>
-
-#include "networktables/RpcCall.h"
-#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  // NTCORE_NETWORKTABLES_RPCCALL_INC_
diff --git a/ntcore/src/main/native/include/networktables/TableEntryListener.h b/ntcore/src/main/native/include/networktables/TableEntryListener.h
deleted file mode 100644
index 180234f..0000000
--- a/ntcore/src/main/native/include/networktables/TableEntryListener.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_NETWORKTABLES_TABLEENTRYLISTENER_H_
-#define NTCORE_NETWORKTABLES_TABLEENTRYLISTENER_H_
-
-#include <functional>
-#include <memory>
-#include <string_view>
-
-namespace nt {
-
-class NetworkTable;
-class NetworkTableEntry;
-class Value;
-
-/**
- * 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
- */
-using TableEntryListener = std::function<void(
-    NetworkTable* table, std::string_view name, NetworkTableEntry entry,
-    std::shared_ptr<Value> value, int flags)>;
-
-}  // 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
deleted file mode 100644
index cc1113e..0000000
--- a/ntcore/src/main/native/include/networktables/TableListener.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_NETWORKTABLES_TABLELISTENER_H_
-#define NTCORE_NETWORKTABLES_TABLELISTENER_H_
-
-#include <functional>
-#include <memory>
-#include <string_view>
-
-namespace nt {
-
-class NetworkTable;
-
-/**
- * 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
- */
-using TableListener =
-    std::function<void(NetworkTable* parent, std::string_view name,
-                       std::shared_ptr<NetworkTable> table)>;
-
-}  // namespace nt
-
-#endif  // NTCORE_NETWORKTABLES_TABLELISTENER_H_
diff --git a/ntcore/src/main/native/include/networktables/Topic.h b/ntcore/src/main/native/include/networktables/Topic.h
new file mode 100644
index 0000000..e2a8a5a
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/Topic.h
@@ -0,0 +1,385 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "networktables/NetworkTableType.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class json;
+}  // namespace wpi
+
+namespace nt {
+
+class GenericEntry;
+class GenericPublisher;
+class GenericSubscriber;
+class NetworkTableInstance;
+
+/** NetworkTables Topic. */
+class Topic {
+ public:
+  Topic() = default;
+  explicit Topic(NT_Topic handle) : m_handle{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 topic.
+   *
+   * @return Native handle
+   */
+  NT_Topic GetHandle() const { return m_handle; }
+
+  /**
+   * Gets the instance for the topic.
+   *
+   * @return Instance
+   */
+  NetworkTableInstance GetInstance() const;
+
+  /**
+   * Gets the name of the topic.
+   *
+   * @return the topic's name
+   */
+  std::string GetName() const;
+
+  /**
+   * Gets the type of the topic.
+   *
+   * @return the topic's type
+   */
+  NetworkTableType GetType() const;
+
+  /**
+   * Gets the type string of the topic. This may have more information
+   * than the numeric type (especially for raw values).
+   *
+   * @return the topic's type
+   */
+  std::string GetTypeString() const;
+
+  /**
+   * Make value persistent through server restarts.
+   *
+   * @param persistent True for persistent, false for not persistent.
+   */
+  void SetPersistent(bool persistent);
+
+  /**
+   * Returns whether the value is persistent through server restarts.
+   *
+   * @return True if the value is persistent.
+   */
+  bool IsPersistent() const;
+
+  /**
+   * Make the server retain the topic even when there are no publishers.
+   *
+   * @param retained True for retained, false for not retained.
+   */
+  void SetRetained(bool retained);
+
+  /**
+   * Returns whether the topic is retained by server when there are no
+   * publishers.
+   *
+   * @return True if the topic is retained.
+   */
+  bool IsRetained() const;
+
+  /**
+   * Determines if the topic is currently being published.
+   *
+   * @return True if the topic exists, false otherwise.
+   */
+  bool Exists() const;
+
+  /**
+   * Gets the current value of a property (as a JSON object).
+   *
+   * @param name property name
+   * @return JSON object; null object if the property does not exist.
+   */
+  wpi::json GetProperty(std::string_view name) const;
+
+  /**
+   * Sets a property value.
+   *
+   * @param name property name
+   * @param value property value
+   */
+  void SetProperty(std::string_view name, const wpi::json& value);
+
+  /**
+   * Deletes a property.  Has no effect if the property does not exist.
+   *
+   * @param name property name
+   */
+  void DeleteProperty(std::string_view name);
+
+  /**
+   * Gets all topic properties as a JSON object.  Each key in the object
+   * is the property name, and the corresponding value is the property value.
+   *
+   * @return JSON object
+   */
+  wpi::json GetProperties() const;
+
+  /**
+   * Updates multiple topic properties.  Each key in the passed-in object is
+   * the name of the property to add/update, and the corresponding value is the
+   * property value to set for that property.  Null values result in deletion
+   * of the corresponding property.
+   *
+   * @param properties JSON object with keys to add/update/delete
+   * @return False if properties is not an object
+   */
+  bool SetProperties(const wpi::json& properties);
+
+  /**
+   * Gets combined information about the topic.
+   *
+   * @return Topic information
+   */
+  TopicInfo GetInfo() const;
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @param options subscribe options
+   * @return subscriber
+   */
+  [[nodiscard]] GenericSubscriber GenericSubscribe(
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note Subscribers that do not match the published data type do not return
+   *     any values. To determine if the data type matches, use the appropriate
+   *     Topic functions.
+   *
+   * @param typeString type string
+   * @param options subscribe options
+   * @return subscriber
+   */
+  [[nodiscard]] GenericSubscriber GenericSubscribe(
+      std::string_view typeString,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new publisher to the topic.
+   *
+   * The publisher is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note It is not possible to publish two different data types to the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored). To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param options publish options
+   * @return publisher
+   */
+  [[nodiscard]] GenericPublisher GenericPublish(
+      std::string_view typeString,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new publisher to the topic, with type string and initial
+   * properties.
+   *
+   * The publisher is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note It is not possible to publish two different data types to the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored). To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param properties JSON properties
+   * @param options publish options
+   * @return publisher
+   */
+  [[nodiscard]] GenericPublisher GenericPublishEx(
+      std::string_view typeString, const wpi::json& properties,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new generic entry for the topic.
+   *
+   * Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not destroyed. The publisher
+   * is created when the entry is first written to, and remains active until
+   * either Unpublish() is called or the entry is destroyed.
+   *
+   * @note It is not possible to use two different data types with the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored), and the entry
+   *     will show no new values if the data type does not match. To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  [[nodiscard]] GenericEntry GetGenericEntry(
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new generic entry for the topic.
+   *
+   * Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not destroyed. The publisher
+   * is created when the entry is first written to, and remains active until
+   * either Unpublish() is called or the entry is destroyed.
+   *
+   * @note It is not possible to use two different data types with the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored), and the entry
+   *     will show no new values if the data type does not match. To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  [[nodiscard]] GenericEntry GetGenericEntry(
+      std::string_view typeString,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Equality operator.  Returns true if both instances refer to the same
+   * native handle.
+   */
+  bool operator==(const Topic&) const = default;
+
+ protected:
+  NT_Topic m_handle{0};
+};
+
+/** NetworkTables subscriber. */
+class Subscriber {
+ public:
+  virtual ~Subscriber();
+
+  Subscriber(const Subscriber&) = delete;
+  Subscriber& operator=(const Subscriber&) = delete;
+
+  Subscriber(Subscriber&&);
+  Subscriber& operator=(Subscriber&&);
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return m_subHandle != 0; }
+
+  /**
+   * Gets the native handle for the subscriber.
+   *
+   * @return Native handle
+   */
+  NT_Subscriber GetHandle() const { return m_subHandle; }
+
+  /**
+   * Determines if the topic is currently being published.
+   *
+   * @return True if the topic exists, false otherwise.
+   */
+  bool Exists() const;
+
+  /**
+   * Gets the last time the value was changed.
+   * Note: this is not atomic with Get(); use GetAtomic() to get
+   * both the value and last change as an atomic operation.
+   *
+   * @return Topic last change time
+   */
+  int64_t GetLastChange() const;
+
+  /**
+   * Gets the subscribed-to topic.
+   *
+   * @return Topic
+   */
+  Topic GetTopic() const;
+
+ protected:
+  Subscriber() = default;
+  explicit Subscriber(NT_Subscriber handle) : m_subHandle{handle} {}
+
+  NT_Subscriber m_subHandle{0};
+};
+
+/** NetworkTables publisher. */
+class Publisher {
+ public:
+  virtual ~Publisher();
+
+  Publisher(const Publisher&) = delete;
+  Publisher& operator=(const Publisher&) = delete;
+
+  Publisher(Publisher&&);
+  Publisher& operator=(Publisher&&);
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return m_pubHandle != 0; }
+
+  /**
+   * Gets the native handle for the publisher.
+   *
+   * @return Native handle
+   */
+  NT_Publisher GetHandle() const { return m_pubHandle; }
+
+  /**
+   * Gets the published-to topic.
+   *
+   * @return Topic
+   */
+  Topic GetTopic() const;
+
+ protected:
+  Publisher() = default;
+  explicit Publisher(NT_Publisher handle) : m_pubHandle{handle} {}
+
+  NT_Publisher m_pubHandle{0};
+};
+
+}  // namespace nt
+
+#include "networktables/Topic.inc"
diff --git a/ntcore/src/main/native/include/networktables/Topic.inc b/ntcore/src/main/native/include/networktables/Topic.inc
new file mode 100644
index 0000000..642e49e
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/Topic.inc
@@ -0,0 +1,115 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <string>
+
+#include "networktables/NetworkTableInstance.h"
+#include "networktables/NetworkTableType.h"
+#include "networktables/Topic.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+inline NetworkTableInstance Topic::GetInstance() const {
+  return NetworkTableInstance{GetInstanceFromHandle(m_handle)};
+}
+
+inline std::string Topic::GetName() const {
+  return ::nt::GetTopicName(m_handle);
+}
+
+inline NetworkTableType Topic::GetType() const {
+  return static_cast<NetworkTableType>(::nt::GetTopicType(m_handle));
+}
+
+inline std::string Topic::GetTypeString() const {
+  return ::nt::GetTopicTypeString(m_handle);
+}
+
+inline void Topic::SetPersistent(bool persistent) {
+  ::nt::SetTopicPersistent(m_handle, persistent);
+}
+
+inline bool Topic::IsPersistent() const {
+  return ::nt::GetTopicPersistent(m_handle);
+}
+
+inline void Topic::SetRetained(bool retained) {
+  ::nt::SetTopicRetained(m_handle, retained);
+}
+
+inline bool Topic::IsRetained() const {
+  return ::nt::GetTopicRetained(m_handle);
+}
+
+inline bool Topic::Exists() const {
+  return nt::GetTopicExists(m_handle);
+}
+
+inline void Topic::DeleteProperty(std::string_view name) {
+  ::nt::DeleteTopicProperty(m_handle, name);
+}
+
+inline bool Topic::SetProperties(const wpi::json& properties) {
+  return ::nt::SetTopicProperties(m_handle, properties);
+}
+
+inline TopicInfo Topic::GetInfo() const {
+  return ::nt::GetTopicInfo(m_handle);
+}
+
+inline Subscriber::~Subscriber() {
+  ::nt::Release(m_subHandle);
+}
+
+inline Subscriber::Subscriber(Subscriber&& rhs) : m_subHandle{rhs.m_subHandle} {
+  rhs.m_subHandle = 0;
+}
+
+inline Subscriber& Subscriber::operator=(Subscriber&& rhs) {
+  if (m_subHandle != 0) {
+    ::nt::Release(m_subHandle);
+  }
+  m_subHandle = rhs.m_subHandle;
+  rhs.m_subHandle = 0;
+  return *this;
+}
+
+inline bool Subscriber::Exists() const {
+  return nt::GetTopicExists(m_subHandle);
+}
+
+inline int64_t Subscriber::GetLastChange() const {
+  return ::nt::GetEntryLastChange(m_subHandle);
+}
+
+inline Topic Subscriber::GetTopic() const {
+  return Topic{::nt::GetTopicFromHandle(m_subHandle)};
+}
+
+inline Publisher::~Publisher() {
+  ::nt::Release(m_pubHandle);
+}
+
+inline Publisher::Publisher(Publisher&& rhs) : m_pubHandle{rhs.m_pubHandle} {
+  rhs.m_pubHandle = 0;
+}
+
+inline Publisher& Publisher::operator=(Publisher&& rhs) {
+  if (m_pubHandle != 0) {
+    ::nt::Release(m_pubHandle);
+  }
+  m_pubHandle = rhs.m_pubHandle;
+  rhs.m_pubHandle = 0;
+  return *this;
+}
+
+inline Topic Publisher::GetTopic() const {
+  return Topic{::nt::GetTopicFromHandle(m_pubHandle)};
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/include/networktables/UnitTopic.h b/ntcore/src/main/native/include/networktables/UnitTopic.h
new file mode 100644
index 0000000..cac9501
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/UnitTopic.h
@@ -0,0 +1,414 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <string_view>
+#include <vector>
+
+#include "networktables/Topic.h"
+#include "ntcore_cpp.h"
+
+namespace wpi {
+class json;
+}  // namespace wpi
+
+namespace nt {
+
+template <typename T>
+class UnitTopic;
+
+/**
+ * Timestamped unit.
+ *
+ * @tparam T unit type, e.g. units::meter_t
+ */
+template <typename T>
+struct TimestampedUnit {
+  TimestampedUnit() = default;
+  TimestampedUnit(int64_t time, int64_t serverTime, T value)
+      : time{time}, serverTime{serverTime}, value{value} {}
+
+  /**
+   * Time in local time base.
+   */
+  int64_t time = 0;
+
+  /**
+   * Time in server time base.  May be 0 or 1 for locally set values.
+   */
+  int64_t serverTime = 0;
+
+  /**
+   * Value.
+   */
+  T value = {};
+};
+
+/**
+ * NetworkTables unit-typed subscriber.
+ *
+ * @tparam T unit type, e.g. units::meter_t
+ */
+template <typename T>
+class UnitSubscriber : public Subscriber {
+ public:
+  using TopicType = UnitTopic<T>;
+  using ValueType = T;
+  using ParamType = T;
+  using TimestampedValueType = TimestampedUnit<T>;
+
+  UnitSubscriber() = default;
+
+  /**
+   * Construct from a subscriber handle; recommended to use
+   * UnitTopic::Subscribe() instead.
+   *
+   * @param handle Native handle
+   * @param defaultValue Default value
+   */
+  UnitSubscriber(NT_Subscriber handle, ParamType defaultValue);
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the stored default value.
+   *
+   * @return value
+   */
+  ValueType Get() const;
+
+  /**
+   * Get the last published value.
+   * If no value has been published, returns the passed defaultValue.
+   *
+   * @param defaultValue default value to return if no value has been published
+   * @return value
+   */
+  ValueType Get(ParamType defaultValue) const;
+
+  /**
+   * Get the last published value along with its timestamp
+   * If no value has been published, returns the stored default value and a
+   * timestamp of 0.
+   *
+   * @return timestamped value
+   */
+  TimestampedValueType GetAtomic() const;
+
+  /**
+   * Get the last published value along with its timestamp.
+   * If no value has been published, returns the passed defaultValue and a
+   * timestamp of 0.
+   *
+   * @param defaultValue default value to return if no value has been published
+   * @return timestamped value
+   */
+  TimestampedValueType GetAtomic(ParamType defaultValue) const;
+
+  /**
+   * Get an array of all value changes since the last call to ReadQueue.
+   * Also provides a timestamp for each value.
+   *
+   * @note The "poll storage" subscribe option can be used to set the queue
+   *     depth.
+   *
+   * @return Array of timestamped values; empty array if no new changes have
+   *     been published since the previous call.
+   */
+  std::vector<TimestampedValueType> ReadQueue();
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+
+ private:
+  ValueType m_defaultValue;
+};
+
+/**
+ * NetworkTables unit-typed publisher.
+ *
+ * @tparam T unit type, e.g. units::meter_t
+ */
+template <typename T>
+class UnitPublisher : public Publisher {
+ public:
+  using TopicType = UnitTopic<T>;
+  using ValueType = T;
+  using ParamType = T;
+
+  using TimestampedValueType = TimestampedUnit<T>;
+
+  UnitPublisher() = default;
+
+  /**
+   * Construct from a publisher handle; recommended to use
+   * UnitTopic::Publish() instead.
+   *
+   * @param handle Native handle
+   */
+  explicit UnitPublisher(NT_Publisher handle);
+
+  /**
+   * Publish a new value.
+   *
+   * @param value value to publish
+   * @param time timestamp; 0 indicates current NT time should be used
+   */
+  void Set(ParamType value, int64_t time = 0);
+
+  /**
+   * Publish a default value.
+   * On reconnect, a default value will never be used in preference to a
+   * published value.
+   *
+   * @param value value
+   */
+  void SetDefault(ParamType value);
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+};
+
+/**
+ * NetworkTables unit-typed entry.
+ *
+ * @note Unlike NetworkTableEntry, the entry goes away when this is destroyed.
+ *
+ * @tparam T unit type, e.g. units::meter_t
+ */
+template <typename T>
+class UnitEntry final : public UnitSubscriber<T>, public UnitPublisher<T> {
+ public:
+  using SubscriberType = UnitSubscriber<T>;
+  using PublisherType = UnitPublisher<T>;
+  using TopicType = UnitTopic<T>;
+  using ValueType = T;
+  using ParamType = T;
+
+  using TimestampedValueType = TimestampedUnit<T>;
+
+  UnitEntry() = default;
+
+  /**
+   * Construct from an entry handle; recommended to use
+   * UnitTopic::GetEntry() instead.
+   *
+   * @param handle Native handle
+   * @param defaultValue Default value
+   */
+  UnitEntry(NT_Entry handle, ParamType defaultValue);
+
+  /**
+   * Determines if the native handle is valid.
+   *
+   * @return True if the native handle is valid, false otherwise.
+   */
+  explicit operator bool() const { return this->m_subHandle != 0; }
+
+  /**
+   * Gets the native handle for the entry.
+   *
+   * @return Native handle
+   */
+  NT_Entry GetHandle() const { return this->m_subHandle; }
+
+  /**
+   * Get the corresponding topic.
+   *
+   * @return Topic
+   */
+  TopicType GetTopic() const;
+
+  /**
+   * Stops publishing the entry if it's published.
+   */
+  void Unpublish();
+};
+
+/**
+ * NetworkTables unit-typed topic. Publishers publish the type name (e.g.
+ * "meter") as the "unit" property. Type conversions are not performed--for
+ * correct behavior the publisher and subscriber must use the same unit type,
+ * but this can be checked at runtime using IsMatchingUnit().
+ *
+ * @tparam T unit type, e.g. units::meter_t
+ */
+template <typename T>
+class UnitTopic final : public Topic {
+ public:
+  using SubscriberType = UnitSubscriber<T>;
+  using PublisherType = UnitPublisher<T>;
+  using EntryType = UnitEntry<T>;
+  using ValueType = T;
+  using ParamType = T;
+  using TimestampedValueType = TimestampedUnit<T>;
+  /** The default type string for this topic type. */
+  static constexpr std::string_view kTypeString = "double";
+
+  UnitTopic() = default;
+
+  /**
+   * Construct from a topic handle.
+   *
+   * @param handle Native handle
+   */
+  explicit UnitTopic(NT_Topic handle) : Topic{handle} {}
+
+  /**
+   * Construct from a generic topic.
+   *
+   * @param topic Topic
+   */
+  explicit UnitTopic(Topic topic) : Topic{topic} {}
+
+  /**
+   * Verify the topic has a matching unit type (if the topic is published).
+   *
+   * @return True if unit matches, false if not matching or topic not published.
+   */
+  bool IsMatchingUnit() const;
+
+  /**
+   * Create a new subscriber to the topic.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note Subscribers that do not match the published data type do not return
+   *     any values. To determine if the data type matches, use the appropriate
+   *     Topic functions.
+   *
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options subscribe options
+   * @return subscriber
+   */
+  [[nodiscard]] SubscriberType Subscribe(
+      ParamType defaultValue,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new subscriber to the topic, with specific type string.
+   *
+   * <p>The subscriber is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note Subscribers that do not match the published data type do not return
+   *     any values. To determine if the data type matches, use the appropriate
+   *     Topic functions.
+   *
+   * @param typeString type string
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options subscribe options
+   * @return subscriber
+   */
+  [[nodiscard]] SubscriberType SubscribeEx(
+      std::string_view typeString, ParamType defaultValue,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new publisher to the topic.
+   *
+   * The publisher is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note It is not possible to publish two different data types to the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored). To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param options publish options
+   * @return publisher
+   */
+  [[nodiscard]] PublisherType Publish(
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new publisher to the topic, with type string and initial
+   * properties.
+   *
+   * The publisher is only active as long as the returned object
+   * is not destroyed.
+   *
+   * @note It is not possible to publish two different data types to the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored). To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param properties JSON properties
+   * @param options publish options
+   * @return publisher
+   */
+  [[nodiscard]] PublisherType PublishEx(
+      std::string_view typeString, const wpi::json& properties,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new entry for the topic.
+   *
+   * Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not destroyed. The publisher
+   * is created when the entry is first written to, and remains active until
+   * either Unpublish() is called or the entry is destroyed.
+   *
+   * @note It is not possible to use two different data types with the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored), and the entry
+   *     will show no new values if the data type does not match. To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  [[nodiscard]] EntryType GetEntry(
+      ParamType defaultValue,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+
+  /**
+   * Create a new entry for the topic, with specific type string.
+   *
+   * Entries act as a combination of a subscriber and a weak publisher. The
+   * subscriber is active as long as the entry is not destroyed. The publisher
+   * is created when the entry is first written to, and remains active until
+   * either Unpublish() is called or the entry is destroyed.
+   *
+   * @note It is not possible to use two different data types with the same
+   *     topic. Conflicts between publishers are typically resolved by the
+   *     server on a first-come, first-served basis. Any published values that
+   *     do not match the topic's data type are dropped (ignored), and the entry
+   *     will show no new values if the data type does not match. To determine
+   *     if the data type matches, use the appropriate Topic functions.
+   *
+   * @param typeString type string
+   * @param defaultValue default value used when a default is not provided to a
+   *        getter function
+   * @param options publish and/or subscribe options
+   * @return entry
+   */
+  [[nodiscard]] EntryType GetEntryEx(
+      std::string_view typeString, ParamType defaultValue,
+      const PubSubOptions& options = kDefaultPubSubOptions);
+};
+
+}  // namespace nt
+
+#include "networktables/UnitTopic.inc"
diff --git a/ntcore/src/main/native/include/networktables/UnitTopic.inc b/ntcore/src/main/native/include/networktables/UnitTopic.inc
new file mode 100644
index 0000000..c107526
--- /dev/null
+++ b/ntcore/src/main/native/include/networktables/UnitTopic.inc
@@ -0,0 +1,140 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <vector>
+
+#include <wpi/json.h>
+
+#include "networktables/NetworkTableType.h"
+#include "networktables/UnitTopic.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+template <typename T>
+inline UnitSubscriber<T>::UnitSubscriber(NT_Subscriber handle, T defaultValue)
+    : Subscriber{handle}, m_defaultValue{defaultValue} {}
+
+template <typename T>
+inline T UnitSubscriber<T>::Get() const {
+  return Get(m_defaultValue);
+}
+
+template <typename T>
+inline T UnitSubscriber<T>::Get(T defaultValue) const {
+  return T{::nt::GetDouble(m_subHandle, defaultValue.value())};
+}
+
+template <typename T>
+inline TimestampedUnit<T> UnitSubscriber<T>::GetAtomic() const {
+  return GetAtomic(m_defaultValue);
+}
+
+template <typename T>
+inline TimestampedUnit<T> UnitSubscriber<T>::GetAtomic(T defaultValue) const {
+  auto doubleVal = ::nt::GetAtomicDouble(m_subHandle, defaultValue.value());
+  return {doubleVal.time, doubleVal.serverTime, doubleVal.value};
+}
+
+template <typename T>
+inline std::vector<TimestampedUnit<T>> UnitSubscriber<T>::ReadQueue() {
+  std::vector<TimestampedUnit<T>> vals;
+  auto doubleVals = ::nt::ReadQueueDouble(m_subHandle);
+  vals.reserve(doubleVals.size());
+  for (auto&& val : doubleVals) {
+    vals.emplace_back(val.time, val.serverTime, val.value);
+  }
+}
+
+template <typename T>
+inline UnitTopic<T> UnitSubscriber<T>::GetTopic() const {
+  return UnitTopic<T>{::nt::GetTopicFromHandle(m_subHandle)};
+}
+
+template <typename T>
+inline UnitPublisher<T>::UnitPublisher(NT_Publisher handle)
+    : Publisher{handle} {}
+
+template <typename T>
+inline void UnitPublisher<T>::Set(T value, int64_t time) {
+  ::nt::SetDouble(m_pubHandle, value.value(), time);
+}
+
+template <typename T>
+inline void UnitPublisher<T>::SetDefault(T value) {
+  ::nt::SetDefaultDouble(m_pubHandle, value.value());
+}
+
+template <typename T>
+inline UnitTopic<T> UnitPublisher<T>::GetTopic() const {
+  return UnitTopic<T>{::nt::GetTopicFromHandle(m_pubHandle)};
+}
+
+template <typename T>
+inline UnitEntry<T>::UnitEntry(NT_Entry handle, T defaultValue)
+    : UnitSubscriber<T>{handle, defaultValue}, UnitPublisher<T>{handle} {}
+
+template <typename T>
+inline UnitTopic<T> UnitEntry<T>::GetTopic() const {
+  return UnitTopic<T>{::nt::GetTopicFromHandle(this->m_subHandle)};
+}
+
+template <typename T>
+inline void UnitEntry<T>::Unpublish() {
+  ::nt::Unpublish(this->m_pubHandle);
+}
+
+template <typename T>
+inline bool UnitTopic<T>::IsMatchingUnit() const {
+  return GetProperty("unit") == T{}.name();
+}
+
+template <typename T>
+inline UnitSubscriber<T> UnitTopic<T>::Subscribe(T defaultValue,
+                                                 const PubSubOptions& options) {
+  return UnitSubscriber<T>{
+      ::nt::Subscribe(m_handle, NT_DOUBLE, "double", options), defaultValue};
+}
+
+template <typename T>
+inline UnitSubscriber<T> UnitTopic<T>::SubscribeEx(
+    std::string_view typeString, T defaultValue, const PubSubOptions& options) {
+  return UnitSubscriber<T>{
+      ::nt::Subscribe(m_handle, NT_DOUBLE, typeString, options), defaultValue};
+}
+
+template <typename T>
+inline UnitPublisher<T> UnitTopic<T>::Publish(const PubSubOptions& options) {
+  return UnitPublisher<T>{::nt::PublishEx(m_handle, NT_DOUBLE, "double",
+                                          {{"unit", T{}.name()}}, options)};
+}
+
+template <typename T>
+inline UnitPublisher<T> UnitTopic<T>::PublishEx(std::string_view typeString,
+                                                const wpi::json& properties,
+                                                const PubSubOptions& options) {
+  wpi::json props = properties;
+  props["unit"] = T{}.name();
+  return UnitPublisher<T>{
+      ::nt::PublishEx(m_handle, NT_DOUBLE, typeString, props, options)};
+}
+
+template <typename T>
+inline UnitEntry<T> UnitTopic<T>::GetEntry(T defaultValue,
+                                           const PubSubOptions& options) {
+  return UnitEntry<T>{::nt::GetEntry(m_handle, NT_DOUBLE, "double", options),
+                      defaultValue};
+}
+
+template <typename T>
+inline UnitEntry<T> UnitTopic<T>::GetEntryEx(std::string_view typeString,
+                                             T defaultValue,
+                                             const PubSubOptions& options) {
+  return UnitEntry<T>{::nt::GetEntry(m_handle, NT_DOUBLE, typeString, options),
+                      defaultValue};
+}
+
+}  // namespace nt
diff --git a/ntcore/src/main/native/include/ntcore.h b/ntcore/src/main/native/include/ntcore.h
index 5cdd473..e4ae7f9 100644
--- a/ntcore/src/main/native/include/ntcore.h
+++ b/ntcore/src/main/native/include/ntcore.h
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NTCORE_H_
-#define NTCORE_NTCORE_H_
+#pragma once
 
 /* C API */
 #include "ntcore_c.h"
@@ -12,5 +11,3 @@
 /* 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
index 3ee6d51..e9e9f81 100644
--- a/ntcore/src/main/native/include/ntcore_c.h
+++ b/ntcore/src/main/native/include/ntcore_c.h
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NTCORE_C_H_
-#define NTCORE_NTCORE_C_H_
+#pragma once
 
 #include <stdint.h>
 
@@ -29,19 +28,22 @@
 typedef int NT_Bool;
 
 typedef unsigned int NT_Handle;
-typedef NT_Handle NT_ConnectionListener;
-typedef NT_Handle NT_ConnectionListenerPoller;
+typedef NT_Handle NT_ConnectionDataLogger;
+typedef NT_Handle NT_DataLogger;
 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;
+typedef NT_Handle NT_Listener;
+typedef NT_Handle NT_ListenerPoller;
+typedef NT_Handle NT_MultiSubscriber;
+typedef NT_Handle NT_Topic;
+typedef NT_Handle NT_Subscriber;
+typedef NT_Handle NT_Publisher;
 
-/** Default network tables port number */
-#define NT_DEFAULT_PORT 1735
+/** Default network tables port number (NT3) */
+#define NT_DEFAULT_PORT3 1735
+
+/** Default network tables port number (NT4) */
+#define NT_DEFAULT_PORT4 5810
 
 /** NetworkTables data types. */
 enum NT_Type {
@@ -53,11 +55,15 @@
   NT_BOOLEAN_ARRAY = 0x10,
   NT_DOUBLE_ARRAY = 0x20,
   NT_STRING_ARRAY = 0x40,
-  NT_RPC = 0x80
+  NT_RPC = 0x80,
+  NT_INTEGER = 0x100,
+  NT_FLOAT = 0x200,
+  NT_INTEGER_ARRAY = 0x400,
+  NT_FLOAT_ARRAY = 0x800
 };
 
 /** NetworkTables entry flags. */
-enum NT_EntryFlags { NT_PERSISTENT = 0x01 };
+enum NT_EntryFlags { NT_PERSISTENT = 0x01, NT_RETAINED = 0x02 };
 
 /** NetworkTables logging levels. */
 enum NT_LogLevel {
@@ -72,27 +78,47 @@
   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_CLIENT3 = 0x02,  /* running in NT3 client mode */
+  NT_NET_MODE_CLIENT4 = 0x04,  /* running in NT4 client mode */
+  NT_NET_MODE_STARTING = 0x08, /* flag for starting (either client or server) */
   NT_NET_MODE_LOCAL = 0x10,    /* running in local-only mode */
 };
 
+/** Event notification flags. */
+enum NT_EventFlags {
+  NT_EVENT_NONE = 0,
+  /** Initial listener addition. */
+  NT_EVENT_IMMEDIATE = 0x01,
+  /** Client connected (on server, any client connected). */
+  NT_EVENT_CONNECTED = 0x02,
+  /** Client disconnected (on server, any client disconnected). */
+  NT_EVENT_DISCONNECTED = 0x04,
+  /** Any connection event (connect or disconnect). */
+  NT_EVENT_CONNECTION = NT_EVENT_CONNECTED | NT_EVENT_DISCONNECTED,
+  /** New topic published. */
+  NT_EVENT_PUBLISH = 0x08,
+  /** Topic unpublished. */
+  NT_EVENT_UNPUBLISH = 0x10,
+  /** Topic properties changed. */
+  NT_EVENT_PROPERTIES = 0x20,
+  /** Any topic event (publish, unpublish, or properties changed). */
+  NT_EVENT_TOPIC = NT_EVENT_PUBLISH | NT_EVENT_UNPUBLISH | NT_EVENT_PROPERTIES,
+  /** Topic value updated (via network). */
+  NT_EVENT_VALUE_REMOTE = 0x40,
+  /** Topic value updated (local). */
+  NT_EVENT_VALUE_LOCAL = 0x80,
+  /** Topic value updated (network or local). */
+  NT_EVENT_VALUE_ALL = NT_EVENT_VALUE_REMOTE | NT_EVENT_VALUE_LOCAL,
+  /** Log message. */
+  NT_EVENT_LOGMESSAGE = 0x100,
+  /** Time synchronized with server. */
+  NT_EVENT_TIMESYNC = 0x200,
+};
+
 /*
  * Structures
  */
@@ -117,12 +143,18 @@
 /** NetworkTables Entry Value.  Note this is a typed union. */
 struct NT_Value {
   enum NT_Type type;
-  uint64_t last_change;
+  int64_t last_change;
+  int64_t server_time;
   union {
     NT_Bool v_boolean;
+    int64_t v_int;
+    float v_float;
     double v_double;
     struct NT_String v_string;
-    struct NT_String v_raw;
+    struct {
+      uint8_t* data;
+      size_t size;
+    } v_raw;
     struct {
       NT_Bool* arr;
       size_t size;
@@ -132,35 +164,42 @@
       size_t size;
     } arr_double;
     struct {
+      float* arr;
+      size_t size;
+    } arr_float;
+    struct {
+      int64_t* arr;
+      size_t size;
+    } arr_int;
+    struct {
       struct NT_String* arr;
       size_t size;
     } arr_string;
   } data;
 };
 
-/** NetworkTables Entry Information */
-struct NT_EntryInfo {
-  /** Entry handle */
-  NT_Entry entry;
+/** NetworkTables Topic Information */
+struct NT_TopicInfo {
+  /** Topic handle */
+  NT_Topic topic;
 
-  /** Entry name */
+  /** Topic name */
   struct NT_String name;
 
-  /** Entry type */
+  /** Topic type */
   enum NT_Type type;
 
-  /** Entry flags */
-  unsigned int flags;
+  /** Topic type string */
+  struct NT_String type_str;
 
-  /** Timestamp of last change to entry (type or value). */
-  uint64_t last_change;
+  /** Topic properties JSON string */
+  struct NT_String properties;
 };
 
 /** NetworkTables Connection Information */
 struct NT_ConnectionInfo {
   /**
-   * The remote identifier (as set on the remote node by
-   * NetworkTableInstance::SetNetworkIdentity() or nt::SetNetworkIdentity()).
+   * The remote identifier (as set on the remote node by NT_StartClient4().
    */
   struct NT_String remote_id;
 
@@ -183,75 +222,20 @@
   unsigned int protocol_version;
 };
 
-/** NetworkTables RPC Version 1 Definition Parameter */
-struct NT_RpcParamDef {
-  struct NT_String name;
-  struct NT_Value def_value;
-};
+/** NetworkTables value event data. */
+struct NT_ValueEventData {
+  /** Topic handle. */
+  NT_Topic topic;
 
-/** 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;
+  /** Subscriber/entry handle. */
+  NT_Handle subentry;
 
   /** 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;
 
@@ -265,6 +249,120 @@
   char* message;
 };
 
+/** NetworkTables time sync event data. */
+struct NT_TimeSyncEventData {
+  /**
+   * Offset between local time and server time, in microseconds. Add this value
+   * to local time to get the estimated equivalent server time.
+   */
+  int64_t serverTimeOffset;
+
+  /** Measured round trip time divided by 2, in microseconds. */
+  int64_t rtt2;
+
+  /**
+   * If serverTimeOffset and RTT are valid. An event with this set to false is
+   * sent when the client disconnects.
+   */
+  NT_Bool valid;
+};
+
+/** NetworkTables event */
+struct NT_Event {
+  /** Listener that triggered this event. */
+  NT_Handle listener;
+
+  /**
+   * Event flags (NT_EventFlags). Also indicates the data included with the
+   * event:
+   * - NT_EVENT_CONNECTED or NT_EVENT_DISCONNECTED: connInfo
+   * - NT_EVENT_PUBLISH, NT_EVENT_UNPUBLISH, or NT_EVENT_PROPERTIES: topicInfo
+   * - NT_EVENT_VALUE_REMOTE, NT_NOTIFY_VALUE_LOCAL: valueData
+   * - NT_EVENT_LOGMESSAGE: logMessage
+   * - NT_EVENT_TIMESYNC: timeSyncData
+   */
+  unsigned int flags;
+
+  /** Event data; content depends on flags. */
+  union {
+    struct NT_ConnectionInfo connInfo;
+    struct NT_TopicInfo topicInfo;
+    struct NT_ValueEventData valueData;
+    struct NT_LogMessage logMessage;
+    struct NT_TimeSyncEventData timeSyncData;
+  } data;
+};
+
+/** NetworkTables publish/subscribe options. */
+struct NT_PubSubOptions {
+  /**
+   * Structure size. Must be set to sizeof(NT_PubSubOptions).
+   */
+  unsigned int structSize;
+
+  /**
+   * Polling storage size for a subscription. Specifies the maximum number of
+   * updates NetworkTables should store between calls to the subscriber's
+   * ReadQueue() function. If zero, defaults to 1 if sendAll is false, 20 if
+   * sendAll is true.
+   */
+  unsigned int pollStorage;
+
+  /**
+   * How frequently changes will be sent over the network, in seconds.
+   * NetworkTables may send more frequently than this (e.g. use a combined
+   * minimum period for all values) or apply a restricted range to this value.
+   * The default is 100 ms.
+   */
+  double periodic;
+
+  /**
+   * For subscriptions, if non-zero, value updates for ReadQueue() are not
+   * queued for this publisher.
+   */
+  NT_Publisher excludePublisher;
+
+  /**
+   * Send all value changes over the network.
+   */
+  NT_Bool sendAll;
+
+  /**
+   * For subscriptions, don't ask for value changes (only topic announcements).
+   */
+  NT_Bool topicsOnly;
+
+  /**
+   * Perform prefix match on subscriber topic names. Is ignored/overridden by
+   * Subscribe() functions; only present in struct for the purposes of getting
+   * information about subscriptions.
+   */
+  NT_Bool prefixMatch;
+
+  /**
+   * Preserve duplicate value changes (rather than ignoring them).
+   */
+  NT_Bool keepDuplicates;
+
+  /**
+   * For subscriptions, if remote value updates should not be queued for
+   * ReadQueue(). See also disableLocal.
+   */
+  NT_Bool disableRemote;
+
+  /**
+   * For subscriptions, if local value updates should not be queued for
+   * ReadQueue(). See also disableRemote.
+   */
+  NT_Bool disableLocal;
+
+  /**
+   * For entries, don't queue (for ReadQueue) value updates for the entry's
+   * internal publisher.
+   */
+  NT_Bool excludeSelf;
+};
+
 /**
  * @defgroup ntcore_instance_cfunc Instance Functions
  * @{
@@ -319,25 +417,6 @@
 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 inst       NetworkTable instance
- * @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      stores number of entry handles returned
- * @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.
  *
@@ -406,21 +485,6 @@
 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
@@ -437,578 +501,544 @@
 unsigned int NT_GetEntryFlags(NT_Entry entry);
 
 /**
- * Delete Entry.
+ * Read Entry Queue.
  *
- * 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.
+ * Returns new entry values since last call. The returned array must be freed
+ * using NT_DisposeValueArray().
  *
- * 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
+ * @param subentry     subscriber or entry handle
+ * @param count        count of items in returned array (output)
+ * @return entry value array; returns NULL and count=0 if no new values
  */
-void NT_DeleteEntry(NT_Entry entry);
+struct NT_Value* NT_ReadQueueValue(NT_Handle subentry, size_t* count);
+
+/** @} */
 
 /**
- * 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
+ * @defgroup ntcore_topic_cfunc Topic Functions
+ * @{
  */
-void NT_DeleteAllEntries(NT_Inst inst);
 
 /**
- * Get Entry Information.
+ * Get Published Topic Handles.
  *
- * 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.
+ * Returns an array of topic handles.  The results are optionally
+ * filtered by string prefix and type to only return a subset of all
+ * topics.
  *
  * @param inst          instance handle
- * @param prefix        entry name required prefix; only entries whose name
+ * @param prefix        name required prefix; only topics 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.
+ * @return Array of topic handles.
  */
-struct NT_EntryInfo* NT_GetEntryInfo(NT_Inst inst, const char* prefix,
-                                     size_t prefix_len, unsigned int types,
-                                     size_t* count);
+NT_Topic* NT_GetTopics(NT_Inst inst, const char* prefix, size_t prefix_len,
+                       unsigned int types, size_t* count);
 
 /**
- * Get Entry Information.
+ * Get Published Topic Handles.
  *
- * Returns information about an entry (name, entry type,
- * and timestamp of last change to type/value).
+ * Returns an array of topic handles.  The results are optionally
+ * filtered by string prefix and type to only return a subset of all
+ * topics.
  *
- * @param entry         entry handle
- * @param info          entry information (output)
+ * @param inst          instance handle
+ * @param prefix        name required prefix; only topics whose name
+ *                      starts with this string are returned
+ * @param prefix_len    length of prefix in bytes
+ * @param types         array of type strings
+ * @param types_len     number of elements in types array
+ * @param count         output parameter; set to length of returned array
+ * @return Array of topic handles.
+ */
+NT_Topic* NT_GetTopicsStr(NT_Inst inst, const char* prefix, size_t prefix_len,
+                          const char* const* types, size_t types_len,
+                          size_t* count);
+
+/**
+ * Get Topics.
+ *
+ * Returns an array of topic information (handle, name, type).  The results are
+ * optionally filtered by string prefix and type to only return a subset
+ * of all topics.
+ *
+ * @param inst          instance handle
+ * @param prefix        name required prefix; only topics 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 topic information.
+ */
+struct NT_TopicInfo* NT_GetTopicInfos(NT_Inst inst, const char* prefix,
+                                      size_t prefix_len, unsigned int types,
+                                      size_t* count);
+
+/**
+ * Get Topics.
+ *
+ * Returns an array of topic information (handle, name, type).  The results are
+ * optionally filtered by string prefix and type to only return a subset
+ * of all topics.
+ *
+ * @param inst          instance handle
+ * @param prefix        name required prefix; only topics whose name
+ *                      starts with this string are returned
+ * @param prefix_len    length of prefix in bytes
+ * @param types         array of type strings
+ * @param types_len     number of elements in types array
+ * @param count         output parameter; set to length of returned array
+ * @return Array of topic information.
+ */
+struct NT_TopicInfo* NT_GetTopicInfosStr(NT_Inst inst, const char* prefix,
+                                         size_t prefix_len,
+                                         const char* const* types,
+                                         size_t types_len, size_t* count);
+
+/**
+ * Gets Topic Information.
+ *
+ * Returns information about a topic (name and type).
+ *
+ * @param topic         handle
+ * @param info          information (output)
  * @return True if successful, false on error.
  */
-NT_Bool NT_GetEntryInfoHandle(NT_Entry entry, struct NT_EntryInfo* info);
+NT_Bool NT_GetTopicInfo(NT_Topic topic, struct NT_TopicInfo* info);
+
+/**
+ * Gets Topic Handle.
+ *
+ * Returns topic handle.
+ *
+ * @param inst      instance handle
+ * @param name      topic name
+ * @param name_len  length of topic name in bytes
+ * @return Topic handle.
+ */
+NT_Topic NT_GetTopic(NT_Inst inst, const char* name, size_t name_len);
+
+/**
+ * Gets the name of the specified topic.
+ *
+ * @param topic     topic handle
+ * @param name_len  length of topic name (output)
+ * @return Topic name; returns NULL and name_len=0 if the handle is invalid.
+ */
+char* NT_GetTopicName(NT_Topic topic, size_t* name_len);
+
+/**
+ * Gets the type for the specified topic, or unassigned if non existent.
+ *
+ * @param topic   topic handle
+ * @return Topic type
+ */
+enum NT_Type NT_GetTopicType(NT_Topic topic);
+
+/**
+ * Gets the type string for the specified topic.  This may have more information
+ * than the numeric type (especially for raw values).
+ *
+ * @param topic     topic handle
+ * @param type_len  length of type string (output)
+ * @return Topic type string; returns NULL if non-existent
+ */
+char* NT_GetTopicTypeString(NT_Topic topic, size_t* type_len);
+
+/**
+ * Sets the persistent property of a topic.  If true, the stored value is
+ * persistent through server restarts.
+ *
+ * @param topic topic handle
+ * @param value True for persistent, false for not persistent.
+ */
+void NT_SetTopicPersistent(NT_Topic topic, NT_Bool value);
+
+/**
+ * Gets the persistent property of a topic.
+ *
+ * @param topic topic handle
+ * @return persistent property value
+ */
+NT_Bool NT_GetTopicPersistent(NT_Topic topic);
+
+/**
+ * Sets the retained property of a topic.  If true, the server retains the
+ * topic even when there are no publishers.
+ *
+ * @param topic topic handle
+ * @param value new retained property value
+ */
+void NT_SetTopicRetained(NT_Topic topic, NT_Bool value);
+
+/**
+ * Gets the retained property of a topic.
+ *
+ * @param topic topic handle
+ * @return retained property value
+ */
+NT_Bool NT_GetTopicRetained(NT_Topic topic);
+
+/**
+ * Determine if topic exists (e.g. has at least one publisher).
+ *
+ * @param handle Topic, entry, or subscriber handle.
+ * @return True if topic exists.
+ */
+NT_Bool NT_GetTopicExists(NT_Handle handle);
+
+/**
+ * Gets the current value of a property (as a JSON string).
+ *
+ * @param topic topic handle
+ * @param name property name
+ * @param len length of returned string (output)
+ * @return JSON string; empty string if the property does not exist.
+ */
+char* NT_GetTopicProperty(NT_Topic topic, const char* name, size_t* len);
+
+/**
+ * Sets a property value.
+ *
+ * @param topic topic handle
+ * @param name property name
+ * @param value property value (JSON string)
+ */
+NT_Bool NT_SetTopicProperty(NT_Topic topic, const char* name,
+                            const char* value);
+
+/**
+ * Deletes a property.  Has no effect if the property does not exist.
+ *
+ * @param topic topic handle
+ * @param name property name
+ */
+void NT_DeleteTopicProperty(NT_Topic topic, const char* name);
+
+/**
+ * Gets all topic properties as a JSON string.  Each key in the object
+ * is the property name, and the corresponding value is the property value.
+ *
+ * @param topic topic handle
+ * @param len length of returned string (output)
+ * @return JSON string
+ */
+char* NT_GetTopicProperties(NT_Topic topic, size_t* len);
+
+/**
+ * Updates multiple topic properties.  Each key in the passed-in JSON object is
+ * the name of the property to add/update, and the corresponding value is the
+ * property value to set for that property.  Null values result in deletion
+ * of the corresponding property.
+ *
+ * @param topic topic handle
+ * @param properties JSON object string with keys to add/update/delete
+ * @return False if properties are not a valid JSON object
+ */
+NT_Bool NT_SetTopicProperties(NT_Topic topic, const char* properties);
+
+/**
+ * Creates a new subscriber to value changes on a topic.
+ *
+ * @param topic topic handle
+ * @param type expected type
+ * @param typeStr expected type string
+ * @param options subscription options
+ * @return Subscriber handle
+ */
+NT_Subscriber NT_Subscribe(NT_Topic topic, enum NT_Type type,
+                           const char* typeStr,
+                           const struct NT_PubSubOptions* options);
+
+/**
+ * Stops subscriber.
+ *
+ * @param sub subscriber handle
+ */
+void NT_Unsubscribe(NT_Subscriber sub);
+
+/**
+ * Creates a new publisher to a topic.
+ *
+ * @param topic topic handle
+ * @param type type
+ * @param typeStr type string
+ * @param options publish options
+ * @return Publisher handle
+ */
+NT_Publisher NT_Publish(NT_Topic topic, enum NT_Type type, const char* typeStr,
+                        const struct NT_PubSubOptions* options);
+
+/**
+ * Creates a new publisher to a topic.
+ *
+ * @param topic topic handle
+ * @param type type
+ * @param typeStr type string
+ * @param properties initial properties (JSON object)
+ * @param options publish options
+ * @return Publisher handle
+ */
+NT_Publisher NT_PublishEx(NT_Topic topic, enum NT_Type type,
+                          const char* typeStr, const char* properties,
+                          const struct NT_PubSubOptions* options);
+
+/**
+ * Stops publisher.
+ *
+ * @param pubentry publisher/entry handle
+ */
+void NT_Unpublish(NT_Handle pubentry);
+
+/**
+ * @brief Creates a new entry (subscriber and weak publisher) to a topic.
+ *
+ * @param topic topic handle
+ * @param type type
+ * @param typeStr type string
+ * @param options publish options
+ * @return Entry handle
+ */
+NT_Entry NT_GetEntryEx(NT_Topic topic, enum NT_Type type, const char* typeStr,
+                       const struct NT_PubSubOptions* options);
+
+/**
+ * Stops entry subscriber/publisher.
+ *
+ * @param entry entry handle
+ */
+void NT_ReleaseEntry(NT_Entry entry);
+
+/**
+ * Stops entry/subscriber/publisher.
+ *
+ * @param pubsubentry entry/subscriber/publisher handle
+ */
+void NT_Release(NT_Handle pubsubentry);
+
+/**
+ * Gets the topic handle from an entry/subscriber/publisher handle.
+ *
+ * @param pubsubentry entry/subscriber/publisher handle
+ * @return Topic handle
+ */
+NT_Topic NT_GetTopicFromHandle(NT_Handle pubsubentry);
 
 /** @} */
 
 /**
- * @defgroup ntcore_entrylistener_cfunc Entry Listener Functions
+ * @defgroup ntcore_advancedsub_cfunc Advanced Subscriber Functions
  * @{
  */
 
 /**
- * Entry listener callback function.
- * Called when a key-value pair is changed.
+ * Subscribes to multiple topics based on one or more topic name prefixes. Can
+ * be used in combination with a Value Listener or ReadQueueValue() to get value
+ * changes across all matching topics.
  *
- * @param data            data pointer provided to callback creation function
- * @param event           event information
+ * @param inst instance handle
+ * @param prefixes topic name prefixes
+ * @param prefixes_len number of elements in prefixes array
+ * @param options subscriber options
+ * @return subscriber handle
  */
-typedef void (*NT_EntryListenerCallback)(
-    void* data, const struct NT_EntryNotification* event);
+NT_MultiSubscriber NT_SubscribeMultiple(NT_Inst inst,
+                                        const struct NT_String* prefixes,
+                                        size_t prefixes_len,
+                                        const struct NT_PubSubOptions* options);
 
 /**
- * Add a listener for all entries starting with a certain prefix.
+ * Unsubscribes a multi-subscriber.
  *
- * @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
+ * @param sub multi-subscriber 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 prefix_len        Length of 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 entry             entry handle
- * @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);
+void NT_UnsubscribeMultiple(NT_MultiSubscriber sub);
 
 /** @} */
 
 /**
- * @defgroup ntcore_connectionlistener_cfunc Connection Listener Functions
+ * @defgroup ntcore_listener_cfunc Listener Functions
  * @{
  */
 
 /**
- * Connection listener callback function.
- * Called when a network connection is made or lost.
+ * Event listener callback function.
  *
  * @param data            data pointer provided to callback creation function
  * @param event           event info
  */
-typedef void (*NT_ConnectionListenerCallback)(
-    void* data, const struct NT_ConnectionNotification* event);
+typedef void (*NT_ListenerCallback)(void* data, const struct NT_Event* event);
 
 /**
- * Add a connection listener.
+ * Creates a listener poller.
  *
- * @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().
+ * poller (using NT_AddPolledXListener()) will be stored in the queue and
+ * must be collected by calling NT_ReadListenerQueue().
+ * The returned handle must be destroyed with NT_DestroyListenerPoller().
  *
  * @param inst      instance handle
  * @return poller handle
  */
-NT_ConnectionListenerPoller NT_CreateConnectionListenerPoller(NT_Inst inst);
+NT_ListenerPoller NT_CreateListenerPoller(NT_Inst inst);
 
 /**
- * Destroy a connection listener poller.  This will abort any blocked polling
+ * Destroys a 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);
+void NT_DestroyListenerPoller(NT_ListenerPoller 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.
+ * Read notifications.
  *
  * @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).
+ * @return Array of events.  Returns NULL and len=0 if no events since last
+ *         call.
  */
-struct NT_ConnectionNotification* NT_PollConnectionListener(
-    NT_ConnectionListenerPoller poller, size_t* len);
+struct NT_Event* NT_ReadListenerQueue(NT_ListenerPoller 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.
+ * Removes a listener.
  *
- * @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).
+ * @param listener Listener handle to remove
  */
-struct NT_ConnectionNotification* NT_PollConnectionListenerTimeout(
-    NT_ConnectionListenerPoller poller, size_t* len, double timeout,
-    NT_Bool* timed_out);
+void NT_RemoveListener(NT_Listener listener);
 
 /**
- * Cancel a PollConnectionListener call.  This wakes up a call to
- * PollConnectionListener for this poller and causes it to immediately return
- * an empty array.
+ * Wait for the listener queue to be empty. This is primarily useful
+ * for deterministic testing. This blocks until either the 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 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
+ * @param handle  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);
-
-/** @} */
+NT_Bool NT_WaitForListenerQueue(NT_Handle handle, double timeout);
 
 /**
- * @defgroup ntcore_rpc_cfunc Remote Procedure Call Functions
- * @{
+ * Create a listener for changes to topics with names that start with
+ * the given prefix. This creates a corresponding internal subscriber with the
+ * lifetime of the listener.
+ *
+ * @param inst Instance handle
+ * @param prefix Topic name string prefix
+ * @param prefix_len Length of topic name string prefix
+ * @param mask Bitmask of NT_EventFlags values (only topic and value events will
+ *             be generated)
+ * @param data Data passed to callback function
+ * @param callback Listener function
+ * @return Listener handle
  */
+NT_Listener NT_AddListenerSingle(NT_Inst inst, const char* prefix,
+                                 size_t prefix_len, unsigned int mask,
+                                 void* data, NT_ListenerCallback callback);
 
 /**
- * Remote Procedure Call (RPC) callback function.
+ * Create a listener for changes to topics with names that start with any of
+ * the given prefixes. This creates a corresponding internal subscriber with the
+ * lifetime of the listener.
  *
- * @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.
+ * @param inst Instance handle
+ * @param prefixes Topic name string prefixes
+ * @param prefixes_len Number of elements in prefixes array
+ * @param mask Bitmask of NT_EventFlags values (only topic and value events will
+ *             be generated)
+ * @param data Data passed to callback function
+ * @param callback Listener function
+ * @return Listener handle
  */
-typedef void (*NT_RpcCallback)(void* data, const struct NT_RpcAnswer* call);
+NT_Listener NT_AddListenerMultiple(NT_Inst inst,
+                                   const struct NT_String* prefixes,
+                                   size_t prefixes_len, unsigned int mask,
+                                   void* data, NT_ListenerCallback callback);
 
 /**
- * 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.
+ * Create a listener.
  *
- * @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
+ * Some combinations of handle and mask have no effect:
+ * - connection and log message events are only generated on instances
+ * - topic and value events are only generated on non-instances
+ *
+ * Adding value and topic events on a topic will create a corresponding internal
+ * subscriber with the lifetime of the listener.
+ *
+ * Adding a log message listener through this function will only result in
+ * events at NT_LOG_INFO or higher; for more customized settings, use
+ * NT_AddLogger().
+ *
+ * @param handle Handle
+ * @param mask Bitmask of NT_EventFlags values
+ * @param data Data passed to callback function
+ * @param callback Listener function
+ * @return Listener handle
  */
-void NT_CreateRpc(NT_Entry entry, const char* def, size_t def_len, void* data,
-                  NT_RpcCallback callback);
+NT_Listener NT_AddListener(NT_Handle handle, unsigned int mask, void* data,
+                           NT_ListenerCallback callback);
 
 /**
- * Create a RPC call poller.  Only valid to use on the server.
+ * Creates a polled topic listener. This creates a corresponding internal
+ * subscriber with the lifetime of the listener.
+ * The caller is responsible for calling NT_ReadListenerQueue() to poll.
  *
- * 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
+ * @param poller            poller handle
+ * @param prefix            UTF-8 string prefix
+ * @param prefix_len        Length of UTF-8 string prefix
+ * @param mask              NT_EventFlags bitmask (only topic and value events
+ * will be generated)
+ * @return Listener handle
  */
-NT_RpcCallPoller NT_CreateRpcCallPoller(NT_Inst inst);
+NT_Listener NT_AddPolledListenerSingle(NT_ListenerPoller poller,
+                                       const char* prefix, size_t prefix_len,
+                                       unsigned int mask);
 
 /**
- * Destroy a RPC call poller.  This will abort any blocked polling call and
- * prevent additional events from being generated for this poller.
+ * Creates a polled topic listener. This creates a corresponding internal
+ * subscriber with the lifetime of the listener.
+ * The caller is responsible for calling NT_ReadListenerQueue() to poll.
  *
- * @param poller    poller handle
+ * @param poller            poller handle
+ * @param prefixes          array of UTF-8 string prefixes
+ * @param prefixes_len      Length of prefixes array
+ * @param mask              NT_EventFlags bitmask (only topic and value events
+ * will be generated)
+ * @return Listener handle
  */
-void NT_DestroyRpcCallPoller(NT_RpcCallPoller poller);
+NT_Listener NT_AddPolledListenerMultiple(NT_ListenerPoller poller,
+                                         const struct NT_String* prefixes,
+                                         size_t prefixes_len,
+                                         unsigned int mask);
 
 /**
- * Create a polled RPC entry point.  Only valid to use on the server.
+ * Creates a polled listener.
+ * The caller is responsible for calling NT_ReadListenerQueue() to poll.
  *
- * The caller is responsible for calling NT_PollRpc() or NT_PollRpcTimeout()
- * to poll for servicing incoming RPC calls.
+ * Some combinations of handle and mask have no effect:
+ * - connection and log message events are only generated on instances
+ * - topic and value events are only generated on non-instances
  *
- * @param entry     entry handle of RPC entry
- * @param def       RPC definition
- * @param def_len   length of def in bytes
- * @param poller    poller handle
+ * Adding value and topic events on a topic will create a corresponding internal
+ * subscriber with the lifetime of the listener.
+ *
+ * Adding a log message listener through this function will only result in
+ * events at NT_LOG_INFO or higher; for more customized settings, use
+ * NT_AddPolledLogger().
+ *
+ * @param poller            poller handle
+ * @param handle            handle
+ * @param mask              NT_NotifyKind bitmask
+ * @return Listener 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);
+NT_Listener NT_AddPolledListener(NT_ListenerPoller poller, NT_Handle handle,
+                                 unsigned int mask);
 
 /** @} */
 
@@ -1018,17 +1048,6 @@
  */
 
 /**
- * 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
@@ -1057,10 +1076,12 @@
  *                          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.
+ * @param port3             port to communicate over (NT3)
+ * @param port4             port to communicate over (NT4)
  */
 void NT_StartServer(NT_Inst inst, const char* persist_filename,
-                    const char* listen_address, unsigned int port);
+                    const char* listen_address, unsigned int port3,
+                    unsigned int port4);
 
 /**
  * Stops the server if it is running.
@@ -1070,42 +1091,22 @@
 void NT_StopServer(NT_Inst inst);
 
 /**
- * Starts a client.  Use NT_SetServer to set the server name and port.
+ * Starts a NT3 client.  Use NT_SetServer or NT_SetServerTeam to set the server
+ * name and port.
  *
- * @param inst  instance handle
+ * @param inst      instance handle
+ * @param identity  network identity to advertise (cannot be empty string)
  */
-void NT_StartClientNone(NT_Inst inst);
+void NT_StartClient3(NT_Inst inst, const char* identity);
 
 /**
- * Starts a client using the specified server and port
+ * Starts a NT4 client.  Use NT_SetServer or NT_SetServerTeam to set the server
+ * name and port.
  *
- * @param inst        instance handle
- * @param server_name server name (UTF-8 string, null terminated)
- * @param port        port to communicate over
+ * @param inst      instance handle
+ * @param identity  network identity to advertise (cannot be empty string)
  */
-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);
+void NT_StartClient4(NT_Inst inst, const char* identity);
 
 /**
  * Stops the client if it is running.
@@ -1152,7 +1153,7 @@
  * server IP address.
  *
  * @param inst  instance handle
- * @param port server port to use in combination with IP from DS
+ * @param port  server port to use in combination with IP from DS
  */
 void NT_StartDSClient(NT_Inst inst, unsigned int port);
 
@@ -1164,20 +1165,23 @@
 void NT_StopDSClient(NT_Inst inst);
 
 /**
- * Set the periodic update rate.
- * Sets how frequently updates are sent to other nodes over the network.
+ * Flush local updates.
+ *
+ * Forces an immediate flush of all local changes to the client/server.
+ * This does not flush to the network.
+ *
+ * Normally this is done on a regularly scheduled interval.
  *
  * @param inst      instance handle
- * @param interval  update interval in seconds (range 0.01 to 1.0)
  */
-void NT_SetUpdateRate(NT_Inst inst, double interval);
+void NT_FlushLocal(NT_Inst inst);
 
 /**
- * Flush Entries.
+ * Flush to network.
  *
  * Forces an immediate flush of all local entry changes to network.
- * Normally this is done on a regularly scheduled interval (see
- * NT_SetUpdateRate()).
+ * Normally this is done on a regularly scheduled interval (set
+ * by update rates on individual publishers).
  *
  * 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
@@ -1208,64 +1212,21 @@
  */
 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.
+ * Get the time offset between server time and local time. Add this value to
+ * local time to get the estimated equivalent server time. In server mode, this
+ * always returns a valid value of 0. In client mode, this returns the time
+ * offset only if the client and server are connected and have exchanged
+ * synchronization messages. Note the time offset may change over time as it is
+ * periodically updated; to receive updates as events, add a listener to the
+ * "time sync" event.
  *
- * @param inst      instance handle
- * @param filename  filename
- * @return error string, or NULL if successful
+ * @param inst instance handle
+ * @param valid set to true if the return value is valid, false otherwise
+ *              (output)
+ * @return Time offset in microseconds (if valid is set to true)
  */
-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));
+int64_t NT_GetServerTimeOffset(NT_Inst inst, NT_Bool* valid);
 
 /** @} */
 
@@ -1305,12 +1266,16 @@
 void NT_InitString(struct NT_String* str);
 
 /**
- * Disposes an entry handle array.
+ * Frees an array of NT_Values.
  *
- * @param arr   pointer to the array to dispose
+ * @param arr   pointer to the value array to free
  * @param count number of elements in the array
+ *
+ * Note that the individual NT_Values in the array should NOT be
+ * freed before calling this. This function will free all the values
+ * individually.
  */
-void NT_DisposeEntryArray(NT_Entry* arr, size_t count);
+void NT_DisposeValueArray(struct NT_Value* arr, size_t count);
 
 /**
  * Disposes a connection info array.
@@ -1321,97 +1286,56 @@
 void NT_DisposeConnectionInfoArray(struct NT_ConnectionInfo* arr, size_t count);
 
 /**
- * Disposes an entry info array.
+ * Disposes a topic 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);
+void NT_DisposeTopicInfoArray(struct NT_TopicInfo* arr, size_t count);
 
 /**
- * Disposes a single entry info (as returned by NT_GetEntryInfoHandle).
+ * Disposes a single topic info (as returned by NT_GetTopicInfo).
  *
  * @param info  pointer to the info to dispose
  */
-void NT_DisposeEntryInfo(struct NT_EntryInfo* info);
+void NT_DisposeTopicInfo(struct NT_TopicInfo* 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.
+ * Disposes an event 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);
+void NT_DisposeEventArray(struct NT_Event* arr, size_t count);
 
 /**
- * Disposes a Rpc Answer structure.
+ * Disposes a single event.
  *
- * @param answer     pointer to the struct to dispose
+ * @param event  pointer to the event 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);
+void NT_DisposeEvent(struct NT_Event* event);
 
 /**
  * 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().
+ * This function by default simply wraps WPI_Now(), but if NT_SetNow() is
+ * called, this function instead returns the value passed to NT_SetNow();
+ * this can be used to reduce overhead.
  *
  * @return Timestamp
  */
-uint64_t NT_Now(void);
+int64_t NT_Now(void);
+
+/**
+ * Sets the current timestamp used for timestamping values that do not
+ * provide a timestamp (e.g. a value of 0 is passed).  For consistency,
+ * it also results in NT_Now() returning the set value.  This should generally
+ * be used only if the overhead of calling WPI_Now() is a concern.
+ * If used, it should be called periodically with the value of WPI_Now().
+ *
+ * @param timestamp timestamp (1 us increments)
+ */
+void NT_SetNow(int64_t timestamp);
 
 /** @} */
 
@@ -1421,14 +1345,6 @@
  */
 
 /**
- * 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
@@ -1436,97 +1352,28 @@
  * 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
+ * @param data        data pointer to pass to func
+ * @param func        listener callback function
+ * @return Listener handle
  */
-NT_Logger NT_AddLogger(NT_Inst inst, void* data, NT_LogFunc func,
-                       unsigned int min_level, unsigned int max_level);
+NT_Listener NT_AddLogger(NT_Inst inst, unsigned int min_level,
+                         unsigned int max_level, void* data,
+                         NT_ListenerCallback func);
 
 /**
- * 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
+ * Set the log level for a listener 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
+ * @return Listener 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);
+NT_Listener NT_AddPolledLogger(NT_ListenerPoller poller, unsigned int min_level,
+                               unsigned int max_level);
 
 /** @} */
 
@@ -1567,6 +1414,32 @@
 NT_Bool* NT_AllocateBooleanArray(size_t size);
 
 /**
+ * Allocates an array of ints.
+ * 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_FreeIntArray()
+ * function.
+ */
+int64_t* NT_AllocateIntegerArray(size_t size);
+
+/**
+ * Allocates an array of floats.
+ * 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_FreeFloatArray()
+ * function.
+ */
+float* NT_AllocateFloatArray(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.
@@ -1600,13 +1473,6 @@
 void NT_FreeCharArray(char* v_char);
 
 /**
- * Frees an array of doubles.
- *
- * @param v_double 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
@@ -1614,6 +1480,27 @@
 void NT_FreeBooleanArray(NT_Bool* v_boolean);
 
 /**
+ * Frees an array of ints.
+ *
+ * @param v_int pointer to the int array to free
+ */
+void NT_FreeIntegerArray(int64_t* v_int);
+
+/**
+ * Frees an array of floats.
+ *
+ * @param v_float pointer to the float array to free
+ */
+void NT_FreeFloatArray(float* v_float);
+
+/**
+ * Frees an array of doubles.
+ *
+ * @param v_double pointer to the double array to free
+ */
+void NT_FreeDoubleArray(double* v_double);
+
+/**
  * Frees an array of NT_Strings.
  *
  * @param v_string  pointer to the string array to free
@@ -1654,12 +1541,36 @@
                            NT_Bool* v_boolean);
 
 /**
+ * Returns the int 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 int from
+ * @param last_change returns time in ms since the last change in the value
+ * @param v_int       returns the int assigned to the name
+ * @return            1 if successful, or 0 if value is null or not an int
+ */
+NT_Bool NT_GetValueInteger(const struct NT_Value* value, uint64_t* last_change,
+                           int64_t* v_int);
+
+/**
+ * Returns the float 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 float from
+ * @param last_change returns time in ms since the last change in the value
+ * @param v_float     returns the float assigned to the name
+ * @return            1 if successful, or 0 if value is null or not a float
+ */
+NT_Bool NT_GetValueFloat(const struct NT_Value* value, uint64_t* last_change,
+                         float* v_float);
+
+/**
  * 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
+ * @param v_double    returns the double 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,
@@ -1696,8 +1607,8 @@
  * 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);
+uint8_t* 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.
@@ -1717,6 +1628,40 @@
                                  uint64_t* last_change, size_t* arr_size);
 
 /**
+ * Returns a copy of the int 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 int 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 int array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeIntArray() function is useful for this purpose.
+ * The returned array is a copy of the array in the value, and must be
+ * freed separately.
+ */
+int64_t* NT_GetValueIntegerArray(const struct NT_Value* value,
+                                 uint64_t* last_change, size_t* arr_size);
+
+/**
+ * Returns a copy of the float 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 float 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 float array, or null if error
+ *
+ * It is the caller's responsibility to free the array once its no longer
+ * needed. The NT_FreeFloatArray() function is useful for this purpose.
+ * The returned array is a copy of the array in the value, and must be
+ * freed separately.
+ */
+float* NT_GetValueFloatArray(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.
  *
@@ -1753,331 +1698,176 @@
                                          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
+ * @defgroup ntcore_c_meta_api ntcore C meta-topic API
+ *
+ * Meta-topic decoders for C.
+ *
  * @{
  */
 
-/** 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
+/**
+ * Subscriber options. Different from PubSubOptions in this reflects only
+ * options that are sent over the network.
  */
-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);
-
-/** @} */
+struct NT_Meta_SubscriberOptions {
+  double periodic;
+  NT_Bool topicsOnly;
+  NT_Bool sendAll;
+  NT_Bool prefixMatch;
+};
 
 /**
- * @defgroup ntcore_valuesetters_cfunc Entry Value Setters
- * @{
+ * Topic publisher (as published via `$pub$<topic>`).
  */
+struct NT_Meta_TopicPublisher {
+  struct NT_String client;
+  uint64_t pubuid;
+};
 
-/** 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.
+/**
+ * Topic subscriber (as published via `$sub$<topic>`).
+ */
+struct NT_Meta_TopicSubscriber {
+  struct NT_String client;
+  uint64_t subuid;
+  struct NT_Meta_SubscriberOptions options;
+};
+
+/**
+ * Client publisher (as published via `$clientpub$<client>` or `$serverpub`).
+ */
+struct NT_Meta_ClientPublisher {
+  int64_t uid;
+  struct NT_String topic;
+};
+
+/**
+ * Client subscriber (as published via `$clientsub$<client>` or `$serversub`).
+ */
+struct NT_Meta_ClientSubscriber {
+  int64_t uid;
+  size_t topicsCount;
+  struct NT_String* topics;
+  struct NT_Meta_SubscriberOptions options;
+};
+
+/**
+ * Client (as published via `$clients`).
+ */
+struct NT_Meta_Client {
+  struct NT_String id;
+  struct NT_String conn;
+  uint16_t version;
+};
+
+/**
+ * Decodes `$pub$<topic>` meta-topic data.
  *
- * @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
+ * @param data data contents
+ * @param size size of data contents
+ * @param count number of elements in returned array (output)
+ * @return Array of TopicPublishers, or NULL on decoding error.
  */
-NT_Bool NT_SetEntryBoolean(NT_Entry entry, uint64_t time, NT_Bool v_boolean,
-                           NT_Bool force);
+struct NT_Meta_TopicPublisher* NT_Meta_DecodeTopicPublishers(
+    const uint8_t* data, size_t size, size_t* count);
 
-/** 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.
+/**
+ * Decodes `$sub$<topic>` meta-topic data.
  *
- * @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
+ * @param data data contents
+ * @param size size of data contents
+ * @param count number of elements in returned array (output)
+ * @return Array of TopicSubscribers, or NULL on decoding error.
  */
-NT_Bool NT_SetEntryDouble(NT_Entry entry, uint64_t time, double v_double,
-                          NT_Bool force);
+struct NT_Meta_TopicSubscriber* NT_Meta_DecodeTopicSubscribers(
+    const uint8_t* data, size_t size, size_t* count);
 
-/** 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.
+/**
+ * Decodes `$clientpub$<topic>` meta-topic data.
  *
- * @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
+ * @param data data contents
+ * @param size size of data contents
+ * @param count number of elements in returned array (output)
+ * @return Array of ClientPublishers, or NULL on decoding error.
  */
-NT_Bool NT_SetEntryString(NT_Entry entry, uint64_t time, const char* str,
-                          size_t str_len, NT_Bool force);
+struct NT_Meta_ClientPublisher* NT_Meta_DecodeClientPublishers(
+    const uint8_t* data, size_t size, size_t* count);
 
-/** 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.
+/**
+ * Decodes `$clientsub$<topic>` meta-topic data.
  *
- * @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
+ * @param data data contents
+ * @param size size of data contents
+ * @param count number of elements in returned array (output)
+ * @return Array of ClientSubscribers, or NULL on decoding error.
  */
-NT_Bool NT_SetEntryRaw(NT_Entry entry, uint64_t time, const char* raw,
-                       size_t raw_len, NT_Bool force);
+struct NT_Meta_ClientSubscriber* NT_Meta_DecodeClientSubscribers(
+    const uint8_t* data, size_t size, size_t* count);
 
-/** 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.
+/**
+ * Decodes `$clients` meta-topic data.
  *
- * @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
+ * @param data data contents
+ * @param size size of data contents
+ * @param count number of elements in returned array (output)
+ * @return Array of Clients, or NULL on decoding error.
  */
-NT_Bool NT_SetEntryBooleanArray(NT_Entry entry, uint64_t time, const int* arr,
-                                size_t size, NT_Bool force);
+struct NT_Meta_Client* NT_Meta_DecodeClients(const uint8_t* data, size_t size,
+                                             size_t* count);
 
-/** 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.
+/**
+ * Frees an array of NT_Meta_TopicPublisher.
  *
- * @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
+ * @param arr   pointer to the array to free
+ * @param count size of the array to free
  */
-NT_Bool NT_SetEntryDoubleArray(NT_Entry entry, uint64_t time, const double* arr,
-                               size_t size, NT_Bool force);
+void NT_Meta_FreeTopicPublishers(struct NT_Meta_TopicPublisher* arr,
+                                 size_t count);
 
-/** 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.
+/**
+ * Frees an array of NT_Meta_TopicSubscriber.
  *
- * @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
+ * @param arr   pointer to the array to free
+ * @param count size of the array to free
  */
-NT_Bool NT_SetEntryStringArray(NT_Entry entry, uint64_t time,
-                               const struct NT_String* arr, size_t size,
-                               NT_Bool force);
+void NT_Meta_FreeTopicSubscribers(struct NT_Meta_TopicSubscriber* arr,
+                                  size_t count);
 
-/** @} */
-/** @} */
+/**
+ * Frees an array of NT_Meta_ClientPublisher.
+ *
+ * @param arr   pointer to the array to free
+ * @param count size of the array to free
+ */
+void NT_Meta_FreeClientPublishers(struct NT_Meta_ClientPublisher* arr,
+                                  size_t count);
+
+/**
+ * Frees an array of NT_Meta_ClientSubscriber.
+ *
+ * @param arr   pointer to the array to free
+ * @param count size of the array to free
+ */
+void NT_Meta_FreeClientSubscribers(struct NT_Meta_ClientSubscriber* arr,
+                                   size_t count);
+
+/**
+ * Frees an array of NT_Meta_Client.
+ *
+ * @param arr   pointer to the array to free
+ * @param count size of the array to free
+ */
+void NT_Meta_FreeClients(struct NT_Meta_Client* arr, size_t count);
+
 /** @} */
 
 #ifdef __cplusplus
 }  // extern "C"
 #endif
 
-#endif  // NTCORE_NTCORE_C_H_
+#include "ntcore_c_types.h"
diff --git a/ntcore/src/main/native/include/ntcore_cpp.h b/ntcore/src/main/native/include/ntcore_cpp.h
index 2d91fe5..cbb541b 100644
--- a/ntcore/src/main/native/include/ntcore_cpp.h
+++ b/ntcore/src/main/native/include/ntcore_cpp.h
@@ -2,23 +2,34 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NTCORE_CPP_H_
-#define NTCORE_NTCORE_CPP_H_
+#pragma once
 
 #include <stdint.h>
 
 #include <cassert>
 #include <functional>
 #include <memory>
+#include <optional>
+#include <span>
 #include <string>
 #include <string_view>
-#include <thread>
 #include <utility>
+#include <variant>
 #include <vector>
 
-#include <wpi/span.h>
-
 #include "networktables/NetworkTableValue.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp_types.h"
+
+namespace wpi {
+template <typename T>
+class SmallVectorImpl;
+class json;
+}  // namespace wpi
+
+namespace wpi::log {
+class DataLog;
+}  // namespace wpi::log
 
 /** NetworkTables (ntcore) namespace */
 namespace nt {
@@ -31,30 +42,76 @@
  * @{
  */
 
-/** NetworkTables Entry Information */
-struct EntryInfo {
-  /** Entry handle */
-  NT_Entry entry;
+/**
+ * Event notification flags.
+ *
+ * The flags are a bitmask and must be OR'ed together to indicate the
+ * combination of events desired to be received.
+ *
+ */
+struct EventFlags {
+  EventFlags() = delete;
 
-  /** Entry name */
+  static constexpr unsigned int kNone = NT_EVENT_NONE;
+  /**
+   * Initial listener addition.
+   * Set this flag to receive immediate notification of matches to the
+   * flag criteria.
+   */
+  static constexpr unsigned int kImmediate = NT_EVENT_IMMEDIATE;
+  /** Client connected (on server, any client connected). */
+  static constexpr unsigned int kConnected = NT_EVENT_CONNECTED;
+  /** Client disconnected (on server, any client disconnected). */
+  static constexpr unsigned int kDisconnected = NT_EVENT_DISCONNECTED;
+  /** Any connection event (connect or disconnect). */
+  static constexpr unsigned int kConnection = kConnected | kDisconnected;
+  /** New topic published. */
+  static constexpr unsigned int kPublish = NT_EVENT_PUBLISH;
+  /** Topic unpublished. */
+  static constexpr unsigned int kUnpublish = NT_EVENT_UNPUBLISH;
+  /** Topic properties changed. */
+  static constexpr unsigned int kProperties = NT_EVENT_PROPERTIES;
+  /** Any topic event (publish, unpublish, or properties changed). */
+  static constexpr unsigned int kTopic = kPublish | kUnpublish | kProperties;
+  /** Topic value updated (via network). */
+  static constexpr unsigned int kValueRemote = NT_EVENT_VALUE_REMOTE;
+  /** Topic value updated (local). */
+  static constexpr unsigned int kValueLocal = NT_EVENT_VALUE_LOCAL;
+  /** Topic value updated (network or local). */
+  static constexpr unsigned int kValueAll = kValueRemote | kValueLocal;
+  /** Log message. */
+  static constexpr unsigned int kLogMessage = NT_EVENT_LOGMESSAGE;
+  /** Time synchronized with server. */
+  static constexpr unsigned int kTimeSync = NT_EVENT_TIMESYNC;
+};
+
+/** NetworkTables Topic Information */
+struct TopicInfo {
+  /** Topic handle */
+  NT_Topic topic{0};
+
+  /** Topic name */
   std::string name;
 
-  /** Entry type */
-  NT_Type type;
+  /** Topic type */
+  NT_Type type{NT_UNASSIGNED};
 
-  /** Entry flags */
-  unsigned int flags;
+  /** Topic type string */
+  std::string type_str;
 
-  /** Timestamp of last change to entry (type or value). */
-  uint64_t last_change;
+  /** Topic properties JSON string */
+  std::string properties;
 
-  friend void swap(EntryInfo& first, EntryInfo& second) {
+  /** Get topic properties as a JSON object. */
+  wpi::json GetProperties() const;
+
+  friend void swap(TopicInfo& first, TopicInfo& second) {
     using std::swap;
-    swap(first.entry, second.entry);
+    swap(first.topic, second.topic);
     swap(first.name, second.name);
     swap(first.type, second.type);
-    swap(first.flags, second.flags);
-    swap(first.last_change, second.last_change);
+    swap(first.type_str, second.type_str);
+    swap(first.properties, second.properties);
   }
 };
 
@@ -62,7 +119,7 @@
 struct ConnectionInfo {
   /**
    * The remote identifier (as set on the remote node by
-   * NetworkTableInstance::SetNetworkIdentity() or nt::SetNetworkIdentity()).
+   * NetworkTableInstance::StartClient4() or nt::StartClient4()).
    */
   std::string remote_id;
 
@@ -76,7 +133,7 @@
    * The last time any update was received from the remote node (same scale as
    * returned by nt::Now()).
    */
-  uint64_t last_update{0};
+  int64_t last_update{0};
 
   /**
    * The protocol version being used for this connection.  This in protocol
@@ -94,165 +151,30 @@
   }
 };
 
-/** NetworkTables RPC Version 1 Definition Parameter */
-struct RpcParamDef {
-  RpcParamDef() = default;
-  RpcParamDef(std::string_view name_, std::shared_ptr<Value> def_value_)
-      : name(name_), def_value(std::move(def_value_)) {}
-
-  std::string name;
-  std::shared_ptr<Value> def_value;
-};
-
-/** NetworkTables RPC Version 1 Definition Result */
-struct RpcResultDef {
-  RpcResultDef() = default;
-  RpcResultDef(std::string_view 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 {
+/** NetworkTables Value Event Data */
+class ValueEventData {
  public:
-  RpcAnswer() = default;
-  RpcAnswer(NT_Entry entry_, NT_RpcCall call_, std::string_view name_,
-            std::string_view params_, ConnectionInfo conn_)
-      : entry(entry_),
-        call(call_),
-        name(name_),
-        params(params_),
-        conn(std::move(conn_)) {}
+  ValueEventData() = default;
+  ValueEventData(NT_Topic topic, NT_Handle subentry, Value value)
+      : topic{topic}, subentry{subentry}, value{std::move(value)} {}
 
-  /** Entry handle. */
-  NT_Entry entry{0};
+  /** Topic handle. */
+  NT_Topic topic{0};
 
-  /** Call handle. */
-  mutable NT_RpcCall call{0};
-
-  /** 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(std::string_view 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() = default;
-  EntryNotification(NT_EntryListener listener_, NT_Entry entry_,
-                    std::string_view name_, std::shared_ptr<Value> value_,
-                    unsigned int flags_)
-      : listener(listener_),
-        entry(entry_),
-        name(name_),
-        value(std::move(value_)),
-        flags(flags_) {}
-
-  /** Listener that was triggered. */
-  NT_EntryListener listener{0};
-
-  /** Entry handle. */
-  NT_Entry entry{0};
-
-  /** Entry name. */
-  std::string name;
+  /** Subscriber/entry handle. */
+  NT_Handle subentry{0};
 
   /** 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{0};
-
-  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() = default;
-  ConnectionNotification(NT_ConnectionListener listener_, bool connected_,
-                         ConnectionInfo conn_)
-      : listener(listener_), connected(connected_), conn(std::move(conn_)) {}
-
-  /** Listener that was triggered. */
-  NT_ConnectionListener listener{0};
-
-  /** 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);
-  }
+  Value value;
 };
 
 /** NetworkTables log message. */
 class LogMessage {
  public:
   LogMessage() = default;
-  LogMessage(NT_Logger logger_, unsigned int level_, std::string_view filename_,
-             unsigned int line_, std::string_view message_)
-      : logger(logger_),
-        level(level_),
-        filename(filename_),
-        line(line_),
-        message(message_) {}
-
-  /** The logger that generated the message. */
-  NT_Logger logger{0};
+  LogMessage(unsigned int level, std::string_view filename, unsigned int line,
+             std::string_view message)
+      : level{level}, filename{filename}, line{line}, message{message} {}
 
   /** Log level of the message.  See NT_LogLevel. */
   unsigned int level{0};
@@ -265,17 +187,199 @@
 
   /** 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);
+/** NetworkTables time sync event data. */
+class TimeSyncEventData {
+ public:
+  TimeSyncEventData() = default;
+  TimeSyncEventData(int64_t serverTimeOffset, int64_t rtt2, bool valid)
+      : serverTimeOffset{serverTimeOffset}, rtt2{rtt2}, valid{valid} {}
+
+  /**
+   * Offset between local time and server time, in microseconds. Add this value
+   * to local time to get the estimated equivalent server time.
+   */
+  int64_t serverTimeOffset;
+
+  /** Measured round trip time divided by 2, in microseconds. */
+  int64_t rtt2;
+
+  /**
+   * If serverTimeOffset and RTT are valid. An event with this set to false is
+   * sent when the client disconnects.
+   */
+  bool valid;
+};
+
+/** NetworkTables event */
+class Event {
+ public:
+  Event() = default;
+  Event(NT_Listener listener, unsigned int flags, ConnectionInfo info)
+      : listener{listener}, flags{flags}, data{std::move(info)} {}
+  Event(NT_Listener listener, unsigned int flags, TopicInfo info)
+      : listener{listener}, flags{flags}, data{std::move(info)} {}
+  Event(NT_Listener listener, unsigned int flags, ValueEventData data)
+      : listener{listener}, flags{flags}, data{std::move(data)} {}
+  Event(NT_Listener listener, unsigned int flags, LogMessage msg)
+      : listener{listener}, flags{flags}, data{std::move(msg)} {}
+  Event(NT_Listener listener, unsigned int flags, NT_Topic topic,
+        NT_Handle subentry, Value value)
+      : listener{listener},
+        flags{flags},
+        data{ValueEventData{topic, subentry, std::move(value)}} {}
+  Event(NT_Listener listener, unsigned int flags, unsigned int level,
+        std::string_view filename, unsigned int line, std::string_view message)
+      : listener{listener},
+        flags{flags},
+        data{LogMessage{level, filename, line, message}} {}
+  Event(NT_Listener listener, unsigned int flags, int64_t serverTimeOffset,
+        int64_t rtt2, bool valid)
+      : listener{listener},
+        flags{flags},
+        data{TimeSyncEventData{serverTimeOffset, rtt2, valid}} {}
+
+  /** Listener that triggered this event. */
+  NT_Listener listener{0};
+
+  /**
+   * Event flags (NT_EventFlags). Also indicates the data included with the
+   * event:
+   * - NT_EVENT_CONNECTED or NT_EVENT_DISCONNECTED: GetConnectionInfo()
+   * - NT_EVENT_PUBLISH, NT_EVENT_UNPUBLISH, or NT_EVENT_PROPERTIES:
+   *   GetTopicInfo()
+   * - NT_EVENT_VALUE, NT_EVENT_VALUE_LOCAL: GetValueData()
+   * - NT_EVENT_LOGMESSAGE: GetLogMessage()
+   * - NT_EVENT_TIMESYNC: GetTimeSyncEventData()
+   */
+  unsigned int flags{0};
+
+  /**
+   * Test event flags.
+   *
+   * @param kind event flag(s) to test
+   * @return True if flags matches kind
+   */
+  bool Is(unsigned int kind) const { return (flags & kind) != 0; }
+
+  /** Event data; content depends on flags. */
+  std::variant<ConnectionInfo, TopicInfo, ValueEventData, LogMessage,
+               TimeSyncEventData>
+      data;
+
+  const ConnectionInfo* GetConnectionInfo() const {
+    return std::get_if<ConnectionInfo>(&data);
+  }
+  ConnectionInfo* GetConnectionInfo() {
+    return std::get_if<ConnectionInfo>(&data);
+  }
+
+  const TopicInfo* GetTopicInfo() const {
+    return std::get_if<TopicInfo>(&data);
+  }
+  TopicInfo* GetTopicInfo() { return std::get_if<TopicInfo>(&data); }
+
+  const ValueEventData* GetValueEventData() const {
+    return std::get_if<ValueEventData>(&data);
+  }
+  ValueEventData* GetValueEventData() {
+    return std::get_if<ValueEventData>(&data);
+  }
+
+  const LogMessage* GetLogMessage() const {
+    return std::get_if<LogMessage>(&data);
+  }
+  LogMessage* GetLogMessage() { return std::get_if<LogMessage>(&data); }
+
+  const TimeSyncEventData* GetTimeSyncEventData() const {
+    return std::get_if<TimeSyncEventData>(&data);
+  }
+  TimeSyncEventData* GetTimeSyncEventData() {
+    return std::get_if<TimeSyncEventData>(&data);
   }
 };
 
+/** NetworkTables publish/subscribe options. */
+struct PubSubOptions {
+  /**
+   * Default value of periodic.
+   */
+  static constexpr double kDefaultPeriodic = 0.1;
+
+  /**
+   * Structure size. Must be set to sizeof(PubSubOptions).
+   */
+  unsigned int structSize = sizeof(PubSubOptions);
+
+  /**
+   * Polling storage size for a subscription. Specifies the maximum number of
+   * updates NetworkTables should store between calls to the subscriber's
+   * ReadQueue() function. If zero, defaults to 1 if sendAll is false, 20 if
+   * sendAll is true.
+   */
+  unsigned int pollStorage = 0;
+
+  /**
+   * How frequently changes will be sent over the network, in seconds.
+   * NetworkTables may send more frequently than this (e.g. use a combined
+   * minimum period for all values) or apply a restricted range to this value.
+   * The default is 100 ms.
+   */
+  double periodic = kDefaultPeriodic;
+
+  /**
+   * For subscriptions, if non-zero, value updates for ReadQueue() are not
+   * queued for this publisher.
+   */
+  NT_Publisher excludePublisher = 0;
+
+  /**
+   * Send all value changes over the network.
+   */
+  bool sendAll = false;
+
+  /**
+   * For subscriptions, don't ask for value changes (only topic announcements).
+   */
+  bool topicsOnly = false;
+
+  /**
+   * Preserve duplicate value changes (rather than ignoring them).
+   */
+  bool keepDuplicates = false;
+
+  /**
+   * Perform prefix match on subscriber topic names. Is ignored/overridden by
+   * Subscribe() functions; only present in struct for the purposes of getting
+   * information about subscriptions.
+   */
+  bool prefixMatch = false;
+
+  /**
+   * For subscriptions, if remote value updates should not be queued for
+   * ReadQueue(). See also disableLocal.
+   */
+  bool disableRemote = false;
+
+  /**
+   * For subscriptions, if local value updates should not be queued for
+   * ReadQueue(). See also disableRemote.
+   */
+  bool disableLocal = false;
+
+  /**
+   * For entries, don't queue (for ReadQueue) value updates for the entry's
+   * internal publisher.
+   */
+  bool excludeSelf = false;
+};
+
+/**
+ * Default publish/subscribe options.
+ */
+constexpr PubSubOptions kDefaultPubSubOptions;
+
 /**
  * @defgroup ntcore_instance_func Instance Functions
  * @{
@@ -297,6 +401,13 @@
 NT_Inst CreateInstance();
 
 /**
+ * Reset the internals of an instance. Every handle previously associated
+ * with this instance will no longer be valid, except for the instance
+ * handle.
+ */
+void ResetInstance(NT_Inst inst);
+
+/**
  * Destroy an instance.
  * The default instance cannot be destroyed.
  *
@@ -329,23 +440,6 @@
 NT_Entry GetEntry(NT_Inst inst, std::string_view 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, std::string_view prefix,
-                                 unsigned int types);
-
-/**
  * Gets the name of the specified entry.
  * Returns an empty string if the handle is invalid.
  *
@@ -366,10 +460,10 @@
  * Gets the last time the entry was changed.
  * Returns 0 if the handle is invalid.
  *
- * @param entry   entry handle
+ * @param subentry   subscriber or entry handle
  * @return Entry last change time
  */
-uint64_t GetEntryLastChange(NT_Entry entry);
+int64_t GetEntryLastChange(NT_Handle subentry);
 
 /**
  * Get Entry Value.
@@ -377,10 +471,10 @@
  * Returns copy of current entry value.
  * Note that one of the type options is "unassigned".
  *
- * @param entry     entry handle
+ * @param subentry     subscriber or entry handle
  * @return entry value
  */
-std::shared_ptr<Value> GetEntryValue(NT_Entry entry);
+Value GetEntryValue(NT_Handle subentry);
 
 /**
  * Set Default Entry Value
@@ -393,7 +487,7 @@
  * @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);
+bool SetDefaultEntryValue(NT_Entry entry, const Value& value);
 
 /**
  * Set Entry Value.
@@ -405,22 +499,7 @@
  * @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 entry     entry handle
- * @param value     new entry value
- */
-void SetEntryTypeValue(NT_Entry entry, std::shared_ptr<Value> value);
+bool SetEntryValue(NT_Entry entry, const Value& value);
 
 /**
  * Set Entry Flags.
@@ -439,533 +518,469 @@
 unsigned int GetEntryFlags(NT_Entry entry);
 
 /**
- * Delete Entry.
+ * Read Entry Queue.
  *
- * 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.
+ * Returns new entry values since last call.
  *
- * 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
+ * @param subentry     subscriber or entry handle
+ * @return entry value array
  */
-void DeleteEntry(NT_Entry entry);
+std::vector<Value> ReadQueueValue(NT_Handle subentry);
+
+/** @} */
 
 /**
- * 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.
- *
- * @param inst      instance handle
+ * @defgroup ntcore_topic_func Topic Functions
+ * @{
  */
-void DeleteAllEntries(NT_Inst inst);
 
 /**
- * Get Entry Information.
+ * Get Published Topics.
  *
- * 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.
+ * Returns an array of topic handles.  The results are optionally filtered by
+ * string prefix and type to only return a subset of all topics.
  *
  * @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 information.
+ * @param prefix  name required prefix; only topics 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 topic handles.
  */
-std::vector<EntryInfo> GetEntryInfo(NT_Inst inst, std::string_view prefix,
+std::vector<NT_Topic> GetTopics(NT_Inst inst, std::string_view prefix,
+                                unsigned int types);
+
+/**
+ * Get Published Topics.
+ *
+ * Returns an array of topic handles.  The results are optionally filtered by
+ * string prefix and type to only return a subset of all topics.
+ *
+ * @param inst    instance handle
+ * @param prefix  name required prefix; only topics whose name
+ *                starts with this string are returned
+ * @param types   array of type strings
+ * @return Array of topic handles.
+ */
+std::vector<NT_Topic> GetTopics(NT_Inst inst, std::string_view prefix,
+                                std::span<const std::string_view> types);
+
+/**
+ * Get Topic Information about multiple topics.
+ *
+ * Returns an array of topic information (handle, name, type, and properties).
+ * The results are optionally filtered by string prefix and type to only
+ * return a subset of all topics.
+ *
+ * @param inst    instance handle
+ * @param prefix  name required prefix; only topics 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 topic information.
+ */
+std::vector<TopicInfo> GetTopicInfo(NT_Inst inst, std::string_view prefix,
                                     unsigned int types);
 
 /**
- * Get Entry Information.
+ * Get Topic Information about multiple topics.
  *
- * Returns information about an entry (name, entry type,
- * and timestamp of last change to type/value).
+ * Returns an array of topic information (handle, name, type, and properties).
+ * The results are optionally filtered by string prefix and type to only
+ * return a subset of all topics.
  *
- * @param entry         entry handle
- * @return Entry information.
+ * @param inst    instance handle
+ * @param prefix  name required prefix; only topics whose name
+ *                starts with this string are returned
+ * @param types   array of type strings
+ * @return Array of topic information.
  */
-EntryInfo GetEntryInfo(NT_Entry entry);
+std::vector<TopicInfo> GetTopicInfo(NT_Inst inst, std::string_view prefix,
+                                    std::span<const std::string_view> types);
+
+/**
+ * Gets Topic Information.
+ *
+ * Returns information about a topic (name, type, and properties).
+ *
+ * @param topic   handle
+ * @return Topic information.
+ */
+TopicInfo GetTopicInfo(NT_Topic topic);
+
+/**
+ * Gets Topic Handle.
+ *
+ * Returns topic handle.
+ *
+ * @param inst   instance handle
+ * @param name   topic name
+ * @return Topic handle.
+ */
+NT_Topic GetTopic(NT_Inst inst, std::string_view name);
+
+/**
+ * Gets the name of the specified topic.
+ * Returns an empty string if the handle is invalid.
+ *
+ * @param topic   topic handle
+ * @return Topic name
+ */
+std::string GetTopicName(NT_Topic topic);
+
+/**
+ * Gets the type for the specified topic, or unassigned if non existent.
+ *
+ * @param topic   topic handle
+ * @return Topic type
+ */
+NT_Type GetTopicType(NT_Topic topic);
+
+/**
+ * Gets the type string for the specified topic, or empty string if non
+ * existent.  This may have more information than the numeric type (especially
+ * for raw values).
+ *
+ * @param topic   topic handle
+ * @return Topic type string
+ */
+std::string GetTopicTypeString(NT_Topic topic);
+
+/**
+ * Sets the persistent property of a topic.  If true, the stored value is
+ * persistent through server restarts.
+ *
+ * @param topic topic handle
+ * @param value True for persistent, false for not persistent.
+ */
+void SetTopicPersistent(NT_Topic topic, bool value);
+
+/**
+ * Gets the persistent property of a topic.  If true, the server retains the
+ * topic even when there are no publishers.
+ *
+ * @param topic topic handle
+ * @return persistent property value
+ */
+bool GetTopicPersistent(NT_Topic topic);
+
+/**
+ * Sets the retained property of a topic.
+ *
+ * @param topic topic handle
+ * @param value new retained property value
+ */
+void SetTopicRetained(NT_Topic topic, bool value);
+
+/**
+ * Gets the retained property of a topic.
+ *
+ * @param topic topic handle
+ * @return retained property value
+ */
+bool GetTopicRetained(NT_Topic topic);
+
+/**
+ * Determine if topic exists (e.g. has at least one publisher).
+ *
+ * @param handle Topic, entry, or subscriber handle.
+ * @return True if topic exists.
+ */
+bool GetTopicExists(NT_Handle handle);
+
+/**
+ * Gets the current value of a property (as a JSON object).
+ *
+ * @param topic topic handle
+ * @param name property name
+ * @return JSON object; null object if the property does not exist.
+ */
+wpi::json GetTopicProperty(NT_Topic topic, std::string_view name);
+
+/**
+ * Sets a property value.
+ *
+ * @param topic topic handle
+ * @param name property name
+ * @param value property value
+ */
+void SetTopicProperty(NT_Topic topic, std::string_view name,
+                      const wpi::json& value);
+
+/**
+ * Deletes a property.  Has no effect if the property does not exist.
+ *
+ * @param topic topic handle
+ * @param name property name
+ */
+void DeleteTopicProperty(NT_Topic topic, std::string_view name);
+
+/**
+ * Gets all topic properties as a JSON object.  Each key in the object
+ * is the property name, and the corresponding value is the property value.
+ *
+ * @param topic topic handle
+ * @return JSON object
+ */
+wpi::json GetTopicProperties(NT_Topic topic);
+
+/**
+ * Updates multiple topic properties.  Each key in the passed-in object is
+ * the name of the property to add/update, and the corresponding value is the
+ * property value to set for that property.  Null values result in deletion
+ * of the corresponding property.
+ *
+ * @param topic topic handle
+ * @param update JSON object with keys to add/update/delete
+ * @return False if update is not a JSON object
+ */
+bool SetTopicProperties(NT_Topic topic, const wpi::json& update);
+
+/**
+ * Creates a new subscriber to value changes on a topic.
+ *
+ * @param topic topic handle
+ * @param type expected type
+ * @param typeStr expected type string
+ * @param options subscription options
+ * @return Subscriber handle
+ */
+NT_Subscriber Subscribe(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                        const PubSubOptions& options = kDefaultPubSubOptions);
+
+/**
+ * Stops subscriber.
+ *
+ * @param sub subscriber handle
+ */
+void Unsubscribe(NT_Subscriber sub);
+
+/**
+ * Creates a new publisher to a topic.
+ *
+ * @param topic topic handle
+ * @param type type
+ * @param typeStr type string
+ * @param options publish options
+ * @return Publisher handle
+ */
+NT_Publisher Publish(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                     const PubSubOptions& options = kDefaultPubSubOptions);
+
+/**
+ * Creates a new publisher to a topic.
+ *
+ * @param topic topic handle
+ * @param type type
+ * @param typeStr type string
+ * @param properties initial properties
+ * @param options publish options
+ * @return Publisher handle
+ */
+NT_Publisher PublishEx(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                       const wpi::json& properties,
+                       const PubSubOptions& options = kDefaultPubSubOptions);
+
+/**
+ * Stops publisher.
+ *
+ * @param pubentry publisher/entry handle
+ */
+void Unpublish(NT_Handle pubentry);
+
+/**
+ * @brief Creates a new entry (subscriber and weak publisher) to a topic.
+ *
+ * @param topic topic handle
+ * @param type type
+ * @param typeStr type string
+ * @param options publish options
+ * @return Entry handle
+ */
+NT_Entry GetEntry(NT_Topic topic, NT_Type type, std::string_view typeStr,
+                  const PubSubOptions& options = kDefaultPubSubOptions);
+
+/**
+ * Stops entry subscriber/publisher.
+ *
+ * @param entry entry handle
+ */
+void ReleaseEntry(NT_Entry entry);
+
+/**
+ * Stops entry/subscriber/publisher.
+ *
+ * @param pubsubentry entry/subscriber/publisher handle
+ */
+void Release(NT_Handle pubsubentry);
+
+/**
+ * Gets the topic handle from an entry/subscriber/publisher handle.
+ *
+ * @param pubsubentry entry/subscriber/publisher handle
+ * @return Topic handle
+ */
+NT_Topic GetTopicFromHandle(NT_Handle pubsubentry);
 
 /** @} */
 
 /**
- * @defgroup ntcore_entrylistener_func Entry Listener Functions
+ * @defgroup ntcore_advancedsub_func Advanced Subscriber Functions
  * @{
  */
 
 /**
- * Entry listener callback function.
- * Called when a key-value pair is changed.
+ * Subscribes to multiple topics based on one or more topic name prefixes. Can
+ * be used in combination with a Value Listener or ReadQueueValue() to get value
+ * changes across all matching topics.
  *
- * @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
+ * @param inst instance handle
+ * @param prefixes topic name prefixes
+ * @param options subscriber options
+ * @return subscriber handle
  */
-using EntryListenerCallback =
-    std::function<void(NT_EntryListener entry_listener, std::string_view name,
-                       std::shared_ptr<Value> value, unsigned int flags)>;
+NT_MultiSubscriber SubscribeMultiple(
+    NT_Inst inst, std::span<const std::string_view> prefixes,
+    const PubSubOptions& options = kDefaultPubSubOptions);
 
 /**
- * Add a listener for all entries starting with a certain prefix.
+ * Unsubscribes a multi-subscriber.
  *
- * @param inst              instance handle
- * @param prefix            UTF-8 string prefix
- * @param callback          listener to add
- * @param flags             NotifyKind bitmask
- * @return Listener handle
+ * @param sub multi-subscriber handle
  */
-NT_EntryListener AddEntryListener(
-    NT_Inst inst, std::string_view prefix,
-    std::function<void(const EntryNotification& event)> callback,
-    unsigned int flags);
+void UnsubscribeMultiple(NT_MultiSubscriber sub);
+
+/** @} */
 
 /**
- * Add a listener for a single entry.
- *
- * @param entry             entry handle
- * @param callback          listener to add
- * @param flags             NotifyKind bitmask
- * @return Listener handle
+ * @defgroup ntcore_listener_func Listener Functions
+ * @{
  */
-NT_EntryListener AddEntryListener(
-    NT_Entry entry,
-    std::function<void(const EntryNotification& event)> callback,
-    unsigned int flags);
+
+using ListenerCallback = std::function<void(const Event&)>;
 
 /**
- * Create a entry listener poller.
+ * Creates a 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().
+ * poller (using AddPolledListener()) will be stored in the queue and
+ * must be collected by calling ReadListenerQueue().
+ * The returned handle must be destroyed with DestroyListenerPoller().
  *
  * @param inst      instance handle
  * @return poller handle
  */
-NT_EntryListenerPoller CreateEntryListenerPoller(NT_Inst inst);
+NT_ListenerPoller CreateListenerPoller(NT_Inst inst);
 
 /**
- * Destroy a entry listener poller.  This will abort any blocked polling
+ * Destroys a 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);
+void DestroyListenerPoller(NT_ListenerPoller 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,
-                                        std::string_view prefix,
-                                        unsigned int flags);
-
-/**
- * Create a polled entry listener.
- * The caller is responsible for calling PollEntryListener() to poll.
- *
- * @param poller            poller handle
- * @param entry             entry handle
- * @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.
+ * Read notifications.
  *
  * @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).
+ * @return Array of events.  Returns empty array if no events since last call.
  */
-std::vector<EntryNotification> PollEntryListener(NT_EntryListenerPoller poller);
+std::vector<Event> ReadListenerQueue(NT_ListenerPoller 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.
+ * Removes a listener.
  *
- * @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).
+ * @param listener Listener handle to remove
  */
-std::vector<EntryNotification> PollEntryListener(NT_EntryListenerPoller poller,
-                                                 double timeout,
-                                                 bool* timed_out);
+void RemoveListener(NT_Listener listener);
 
 /**
- * Cancel a PollEntryListener call.  This wakes up a call to
- * PollEntryListener for this poller and causes it to immediately return
- * an empty array.
+ * Wait for the listener queue to be empty. This is primarily useful
+ * for deterministic testing. This blocks until either the 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 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
+ * @param handle  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);
-
-/** @} */
+bool WaitForListenerQueue(NT_Handle handle, double timeout);
 
 /**
- * @defgroup ntcore_connectionlistener_func Connection Listener Functions
- * @{
- */
-
-/**
- * Connection listener callback function.
- * Called when a network connection is made or lost.
+ * Create a listener for changes to topics with names that start with any of
+ * the given prefixes. This creates a corresponding internal subscriber with the
+ * lifetime of the listener.
  *
- * @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
+ * @param inst Instance handle
+ * @param prefixes Topic name string prefixes
+ * @param mask Bitmask of NT_EventFlags values (only topic and value events will
+ *             be generated)
+ * @param callback Listener function
  */
-using ConnectionListenerCallback =
-    std::function<void(NT_ConnectionListener, bool, const ConnectionInfo&)>;
+NT_Listener AddListener(NT_Inst inst,
+                        std::span<const std::string_view> prefixes,
+                        unsigned int mask, ListenerCallback callback);
 
 /**
- * Add a connection listener.
+ * Create a listener.
  *
- * @param inst              instance handle
- * @param callback          listener to add
- * @param immediate_notify  notify listener of all existing connections
+ * Some combinations of handle and mask have no effect:
+ * - connection and log message events are only generated on instances
+ * - topic and value events are only generated on non-instances
+ *
+ * Adding value and topic events on a topic will create a corresponding internal
+ * subscriber with the lifetime of the listener.
+ *
+ * Adding a log message listener through this function will only result in
+ * events at NT_LOG_INFO or higher; for more customized settings, use
+ * AddLogger().
+ *
+ * @param handle Instance, topic, subscriber, multi-subscriber, or entry handle
+ * @param mask Bitmask of NT_EventFlags values
+ * @param callback Listener function
+ */
+NT_Listener AddListener(NT_Handle handle, unsigned int mask,
+                        ListenerCallback callback);
+
+/**
+ * Creates a polled listener. This creates a corresponding internal subscriber
+ * with the lifetime of the listener.
+ * The caller is responsible for calling ReadListenerQueue() to poll.
+ *
+ * @param poller poller handle
+ * @param prefixes array of UTF-8 string prefixes
+ * @param mask Bitmask of NT_EventFlags values (only topic and value events will
+ *             be generated)
  * @return Listener handle
  */
-NT_ConnectionListener AddConnectionListener(
-    NT_Inst inst,
-    std::function<void(const ConnectionNotification& event)> callback,
-    bool immediate_notify);
+NT_Listener AddPolledListener(NT_ListenerPoller poller,
+                              std::span<const std::string_view> prefixes,
+                              unsigned int mask);
 
 /**
- * Create a connection listener poller.
+ * Creates a polled listener.
+ * The caller is responsible for calling ReadListenerQueue() to poll.
  *
- * 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().
+ * Some combinations of handle and mask have no effect:
+ * - connection and log message events are only generated on instances
+ * - topic and value events are only generated on non-instances
  *
- * @param inst      instance handle
- * @return poller handle
+ * Adding value and topic events on a topic will create a corresponding internal
+ * subscriber with the lifetime of the listener.
+ *
+ * Adding a log message listener through this function will only result in
+ * events at NT_LOG_INFO or higher; for more customized settings, use
+ * AddPolledLogger().
+ *
+ * @param poller poller handle
+ * @param handle instance, topic, subscriber, multi-subscriber, or entry handle
+ * @param mask NT_EventFlags bitmask
+ * @return Listener 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, std::string_view 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, std::string_view 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, std::string_view 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, std::string_view 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(std::string_view 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(wpi::span<const 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(
-    std::string_view packed, wpi::span<const NT_Type> types);
+NT_Listener AddPolledListener(NT_ListenerPoller poller, NT_Handle handle,
+                              unsigned int mask);
 
 /** @} */
 
@@ -975,16 +990,6 @@
  */
 
 /**
- * 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 inst      instance handle
- * @param name      identity to advertise
- */
-void SetNetworkIdentity(NT_Inst inst, std::string_view name);
-
-/**
  * Get the current network mode.
  *
  * @param inst  instance handle
@@ -1013,10 +1018,12 @@
  *                          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.
+ * @param port3             port to communicate over (NT3)
+ * @param port4             port to communicate over (NT4)
  */
 void StartServer(NT_Inst inst, std::string_view persist_filename,
-                 const char* listen_address, unsigned int port);
+                 const char* listen_address, unsigned int port3,
+                 unsigned int port4);
 
 /**
  * Stops the server if it is running.
@@ -1026,41 +1033,22 @@
 void StopServer(NT_Inst inst);
 
 /**
- * Starts a client.  Use SetServer to set the server name and port.
- *
- * @param inst  instance handle
- */
-void StartClient(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 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.
+ * Starts a NT3 client.  Use SetServer or SetServerTeam to set the server name
+ * and port.
  *
  * @param inst      instance handle
- * @param servers   array of server name and port pairs
+ * @param identity  network identity to advertise (cannot be empty string)
  */
-void StartClient(
-    NT_Inst inst,
-    wpi::span<const std::pair<std::string_view, unsigned int>> servers);
+void StartClient3(NT_Inst inst, std::string_view identity);
 
 /**
- * Starts a client using commonly known robot addresses for the specified
- * team.
+ * Starts a NT4 client.  Use SetServer or SetServerTeam to set the server name
+ * and port.
  *
- * @param inst        instance handle
- * @param team        team number
- * @param port        port to communicate over
+ * @param inst      instance handle
+ * @param identity  network identity to advertise (cannot be empty string)
  */
-void StartClientTeam(NT_Inst inst, unsigned int team, unsigned int port);
+void StartClient4(NT_Inst inst, std::string_view identity);
 
 /**
  * Stops the client if it is running.
@@ -1087,7 +1075,7 @@
  */
 void SetServer(
     NT_Inst inst,
-    wpi::span<const std::pair<std::string_view, unsigned int>> servers);
+    std::span<const std::pair<std::string_view, unsigned int>> servers);
 
 /**
  * Sets server addresses and port for client (without restarting client).
@@ -1105,7 +1093,7 @@
  * server IP address.
  *
  * @param inst  instance handle
- * @param port server port to use in combination with IP from DS
+ * @param port  server port to use in combination with IP from DS
  */
 void StartDSClient(NT_Inst inst, unsigned int port);
 
@@ -1117,20 +1105,23 @@
 void StopDSClient(NT_Inst inst);
 
 /**
- * Set the periodic update rate.
- * Sets how frequently updates are sent to other nodes over the network.
+ * Flush local updates.
+ *
+ * Forces an immediate flush of all local changes to the client/server.
+ * This does not flush to the network.
+ *
+ * Normally this is done on a regularly scheduled interval.
  *
  * @param inst      instance handle
- * @param interval  update interval in seconds (range 0.01 to 1.0)
  */
-void SetUpdateRate(NT_Inst inst, double interval);
+void FlushLocal(NT_Inst inst);
 
 /**
- * Flush Entries.
+ * Flush to network.
  *
  * Forces an immediate flush of all local entry changes to network.
- * Normally this is done on a regularly scheduled interval (see
- * SetUpdateRate()).
+ * Normally this is done on a regularly scheduled interval (set
+ * by update rates on individual publishers).
  *
  * 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
@@ -1157,63 +1148,18 @@
  */
 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.
+ * Get the time offset between server time and local time. Add this value to
+ * local time to get the estimated equivalent server time. In server mode, this
+ * always returns 0. In client mode, this returns the time offset only if the
+ * client and server are connected and have exchanged synchronization messages.
+ * Note the time offset may change over time as it is periodically updated; to
+ * receive updates as events, add a listener to the "time sync" event.
  *
- * @param inst      instance handle
- * @param filename  filename
- * @return error string, or nullptr if successful
+ * @param inst instance handle
+ * @return Time offset in microseconds (optional)
  */
-const char* SavePersistent(NT_Inst inst, std::string_view 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 nullptr if successful
- */
-const char* LoadPersistent(
-    NT_Inst inst, std::string_view 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, std::string_view filename,
-                        std::string_view 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, std::string_view filename,
-                        std::string_view prefix,
-                        std::function<void(size_t line, const char* msg)> warn);
+std::optional<int64_t> GetServerTimeOffset(NT_Inst inst);
 
 /** @} */
 
@@ -1224,12 +1170,90 @@
 
 /**
  * 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().
+ * This is the same time base used for value and connection timestamps.
+ * This function by default simply wraps wpi::Now(), but if SetNow() is
+ * called, this function instead returns the value passed to SetNow();
+ * this can be used to reduce overhead.
  *
  * @return Timestamp
  */
-uint64_t Now();
+int64_t Now();
+
+/**
+ * Sets the current timestamp used for timestamping values that do not
+ * provide a timestamp (e.g. a value of 0 is passed).  For consistency,
+ * it also results in Now() returning the set value.  This should generally
+ * be used only if the overhead of calling wpi::Now() is a concern.
+ * If used, it should be called periodically with the value of wpi::Now().
+ *
+ * @param timestamp timestamp (1 us increments)
+ */
+void SetNow(int64_t timestamp);
+
+/**
+ * Turns a type string into a type enum value.
+ *
+ * @param typeString type string
+ * @return Type value
+ */
+NT_Type GetTypeFromString(std::string_view typeString);
+
+/**
+ * Turns a type enum value into a type string.
+ *
+ * @param type type enum
+ * @return Type string
+ */
+std::string_view GetStringFromType(NT_Type type);
+
+/** @} */
+
+/**
+ * @defgroup ntcore_data_logger_func Data Logger Functions
+ * @{
+ */
+
+/**
+ * Starts logging entry changes to a DataLog.
+ *
+ * @param inst instance handle
+ * @param log data log object; lifetime must extend until StopEntryDataLog is
+ *            called or the instance is destroyed
+ * @param prefix only store entries with names that start with this prefix;
+ *               the prefix is not included in the data log entry name
+ * @param logPrefix prefix to add to data log entry names
+ * @return Data logger handle
+ */
+NT_DataLogger StartEntryDataLog(NT_Inst inst, wpi::log::DataLog& log,
+                                std::string_view prefix,
+                                std::string_view logPrefix);
+
+/**
+ * Stops logging entry changes to a DataLog.
+ *
+ * @param logger data logger handle
+ */
+void StopEntryDataLog(NT_DataLogger logger);
+
+/**
+ * Starts logging connection changes to a DataLog.
+ *
+ * @param inst instance handle
+ * @param log data log object; lifetime must extend until StopConnectionDataLog
+ *            is called or the instance is destroyed
+ * @param name data log entry name
+ * @return Data logger handle
+ */
+NT_ConnectionDataLogger StartConnectionDataLog(NT_Inst inst,
+                                               wpi::log::DataLog& log,
+                                               std::string_view name);
+
+/**
+ * Stops logging connection changes to a DataLog.
+ *
+ * @param logger data logger handle
+ */
+void StopConnectionDataLog(NT_ConnectionDataLogger logger);
 
 /** @} */
 
@@ -1246,31 +1270,13 @@
  * 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
+ * @param func        listener callback function
+ * @return Listener 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);
+NT_Listener AddLogger(NT_Inst inst, unsigned int min_level,
+                      unsigned int max_level, ListenerCallback func);
 
 /**
  * Set the log level for a log poller.  Events will only be generated for
@@ -1282,69 +1288,125 @@
  * @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);
+NT_Listener AddPolledLogger(NT_ListenerPoller poller, unsigned int min_level,
+                            unsigned int max_level);
 
 /** @} */
 /** @} */
 
-inline bool RpcAnswer::PostResponse(std::string_view result) const {
-  auto ret = PostRpcResponse(entry, call, result);
-  call = 0;
-  return ret;
-}
+/**
+ * NetworkTables meta-topic decoding functions.
+ */
+namespace meta {
 
+/**
+ * @defgroup ntcore_cpp_meta_api ntcore C++ meta-topic API
+ *
+ * Meta-topic decoders for C++.
+ *
+ * @{
+ */
+
+/**
+ * Subscriber options. Different from PubSubOptions in this reflects only
+ * options that are sent over the network.
+ */
+struct SubscriberOptions {
+  double periodic = 0.1;
+  bool topicsOnly = false;
+  bool sendAll = false;
+  bool prefixMatch = false;
+  // std::string otherStr;
+};
+
+/**
+ * Topic publisher (as published via `$pub$<topic>`).
+ */
+struct TopicPublisher {
+  std::string client;
+  uint64_t pubuid = 0;
+};
+
+/**
+ * Topic subscriber (as published via `$sub$<topic>`).
+ */
+struct TopicSubscriber {
+  std::string client;
+  uint64_t subuid = 0;
+  SubscriberOptions options;
+};
+
+/**
+ * Client publisher (as published via `$clientpub$<client>` or `$serverpub`).
+ */
+struct ClientPublisher {
+  int64_t uid = -1;
+  std::string topic;
+};
+
+/**
+ * Client subscriber (as published via `$clientsub$<client>` or `$serversub`).
+ */
+struct ClientSubscriber {
+  int64_t uid = -1;
+  std::vector<std::string> topics;
+  SubscriberOptions options;
+};
+
+/**
+ * Client (as published via `$clients`).
+ */
+struct Client {
+  std::string id;
+  std::string conn;
+  uint16_t version = 0;
+};
+
+/**
+ * Decodes `$pub$<topic>` meta-topic data.
+ *
+ * @param data data contents
+ * @return Vector of TopicPublishers, or empty optional on decoding error.
+ */
+std::optional<std::vector<TopicPublisher>> DecodeTopicPublishers(
+    std::span<const uint8_t> data);
+
+/**
+ * Decodes `$sub$<topic>` meta-topic data.
+ *
+ * @param data data contents
+ * @return Vector of TopicSubscribers, or empty optional on decoding error.
+ */
+std::optional<std::vector<TopicSubscriber>> DecodeTopicSubscribers(
+    std::span<const uint8_t> data);
+
+/**
+ * Decodes `$clientpub$<topic>` meta-topic data.
+ *
+ * @param data data contents
+ * @return Vector of ClientPublishers, or empty optional on decoding error.
+ */
+std::optional<std::vector<ClientPublisher>> DecodeClientPublishers(
+    std::span<const uint8_t> data);
+
+/**
+ * Decodes `$clientsub$<topic>` meta-topic data.
+ *
+ * @param data data contents
+ * @return Vector of ClientSubscribers, or empty optional on decoding error.
+ */
+std::optional<std::vector<ClientSubscriber>> DecodeClientSubscribers(
+    std::span<const uint8_t> data);
+
+/**
+ * Decodes `$clients` meta-topic data.
+ *
+ * @param data data contents
+ * @return Vector of Clients, or empty optional on decoding error.
+ */
+std::optional<std::vector<Client>> DecodeClients(std::span<const uint8_t> data);
+
+/** @} */
+
+}  // namespace meta
 }  // 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
index 65d1243..7e02446 100644
--- a/ntcore/src/main/native/include/ntcore_test.h
+++ b/ntcore/src/main/native/include/ntcore_test.h
@@ -2,19 +2,19 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_NTCORE_TEST_H_
-#define NTCORE_NTCORE_TEST_H_
+#pragma once
 
 #include <stdint.h>
 
-#include <string>
-
 #include "ntcore.h"
 
 // Functions in this header are to be used only for testing
 
+#ifdef __cplusplus
 extern "C" {
-struct NT_String* NT_GetStringForTesting(const char* string, int* struct_size);
+#endif
+
+struct NT_String* NT_GetStringForTesting(const char* str, int* struct_size);
 // No need for free as one already exists in main library
 
 struct NT_EntryInfo* NT_GetEntryInfoForTesting(const char* name,
@@ -59,28 +59,6 @@
                                                   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
+#ifdef __cplusplus
 }  // extern "C"
-
-#endif  // NTCORE_NTCORE_TEST_H_
+#endif
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java
index 3c38853..9fac048 100644
--- a/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/ConnectionListenerTest.java
@@ -11,13 +11,13 @@
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
+import edu.wpi.first.util.WPIUtilJNI;
 import java.util.ArrayList;
+import java.util.EnumSet;
 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;
 
@@ -28,10 +28,7 @@
   @BeforeEach
   void setUp() {
     m_serverInst = NetworkTableInstance.create();
-    m_serverInst.setNetworkIdentity("server");
-
     m_clientInst = NetworkTableInstance.create();
-    m_clientInst.setNetworkIdentity("client");
   }
 
   @AfterEach
@@ -42,13 +39,19 @@
 
   /** Connect to the server. */
   private void connect(int port) {
-    m_serverInst.startServer("connectionlistenertest.ini", "127.0.0.1", port);
-    m_clientInst.startClient("127.0.0.1", port);
+    m_serverInst.startServer("connectionlistenertest.json", "127.0.0.1", 0, port);
+    m_clientInst.startClient4("client");
+    m_clientInst.setServer("127.0.0.1", port);
 
-    // wait for client to report it's started, then wait another 0.1 sec
+    // wait for client to report it's connected, then wait another 0.1 sec
     try {
-      while ((m_clientInst.getNetworkMode() & NetworkTableInstance.kNetModeStarting) != 0) {
+      int count = 0;
+      while (!m_clientInst.isConnected()) {
         Thread.sleep(100);
+        count++;
+        if (count > 30) {
+          throw new InterruptedException();
+        }
       }
       Thread.sleep(100);
     } catch (InterruptedException ex) {
@@ -57,31 +60,31 @@
   }
 
   @Test
-  @DisabledOnOs(OS.WINDOWS)
   void testJNI() {
     // set up the poller
-    int poller = NetworkTablesJNI.createConnectionListenerPoller(m_serverInst.getHandle());
+    int poller = NetworkTablesJNI.createListenerPoller(m_serverInst.getHandle());
     assertNotSame(poller, 0, "bad poller handle");
-    int handle = NetworkTablesJNI.addPolledConnectionListener(poller, false);
+    int handle =
+        NetworkTablesJNI.addListener(
+            poller, m_serverInst.getHandle(), EnumSet.of(NetworkTableEvent.Kind.kConnection));
     assertNotSame(handle, 0, "bad listener handle");
 
     // trigger a connect event
     connect(10020);
 
     // get the event
-    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
-    ConnectionNotification[] events = null;
     try {
-      events = NetworkTablesJNI.pollConnectionListenerTimeout(m_serverInst, poller, 0.0);
+      assertFalse(WPIUtilJNI.waitForObjectTimeout(handle, 1.0));
     } catch (InterruptedException ex) {
-      Thread.currentThread().interrupt();
-      fail("unexpected interrupted exception" + ex);
+      fail("interrupted while waiting for queue");
     }
+    NetworkTableEvent[] events = NetworkTablesJNI.readListenerQueue(m_serverInst, poller);
 
     assertNotNull(events);
     assertEquals(1, events.length);
     assertEquals(handle, events[0].listener);
-    assertTrue(events[0].connected);
+    assertNotNull(events[0].connInfo);
+    assertTrue(events[0].is(NetworkTableEvent.Kind.kConnected));
 
     // trigger a disconnect event
     m_clientInst.stopClient();
@@ -92,50 +95,71 @@
     }
 
     // get the event
-    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
     try {
-      events = NetworkTablesJNI.pollConnectionListenerTimeout(m_serverInst, poller, 0.0);
+      assertFalse(WPIUtilJNI.waitForObjectTimeout(handle, 1.0));
     } catch (InterruptedException ex) {
-      Thread.currentThread().interrupt();
-      fail("unexpected interrupted exception" + ex);
+      fail("interrupted while waiting for queue");
     }
+    events = NetworkTablesJNI.readListenerQueue(m_serverInst, poller);
 
     assertNotNull(events);
     assertEquals(1, events.length);
     assertEquals(handle, events[0].listener);
-    assertFalse(events[0].connected);
+    assertTrue(events[0].is(NetworkTableEvent.Kind.kDisconnected));
   }
 
   private static int threadedPort = 10001;
 
   @ParameterizedTest
-  @DisabledOnOs(OS.WINDOWS)
   @ValueSource(strings = {"127.0.0.1", "127.0.0.1 ", " 127.0.0.1 "})
   void testThreaded(String address) {
-    m_serverInst.startServer("connectionlistenertest.ini", address, threadedPort);
-    List<ConnectionNotification> events = new ArrayList<>();
-    final int handle = m_serverInst.addConnectionListener(events::add, false);
+    m_serverInst.startServer("connectionlistenertest.json", address, 0, threadedPort);
+    List<NetworkTableEvent> events = new ArrayList<>();
+    final int handle =
+        m_serverInst.addConnectionListener(
+            false,
+            e -> {
+              synchronized (events) {
+                events.add(e);
+              }
+            });
 
     // trigger a connect event
-    m_clientInst.startClient(address, threadedPort);
+    m_clientInst.startClient4("client");
+    m_clientInst.setServer(address, threadedPort);
     threadedPort++;
 
-    // wait for client to report it's started, then wait another 0.1 sec
+    // wait for client to report it's connected, then wait another 0.1 sec
     try {
-      while ((m_clientInst.getNetworkMode() & NetworkTableInstance.kNetModeStarting) != 0) {
+      int count = 0;
+      while (!m_clientInst.isConnected()) {
         Thread.sleep(100);
+        count++;
+        if (count > 30) {
+          throw new InterruptedException();
+        }
       }
       Thread.sleep(100);
     } catch (InterruptedException ex) {
       fail("interrupted while waiting for client to start");
     }
-    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
+    try {
+      assertFalse(WPIUtilJNI.waitForObjectTimeout(handle, 1.0));
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for queue");
+    }
+
+    // wait for thread
+    m_serverInst.waitForListenerQueue(1.0);
 
     // get the event
-    assertEquals(1, events.size());
-    assertEquals(handle, events.get(0).listener);
-    assertTrue(events.get(0).connected);
-    events.clear();
+    synchronized (events) {
+      assertEquals(1, events.size());
+      assertEquals(handle, events.get(0).listener);
+      assertNotNull(events.get(0).connInfo);
+      assertTrue(events.get(0).is(NetworkTableEvent.Kind.kConnected));
+      events.clear();
+    }
 
     // trigger a disconnect event
     m_clientInst.stopClient();
@@ -145,10 +169,20 @@
       fail("interrupted while waiting for client to stop");
     }
 
+    // wait for thread
+    m_serverInst.waitForListenerQueue(1.0);
+
     // get the event
-    assertTrue(m_serverInst.waitForConnectionListenerQueue(1.0));
-    assertEquals(1, events.size());
-    assertEquals(handle, events.get(0).listener);
-    assertFalse(events.get(0).connected);
+    try {
+      assertFalse(WPIUtilJNI.waitForObjectTimeout(handle, 1.0));
+    } catch (InterruptedException ex) {
+      fail("interrupted while waiting for queue");
+    }
+    synchronized (events) {
+      assertEquals(1, events.size());
+      assertEquals(handle, events.get(0).listener);
+      assertNotNull(events.get(0).connInfo);
+      assertTrue(events.get(0).is(NetworkTableEvent.Kind.kDisconnected));
+    }
   }
 }
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/EntryListenerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/EntryListenerTest.java
deleted file mode 100644
index 7b31c26..0000000
--- a/ntcore/src/test/java/edu/wpi/first/networktables/EntryListenerTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-package edu.wpi.first.networktables;
-
-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;
-
-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;
-
-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();
-  }
-
-  private void connect() {
-    m_serverInst.startServer("connectionlistenertest.ini", "127.0.0.1", 10010);
-    m_clientInst.startClient("127.0.0.1", 10010);
-
-    // 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/LoggerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/LoggerTest.java
index 1dc26ab..c562291 100644
--- a/ntcore/src/test/java/edu/wpi/first/networktables/LoggerTest.java
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/LoggerTest.java
@@ -28,15 +28,21 @@
 
   @Test
   void addMessageTest() {
-    List<LogMessage> msgs = new ArrayList<>();
-    m_clientInst.addLogger(msgs::add, LogMessage.kInfo, 100);
+    List<NetworkTableEvent> msgs = new ArrayList<>();
+    m_clientInst.addLogger(LogMessage.kInfo, 100, msgs::add);
 
-    m_clientInst.startClient("127.0.0.1", 10000);
+    m_clientInst.startClient4("client");
+    m_clientInst.setServer("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) {
+      int count = 0;
+      while (!m_clientInst.getNetworkMode().contains(NetworkTableInstance.NetworkMode.kClient4)) {
         Thread.sleep(100);
+        count++;
+        if (count > 30) {
+          throw new InterruptedException();
+        }
       }
       Thread.sleep(100);
     } catch (InterruptedException ex) {
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/TableListenerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/TableListenerTest.java
new file mode 100644
index 0000000..d59e174
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/TableListenerTest.java
@@ -0,0 +1,65 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.EnumSet;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class TableListenerTest {
+  private NetworkTableInstance m_inst;
+
+  @BeforeEach
+  void setUp() {
+    m_inst = NetworkTableInstance.create();
+  }
+
+  @AfterEach
+  void tearDown() {
+    m_inst.close();
+  }
+
+  private void publishTopics() {
+    m_inst.getDoubleTopic("/foo/foovalue").publish();
+    m_inst.getDoubleTopic("/foo/bar/barvalue").publish();
+    m_inst.getDoubleTopic("/baz/bazvalue").publish();
+  }
+
+  @Test
+  void testAddListener() {
+    NetworkTable table = m_inst.getTable("/foo");
+    AtomicInteger count = new AtomicInteger();
+    table.addListener(
+        EnumSet.of(NetworkTableEvent.Kind.kTopic),
+        (atable, key, event) -> {
+          count.incrementAndGet();
+          assertEquals(atable, table);
+          assertEquals(key, "foovalue");
+        });
+    publishTopics();
+    assertTrue(m_inst.waitForListenerQueue(1.0));
+    assertEquals(count.get(), 1);
+  }
+
+  @Test
+  void testAddSubTableListener() {
+    NetworkTable table = m_inst.getTable("/foo");
+    AtomicInteger count = new AtomicInteger();
+    table.addSubTableListener(
+        (atable, key, event) -> {
+          count.incrementAndGet();
+          assertEquals(atable, table);
+          assertEquals(key, "bar");
+        });
+    publishTopics();
+    assertTrue(m_inst.waitForListenerQueue(1.0));
+    assertEquals(count.get(), 1);
+  }
+}
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/TimeSyncTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/TimeSyncTest.java
new file mode 100644
index 0000000..c539d20
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/TimeSyncTest.java
@@ -0,0 +1,83 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+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.assertTrue;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class TimeSyncTest {
+  private NetworkTableInstance m_inst;
+
+  @BeforeEach
+  void setUp() {
+    m_inst = NetworkTableInstance.create();
+  }
+
+  @AfterEach
+  void tearDown() {
+    m_inst.close();
+  }
+
+  @Test
+  void testLocal() {
+    var offset = m_inst.getServerTimeOffset();
+    assertFalse(offset.isPresent());
+  }
+
+  @Test
+  void testServer() {
+    var poller = new NetworkTableListenerPoller(m_inst);
+    poller.addTimeSyncListener(false);
+
+    m_inst.startServer("timesynctest.json", "127.0.0.1", 0, 10030);
+    var offset = m_inst.getServerTimeOffset();
+    assertTrue(offset.isPresent());
+    assertEquals(0L, offset.getAsLong());
+
+    NetworkTableEvent[] events = poller.readQueue();
+    assertEquals(1, events.length);
+    assertNotNull(events[0].timeSyncData);
+    assertTrue(events[0].timeSyncData.valid);
+    assertEquals(0L, events[0].timeSyncData.serverTimeOffset);
+    assertEquals(0L, events[0].timeSyncData.rtt2);
+
+    m_inst.stopServer();
+    offset = m_inst.getServerTimeOffset();
+    assertFalse(offset.isPresent());
+
+    events = poller.readQueue();
+    assertEquals(1, events.length);
+    assertNotNull(events[0].timeSyncData);
+    assertFalse(events[0].timeSyncData.valid);
+  }
+
+  @Test
+  void testClient3() {
+    m_inst.startClient3("client");
+    var offset = m_inst.getServerTimeOffset();
+    assertFalse(offset.isPresent());
+
+    m_inst.stopClient();
+    offset = m_inst.getServerTimeOffset();
+    assertFalse(offset.isPresent());
+  }
+
+  @Test
+  void testClient4() {
+    m_inst.startClient4("client");
+    var offset = m_inst.getServerTimeOffset();
+    assertFalse(offset.isPresent());
+
+    m_inst.stopClient();
+    offset = m_inst.getServerTimeOffset();
+    assertFalse(offset.isPresent());
+  }
+}
diff --git a/ntcore/src/test/java/edu/wpi/first/networktables/TopicListenerTest.java b/ntcore/src/test/java/edu/wpi/first/networktables/TopicListenerTest.java
new file mode 100644
index 0000000..9f1d67f
--- /dev/null
+++ b/ntcore/src/test/java/edu/wpi/first/networktables/TopicListenerTest.java
@@ -0,0 +1,92 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.networktables;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import edu.wpi.first.util.WPIUtilJNI;
+import java.util.EnumSet;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+class TopicListenerTest {
+  private NetworkTableInstance m_serverInst;
+  private NetworkTableInstance m_clientInst;
+
+  @BeforeEach
+  void setUp() {
+    m_serverInst = NetworkTableInstance.create();
+    m_clientInst = NetworkTableInstance.create();
+  }
+
+  @AfterEach
+  void tearDown() {
+    m_clientInst.close();
+    m_serverInst.close();
+  }
+
+  private void connect() {
+    m_serverInst.startServer("topiclistenertest.json", "127.0.0.1", 0, 10010);
+    m_clientInst.startClient4("client");
+    m_clientInst.setServer("127.0.0.1", 10010);
+
+    // Use connection listener to ensure we've connected
+    int poller = NetworkTablesJNI.createListenerPoller(m_clientInst.getHandle());
+    NetworkTablesJNI.addListener(
+        poller, m_clientInst.getHandle(), EnumSet.of(NetworkTableEvent.Kind.kConnected));
+    try {
+      if (WPIUtilJNI.waitForObjectTimeout(poller, 1.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. */
+  @Disabled("unreliable in CI")
+  @Test
+  void testPrefixNewRemote() {
+    connect();
+    final int poller = NetworkTablesJNI.createListenerPoller(m_serverInst.getHandle());
+    final int handle =
+        NetworkTablesJNI.addListener(
+            poller, new String[] {"/foo"}, EnumSet.of(NetworkTableEvent.Kind.kPublish));
+
+    // 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");
+    }
+
+    try {
+      if (WPIUtilJNI.waitForObjectTimeout(poller, 1.0)) {
+        fail("never got signaled");
+      }
+    } catch (InterruptedException ex) {
+      Thread.currentThread().interrupt();
+      fail("interrupted while waiting for signal");
+    }
+    NetworkTableEvent[] events = NetworkTablesJNI.readListenerQueue(m_serverInst, poller);
+
+    // Check the event
+    assertEquals(1, events.length);
+    assertEquals(handle, events[0].listener);
+    assertNotNull(events[0].topicInfo);
+    assertEquals(m_serverInst.getTopic("/foo/bar"), events[0].topicInfo.getTopic());
+    assertEquals("/foo/bar", events[0].topicInfo.name);
+    assertTrue(events[0].is(NetworkTableEvent.Kind.kPublish));
+  }
+}
diff --git a/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp b/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp
index 14c327c..1561277 100644
--- a/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp
+++ b/ntcore/src/test/native/cpp/ConnectionListenerTest.cpp
@@ -5,6 +5,9 @@
 #include <chrono>
 #include <thread>
 
+#include <wpi/Synchronization.h>
+#include <wpi/mutex.h>
+
 #include "TestPrinters.h"
 #include "gtest/gtest.h"
 #include "ntcore_cpp.h"
@@ -12,94 +15,123 @@
 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");
-  }
+      : server_inst(nt::CreateInstance()), client_inst(nt::CreateInstance()) {}
 
   ~ConnectionListenerTest() override {
     nt::DestroyInstance(server_inst);
     nt::DestroyInstance(client_inst);
   }
 
-  void Connect(unsigned int port);
+  void Connect(const char* address, unsigned int port3, unsigned int port4);
 
  protected:
   NT_Inst server_inst;
   NT_Inst client_inst;
 };
 
-void ConnectionListenerTest::Connect(unsigned int port) {
-  nt::StartServer(server_inst, "connectionlistenertest.ini", "127.0.0.1", port);
-  nt::StartClient(client_inst, "127.0.0.1", port);
+void ConnectionListenerTest::Connect(const char* address, unsigned int port3,
+                                     unsigned int port4) {
+  nt::StartServer(server_inst, "connectionlistenertest.ini", address, port3,
+                  port4);
+  nt::StartClient4(client_inst, "client");
+  nt::SetServer(client_inst, address, port4);
 
-  // wait for client to report it's started, then wait another 0.1 sec
-  while ((nt::GetNetworkMode(client_inst) & NT_NET_MODE_STARTING) != 0) {
+  // wait for client to report it's connected, then wait another 0.1 sec
+  int count = 0;
+  while (!nt::IsConnected(client_inst)) {
     std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    if (++count > 30) {
+      FAIL() << "timed out waiting for client to start";
+    }
   }
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
 }
 
 TEST_F(ConnectionListenerTest, Polled) {
   // set up the poller
-  NT_ConnectionListenerPoller poller =
-      nt::CreateConnectionListenerPoller(server_inst);
+  NT_ListenerPoller poller = nt::CreateListenerPoller(server_inst);
   ASSERT_NE(poller, 0u);
-  NT_ConnectionListener handle = nt::AddPolledConnectionListener(poller, false);
+  NT_Listener handle =
+      nt::AddPolledListener(poller, server_inst, nt::EventFlags::kConnection);
   ASSERT_NE(handle, 0u);
 
   // trigger a connect event
-  Connect(10000);
+  Connect("127.0.0.1", 0, 10020);
 
   // 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_TRUE(wpi::WaitForObject(poller, 1.0, &timed_out));
+  ASSERT_FALSE(timed_out);
+  auto result = nt::ReadListenerQueue(poller);
   ASSERT_EQ(result.size(), 1u);
   EXPECT_EQ(handle, result[0].listener);
-  EXPECT_TRUE(result[0].connected);
+  EXPECT_TRUE(result[0].GetConnectionInfo());
+  EXPECT_EQ(result[0].flags, nt::EventFlags::kConnected);
 
   // 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_TRUE(wpi::WaitForObject(poller, 1.0, &timed_out));
+  ASSERT_FALSE(timed_out);
+  result = nt::ReadListenerQueue(poller);
   ASSERT_EQ(result.size(), 1u);
   EXPECT_EQ(handle, result[0].listener);
-  EXPECT_FALSE(result[0].connected);
-
-  // trigger a disconnect event
+  EXPECT_TRUE(result[0].GetConnectionInfo());
+  EXPECT_EQ(result[0].flags, nt::EventFlags::kDisconnected);
 }
 
-TEST_F(ConnectionListenerTest, Threaded) {
-  std::vector<nt::ConnectionNotification> result;
-  auto handle = nt::AddConnectionListener(
-      server_inst,
-      [&](const nt::ConnectionNotification& event) { result.push_back(event); },
-      false);
+class ConnectionListenerVariantTest
+    : public ConnectionListenerTest,
+      public ::testing::WithParamInterface<std::pair<const char*, int>> {};
+
+TEST_P(ConnectionListenerVariantTest, Threaded) {
+  wpi::mutex m;
+  std::vector<nt::Event> result;
+  auto handle = nt::AddListener(server_inst, nt::EventFlags::kConnection,
+                                [&](auto& event) {
+                                  std::scoped_lock lock{m};
+                                  result.push_back(event);
+                                });
 
   // trigger a connect event
-  Connect(10001);
+  Connect(GetParam().first, 0, 20001 + GetParam().second);
 
-  ASSERT_TRUE(nt::WaitForConnectionListenerQueue(server_inst, 1.0));
+  bool timed_out = false;
+  ASSERT_TRUE(wpi::WaitForObject(handle, 1.0, &timed_out));
+  ASSERT_FALSE(timed_out);
 
   // get the event
-  ASSERT_EQ(result.size(), 1u);
-  EXPECT_EQ(handle, result[0].listener);
-  EXPECT_TRUE(result[0].connected);
-  result.clear();
+  {
+    std::scoped_lock lock{m};
+    ASSERT_EQ(result.size(), 1u);
+    EXPECT_EQ(handle, result[0].listener);
+    EXPECT_TRUE(result[0].GetConnectionInfo());
+    EXPECT_EQ(result[0].flags, nt::EventFlags::kConnected);
+    result.clear();
+  }
 
   // trigger a disconnect event
   nt::StopClient(client_inst);
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
+  // wait for thread
+  nt::WaitForListenerQueue(server_inst, 1.0);
+
   // get the event
-  ASSERT_EQ(result.size(), 1u);
-  EXPECT_EQ(handle, result[0].listener);
-  EXPECT_FALSE(result[0].connected);
+  {
+    std::scoped_lock lock{m};
+    ASSERT_EQ(result.size(), 1u);
+    EXPECT_EQ(handle, result[0].listener);
+    EXPECT_TRUE(result[0].GetConnectionInfo());
+    EXPECT_EQ(result[0].flags, nt::EventFlags::kDisconnected);
+  }
 }
+
+INSTANTIATE_TEST_SUITE_P(ConnectionListenerVariantTests,
+                         ConnectionListenerVariantTest,
+                         testing::Values(std::pair{"127.0.0.1", 0},
+                                         std::pair{"127.0.0.1 ", 1},
+                                         std::pair{" 127.0.0.1 ", 2}));
diff --git a/ntcore/src/test/native/cpp/EntryListenerTest.cpp b/ntcore/src/test/native/cpp/EntryListenerTest.cpp
deleted file mode 100644
index 8349484..0000000
--- a/ntcore/src/test/native/cpp/EntryListenerTest.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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(unsigned int port);
-
- protected:
-  NT_Inst server_inst;
-  NT_Inst client_inst;
-};
-
-void EntryListenerTest::Connect(unsigned int port) {
-  nt::StartServer(server_inst, "entrylistenertest.ini", "127.0.0.1", port);
-  nt::StartClient(client_inst, "127.0.0.1", port);
-
-  // 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(10010);
-  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(10011);
-  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
deleted file mode 100644
index e781b49..0000000
--- a/ntcore/src/test/native/cpp/EntryNotifierTest.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include <wpi/Logger.h>
-#include <wpi/StringExtras.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(wpi::starts_with(result.name, "/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/LocalStorageTest.cpp b/ntcore/src/test/native/cpp/LocalStorageTest.cpp
new file mode 100644
index 0000000..5734284
--- /dev/null
+++ b/ntcore/src/test/native/cpp/LocalStorageTest.cpp
@@ -0,0 +1,919 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "LocalStorage.h"
+#include "MockListenerStorage.h"
+#include "MockLogger.h"
+#include "PubSubOptionsMatcher.h"
+#include "SpanMatcher.h"
+#include "TestPrinters.h"
+#include "ValueMatcher.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "net/MockNetworkInterface.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::ElementsAre;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::Property;
+using ::testing::Return;
+
+namespace nt {
+
+::testing::Matcher<const PubSubOptionsImpl&> IsPubSubOptions(
+    const PubSubOptionsImpl& good) {
+  return AllOf(
+      Field("periodic", &PubSubOptionsImpl::periodicMs, good.periodicMs),
+      Field("pollStorage", &PubSubOptionsImpl::pollStorage, good.pollStorage),
+      Field("sendAll", &PubSubOptionsImpl::sendAll, good.sendAll),
+      Field("keepDuplicates", &PubSubOptionsImpl::keepDuplicates,
+            good.keepDuplicates));
+}
+
+::testing::Matcher<const PubSubOptionsImpl&> IsDefaultPubSubOptions() {
+  static constexpr PubSubOptionsImpl kDefaultPubSubOptionsImpl;
+  return IsPubSubOptions(kDefaultPubSubOptionsImpl);
+}
+
+class LocalStorageTest : public ::testing::Test {
+ public:
+  LocalStorageTest() { storage.StartNetwork(&network); }
+
+  ::testing::StrictMock<net::MockNetworkInterface> network;
+  wpi::MockLogger logger;
+  MockListenerStorage listenerStorage;
+  LocalStorage storage{0, listenerStorage, logger};
+  NT_Topic fooTopic{storage.GetTopic("foo")};
+  NT_Topic barTopic{storage.GetTopic("bar")};
+  NT_Topic bazTopic{storage.GetTopic("baz")};
+};
+
+TEST_F(LocalStorageTest, GetTopicsUnpublished) {
+  EXPECT_TRUE(storage.GetTopics("", 0).empty());
+  EXPECT_TRUE(storage.GetTopics("", {}).empty());
+  EXPECT_TRUE(storage.GetTopicInfo("", 0).empty());
+  EXPECT_TRUE(storage.GetTopicInfo("", {}).empty());
+}
+
+TEST_F(LocalStorageTest, GetTopic2) {
+  auto foo2 = storage.GetTopic("foo");
+  EXPECT_EQ(fooTopic, foo2);
+  EXPECT_NE(fooTopic, barTopic);
+}
+
+TEST_F(LocalStorageTest, GetTopicEmptyName) {
+  EXPECT_EQ(storage.GetTopic(""), 0u);
+}
+
+TEST_F(LocalStorageTest, GetEntryEmptyName) {
+  EXPECT_EQ(storage.GetEntry(""), 0u);
+}
+
+TEST_F(LocalStorageTest, GetEntryCached) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"tocache"}}),
+                                 IsDefaultPubSubOptions()));
+
+  auto entry1 = storage.GetEntry("tocache");
+  EXPECT_EQ(entry1, storage.GetEntry("tocache"));
+}
+
+TEST_F(LocalStorageTest, GetTopicName) {
+  EXPECT_EQ(storage.GetTopicName(fooTopic), "foo");
+  EXPECT_EQ(storage.GetTopicName(barTopic), "bar");
+}
+
+TEST_F(LocalStorageTest, GetTopicInfoUnpublished) {
+  auto info = storage.GetTopicInfo(fooTopic);
+  EXPECT_EQ(info.topic, fooTopic);
+  EXPECT_EQ(info.name, "foo");
+  EXPECT_EQ(info.type, NT_UNASSIGNED);
+  EXPECT_TRUE(info.type_str.empty());
+  EXPECT_EQ(info.properties, "{}");
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_UNASSIGNED);
+  EXPECT_TRUE(storage.GetTopicTypeString(fooTopic).empty());
+  EXPECT_FALSE(storage.GetTopicExists(fooTopic));
+}
+
+TEST_F(LocalStorageTest, PublishNewNoProps) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  storage.Publish(fooTopic, NT_BOOLEAN, "boolean", wpi::json::object(), {});
+
+  auto info = storage.GetTopicInfo(fooTopic);
+  EXPECT_EQ(info.properties, "{}");
+}
+
+TEST_F(LocalStorageTest, PublishNewNoPropsNull) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  auto info = storage.GetTopicInfo(fooTopic);
+  EXPECT_EQ(info.properties, "{}");
+}
+
+TEST_F(LocalStorageTest, PublishNew) {
+  wpi::json properties = {{"persistent", true}};
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, properties,
+                               IsDefaultPubSubOptions()));
+  storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {{"persistent", true}}, {});
+
+  auto info = storage.GetTopicInfo(fooTopic);
+  EXPECT_EQ(info.topic, fooTopic);
+  EXPECT_EQ(info.name, "foo");
+  EXPECT_EQ(info.type, NT_BOOLEAN);
+  EXPECT_EQ(info.type_str, "boolean");
+  EXPECT_EQ(info.properties, "{\"persistent\":true}");
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+}
+
+TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPost) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto sub = storage.Subscribe(fooTopic, NT_UNASSIGNED, "", {});
+
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  auto val = Value::MakeBoolean(true, 5);
+  EXPECT_CALL(network, SetValue(pub, val));
+  storage.SetEntryValue(pub, val);
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  auto value = storage.GetEntryValue(sub);
+  ASSERT_TRUE(value.IsBoolean());
+  EXPECT_EQ(value.GetBoolean(), true);
+  EXPECT_EQ(value.time(), 5);
+
+  auto vals = storage.ReadQueueBoolean(sub);
+  ASSERT_EQ(vals.size(), 1u);
+  EXPECT_EQ(vals[0].value, true);
+  EXPECT_EQ(vals[0].time, 5);
+
+  val = Value::MakeBoolean(false, 6);
+  EXPECT_CALL(network, SetValue(pub, val));
+  storage.SetEntryValue(pub, val);
+
+  auto vals2 = storage.ReadQueueInteger(sub);  // mismatched type
+  ASSERT_TRUE(vals2.empty());
+}
+
+TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPre) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  auto val = Value::MakeBoolean(true, 5);
+  EXPECT_CALL(network, SetValue(pub, val));
+  storage.SetEntryValue(pub, val);
+
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto sub = storage.Subscribe(fooTopic, NT_UNASSIGNED, "", {});
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  auto value = storage.GetEntryValue(sub);
+  ASSERT_TRUE(value.IsBoolean());
+  EXPECT_EQ(value.GetBoolean(), true);
+  EXPECT_EQ(value.time(), 5);
+
+  auto vals = storage.ReadQueueValue(sub);  // read queue won't get anything
+  ASSERT_TRUE(vals.empty());
+}
+
+TEST_F(LocalStorageTest, EntryNoTypeLocalSet) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto entry = storage.GetEntry(fooTopic, NT_UNASSIGNED, "", {});
+
+  // results in a publish and value set
+  auto val = Value::MakeBoolean(true, 5);
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  EXPECT_CALL(network, SetValue(_, val));
+  EXPECT_TRUE(storage.SetEntryValue(entry, val));
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  auto value = storage.GetEntryValue(entry);
+  ASSERT_TRUE(value.IsBoolean());
+  EXPECT_EQ(value.GetBoolean(), true);
+  EXPECT_EQ(value.time(), 5);
+
+  auto vals = storage.ReadQueueBoolean(entry);
+  ASSERT_EQ(vals.size(), 1u);
+  EXPECT_EQ(vals[0].value, true);
+  EXPECT_EQ(vals[0].time, 5);
+
+  // normal set with same type
+  val = Value::MakeBoolean(false, 6);
+  EXPECT_CALL(network, SetValue(_, val));
+  EXPECT_TRUE(storage.SetEntryValue(entry, val));
+
+  auto vals2 = storage.ReadQueueInteger(entry);  // mismatched type
+  ASSERT_TRUE(vals2.empty());
+
+  // cannot change type; won't generate network message
+  EXPECT_FALSE(storage.SetEntryValue(entry, Value::MakeInteger(5, 7)));
+
+  // should not change type or generate queue items
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+
+  auto vals3 = storage.ReadQueueInteger(entry);  // mismatched type
+  ASSERT_TRUE(vals3.empty());
+}
+
+TEST_F(LocalStorageTest, PubUnpubPub) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto sub = storage.Subscribe(fooTopic, NT_INTEGER, "int", {});
+
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  EXPECT_CALL(logger, Call(NT_LOG_INFO, _, _,
+                           "local subscribe to 'foo' disabled due to type "
+                           "mismatch (wanted 'int', published as 'boolean')"));
+  auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  auto val = Value::MakeBoolean(true, 5);
+  EXPECT_CALL(network, SetValue(pub, val));
+  EXPECT_TRUE(storage.SetEntryValue(pub, val));
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  EXPECT_TRUE(storage.ReadQueueInteger(sub).empty());
+
+  EXPECT_CALL(network, Unpublish(pub, fooTopic));
+  storage.Unpublish(pub);
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_UNASSIGNED);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "");
+  EXPECT_FALSE(storage.GetTopicExists(fooTopic));
+
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"int"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  pub = storage.Publish(fooTopic, NT_INTEGER, "int", {}, {});
+
+  val = Value::MakeInteger(3, 5);
+  EXPECT_CALL(network, SetValue(pub, val));
+  EXPECT_TRUE(storage.SetEntryValue(pub, val));
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_INTEGER);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "int");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  EXPECT_EQ(storage.ReadQueueInteger(sub).size(), 1u);
+}
+
+TEST_F(LocalStorageTest, LocalPubConflict) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto pub1 = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  EXPECT_CALL(logger, Call(NT_LOG_INFO, _, _,
+                           "local publish to 'foo' disabled due to type "
+                           "mismatch (wanted 'int', currently 'boolean')"));
+  auto pub2 = storage.Publish(fooTopic, NT_INTEGER, "int", {}, {});
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  EXPECT_CALL(network, SetValue(pub1, _));
+
+  EXPECT_TRUE(storage.SetEntryValue(pub1, Value::MakeBoolean(true, 5)));
+  EXPECT_FALSE(storage.SetEntryValue(pub2, Value::MakeInteger(3, 5)));
+
+  // unpublishing pub1 will publish pub2 to the network
+  EXPECT_CALL(network, Unpublish(pub1, fooTopic));
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"int"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  storage.Unpublish(pub1);
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_INTEGER);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "int");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  EXPECT_CALL(network, SetValue(pub2, _));
+
+  EXPECT_FALSE(storage.SetEntryValue(pub1, Value::MakeBoolean(true, 5)));
+  EXPECT_TRUE(storage.SetEntryValue(pub2, Value::MakeInteger(3, 5)));
+}
+
+TEST_F(LocalStorageTest, LocalSubConflict) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  EXPECT_CALL(logger, Call(NT_LOG_INFO, _, _,
+                           "local subscribe to 'foo' disabled due to type "
+                           "mismatch (wanted 'int', published as 'boolean')"));
+  storage.Subscribe(fooTopic, NT_INTEGER, "int", {});
+}
+
+TEST_F(LocalStorageTest, RemotePubConflict) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+
+  storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  EXPECT_CALL(logger, Call(NT_LOG_INFO, _, _,
+                           "network announce of 'foo' overriding local publish "
+                           "(was 'boolean', now 'int')"));
+
+  storage.NetworkAnnounce("foo", "int", wpi::json::object(), {});
+
+  // network overrides local
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_INTEGER);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "int");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+
+  storage.NetworkUnannounce("foo");
+
+  EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
+  EXPECT_TRUE(storage.GetTopicExists(fooTopic));
+}
+
+TEST_F(LocalStorageTest, SubNonExist) {
+  // makes sure no warning is emitted
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  storage.Subscribe(fooTopic, NT_BOOLEAN, "boolean", {});
+}
+
+TEST_F(LocalStorageTest, SetDefaultSubscribe) {
+  // no publish, no value on wire, this is just handled locally
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto sub = storage.Subscribe(fooTopic, NT_BOOLEAN, "boolean", {});
+  EXPECT_TRUE(storage.SetDefaultEntryValue(sub, Value::MakeBoolean(true)));
+  auto val = storage.GetEntryValue(sub);
+  ASSERT_TRUE(val.IsBoolean());
+  ASSERT_TRUE(val.GetBoolean());
+  ASSERT_EQ(val.time(), 0);
+}
+
+TEST_F(LocalStorageTest, SetDefaultPublish) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
+
+  // expect a value across the wire
+  auto expectVal = Value::MakeBoolean(true, 0);
+  EXPECT_CALL(network, SetValue(pub, expectVal));
+  EXPECT_TRUE(storage.SetDefaultEntryValue(pub, Value::MakeBoolean(true)));
+
+  EXPECT_CALL(network, Subscribe(_, _, IsDefaultPubSubOptions()));
+  auto sub = storage.Subscribe(fooTopic, NT_BOOLEAN, "boolean", {});
+  auto val = storage.GetEntryValue(sub);
+  ASSERT_TRUE(val.IsBoolean());
+  ASSERT_TRUE(val.GetBoolean());
+  ASSERT_EQ(val.time(), 0);
+}
+
+TEST_F(LocalStorageTest, SetDefaultEntry) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto entry = storage.GetEntry(fooTopic, NT_BOOLEAN, "boolean", {});
+
+  // expect a publish and value
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto expectVal = Value::MakeBoolean(true, 0);
+  EXPECT_CALL(network, SetValue(_, expectVal));
+  EXPECT_TRUE(storage.SetDefaultEntryValue(entry, Value::MakeBoolean(true)));
+
+  auto val = storage.GetEntryValue(entry);
+  ASSERT_TRUE(val.IsBoolean());
+  ASSERT_TRUE(val.GetBoolean());
+  ASSERT_EQ(val.time(), 0);
+}
+
+TEST_F(LocalStorageTest, SetDefaultEntryUnassigned) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto entry = storage.GetEntry(fooTopic, NT_UNASSIGNED, "", {});
+
+  // expect a publish and value
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"boolean"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto expectVal = Value::MakeBoolean(true, 0);
+  EXPECT_CALL(network, SetValue(_, expectVal));
+  EXPECT_TRUE(storage.SetDefaultEntryValue(entry, Value::MakeBoolean(true)));
+
+  ASSERT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
+  auto val = storage.GetEntryValue(entry);
+  ASSERT_TRUE(val.IsBoolean());
+  ASSERT_TRUE(val.GetBoolean());
+  ASSERT_EQ(val.time(), 0);
+}
+
+TEST_F(LocalStorageTest, SetDefaultEntryDiffType) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"string"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto pub = storage.Publish(fooTopic, NT_STRING, "string", {}, {});
+
+  EXPECT_FALSE(storage.SetDefaultEntryValue(pub, Value::MakeBoolean(true)));
+  ASSERT_EQ(storage.GetTopicType(fooTopic), NT_STRING);
+}
+
+TEST_F(LocalStorageTest, SetValueEmptyValue) {
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"string"}, wpi::json::object(),
+                               IsDefaultPubSubOptions()));
+  auto pub = storage.Publish(fooTopic, NT_STRING, "string", {}, {});
+
+  EXPECT_FALSE(storage.SetEntryValue(pub, {}));
+}
+
+TEST_F(LocalStorageTest, SetValueEmptyUntypedEntry) {
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsDefaultPubSubOptions()));
+  auto entry = storage.GetEntry(fooTopic, NT_UNASSIGNED, "", {});
+  EXPECT_FALSE(storage.SetEntryValue(entry, {}));
+}
+
+TEST_F(LocalStorageTest, PublishUntyped) {
+  EXPECT_CALL(
+      logger,
+      Call(
+          NT_LOG_ERROR, _, _,
+          "cannot publish 'foo' with an unassigned type or empty type string"));
+
+  EXPECT_EQ(storage.Publish(fooTopic, NT_UNASSIGNED, "", {}, {}), 0u);
+}
+
+TEST_F(LocalStorageTest, SetValueInvalidHandle) {
+  EXPECT_FALSE(storage.SetEntryValue(0u, {}));
+}
+
+class LocalStorageDuplicatesTest : public LocalStorageTest {
+ public:
+  void SetupPubSub(bool keepPub, bool keepSub);
+  void SetValues();
+
+  NT_Publisher pub;
+  NT_Subscriber sub;
+  Value val1 = Value::MakeDouble(1.0, 10);
+  Value val2 = Value::MakeDouble(1.0, 20);  // duplicate value
+  Value val3 = Value::MakeDouble(2.0, 30);
+};
+
+void LocalStorageDuplicatesTest::SetupPubSub(bool keepPub, bool keepSub) {
+  PubSubOptionsImpl pubOptions;
+  pubOptions.keepDuplicates = keepPub;
+  EXPECT_CALL(network, Publish(_, fooTopic, std::string_view{"foo"},
+                               std::string_view{"double"}, wpi::json::object(),
+                               IsPubSubOptions(pubOptions)));
+  pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {},
+                        {.keepDuplicates = keepPub});
+
+  PubSubOptionsImpl subOptions;
+  subOptions.pollStorage = 10;
+  subOptions.keepDuplicates = keepSub;
+  EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
+                                 IsPubSubOptions(subOptions)));
+  sub = storage.Subscribe(fooTopic, NT_DOUBLE, "double",
+                          {.pollStorage = 10, .keepDuplicates = keepSub});
+}
+
+void LocalStorageDuplicatesTest::SetValues() {
+  storage.SetEntryValue(pub, val1);
+  storage.SetEntryValue(pub, val2);
+  // verify the timestamp was updated
+  EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
+  storage.SetEntryValue(pub, val3);
+}
+
+TEST_F(LocalStorageDuplicatesTest, Defaults) {
+  SetupPubSub(false, false);
+
+  EXPECT_CALL(network, SetValue(pub, val1));
+  EXPECT_CALL(network, SetValue(pub, val3));
+  SetValues();
+
+  // verify 2nd update was dropped locally
+  auto values = storage.ReadQueueDouble(sub);
+  ASSERT_EQ(values.size(), 2u);
+  ASSERT_EQ(values[0].value, val1.GetDouble());
+  ASSERT_EQ(values[0].time, val1.time());
+  ASSERT_EQ(values[1].value, val3.GetDouble());
+  ASSERT_EQ(values[1].time, val3.time());
+}
+
+TEST_F(LocalStorageDuplicatesTest, KeepPub) {
+  SetupPubSub(true, false);
+
+  EXPECT_CALL(network, SetValue(pub, val1)).Times(2);
+  // EXPECT_CALL(network, SetValue(pub, val2));
+  EXPECT_CALL(network, SetValue(pub, val3));
+  SetValues();
+
+  // verify all 3 updates were received locally
+  auto values = storage.ReadQueueDouble(sub);
+  ASSERT_EQ(values.size(), 3u);
+}
+
+TEST_F(LocalStorageDuplicatesTest, KeepSub) {
+  SetupPubSub(false, true);
+
+  // second update should NOT go to the network
+  EXPECT_CALL(network, SetValue(pub, val1));
+  EXPECT_CALL(network, SetValue(pub, val3));
+  SetValues();
+
+  // verify all 3 updates were received locally
+  auto values = storage.ReadQueueDouble(sub);
+  ASSERT_EQ(values.size(), 3u);
+}
+
+TEST_F(LocalStorageDuplicatesTest, FromNetwork) {
+  SetupPubSub(false, false);
+
+  // incoming from the network are treated like a normal local publish
+  auto topic = storage.NetworkAnnounce("foo", "double", {{}}, 0);
+  storage.NetworkSetValue(topic, val1);
+  storage.NetworkSetValue(topic, val2);
+  // verify the timestamp was updated
+  EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
+  storage.NetworkSetValue(topic, val3);
+
+  // verify 2nd update was dropped locally
+  auto values = storage.ReadQueueDouble(sub);
+  ASSERT_EQ(values.size(), 2u);
+  ASSERT_EQ(values[0].value, val1.GetDouble());
+  ASSERT_EQ(values[0].time, val1.time());
+  ASSERT_EQ(values[1].value, val3.GetDouble());
+  ASSERT_EQ(values[1].time, val3.time());
+}
+
+class LocalStorageNumberVariantsTest : public LocalStorageTest {
+ public:
+  void CreateSubscriber(NT_Handle* handle, std::string_view name, NT_Type type,
+                        std::string_view typeStr);
+  void CreateSubscribers();
+  void CreateSubscribersArray();
+
+  NT_Subscriber sub1, sub2, sub3, sub4;
+  NT_Entry entry;
+
+  struct SubEntry {
+    SubEntry(NT_Handle subentry, NT_Type type, std::string_view name)
+        : subentry{subentry}, type{type}, name{name} {}
+    NT_Handle subentry;
+    NT_Type type;
+    std::string name;
+  };
+  std::vector<SubEntry> subentries;
+};
+
+void LocalStorageNumberVariantsTest::CreateSubscriber(
+    NT_Handle* handle, std::string_view name, NT_Type type,
+    std::string_view typeStr) {
+  *handle = storage.Subscribe(fooTopic, type, typeStr, {});
+  subentries.emplace_back(*handle, type, name);
+}
+
+void LocalStorageNumberVariantsTest::CreateSubscribers() {
+  EXPECT_CALL(logger,
+              Call(NT_LOG_INFO, _, _,
+                   "local subscribe to 'foo' disabled due to type "
+                   "mismatch (wanted 'boolean', published as 'double')"));
+  CreateSubscriber(&sub1, "subDouble", NT_DOUBLE, "double");
+  CreateSubscriber(&sub2, "subInteger", NT_INTEGER, "int");
+  CreateSubscriber(&sub3, "subFloat", NT_FLOAT, "float");
+  CreateSubscriber(&sub4, "subBoolean", NT_BOOLEAN, "boolean");
+  entry = storage.GetEntry("foo");
+  subentries.emplace_back(entry, NT_UNASSIGNED, "entry");
+}
+
+void LocalStorageNumberVariantsTest::CreateSubscribersArray() {
+  EXPECT_CALL(logger,
+              Call(NT_LOG_INFO, _, _,
+                   "local subscribe to 'foo' disabled due to type "
+                   "mismatch (wanted 'boolean[]', published as 'double[]')"));
+  CreateSubscriber(&sub1, "subDouble", NT_DOUBLE_ARRAY, "double[]");
+  CreateSubscriber(&sub2, "subInteger", NT_INTEGER_ARRAY, "int[]");
+  CreateSubscriber(&sub3, "subFloat", NT_FLOAT_ARRAY, "float[]");
+  CreateSubscriber(&sub4, "subBoolean", NT_BOOLEAN_ARRAY, "boolean[]");
+  entry = storage.GetEntry("foo");
+  subentries.emplace_back(entry, NT_UNASSIGNED, "entry");
+}
+
+TEST_F(LocalStorageNumberVariantsTest, GetEntryPubAfter) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(network, SetValue(_, _)).Times(1);
+  CreateSubscribers();
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+  // all subscribers get the actual type and time
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    EXPECT_EQ(storage.GetEntryType(subentry.subentry), NT_DOUBLE);
+    EXPECT_EQ(storage.GetEntryLastChange(subentry.subentry), 50);
+  }
+  // for subscribers, they get a converted value or nothing on mismatch
+  EXPECT_EQ(storage.GetEntryValue(sub1), Value::MakeDouble(1.0, 50));
+  EXPECT_EQ(storage.GetEntryValue(sub2), Value::MakeInteger(1, 50));
+  EXPECT_EQ(storage.GetEntryValue(sub3), Value::MakeFloat(1.0, 50));
+  EXPECT_EQ(storage.GetEntryValue(sub4), Value{});
+  // entrys just get whatever the value is
+  EXPECT_EQ(storage.GetEntryValue(entry), Value::MakeDouble(1.0, 50));
+}
+
+TEST_F(LocalStorageNumberVariantsTest, GetEntryPubBefore) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(network, SetValue(_, _)).Times(1);
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  CreateSubscribers();
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+  // all subscribers get the actual type and time
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    EXPECT_EQ(storage.GetEntryType(subentry.subentry), NT_DOUBLE);
+    EXPECT_EQ(storage.GetEntryLastChange(subentry.subentry), 50);
+  }
+  // for subscribers, they get a converted value or nothing on mismatch
+  EXPECT_EQ(storage.GetEntryValue(sub1), Value::MakeDouble(1.0, 50));
+  EXPECT_EQ(storage.GetEntryValue(sub2), Value::MakeInteger(1, 50));
+  EXPECT_EQ(storage.GetEntryValue(sub3), Value::MakeFloat(1.0, 50));
+  EXPECT_EQ(storage.GetEntryValue(sub4), Value{});
+  // entrys just get whatever the value is
+  EXPECT_EQ(storage.GetEntryValue(entry), Value::MakeDouble(1.0, 50));
+}
+
+template <typename T>
+::testing::Matcher<const T&> TSEq(auto value, int64_t time) {
+  return AllOf(Field("value", &T::value, value), Field("time", &T::time, time));
+}
+
+TEST_F(LocalStorageNumberVariantsTest, GetAtomic) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(network, SetValue(_, _)).Times(1);
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  CreateSubscribers();
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    EXPECT_THAT(storage.GetAtomicDouble(subentry.subentry, 0),
+                TSEq<TimestampedDouble>(1.0, 50));
+    EXPECT_THAT(storage.GetAtomicInteger(subentry.subentry, 0),
+                TSEq<TimestampedInteger>(1, 50));
+    EXPECT_THAT(storage.GetAtomicFloat(subentry.subentry, 0),
+                TSEq<TimestampedFloat>(1.0, 50));
+    EXPECT_THAT(storage.GetAtomicBoolean(subentry.subentry, false),
+                TSEq<TimestampedBoolean>(false, 0));
+  }
+}
+
+template <typename T, typename U>
+::testing::Matcher<const T&> TSSpanEq(std::span<U> value, int64_t time) {
+  return AllOf(
+      Field("value", &T::value, wpi::SpanEq(std::span<const U>(value))),
+      Field("time", &T::time, time));
+}
+
+TEST_F(LocalStorageNumberVariantsTest, GetAtomicArray) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(network, SetValue(_, _)).Times(1);
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE_ARRAY, "double[]", {}, {});
+  CreateSubscribersArray();
+  storage.SetEntryValue(pub, Value::MakeDoubleArray({1.0}, 50));
+
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    double doubleVal = 1.0;
+    EXPECT_THAT(storage.GetAtomicDoubleArray(subentry.subentry, {}),
+                TSSpanEq<TimestampedDoubleArray>(std::span{&doubleVal, 1}, 50));
+    int64_t intVal = 1;
+    EXPECT_THAT(storage.GetAtomicIntegerArray(subentry.subentry, {}),
+                TSSpanEq<TimestampedIntegerArray>(std::span{&intVal, 1}, 50));
+    float floatVal = 1.0;
+    EXPECT_THAT(storage.GetAtomicFloatArray(subentry.subentry, {}),
+                TSSpanEq<TimestampedFloatArray>(std::span{&floatVal, 1}, 50));
+    EXPECT_THAT(storage.GetAtomicBooleanArray(subentry.subentry, {}),
+                TSSpanEq<TimestampedBooleanArray>(std::span<int>{}, 0));
+  }
+}
+
+TEST_F(LocalStorageNumberVariantsTest, ReadQueue) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(network, SetValue(_, _)).Times(4);
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  CreateSubscribers();
+
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    if (subentry.type == NT_BOOLEAN) {
+      EXPECT_THAT(storage.ReadQueueDouble(subentry.subentry), IsEmpty());
+    } else {
+      EXPECT_THAT(storage.ReadQueueDouble(subentry.subentry),
+                  ElementsAre(TSEq<TimestampedDouble>(1.0, 50)));
+    }
+  }
+
+  storage.SetEntryValue(pub, Value::MakeDouble(2.0, 50));
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    if (subentry.type == NT_BOOLEAN) {
+      EXPECT_THAT(storage.ReadQueueInteger(subentry.subentry), IsEmpty());
+    } else {
+      EXPECT_THAT(storage.ReadQueueInteger(subentry.subentry),
+                  ElementsAre(TSEq<TimestampedInteger>(2, 50)));
+    }
+  }
+
+  storage.SetEntryValue(pub, Value::MakeDouble(3.0, 50));
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    if (subentry.type == NT_BOOLEAN) {
+      EXPECT_THAT(storage.ReadQueueFloat(subentry.subentry), IsEmpty());
+    } else {
+      EXPECT_THAT(storage.ReadQueueFloat(subentry.subentry),
+                  ElementsAre(TSEq<TimestampedFloat>(3.0, 50)));
+    }
+  }
+
+  storage.SetEntryValue(pub, Value::MakeDouble(4.0, 50));
+  for (auto&& subentry : subentries) {
+    SCOPED_TRACE(subentry.name);
+    EXPECT_THAT(storage.ReadQueueBoolean(subentry.subentry), IsEmpty());
+  }
+}
+
+TEST_F(LocalStorageTest, MultiSubSpecial) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(2);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(2);
+  EXPECT_CALL(network, SetValue(_, _)).Times(2);
+  EXPECT_CALL(listenerStorage, Activate(_, _, _)).Times(2);
+
+  auto subnormal = storage.SubscribeMultiple({{""}}, {});
+  auto subspecial = storage.SubscribeMultiple({{"", "$"}}, {});
+  auto pubnormal = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  auto specialTopic = storage.GetTopic("$topic");
+  auto pubspecial = storage.Publish(specialTopic, NT_DOUBLE, "double", {}, {});
+  storage.AddListener(1, subnormal, NT_EVENT_VALUE_ALL);
+  storage.AddListener(2, subspecial, NT_EVENT_VALUE_ALL);
+
+  EXPECT_CALL(
+      listenerStorage,
+      Notify(wpi::SpanEq(std::span<const NT_Listener>{{2}}), _, _, _, _));
+  storage.SetEntryValue(pubspecial, Value::MakeDouble(1.0, 30));
+
+  EXPECT_CALL(
+      listenerStorage,
+      Notify(wpi::SpanEq(std::span<const NT_Listener>{{1}}), _, _, _, _));
+  EXPECT_CALL(
+      listenerStorage,
+      Notify(wpi::SpanEq(std::span<const NT_Listener>{{2}}), _, _, _, _));
+  storage.SetEntryValue(pubnormal, Value::MakeDouble(2.0, 40));
+}
+
+TEST_F(LocalStorageTest, NetworkDuplicateDetect) {
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _));
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  auto remoteTopic =
+      storage.NetworkAnnounce("foo", "double", wpi::json::object(), 0);
+
+  // local set
+  EXPECT_CALL(network, SetValue(_, _));
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+  // 2nd local set with same value - no SetValue call to network
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 60));
+  // network set with different value
+  storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 70));
+  // 3rd local set with same value generates a SetValue call to network
+  EXPECT_CALL(network, SetValue(_, _));
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 80));
+}
+
+TEST_F(LocalStorageTest, ReadQueueLocalRemote) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(3);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+
+  auto subBoth =
+      storage.Subscribe(fooTopic, NT_DOUBLE, "double", kDefaultPubSubOptions);
+  auto subLocal =
+      storage.Subscribe(fooTopic, NT_DOUBLE, "double", {.disableRemote = true});
+  auto subRemote =
+      storage.Subscribe(fooTopic, NT_DOUBLE, "double", {.disableLocal = true});
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  auto remoteTopic =
+      storage.NetworkAnnounce("foo", "double", wpi::json::object(), 0);
+
+  // local set
+  EXPECT_CALL(network, SetValue(_, _));
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+  EXPECT_THAT(storage.ReadQueueDouble(subBoth),
+              ElementsAre(TSEq<TimestampedDouble>(1.0, 50)));
+  EXPECT_THAT(storage.ReadQueueDouble(subLocal),
+              ElementsAre(TSEq<TimestampedDouble>(1.0, 50)));
+  EXPECT_THAT(storage.ReadQueueDouble(subRemote), IsEmpty());
+
+  // network set
+  storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
+  EXPECT_THAT(storage.ReadQueueDouble(subBoth),
+              ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
+  EXPECT_THAT(storage.ReadQueueDouble(subRemote),
+              ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
+  EXPECT_THAT(storage.ReadQueueDouble(subLocal), IsEmpty());
+}
+
+TEST_F(LocalStorageTest, SubExcludePub) {
+  EXPECT_CALL(network, Subscribe(_, _, _)).Times(2);
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _)).Times(1);
+
+  auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
+  auto subActive = storage.Subscribe(fooTopic, NT_DOUBLE, "double", {});
+  auto subExclude = storage.Subscribe(fooTopic, NT_DOUBLE, "double",
+                                      {.excludePublisher = pub});
+  auto remoteTopic =
+      storage.NetworkAnnounce("foo", "double", wpi::json::object(), 0);
+
+  // local set
+  EXPECT_CALL(network, SetValue(_, _));
+  storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
+  EXPECT_THAT(storage.ReadQueueDouble(subActive),
+              ElementsAre(TSEq<TimestampedDouble>(1.0, 50)));
+  EXPECT_THAT(storage.ReadQueueDouble(subExclude), IsEmpty());
+
+  // network set
+  storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
+  EXPECT_THAT(storage.ReadQueueDouble(subActive),
+              ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
+  EXPECT_THAT(storage.ReadQueueDouble(subExclude),
+              ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
+}
+
+TEST_F(LocalStorageTest, EntryExcludeSelf) {
+  EXPECT_CALL(network, Subscribe(_, _, _));
+
+  auto entry =
+      storage.GetEntry(fooTopic, NT_DOUBLE, "double", {.excludeSelf = true});
+  auto remoteTopic =
+      storage.NetworkAnnounce("foo", "double", wpi::json::object(), 0);
+
+  // local set
+  EXPECT_CALL(network, Publish(_, _, _, _, _, _));
+  EXPECT_CALL(network, SetValue(_, _));
+  storage.SetEntryValue(entry, Value::MakeDouble(1.0, 50));
+  EXPECT_THAT(storage.ReadQueueDouble(entry), IsEmpty());
+
+  // network set
+  storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
+  EXPECT_THAT(storage.ReadQueueDouble(entry),
+              ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/LoggerTest.cpp b/ntcore/src/test/native/cpp/LoggerTest.cpp
new file mode 100644
index 0000000..a9f499c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/LoggerTest.cpp
@@ -0,0 +1,96 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <wpi/Synchronization.h>
+
+#include "Handle.h"
+#include "TestPrinters.h"
+#include "gtest/gtest.h"
+#include "ntcore_cpp.h"
+
+class LoggerTest : public ::testing::Test {
+ public:
+  LoggerTest() : m_inst(nt::CreateInstance()) {}
+
+  ~LoggerTest() override { nt::DestroyInstance(m_inst); }
+
+  void Generate();
+  void Check(const std::vector<nt::Event>& events, NT_Listener handle,
+             bool infoMsg, bool errMsg);
+
+ protected:
+  NT_Inst m_inst;
+};
+
+void LoggerTest::Generate() {
+  // generate info message
+  nt::StartClient4(m_inst, "");
+
+  // generate error message
+  nt::Publish(nt::Handle(nt::Handle{m_inst}.GetInst(), 5, nt::Handle::kTopic),
+              NT_DOUBLE, "");
+}
+
+void LoggerTest::Check(const std::vector<nt::Event>& events, NT_Listener handle,
+                       bool infoMsg, bool errMsg) {
+  size_t count = (infoMsg ? 1u : 0u) + (errMsg ? 1u : 0u);
+  ASSERT_EQ(events.size(), count);
+  for (size_t i = 0; i < count; ++i) {
+    ASSERT_EQ(events[i].listener, handle);
+    ASSERT_EQ(events[i].flags & nt::EventFlags::kLogMessage,
+              nt::EventFlags::kLogMessage);
+    auto log = events[i].GetLogMessage();
+    ASSERT_TRUE(log);
+    if (infoMsg) {
+      ASSERT_EQ(log->message, "starting network client");
+      ASSERT_EQ(log->level, NT_LOG_INFO);
+      infoMsg = false;
+    } else if (errMsg) {
+      ASSERT_EQ(log->message,
+                "trying to publish invalid topic handle (386924549)");
+      ASSERT_EQ(log->level, NT_LOG_ERROR);
+      errMsg = false;
+    }
+  }
+}
+
+TEST_F(LoggerTest, DefaultLogRange) {
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto handle =
+      nt::AddPolledListener(poller, m_inst, nt::EventFlags::kLogMessage);
+
+  Generate();
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+
+  Check(events, handle, true, true);
+}
+
+TEST_F(LoggerTest, InfoOnly) {
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto handle = nt::AddPolledLogger(poller, NT_LOG_INFO, NT_LOG_INFO);
+
+  Generate();
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+
+  Check(events, handle, true, false);
+}
+
+TEST_F(LoggerTest, Error) {
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto handle = nt::AddPolledLogger(poller, NT_LOG_ERROR, 100);
+
+  Generate();
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+
+  Check(events, handle, false, true);
+}
diff --git a/ntcore/src/test/native/cpp/MessageMatcher.cpp b/ntcore/src/test/native/cpp/MessageMatcher.cpp
deleted file mode 100644
index 69c87a0..0000000
--- a/ntcore/src/test/native/cpp/MessageMatcher.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 7afeeef..0000000
--- a/ntcore/src/test/native/cpp/MessageMatcher.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#ifndef NTCORE_MESSAGEMATCHER_H_
-#define NTCORE_MESSAGEMATCHER_H_
-
-#include <memory>
-#include <ostream>
-#include <utility>
-
-#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(std::move(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/MockConnectionList.h b/ntcore/src/test/native/cpp/MockConnectionList.h
new file mode 100644
index 0000000..cd93343
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockConnectionList.h
@@ -0,0 +1,24 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <vector>
+
+#include "IConnectionList.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockConnectionList : public IConnectionList {
+ public:
+  MOCK_METHOD(int, AddConnection, (const ConnectionInfo& info), (override));
+  MOCK_METHOD(void, RemoveConnection, (int handle), (override));
+  MOCK_METHOD(void, ClearConnections, (), (override));
+  MOCK_METHOD(std::vector<ConnectionInfo>, GetConnections, (),
+              (const, override));
+  MOCK_METHOD(bool, IsConnected, (), (const, override));
+};
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/MockConnectionNotifier.h b/ntcore/src/test/native/cpp/MockConnectionNotifier.h
deleted file mode 100644
index d632d5c..0000000
--- a/ntcore/src/test/native/cpp/MockConnectionNotifier.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 22b0fba..0000000
--- a/ntcore/src/test/native/cpp/MockDispatcher.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index 58518c6..0000000
--- a/ntcore/src/test/native/cpp/MockEntryNotifier.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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,
-                   std::string_view 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, std::string_view 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, std::string_view 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/MockListenerStorage.h b/ntcore/src/test/native/cpp/MockListenerStorage.h
new file mode 100644
index 0000000..6e1dc4e
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockListenerStorage.h
@@ -0,0 +1,45 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <memory>
+#include <span>
+#include <string_view>
+
+#include "IListenerStorage.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class MockListenerStorage : public IListenerStorage {
+ public:
+  MOCK_METHOD(void, Activate,
+              (NT_Listener listenerHandle, unsigned int mask,
+               FinishEventFunc finishEvent),
+              (override));
+  MOCK_METHOD(void, Notify,
+              (std::span<const NT_Listener> handles, unsigned int flags,
+               std::span<ConnectionInfo const* const> infos),
+              (override));
+  MOCK_METHOD(void, Notify,
+              (std::span<const NT_Listener> handles, unsigned int flags,
+               std::span<const TopicInfo> infos),
+              (override));
+  MOCK_METHOD(void, Notify,
+              (std::span<const NT_Listener> handles, unsigned int flags,
+               NT_Topic topic, NT_Handle subentry, const Value& value),
+              (override));
+  MOCK_METHOD(void, Notify,
+              (unsigned int flags, unsigned int level,
+               std::string_view filename, unsigned int line,
+               std::string_view message),
+              (override));
+  MOCK_METHOD(void, NotifyTimeSync,
+              (std::span<const NT_Listener> handles, unsigned int flags,
+               int64_t serverTimeOffset, int64_t rtt2, bool valid),
+              (override));
+};
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/MockLogger.h b/ntcore/src/test/native/cpp/MockLogger.h
new file mode 100644
index 0000000..f20a12f
--- /dev/null
+++ b/ntcore/src/test/native/cpp/MockLogger.h
@@ -0,0 +1,24 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <wpi/Logger.h>
+
+#include "gmock/gmock.h"
+
+namespace wpi {
+
+class MockLogger : public Logger,
+                   public ::testing::MockFunction<void(
+                       unsigned int level, std::string_view file,
+                       unsigned int line, std::string_view msg)> {
+ public:
+  MockLogger() {
+    SetLogger([this](unsigned int level, const char* file, unsigned int line,
+                     const char* msg) { Call(level, file, line, msg); });
+  }
+};
+
+}  // namespace wpi
diff --git a/ntcore/src/test/native/cpp/MockNetworkConnection.h b/ntcore/src/test/native/cpp/MockNetworkConnection.h
deleted file mode 100644
index be9c2c6..0000000
--- a/ntcore/src/test/native/cpp/MockNetworkConnection.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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
deleted file mode 100644
index be9e512..0000000
--- a/ntcore/src/test/native/cpp/MockRpcServer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this 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,
-                    std::string_view name, std::string_view 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
index 73c4786..aa28afd 100644
--- a/ntcore/src/test/native/cpp/NetworkTableTest.cpp
+++ b/ntcore/src/test/native/cpp/NetworkTableTest.cpp
@@ -89,3 +89,15 @@
   ASSERT_TRUE(inst.GetEntry("/testkey").Exists());
   nt::NetworkTableInstance::Destroy(inst);
 }
+
+TEST_F(NetworkTableTest, ResetInstance) {
+  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());
+  nt::ResetInstance(inst.GetHandle());
+  ASSERT_FALSE(nt->ContainsKey("testkey"));
+  nt::NetworkTableInstance::Destroy(inst);
+}
diff --git a/ntcore/src/test/native/cpp/PubSubOptionsMatcher.cpp b/ntcore/src/test/native/cpp/PubSubOptionsMatcher.cpp
new file mode 100644
index 0000000..3437a91
--- /dev/null
+++ b/ntcore/src/test/native/cpp/PubSubOptionsMatcher.cpp
@@ -0,0 +1,43 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "PubSubOptionsMatcher.h"
+
+#include "TestPrinters.h"
+
+namespace nt {
+
+bool PubSubOptionsMatcher::MatchAndExplain(
+    const PubSubOptionsImpl& val,
+    ::testing::MatchResultListener* listener) const {
+  bool match = true;
+  if (val.periodicMs != good.periodicMs) {
+    *listener << "periodic mismatch ";
+    match = false;
+  }
+  if (val.pollStorage != good.pollStorage) {
+    *listener << "pollStorage mismatch ";
+    match = false;
+  }
+  if (val.sendAll != good.sendAll) {
+    *listener << "sendAll mismatch ";
+    match = false;
+  }
+  if (val.keepDuplicates != good.keepDuplicates) {
+    *listener << "keepDuplicates mismatch ";
+    match = false;
+  }
+  return match;
+}
+
+void PubSubOptionsMatcher::DescribeTo(::std::ostream* os) const {
+  PrintTo(good, os);
+}
+
+void PubSubOptionsMatcher::DescribeNegationTo(::std::ostream* os) const {
+  *os << "is not equal to ";
+  PrintTo(good, os);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/PubSubOptionsMatcher.h b/ntcore/src/test/native/cpp/PubSubOptionsMatcher.h
new file mode 100644
index 0000000..925f17d
--- /dev/null
+++ b/ntcore/src/test/native/cpp/PubSubOptionsMatcher.h
@@ -0,0 +1,35 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <ostream>
+#include <utility>
+
+#include "PubSubOptions.h"
+#include "gmock/gmock.h"
+
+namespace nt {
+
+class PubSubOptionsMatcher
+    : public ::testing::MatcherInterface<const PubSubOptionsImpl&> {
+ public:
+  explicit PubSubOptionsMatcher(PubSubOptionsImpl good)
+      : good{std::move(good)} {}
+
+  bool MatchAndExplain(const PubSubOptionsImpl& val,
+                       ::testing::MatchResultListener* listener) const override;
+  void DescribeTo(::std::ostream* os) const override;
+  void DescribeNegationTo(::std::ostream* os) const override;
+
+ private:
+  PubSubOptionsImpl good;
+};
+
+inline ::testing::Matcher<const PubSubOptionsImpl&> PubSubOptionsEq(
+    PubSubOptionsImpl good) {
+  return ::testing::MakeMatcher(new PubSubOptionsMatcher(std::move(good)));
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/SpanMatcher.h b/ntcore/src/test/native/cpp/SpanMatcher.h
new file mode 100644
index 0000000..9973c03
--- /dev/null
+++ b/ntcore/src/test/native/cpp/SpanMatcher.h
@@ -0,0 +1,72 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <algorithm>
+#include <initializer_list>
+#include <memory>
+#include <ostream>
+#include <span>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "TestPrinters.h"
+#include "gmock/gmock.h"
+
+namespace wpi {
+
+template <typename T>
+class SpanMatcher : public ::testing::MatcherInterface<std::span<T>> {
+ public:
+  explicit SpanMatcher(std::span<T> good_) : good{good_.begin(), good_.end()} {}
+
+  bool MatchAndExplain(std::span<T> val,
+                       ::testing::MatchResultListener* listener) const override;
+  void DescribeTo(::std::ostream* os) const override;
+  void DescribeNegationTo(::std::ostream* os) const override;
+
+ private:
+  std::vector<std::remove_cv_t<T>> good;
+};
+
+template <typename T>
+inline ::testing::Matcher<std::span<const T>> SpanEq(std::span<const T> good) {
+  return ::testing::MakeMatcher(new SpanMatcher(good));
+}
+
+template <typename T>
+inline ::testing::Matcher<std::span<const T>> SpanEq(
+    std::initializer_list<const T> good) {
+  return ::testing::MakeMatcher(
+      new SpanMatcher<const T>({good.begin(), good.end()}));
+}
+
+template <typename T>
+bool SpanMatcher<T>::MatchAndExplain(
+    std::span<T> val, ::testing::MatchResultListener* listener) const {
+  if (val.size() != good.size() ||
+      !std::equal(val.begin(), val.end(), good.begin())) {
+    return false;
+  }
+  return true;
+}
+
+template <typename T>
+void SpanMatcher<T>::DescribeTo(::std::ostream* os) const {
+  PrintTo(std::span<T>{good}, os);
+}
+
+template <typename T>
+void SpanMatcher<T>::DescribeNegationTo(::std::ostream* os) const {
+  *os << "is not equal to ";
+  PrintTo(std::span<T>{good}, os);
+}
+
+}  // namespace wpi
+
+inline std::span<const uint8_t> operator"" _us(const char* str, size_t len) {
+  return {reinterpret_cast<const uint8_t*>(str), len};
+}
diff --git a/ntcore/src/test/native/cpp/StorageTest.cpp b/ntcore/src/test/native/cpp/StorageTest.cpp
deleted file mode 100644
index e1ee1c7..0000000
--- a/ntcore/src/test/native/cpp/StorageTest.cpp
+++ /dev/null
@@ -1,1003 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "StorageTest.h"
-
-#include <wpi/SmallString.h>
-#include <wpi/StringExtras.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 StorageEmptyTest : public StorageTest,
-                         public ::testing::TestWithParam<bool> {
- public:
-  StorageEmptyTest() {
-    HookOutgoing(GetParam());
-    EXPECT_CALL(notifier, local_notifiers())
-        .Times(AnyNumber())
-        .WillRepeatedly(Return(true));
-  }
-};
-
-class StoragePopulateOneTest : public StorageEmptyTest {
- public:
-  StoragePopulateOneTest() {
-    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 StoragePopulatedTest : public StorageEmptyTest {
- public:
-  StoragePopulatedTest() {
-    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 StoragePersistentTest : public StorageEmptyTest {
- public:
-  StoragePersistentTest() {
-    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(std::string_view("\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(std::string_view("\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(std::string_view("\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, std::string_view msg));
-};
-
-TEST_P(StorageEmptyTest, Construct) {
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, 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(StorageEmptyTest, GetEntryValueNotExist) {
-  EXPECT_FALSE(storage.GetEntryValue("foo"));
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, 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(StorageEmptyTest, 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, std::string_view("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(StoragePopulateOneTest, 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, std::string_view("foo"), value,
-                          NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL, UINT_MAX));
-
-  storage.SetEntryTypeValue("foo", value);
-  EXPECT_EQ(value, GetEntry("foo")->value);
-}
-
-TEST_P(StoragePopulateOneTest, 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(StoragePopulatedTest, 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, std::string_view("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(StorageEmptyTest, SetEntryTypeValueEmptyName) {
-  auto value = Value::MakeBoolean(true);
-  storage.SetEntryTypeValue("", value);
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, SetEntryTypeValueEmptyValue) {
-  storage.SetEntryTypeValue("foo", nullptr);
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, 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, std::string_view("foo"), value,
-                                    NT_NOTIFY_NEW | NT_NOTIFY_LOCAL, UINT_MAX));
-
-  EXPECT_TRUE(storage.SetEntryValue("foo", value));
-  EXPECT_EQ(value, GetEntry("foo")->value);
-}
-
-TEST_P(StoragePopulateOneTest, 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(StoragePopulateOneTest, 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(StoragePopulatedTest, 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, std::string_view("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(StorageEmptyTest, SetEntryValueEmptyName) {
-  auto value = Value::MakeBoolean(true);
-  EXPECT_TRUE(storage.SetEntryValue("", value));
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, SetEntryValueEmptyValue) {
-  EXPECT_TRUE(storage.SetEntryValue("foo", nullptr));
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, 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, std::string_view("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(StoragePopulateOneTest, 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(StoragePopulateOneTest, 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(StorageEmptyTest, 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(StorageEmptyTest, 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(StoragePopulatedTest, 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(StoragePopulatedTest, 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(StorageEmptyTest, SetEntryFlagsNew) {
-  // flags setting doesn't create an entry
-  storage.SetEntryFlags("foo", 0u);
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StoragePopulateOneTest, 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(StoragePopulatedTest, 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, std::string_view("foo2"), _,
-                          NT_NOTIFY_FLAGS | NT_NOTIFY_LOCAL, UINT_MAX));
-  storage.SetEntryFlags("foo2", 1u);
-  EXPECT_EQ(1u, GetEntry("foo2")->flags);
-}
-
-TEST_P(StorageEmptyTest, SetEntryFlagsEmptyName) {
-  storage.SetEntryFlags("", 0u);
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StorageEmptyTest, GetEntryFlagsNotExist) {
-  EXPECT_EQ(0u, storage.GetEntryFlags("foo"));
-  EXPECT_TRUE(entries().empty());
-  EXPECT_TRUE(idmap().empty());
-}
-
-TEST_P(StoragePopulateOneTest, 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(StorageEmptyTest, DeleteEntryNotExist) {
-  storage.DeleteEntry("foo");
-}
-
-TEST_P(StoragePopulatedTest, 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, std::string_view("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(StorageEmptyTest, DeleteAllEntriesEmpty) {
-  storage.DeleteAllEntries();
-  ASSERT_TRUE(entries().empty());
-}
-
-TEST_P(StoragePopulatedTest, 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(StoragePopulatedTest, 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(StoragePopulatedTest, GetEntryInfoAll) {
-  auto info = storage.GetEntryInfo(0, "", 0u);
-  ASSERT_EQ(4u, info.size());
-}
-
-TEST_P(StoragePopulatedTest, 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(StoragePopulatedTest, 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(StoragePopulatedTest, 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(StoragePersistentTest, 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(StoragePersistentTest, SavePersistent) {
-  for (auto& i : entries()) {
-    i.getValue()->flags = NT_PERSISTENT;
-  }
-  wpi::SmallString<256> buf;
-  wpi::raw_svector_ostream oss(buf);
-  storage.SavePersistent(oss, false);
-  std::string_view out = oss.str();
-  // std::fputs(out.c_str(), stderr);
-  std::string_view line, rem = out;
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("[NetworkTables Storage 3.0]", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("boolean \"\\x00\\x03\\x05\\n\"=true", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("boolean \"\\x3D\"=true", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("boolean \"boolean/false\"=false", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("boolean \"boolean/true\"=true", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array boolean \"booleanarr/empty\"=", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array boolean \"booleanarr/one\"=true", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array boolean \"booleanarr/two\"=true,false", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("double \"double/big\"=1.3e+08", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("double \"double/neg\"=-1.5", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("double \"double/zero\"=0", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array double \"doublearr/empty\"=", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array double \"doublearr/one\"=0.5", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array double \"doublearr/two\"=0.5,-0.25", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("raw \"raw/empty\"=", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("raw \"raw/normal\"=aGVsbG8=", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("raw \"raw/special\"=AAMFCg==", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("string \"string/empty\"=\"\"", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("string \"string/normal\"=\"hello\"", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("string \"string/quoted\"=\"\\\"a\\\"\"", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("string \"string/special\"=\"\\x00\\x03\\x05\\n\"", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array string \"stringarr/empty\"=", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array string \"stringarr/one\"=\"hello\"", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("array string \"stringarr/two\"=\"hello\",\"world\\n\"", line);
-  std::tie(line, rem) = wpi::split(rem, '\n');
-  ASSERT_EQ("", line);
-}
-
-TEST_P(StorageEmptyTest, 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, std::string_view("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, std::string_view("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(StorageEmptyTest, 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(StorageEmptyTest, 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(StorageEmptyTest, 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, std::string_view("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(StoragePopulatedTest, 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, std::string_view("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(StoragePopulatedTest, 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, std::string_view("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(StoragePopulatedTest, 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, std::string_view("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(StorageEmptyTest, 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(std::string_view("\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(std::string_view("\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(std::string_view("\0\3\5\n", 4)));
-  EXPECT_EQ(*Value::MakeBoolean(true), *storage.GetEntryValue("="));
-}
-
-TEST_P(StorageEmptyTest, 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, std::string_view(
-                        "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(StorageEmptyTest, 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, std::string_view("foo"), ValueEq(value),
-                                    NT_NOTIFY_NEW, UINT_MAX));
-
-  storage.ProcessIncoming(
-      Message::EntryAssign("foo", GetParam() ? 0xffff : 0, 0, value, 0),
-      conn.get(), conn);
-}
-
-TEST_P(StoragePopulateOneTest, 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, std::string_view("foo"), ValueEq(value),
-                                    NT_NOTIFY_UPDATE, UINT_MAX));
-
-  storage.ProcessIncoming(Message::EntryAssign("foo", 0, 1, value, 0),
-                          conn.get(), conn);
-}
-
-TEST_P(StoragePopulateOneTest, 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(StoragePopulateOneTest, 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, std::string_view("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, std::string_view("foo"), ValueEq(value),
-                            NT_NOTIFY_UPDATE, UINT_MAX));
-  }
-
-  storage.ProcessIncoming(Message::EntryAssign("foo", 0, 1, value, 0x2),
-                          conn.get(), conn);
-}
-
-TEST_P(StoragePopulateOneTest, 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(StoragePopulateOneTest, 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(StoragePopulateOneTest, 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(StoragePopulateOneTest, 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(StorageEmptyTests, StorageEmptyTest,
-                         ::testing::Bool());
-INSTANTIATE_TEST_SUITE_P(StoragePopulateOneTests, StoragePopulateOneTest,
-                         ::testing::Bool());
-INSTANTIATE_TEST_SUITE_P(StoragePopulatedTests, StoragePopulatedTest,
-                         ::testing::Bool());
-INSTANTIATE_TEST_SUITE_P(StoragePersistentTests, StoragePersistentTest,
-                         ::testing::Bool());
-
-}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/StorageTest.h b/ntcore/src/test/native/cpp/StorageTest.h
index 3a1755f..a0cc737 100644
--- a/ntcore/src/test/native/cpp/StorageTest.h
+++ b/ntcore/src/test/native/cpp/StorageTest.h
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_STORAGETEST_H_
-#define NTCORE_STORAGETEST_H_
+#pragma once
 
 #include <functional>
 #include <memory>
@@ -11,15 +10,13 @@
 
 #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") {}
+  StorageTest() : storage(logger), tmp_entry("foobar") {}
 
   Storage::EntriesMap& entries() { return storage.m_entries; }
   Storage::IdMap& idmap() { return storage.m_idmap; }
@@ -32,13 +29,9 @@
   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/TableListenerTest.cpp b/ntcore/src/test/native/cpp/TableListenerTest.cpp
new file mode 100644
index 0000000..7fb1947
--- /dev/null
+++ b/ntcore/src/test/native/cpp/TableListenerTest.cpp
@@ -0,0 +1,60 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <memory>
+
+#include "TestPrinters.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "networktables/DoubleTopic.h"
+#include "networktables/NetworkTableInstance.h"
+#include "ntcore_cpp.h"
+
+using ::testing::_;
+
+using MockTableEventListener = testing::MockFunction<void(
+    nt::NetworkTable* table, std::string_view key, const nt::Event& event)>;
+using MockSubTableListener =
+    testing::MockFunction<void(nt::NetworkTable* parent, std::string_view name,
+                               std::shared_ptr<nt::NetworkTable> table)>;
+
+class TableListenerTest : public ::testing::Test {
+ public:
+  TableListenerTest() : m_inst(nt::NetworkTableInstance::Create()) {}
+
+  ~TableListenerTest() override { nt::NetworkTableInstance::Destroy(m_inst); }
+
+  void PublishTopics();
+
+ protected:
+  nt::NetworkTableInstance m_inst;
+  nt::DoublePublisher m_foovalue;
+  nt::DoublePublisher m_barvalue;
+  nt::DoublePublisher m_bazvalue;
+};
+
+void TableListenerTest::PublishTopics() {
+  m_foovalue = m_inst.GetDoubleTopic("/foo/foovalue").Publish();
+  m_barvalue = m_inst.GetDoubleTopic("/foo/bar/barvalue").Publish();
+  m_bazvalue = m_inst.GetDoubleTopic("/baz/bazvalue").Publish();
+}
+
+TEST_F(TableListenerTest, AddListener) {
+  auto table = m_inst.GetTable("/foo");
+  MockTableEventListener listener;
+  table->AddListener(NT_EVENT_TOPIC | NT_EVENT_IMMEDIATE,
+                     listener.AsStdFunction());
+  EXPECT_CALL(listener, Call(table.get(), "foovalue", _));
+  PublishTopics();
+  EXPECT_TRUE(m_inst.WaitForListenerQueue(1.0));
+}
+
+TEST_F(TableListenerTest, AddSubTableListener) {
+  auto table = m_inst.GetTable("/foo");
+  MockSubTableListener listener;
+  table->AddSubTableListener(listener.AsStdFunction());
+  EXPECT_CALL(listener, Call(table.get(), "bar", _));
+  PublishTopics();
+  EXPECT_TRUE(m_inst.WaitForListenerQueue(1.0));
+}
diff --git a/ntcore/src/test/native/cpp/TestPrinters.cpp b/ntcore/src/test/native/cpp/TestPrinters.cpp
index 49b407b..66afe4e 100644
--- a/ntcore/src/test/native/cpp/TestPrinters.cpp
+++ b/ntcore/src/test/native/cpp/TestPrinters.cpp
@@ -4,55 +4,56 @@
 
 #include "TestPrinters.h"
 
+#include <wpi/json.h>
+
 #include "Handle.h"
-#include "Message.h"
+#include "PubSubOptions.h"
+#include "net/Message.h"
+#include "net3/Message3.h"
 #include "networktables/NetworkTableValue.h"
 #include "ntcore_cpp.h"
 
+namespace wpi {
+void PrintTo(const json& val, ::std::ostream* os) {
+  *os << val.dump();
+}
+}  // namespace wpi
+
 namespace nt {
 
-void PrintTo(const EntryNotification& event, std::ostream* os) {
-  *os << "EntryNotification{listener=";
+void PrintTo(const Event& event, std::ostream* os) {
+  *os << "Event{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 << ", flags=" << event.flags;
+  // *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";
+    case Handle::kListener:
+      *os << "kListener";
       break;
-    case Handle::kConnectionListenerPoller:
-      *os << "kConnectionListenerPoller";
+    case Handle::kListenerPoller:
+      *os << "kListenerPoller";
       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";
+    case Handle::kTopic:
+      *os << "kTopic";
       break;
-    case Handle::kLoggerPoller:
-      *os << "kLoggerPoller";
+    case Handle::kSubscriber:
+      *os << "kSubscriber";
       break;
-    case Handle::kRpcCall:
-      *os << "kRpcCall";
-      break;
-    case Handle::kRpcCallPoller:
-      *os << "kRpcCallPoller";
+    case Handle::kPublisher:
+      *os << "kPublisher";
       break;
     default:
       *os << "UNKNOWN";
@@ -61,46 +62,46 @@
   *os << ", " << handle.GetInst() << ", " << handle.GetIndex() << '}';
 }
 
-void PrintTo(const Message& msg, std::ostream* os) {
+void PrintTo(const net3::Message3& msg, std::ostream* os) {
   *os << "Message{";
   switch (msg.type()) {
-    case Message::kKeepAlive:
+    case net3::Message3::kKeepAlive:
       *os << "kKeepAlive";
       break;
-    case Message::kClientHello:
+    case net3::Message3::kClientHello:
       *os << "kClientHello";
       break;
-    case Message::kProtoUnsup:
+    case net3::Message3::kProtoUnsup:
       *os << "kProtoUnsup";
       break;
-    case Message::kServerHelloDone:
+    case net3::Message3::kServerHelloDone:
       *os << "kServerHelloDone";
       break;
-    case Message::kServerHello:
+    case net3::Message3::kServerHello:
       *os << "kServerHello";
       break;
-    case Message::kClientHelloDone:
+    case net3::Message3::kClientHelloDone:
       *os << "kClientHelloDone";
       break;
-    case Message::kEntryAssign:
+    case net3::Message3::kEntryAssign:
       *os << "kEntryAssign";
       break;
-    case Message::kEntryUpdate:
+    case net3::Message3::kEntryUpdate:
       *os << "kEntryUpdate";
       break;
-    case Message::kFlagsUpdate:
+    case net3::Message3::kFlagsUpdate:
       *os << "kFlagsUpdate";
       break;
-    case Message::kEntryDelete:
+    case net3::Message3::kEntryDelete:
       *os << "kEntryDelete";
       break;
-    case Message::kClearEntries:
+    case net3::Message3::kClearEntries:
       *os << "kClearEntries";
       break;
-    case Message::kExecuteRpc:
+    case net3::Message3::kExecuteRpc:
       *os << "kExecuteRpc";
       break;
-    case Message::kRpcResponse:
+    case net3::Message3::kRpcResponse:
       *os << "kRpcResponse";
       break;
     default:
@@ -120,28 +121,37 @@
     case NT_UNASSIGNED:
       break;
     case NT_BOOLEAN:
-      *os << (value.GetBoolean() ? "true" : "false");
+      *os << "boolean, " << (value.GetBoolean() ? "true" : "false");
       break;
     case NT_DOUBLE:
-      *os << value.GetDouble();
+      *os << "double, " << value.GetDouble();
+      break;
+    case NT_FLOAT:
+      *os << "float, " << value.GetFloat();
+      break;
+    case NT_INTEGER:
+      *os << "int, " << value.GetInteger();
       break;
     case NT_STRING:
-      *os << '"' << value.GetString() << '"';
+      *os << "string, \"" << value.GetString() << '"';
       break;
     case NT_RAW:
-      *os << ::testing::PrintToString(value.GetRaw());
+      *os << "raw, " << ::testing::PrintToString(value.GetRaw());
       break;
     case NT_BOOLEAN_ARRAY:
-      *os << ::testing::PrintToString(value.GetBooleanArray());
+      *os << "boolean[], " << ::testing::PrintToString(value.GetBooleanArray());
       break;
     case NT_DOUBLE_ARRAY:
-      *os << ::testing::PrintToString(value.GetDoubleArray());
+      *os << "double[], " << ::testing::PrintToString(value.GetDoubleArray());
+      break;
+    case NT_FLOAT_ARRAY:
+      *os << "float[], " << ::testing::PrintToString(value.GetFloatArray());
+      break;
+    case NT_INTEGER_ARRAY:
+      *os << "int[], " << ::testing::PrintToString(value.GetIntegerArray());
       break;
     case NT_STRING_ARRAY:
-      *os << ::testing::PrintToString(value.GetStringArray());
-      break;
-    case NT_RPC:
-      *os << ::testing::PrintToString(value.GetRpc());
+      *os << "string[], " << ::testing::PrintToString(value.GetStringArray());
       break;
     default:
       *os << "UNKNOWN TYPE " << value.type();
@@ -150,4 +160,11 @@
   *os << '}';
 }
 
+void PrintTo(const PubSubOptionsImpl& options, std::ostream* os) {
+  *os << "PubSubOptions{periodicMs=" << options.periodicMs
+      << ", pollStorage=" << options.pollStorage
+      << ", sendAll=" << options.sendAll
+      << ", keepDuplicates=" << options.keepDuplicates << '}';
+}
+
 }  // namespace nt
diff --git a/ntcore/src/test/native/cpp/TestPrinters.h b/ntcore/src/test/native/cpp/TestPrinters.h
index 47c9eb4..2b8f1da 100644
--- a/ntcore/src/test/native/cpp/TestPrinters.h
+++ b/ntcore/src/test/native/cpp/TestPrinters.h
@@ -2,11 +2,10 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_TESTPRINTERS_H_
-#define NTCORE_TESTPRINTERS_H_
+#pragma once
 
-#include <memory>
 #include <ostream>
+#include <span>
 #include <string>
 #include <string_view>
 
@@ -14,42 +13,53 @@
 
 namespace wpi {
 
+class json;
+
 inline void PrintTo(std::string_view str, ::std::ostream* os) {
   ::testing::internal::PrintStringTo(std::string{str}, os);
 }
 
+template <typename T>
+void PrintTo(std::span<T> val, ::std::ostream* os) {
+  *os << '{';
+  bool first = true;
+  for (auto v : val) {
+    if (first) {
+      first = false;
+    } else {
+      *os << ", ";
+    }
+    *os << ::testing::PrintToString(v);
+  }
+  *os << '}';
+}
+
+void PrintTo(const json& val, ::std::ostream* os);
+
 }  // namespace wpi
 
 namespace nt {
 
-class EntryNotification;
+namespace net3 {
+class Message3;
+}  // namespace net3
+
+namespace net {
+struct ClientMessage;
+struct ServerMessage;
+}  // namespace net
+
+class Event;
 class Handle;
-class Message;
+class PubSubOptionsImpl;
 class Value;
 
-void PrintTo(const EntryNotification& event, std::ostream* os);
+void PrintTo(const Event& 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 net3::Message3& msg, std::ostream* os);
+void PrintTo(const net::ClientMessage& msg, std::ostream* os);
+void PrintTo(const net::ServerMessage& msg, std::ostream* 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 << '}';
-}
+void PrintTo(const PubSubOptionsImpl& options, std::ostream* os);
 
 }  // namespace nt
-
-#endif  // NTCORE_TESTPRINTERS_H_
diff --git a/ntcore/src/test/native/cpp/TimeSyncTest.cpp b/ntcore/src/test/native/cpp/TimeSyncTest.cpp
new file mode 100644
index 0000000..54e1f7c
--- /dev/null
+++ b/ntcore/src/test/native/cpp/TimeSyncTest.cpp
@@ -0,0 +1,70 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "gtest/gtest.h"
+#include "networktables/NetworkTableInstance.h"
+#include "networktables/NetworkTableListener.h"
+
+class TimeSyncTest : public ::testing::Test {
+ public:
+  TimeSyncTest() : m_inst(nt::NetworkTableInstance::Create()) {}
+
+  ~TimeSyncTest() override { nt::NetworkTableInstance::Destroy(m_inst); }
+
+ protected:
+  nt::NetworkTableInstance m_inst;
+};
+
+TEST_F(TimeSyncTest, TestLocal) {
+  auto offset = m_inst.GetServerTimeOffset();
+  ASSERT_FALSE(offset);
+}
+
+TEST_F(TimeSyncTest, TestServer) {
+  nt::NetworkTableListenerPoller poller{m_inst};
+  poller.AddTimeSyncListener(false);
+
+  m_inst.StartServer("timesynctest.json", "127.0.0.1", 0, 10030);
+  auto offset = m_inst.GetServerTimeOffset();
+  ASSERT_TRUE(offset);
+  ASSERT_EQ(0, *offset);
+
+  auto events = poller.ReadQueue();
+  ASSERT_EQ(1u, events.size());
+  auto data = events[0].GetTimeSyncEventData();
+  ASSERT_TRUE(data);
+  ASSERT_TRUE(data->valid);
+  ASSERT_EQ(0, data->serverTimeOffset);
+  ASSERT_EQ(0, data->rtt2);
+
+  m_inst.StopServer();
+  offset = m_inst.GetServerTimeOffset();
+  ASSERT_FALSE(offset);
+
+  events = poller.ReadQueue();
+  ASSERT_EQ(1u, events.size());
+  data = events[0].GetTimeSyncEventData();
+  ASSERT_TRUE(data);
+  ASSERT_FALSE(data->valid);
+}
+
+TEST_F(TimeSyncTest, TestClient3) {
+  m_inst.StartClient3("client");
+  auto offset = m_inst.GetServerTimeOffset();
+  ASSERT_FALSE(offset);
+
+  m_inst.StopClient();
+  offset = m_inst.GetServerTimeOffset();
+  ASSERT_FALSE(offset);
+}
+
+TEST_F(TimeSyncTest, TestClient4) {
+  m_inst.StartClient4("client");
+  auto offset = m_inst.GetServerTimeOffset();
+  ASSERT_FALSE(offset);
+
+  m_inst.StopClient();
+  offset = m_inst.GetServerTimeOffset();
+  ASSERT_FALSE(offset);
+}
diff --git a/ntcore/src/test/native/cpp/TopicListenerTest.cpp b/ntcore/src/test/native/cpp/TopicListenerTest.cpp
new file mode 100644
index 0000000..f0a002a
--- /dev/null
+++ b/ntcore/src/test/native/cpp/TopicListenerTest.cpp
@@ -0,0 +1,285 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <chrono>
+#include <thread>
+
+#include <wpi/Synchronization.h>
+#include <wpi/json.h>
+
+#include "TestPrinters.h"
+#include "ValueMatcher.h"
+#include "gtest/gtest.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+class TopicListenerTest : public ::testing::Test {
+ public:
+  TopicListenerTest()
+      : m_serverInst(nt::CreateInstance()), m_clientInst(nt::CreateInstance()) {
+#if 0
+    nt::AddLogger(m_serverInst, 0, UINT_MAX, [](auto& event) {
+      if (auto msg = event.GetLogMessage()) {
+        std::fprintf(stderr, "SERVER: %s\n", msg->message.c_str());
+      }
+    });
+    nt::AddLogger(m_clientInst, 0, UINT_MAX, [](auto& event) {
+      if (auto msg = event.GetLogMessage()) {
+        std::fprintf(stderr, "CLIENT: %s\n", msg.message.c_str());
+      }
+    });
+#endif
+  }
+
+  ~TopicListenerTest() override {
+    nt::DestroyInstance(m_serverInst);
+    nt::DestroyInstance(m_clientInst);
+  }
+
+  void Connect(unsigned int port);
+  static void PublishTopics(NT_Inst inst);
+  void CheckEvents(const std::vector<nt::Event>& events, NT_Listener handle,
+                   unsigned int flags, std::string_view topicName = "/foo/bar");
+
+ protected:
+  NT_Inst m_serverInst;
+  NT_Inst m_clientInst;
+};
+
+void TopicListenerTest::Connect(unsigned int port) {
+  nt::StartServer(m_serverInst, "topiclistenertest.json", "127.0.0.1", 0, port);
+  nt::StartClient4(m_clientInst, "client");
+  nt::SetServer(m_clientInst, "127.0.0.1", port);
+
+  // Use connection listener to ensure we've connected
+  NT_ListenerPoller poller = nt::CreateListenerPoller(m_clientInst);
+  nt::AddPolledListener(poller, m_clientInst, nt::EventFlags::kConnected);
+  bool timedOut = false;
+  if (!wpi::WaitForObject(poller, 1.0, &timedOut)) {
+    FAIL() << "client didn't connect to server";
+  }
+}
+
+void TopicListenerTest::PublishTopics(NT_Inst inst) {
+  nt::Publish(nt::GetTopic(inst, "/foo/bar"), NT_DOUBLE, "double");
+  nt::Publish(nt::GetTopic(inst, "/foo"), NT_DOUBLE, "double");
+  nt::Publish(nt::GetTopic(inst, "/baz"), NT_DOUBLE, "double");
+}
+
+void TopicListenerTest::CheckEvents(const std::vector<nt::Event>& events,
+                                    NT_Listener handle, unsigned int flags,
+                                    std::string_view topicName) {
+  ASSERT_EQ(events.size(), 1u);
+  ASSERT_EQ(events[0].listener, handle);
+  ASSERT_EQ(events[0].flags, flags);
+  auto topicInfo = events[0].GetTopicInfo();
+  ASSERT_TRUE(topicInfo);
+  ASSERT_EQ(topicInfo->topic, nt::GetTopic(m_serverInst, topicName));
+  ASSERT_EQ(topicInfo->name, topicName);
+}
+
+TEST_F(TopicListenerTest, TopicNewLocal) {
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle = nt::AddPolledListener(
+      poller, nt::GetTopic(m_serverInst, "/foo"), nt::EventFlags::kPublish);
+
+  PublishTopics(m_serverInst);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kPublish, "/foo");
+}
+
+TEST_F(TopicListenerTest, DISABLED_TopicNewRemote) {
+  Connect(10010);
+  if (HasFatalFailure()) {
+    return;
+  }
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle = nt::AddPolledListener(
+      poller, nt::GetTopic(m_serverInst, "/foo"), nt::EventFlags::kPublish);
+
+  PublishTopics(m_clientInst);
+
+  nt::Flush(m_clientInst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kPublish, "/foo");
+}
+
+TEST_F(TopicListenerTest, TopicPublishImm) {
+  PublishTopics(m_serverInst);
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle = nt::AddPolledListener(
+      poller, nt::GetTopic(m_serverInst, "/foo"),
+      nt::EventFlags::kPublish | nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle,
+              nt::EventFlags::kPublish | nt::EventFlags::kImmediate, "/foo");
+}
+
+TEST_F(TopicListenerTest, TopicUnpublishPropsImm) {
+  PublishTopics(m_serverInst);
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  nt::AddPolledListener(poller, nt::GetTopic(m_serverInst, "/foo"),
+                        nt::EventFlags::kUnpublish |
+                            nt::EventFlags::kProperties |
+                            nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_FALSE(wpi::WaitForObject(poller, 0.02, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  ASSERT_TRUE(events.empty());
+}
+
+TEST_F(TopicListenerTest, TopicUnpublishLocal) {
+  auto topic = nt::GetTopic(m_serverInst, "/foo");
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle =
+      nt::AddPolledListener(poller, topic, nt::EventFlags::kUnpublish);
+
+  auto pub = nt::Publish(topic, NT_DOUBLE, "double");
+  nt::Unpublish(pub);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kUnpublish, "/foo");
+}
+
+TEST_F(TopicListenerTest, DISABLED_TopicUnpublishRemote) {
+  Connect(10010);
+  if (HasFatalFailure()) {
+    return;
+  }
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle = nt::AddPolledListener(
+      poller, nt::GetTopic(m_serverInst, "/foo"), nt::EventFlags::kUnpublish);
+
+  auto pub =
+      nt::Publish(nt::GetTopic(m_clientInst, "/foo"), NT_DOUBLE, "double");
+  nt::Flush(m_clientInst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  nt::Unpublish(pub);
+
+  nt::Flush(m_clientInst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kUnpublish, "/foo");
+}
+
+TEST_F(TopicListenerTest, TopicPropertiesLocal) {
+  auto topic = nt::GetTopic(m_serverInst, "/foo");
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle =
+      nt::AddPolledListener(poller, topic, nt::EventFlags::kProperties);
+
+  nt::SetTopicProperty(topic, "foo", 5);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kProperties, "/foo");
+}
+
+TEST_F(TopicListenerTest, DISABLED_TopicPropertiesRemote) {
+  Connect(10010);
+  if (HasFatalFailure()) {
+    return;
+  }
+  // the topic needs to actually exist
+  nt::Publish(nt::GetTopic(m_serverInst, "/foo"), NT_BOOLEAN, "boolean");
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle = nt::AddPolledListener(
+      poller, nt::GetTopic(m_serverInst, "/foo"), nt::EventFlags::kProperties);
+  nt::FlushLocal(m_serverInst);
+
+  nt::SetTopicProperty(nt::GetTopic(m_clientInst, "/foo"), "foo", 5);
+  nt::Flush(m_clientInst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kProperties, "/foo");
+}
+
+TEST_F(TopicListenerTest, PrefixPublishLocal) {
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle =
+      nt::AddPolledListener(poller, {{"/foo/"}}, nt::EventFlags::kPublish);
+
+  PublishTopics(m_serverInst);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kPublish);
+}
+
+TEST_F(TopicListenerTest, DISABLED_PrefixPublishRemote) {
+  Connect(10011);
+  if (HasFatalFailure()) {
+    return;
+  }
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle =
+      nt::AddPolledListener(poller, {{"/foo/"}}, nt::EventFlags::kPublish);
+
+  PublishTopics(m_clientInst);
+
+  nt::Flush(m_clientInst);
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle, nt::EventFlags::kPublish);
+}
+
+TEST_F(TopicListenerTest, PrefixPublishImm) {
+  PublishTopics(m_serverInst);
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  auto handle = nt::AddPolledListener(
+      poller, {{"/foo/"}},
+      nt::EventFlags::kPublish | nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  CheckEvents(events, handle,
+              nt::EventFlags::kPublish | nt::EventFlags::kImmediate);
+}
+
+TEST_F(TopicListenerTest, PrefixUnpublishPropsImm) {
+  PublishTopics(m_serverInst);
+
+  auto poller = nt::CreateListenerPoller(m_serverInst);
+  nt::AddPolledListener(poller, {{"/foo/"}},
+                        nt::EventFlags::kUnpublish |
+                            nt::EventFlags::kProperties |
+                            nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_FALSE(wpi::WaitForObject(poller, 0.02, &timedOut));
+  auto events = nt::ReadListenerQueue(poller);
+  ASSERT_TRUE(events.empty());
+}
diff --git a/ntcore/src/test/native/cpp/ValueListenerTest.cpp b/ntcore/src/test/native/cpp/ValueListenerTest.cpp
new file mode 100644
index 0000000..dbe3201
--- /dev/null
+++ b/ntcore/src/test/native/cpp/ValueListenerTest.cpp
@@ -0,0 +1,409 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <wpi/StringExtras.h>
+#include <wpi/Synchronization.h>
+
+#include "TestPrinters.h"
+#include "ValueMatcher.h"
+#include "gtest/gtest.h"
+#include "ntcore_c.h"
+#include "ntcore_cpp.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::IsNull;
+using ::testing::Return;
+
+namespace nt {
+
+// Test only local here; it's more reliable to mock the network
+class ValueListenerTest : public ::testing::Test {
+ public:
+  ValueListenerTest() : m_inst{nt::CreateInstance()} {}
+
+  ~ValueListenerTest() override { nt::DestroyInstance(m_inst); }
+
+ protected:
+  NT_Inst m_inst;
+};
+
+TEST_F(ValueListenerTest, MultiPollSub) {
+  auto topic = nt::GetTopic(m_inst, "foo");
+  auto pub = nt::Publish(topic, NT_DOUBLE, "double");
+  auto sub = nt::Subscribe(topic, NT_DOUBLE, "double");
+
+  auto poller1 = nt::CreateListenerPoller(m_inst);
+  auto poller2 = nt::CreateListenerPoller(m_inst);
+  auto poller3 = nt::CreateListenerPoller(m_inst);
+  auto h1 = nt::AddPolledListener(poller1, sub, nt::EventFlags::kValueLocal);
+  auto h2 = nt::AddPolledListener(poller2, sub, nt::EventFlags::kValueLocal);
+  auto h3 = nt::AddPolledListener(poller3, sub, nt::EventFlags::kValueLocal);
+
+  nt::SetDouble(pub, 0);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller1, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  ASSERT_TRUE(wpi::WaitForObject(poller2, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  ASSERT_TRUE(wpi::WaitForObject(poller3, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results1 = nt::ReadListenerQueue(poller1);
+  auto results2 = nt::ReadListenerQueue(poller2);
+  auto results3 = nt::ReadListenerQueue(poller3);
+
+  ASSERT_EQ(results1.size(), 1u);
+  EXPECT_EQ(results1[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results1[0].listener, h1);
+  auto valueData = results1[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  ASSERT_EQ(results2.size(), 1u);
+  EXPECT_EQ(results2[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results2[0].listener, h2);
+  valueData = results2[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  ASSERT_EQ(results3.size(), 1u);
+  EXPECT_EQ(results3[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results3[0].listener, h3);
+  valueData = results3[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+TEST_F(ValueListenerTest, PollMultiSub) {
+  auto topic = nt::GetTopic(m_inst, "foo");
+  auto pub = nt::Publish(topic, NT_DOUBLE, "double");
+  auto sub1 = nt::Subscribe(topic, NT_DOUBLE, "double");
+  auto sub2 = nt::Subscribe(topic, NT_DOUBLE, "double");
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h1 = nt::AddPolledListener(poller, sub1, nt::EventFlags::kValueLocal);
+  auto h2 = nt::AddPolledListener(poller, sub2, nt::EventFlags::kValueLocal);
+
+  nt::SetDouble(pub, 0);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 2u);
+  EXPECT_EQ(results[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h1);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub1);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  EXPECT_EQ(results[1].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[1].listener, h2);
+  valueData = results[1].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub2);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+TEST_F(ValueListenerTest, PollMultiSubTopic) {
+  auto topic1 = nt::GetTopic(m_inst, "foo");
+  auto topic2 = nt::GetTopic(m_inst, "bar");
+  auto pub1 = nt::Publish(topic1, NT_DOUBLE, "double");
+  auto pub2 = nt::Publish(topic2, NT_DOUBLE, "double");
+  auto sub1 = nt::Subscribe(topic1, NT_DOUBLE, "double");
+  auto sub2 = nt::Subscribe(topic2, NT_DOUBLE, "double");
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h1 = nt::AddPolledListener(poller, sub1, nt::EventFlags::kValueLocal);
+  auto h2 = nt::AddPolledListener(poller, sub2, nt::EventFlags::kValueLocal);
+
+  nt::SetDouble(pub1, 0);
+  nt::SetDouble(pub2, 1);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 2u);
+  EXPECT_EQ(results[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h1);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub1);
+  EXPECT_EQ(valueData->topic, topic1);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  EXPECT_EQ(results[1].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[1].listener, h2);
+  valueData = results[1].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub2);
+  EXPECT_EQ(valueData->topic, topic2);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(1.0));
+}
+
+TEST_F(ValueListenerTest, PollSubMultiple) {
+  auto topic1 = nt::GetTopic(m_inst, "foo/1");
+  auto topic2 = nt::GetTopic(m_inst, "foo/2");
+  auto pub1 = nt::Publish(topic1, NT_DOUBLE, "double");
+  auto pub2 = nt::Publish(topic2, NT_DOUBLE, "double");
+  auto sub = nt::SubscribeMultiple(m_inst, {{"foo"}});
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(poller, sub, nt::EventFlags::kValueLocal);
+
+  nt::SetDouble(pub1, 0);
+  nt::SetDouble(pub2, 1);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 2u);
+  EXPECT_EQ(results[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic1);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  EXPECT_EQ(results[1].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[1].listener, h);
+  valueData = results[1].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic2);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(1.0));
+}
+
+TEST_F(ValueListenerTest, PollSubPrefixCreated) {
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h =
+      nt::AddPolledListener(poller, {{"foo"}}, nt::EventFlags::kValueLocal);
+
+  auto topic1 = nt::GetTopic(m_inst, "foo/1");
+  auto topic2 = nt::GetTopic(m_inst, "foo/2");
+  auto topic3 = nt::GetTopic(m_inst, "bar/3");
+  auto pub1 = nt::Publish(topic1, NT_DOUBLE, "double");
+  auto pub2 = nt::Publish(topic2, NT_DOUBLE, "double");
+  auto pub3 = nt::Publish(topic3, NT_DOUBLE, "double");
+
+  nt::SetDouble(pub1, 0);
+  nt::SetDouble(pub2, 1);
+  nt::SetDouble(pub3, 1);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 2u);
+  EXPECT_EQ(results[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->topic, topic1);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  EXPECT_EQ(results[1].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[1].listener, h);
+  valueData = results[1].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->topic, topic2);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(1.0));
+}
+
+TEST_F(ValueListenerTest, PollEntry) {
+  auto entry = nt::GetEntry(m_inst, "foo");
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(poller, entry, nt::EventFlags::kValueLocal);
+
+  ASSERT_TRUE(nt::SetDouble(entry, 0));
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 1u);
+  EXPECT_EQ(results[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, entry);
+  EXPECT_EQ(valueData->topic, nt::GetTopic(m_inst, "foo"));
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+TEST_F(ValueListenerTest, PollImmediate) {
+  auto entry = nt::GetEntry(m_inst, "foo");
+  ASSERT_TRUE(nt::SetDouble(entry, 0));
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(
+      poller, entry, nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 1u);
+  EXPECT_EQ(results[0].flags &
+                (nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate),
+            nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, entry);
+  EXPECT_EQ(valueData->topic, nt::GetTopic(m_inst, "foo"));
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+TEST_F(ValueListenerTest, PollImmediateNoValue) {
+  auto entry = nt::GetEntry(m_inst, "foo");
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(
+      poller, entry, nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_FALSE(wpi::WaitForObject(poller, 0.02, &timedOut));
+  ASSERT_TRUE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+  ASSERT_TRUE(results.empty());
+
+  // now set a value
+  ASSERT_TRUE(nt::SetDouble(entry, 0));
+
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  results = nt::ReadListenerQueue(poller);
+  ASSERT_FALSE(timedOut);
+
+  ASSERT_EQ(results.size(), 1u);
+  EXPECT_EQ(results[0].flags, nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, entry);
+  EXPECT_EQ(valueData->topic, nt::GetTopic(m_inst, "foo"));
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+TEST_F(ValueListenerTest, PollImmediateSubMultiple) {
+  auto topic1 = nt::GetTopic(m_inst, "foo/1");
+  auto topic2 = nt::GetTopic(m_inst, "foo/2");
+  auto pub1 = nt::Publish(topic1, NT_DOUBLE, "double");
+  auto pub2 = nt::Publish(topic2, NT_DOUBLE, "double");
+  auto sub = nt::SubscribeMultiple(m_inst, {{"foo"}});
+  nt::SetDouble(pub1, 0);
+  nt::SetDouble(pub2, 1);
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(
+      poller, sub, nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 2u);
+  EXPECT_EQ(results[0].flags &
+                (nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate),
+            nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic1);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+
+  EXPECT_EQ(results[1].flags &
+                (nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate),
+            nt::EventFlags::kValueLocal | nt::EventFlags::kImmediate);
+  EXPECT_EQ(results[1].listener, h);
+  valueData = results[1].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub);
+  EXPECT_EQ(valueData->topic, topic2);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(1.0));
+}
+
+TEST_F(ValueListenerTest, TwoSubOneListener) {
+  auto topic = nt::GetTopic(m_inst, "foo");
+  auto pub = nt::Publish(topic, NT_DOUBLE, "double");
+  auto sub1 = nt::Subscribe(topic, NT_DOUBLE, "double");
+  auto sub2 = nt::Subscribe(topic, NT_DOUBLE, "double");
+  auto sub3 = nt::SubscribeMultiple(m_inst, {{"foo"}});
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(poller, sub1, nt::EventFlags::kValueLocal);
+  (void)sub2;
+  (void)sub3;
+
+  nt::SetDouble(pub, 0);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 1u);
+  EXPECT_EQ(results[0].flags & nt::EventFlags::kValueLocal,
+            nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub1);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+TEST_F(ValueListenerTest, TwoSubOneMultiListener) {
+  auto topic = nt::GetTopic(m_inst, "foo");
+  auto pub = nt::Publish(topic, NT_DOUBLE, "double");
+  auto sub1 = nt::Subscribe(topic, NT_DOUBLE, "double");
+  auto sub2 = nt::Subscribe(topic, NT_DOUBLE, "double");
+  auto sub3 = nt::SubscribeMultiple(m_inst, {{"foo"}});
+
+  auto poller = nt::CreateListenerPoller(m_inst);
+  auto h = nt::AddPolledListener(poller, sub3, nt::EventFlags::kValueLocal);
+  (void)sub1;
+  (void)sub2;
+
+  nt::SetDouble(pub, 0);
+
+  bool timedOut = false;
+  ASSERT_TRUE(wpi::WaitForObject(poller, 1.0, &timedOut));
+  ASSERT_FALSE(timedOut);
+  auto results = nt::ReadListenerQueue(poller);
+
+  ASSERT_EQ(results.size(), 1u);
+  EXPECT_EQ(results[0].flags & nt::EventFlags::kValueLocal,
+            nt::EventFlags::kValueLocal);
+  EXPECT_EQ(results[0].listener, h);
+  auto valueData = results[0].GetValueEventData();
+  ASSERT_TRUE(valueData);
+  EXPECT_EQ(valueData->subentry, sub3);
+  EXPECT_EQ(valueData->topic, topic);
+  EXPECT_EQ(valueData->value, nt::Value::MakeDouble(0.0));
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/ValueMatcher.cpp b/ntcore/src/test/native/cpp/ValueMatcher.cpp
index 1f55c01..7a0d453 100644
--- a/ntcore/src/test/native/cpp/ValueMatcher.cpp
+++ b/ntcore/src/test/native/cpp/ValueMatcher.cpp
@@ -9,10 +9,9 @@
 namespace nt {
 
 bool ValueMatcher::MatchAndExplain(
-    std::shared_ptr<Value> val,
-    ::testing::MatchResultListener* listener) const {
+    Value val, ::testing::MatchResultListener* listener) const {
   if ((!val && goodval) || (val && !goodval) ||
-      (val && goodval && *val != *goodval)) {
+      (val && goodval && val != goodval)) {
     return false;
   }
   return true;
diff --git a/ntcore/src/test/native/cpp/ValueMatcher.h b/ntcore/src/test/native/cpp/ValueMatcher.h
index ab68448..c77e04d 100644
--- a/ntcore/src/test/native/cpp/ValueMatcher.h
+++ b/ntcore/src/test/native/cpp/ValueMatcher.h
@@ -2,8 +2,7 @@
 // Open Source Software; you can modify and/or share it under the terms of
 // the WPILib BSD license file in the root directory of this project.
 
-#ifndef NTCORE_VALUEMATCHER_H_
-#define NTCORE_VALUEMATCHER_H_
+#pragma once
 
 #include <memory>
 #include <ostream>
@@ -14,26 +13,21 @@
 
 namespace nt {
 
-class ValueMatcher
-    : public ::testing::MatcherInterface<std::shared_ptr<Value>> {
+class ValueMatcher : public ::testing::MatcherInterface<Value> {
  public:
-  explicit ValueMatcher(std::shared_ptr<Value> goodval_)
-      : goodval(std::move(goodval_)) {}
+  explicit ValueMatcher(Value goodval_) : goodval(std::move(goodval_)) {}
 
-  bool MatchAndExplain(std::shared_ptr<Value> msg,
+  bool MatchAndExplain(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;
+  Value goodval;
 };
 
-inline ::testing::Matcher<std::shared_ptr<Value>> ValueEq(
-    std::shared_ptr<Value> goodval) {
+inline ::testing::Matcher<Value> ValueEq(const 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
index a9f2218..d49be44 100644
--- a/ntcore/src/test/native/cpp/ValueTest.cpp
+++ b/ntcore/src/test/native/cpp/ValueTest.cpp
@@ -12,15 +12,15 @@
 
 using namespace std::string_view_literals;
 
-namespace wpi {
-template <typename T>
-inline bool operator==(span<T> lhs, span<T> rhs) {
+namespace std {  // NOLINT (clang-tidy.cert-dcl58-cpp)
+template <typename T, typename U>
+inline bool operator==(std::span<T> lhs, std::span<U> rhs) {
   if (lhs.size() != rhs.size()) {
     return false;
   }
   return std::equal(lhs.begin(), lhs.end(), rhs.begin());
 }
-}  // namespace wpi
+}  // namespace std
 
 namespace nt {
 
@@ -35,19 +35,19 @@
 
 TEST_F(ValueTest, Boolean) {
   auto v = Value::MakeBoolean(false);
-  ASSERT_EQ(NT_BOOLEAN, v->type());
-  ASSERT_FALSE(v->GetBoolean());
+  ASSERT_EQ(NT_BOOLEAN, v.type());
+  ASSERT_FALSE(v.GetBoolean());
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &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());
+  ASSERT_EQ(NT_BOOLEAN, v.type());
+  ASSERT_TRUE(v.GetBoolean());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_BOOLEAN, cv.type);
   ASSERT_EQ(1, cv.data.v_boolean);
 
@@ -56,19 +56,19 @@
 
 TEST_F(ValueTest, Double) {
   auto v = Value::MakeDouble(0.5);
-  ASSERT_EQ(NT_DOUBLE, v->type());
-  ASSERT_EQ(0.5, v->GetDouble());
+  ASSERT_EQ(NT_DOUBLE, v.type());
+  ASSERT_EQ(0.5, v.GetDouble());
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &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());
+  ASSERT_EQ(NT_DOUBLE, v.type());
+  ASSERT_EQ(0.25, v.GetDouble());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_DOUBLE, cv.type);
   ASSERT_EQ(0.25, cv.data.v_double);
 
@@ -77,20 +77,20 @@
 
 TEST_F(ValueTest, String) {
   auto v = Value::MakeString("hello");
-  ASSERT_EQ(NT_STRING, v->type());
-  ASSERT_EQ("hello", v->GetString());
+  ASSERT_EQ(NT_STRING, v.type());
+  ASSERT_EQ("hello", v.GetString());
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_STRING, cv.type);
   ASSERT_EQ("hello"sv, 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());
+  ASSERT_EQ(NT_STRING, v.type());
+  ASSERT_EQ("goodbye", v.GetString());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_STRING, cv.type);
   ASSERT_EQ("goodbye"sv, cv.data.v_string.str);
   ASSERT_EQ(7u, cv.data.v_string.len);
@@ -99,24 +99,28 @@
 }
 
 TEST_F(ValueTest, Raw) {
-  auto v = Value::MakeRaw("hello");
-  ASSERT_EQ(NT_RAW, v->type());
-  ASSERT_EQ("hello", v->GetRaw());
+  std::vector<uint8_t> arr{5, 4, 3, 2, 1};
+  auto v = Value::MakeRaw(arr);
+  ASSERT_EQ(NT_RAW, v.type());
+  ASSERT_EQ(std::span<const uint8_t>(arr), v.GetRaw());
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_RAW, cv.type);
-  ASSERT_EQ("hello"sv, cv.data.v_string.str);
-  ASSERT_EQ(5u, cv.data.v_string.len);
+  ASSERT_EQ(5u, cv.data.v_raw.size);
+  ASSERT_EQ(std::span(reinterpret_cast<const uint8_t*>("\5\4\3\2\1"), 5),
+            std::span(cv.data.v_raw.data, 5));
 
-  v = Value::MakeRaw("goodbye");
-  ASSERT_EQ(NT_RAW, v->type());
-  ASSERT_EQ("goodbye", v->GetRaw());
+  std::vector<uint8_t> arr2{1, 2, 3, 4, 5, 6};
+  v = Value::MakeRaw(arr2);
+  ASSERT_EQ(NT_RAW, v.type());
+  ASSERT_EQ(std::span<const uint8_t>(arr2), v.GetRaw());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_RAW, cv.type);
-  ASSERT_EQ("goodbye"sv, cv.data.v_string.str);
-  ASSERT_EQ(7u, cv.data.v_string.len);
+  ASSERT_EQ(6u, cv.data.v_raw.size);
+  ASSERT_EQ(std::span(reinterpret_cast<const uint8_t*>("\1\2\3\4\5\6"), 6),
+            std::span(cv.data.v_raw.data, 6));
 
   NT_DisposeValue(&cv);
 }
@@ -124,11 +128,11 @@
 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::span<const int>(vec), v->GetBooleanArray());
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, v.type());
+  ASSERT_EQ(std::span<const int>(vec), v.GetBooleanArray());
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &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]);
@@ -138,10 +142,10 @@
   // assign with same size
   vec = {0, 1, 0};
   v = Value::MakeBooleanArray(vec);
-  ASSERT_EQ(NT_BOOLEAN_ARRAY, v->type());
-  ASSERT_EQ(wpi::span<const int>(vec), v->GetBooleanArray());
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, v.type());
+  ASSERT_EQ(std::span<const int>(vec), v.GetBooleanArray());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &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]);
@@ -151,10 +155,10 @@
   // assign with different size
   vec = {1, 0};
   v = Value::MakeBooleanArray(vec);
-  ASSERT_EQ(NT_BOOLEAN_ARRAY, v->type());
-  ASSERT_EQ(wpi::span<const int>(vec), v->GetBooleanArray());
+  ASSERT_EQ(NT_BOOLEAN_ARRAY, v.type());
+  ASSERT_EQ(std::span<const int>(vec), v.GetBooleanArray());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  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]);
@@ -166,11 +170,11 @@
 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::span<const double>(vec), v->GetDoubleArray());
+  ASSERT_EQ(NT_DOUBLE_ARRAY, v.type());
+  ASSERT_EQ(std::span<const double>(vec), v.GetDoubleArray());
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &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]);
@@ -180,10 +184,10 @@
   // 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::span<const double>(vec), v->GetDoubleArray());
+  ASSERT_EQ(NT_DOUBLE_ARRAY, v.type());
+  ASSERT_EQ(std::span<const double>(vec), v.GetDoubleArray());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &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]);
@@ -193,10 +197,10 @@
   // assign with different size
   vec = {0.5, 0.25};
   v = Value::MakeDoubleArray(vec);
-  ASSERT_EQ(NT_DOUBLE_ARRAY, v->type());
-  ASSERT_EQ(wpi::span<const double>(vec), v->GetDoubleArray());
+  ASSERT_EQ(NT_DOUBLE_ARRAY, v.type());
+  ASSERT_EQ(std::span<const double>(vec), v.GetDoubleArray());
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  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]);
@@ -211,14 +215,14 @@
   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("hello"sv, v->GetStringArray()[0]);
-  ASSERT_EQ("goodbye"sv, v->GetStringArray()[1]);
-  ASSERT_EQ("string"sv, v->GetStringArray()[2]);
+  ASSERT_EQ(NT_STRING_ARRAY, v.type());
+  ASSERT_EQ(3u, v.GetStringArray().size());
+  ASSERT_EQ("hello"sv, v.GetStringArray()[0]);
+  ASSERT_EQ("goodbye"sv, v.GetStringArray()[1]);
+  ASSERT_EQ("string"sv, v.GetStringArray()[2]);
   NT_Value cv;
   NT_InitValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_STRING_ARRAY, cv.type);
   ASSERT_EQ(3u, cv.data.arr_string.size);
   ASSERT_EQ("hello"sv, cv.data.arr_string.arr[0].str);
@@ -231,13 +235,13 @@
   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("s1"sv, v->GetStringArray()[0]);
-  ASSERT_EQ("str2"sv, v->GetStringArray()[1]);
-  ASSERT_EQ("string3"sv, v->GetStringArray()[2]);
+  ASSERT_EQ(NT_STRING_ARRAY, v.type());
+  ASSERT_EQ(3u, v.GetStringArray().size());
+  ASSERT_EQ("s1"sv, v.GetStringArray()[0]);
+  ASSERT_EQ("str2"sv, v.GetStringArray()[1]);
+  ASSERT_EQ("string3"sv, v.GetStringArray()[2]);
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_STRING_ARRAY, cv.type);
   ASSERT_EQ(3u, cv.data.arr_string.size);
   ASSERT_EQ("s1"sv, cv.data.arr_string.arr[0].str);
@@ -249,12 +253,12 @@
   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("short"sv, v->GetStringArray()[0]);
-  ASSERT_EQ("er"sv, v->GetStringArray()[1]);
+  ASSERT_EQ(NT_STRING_ARRAY, v.type());
+  ASSERT_EQ(2u, v.GetStringArray().size());
+  ASSERT_EQ("short"sv, v.GetStringArray()[0]);
+  ASSERT_EQ("er"sv, v.GetStringArray()[1]);
   NT_DisposeValue(&cv);
-  ConvertToC(*v, &cv);
+  ConvertToC(v, &cv);
   ASSERT_EQ(NT_STRING_ARRAY, cv.type);
   ASSERT_EQ(2u, cv.data.arr_string.size);
   ASSERT_EQ("short"sv, cv.data.arr_string.arr[0].str);
@@ -286,69 +290,69 @@
 TEST_F(ValueTest, MixedComparison) {
   Value v1;
   auto v2 = Value::MakeBoolean(true);
-  ASSERT_NE(v1, *v2);  // unassigned vs boolean
+  ASSERT_NE(v1, v2);  // unassigned vs boolean
   auto v3 = Value::MakeDouble(0.5);
-  ASSERT_NE(*v2, *v3);  // boolean vs double
+  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);
+  ASSERT_EQ(v1, v2);
   v2 = Value::MakeBoolean(false);
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
 }
 
 TEST_F(ValueTest, DoubleComparison) {
   auto v1 = Value::MakeDouble(0.25);
   auto v2 = Value::MakeDouble(0.25);
-  ASSERT_EQ(*v1, *v2);
+  ASSERT_EQ(v1, v2);
   v2 = Value::MakeDouble(0.5);
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
 }
 
 TEST_F(ValueTest, StringComparison) {
   auto v1 = Value::MakeString("hello");
   auto v2 = Value::MakeString("hello");
-  ASSERT_EQ(*v1, *v2);
+  ASSERT_EQ(v1, v2);
   v2 = Value::MakeString("world");  // different contents
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
   v2 = Value::MakeString("goodbye");  // different size
-  ASSERT_NE(*v1, *v2);
+  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);
+  ASSERT_EQ(v1, v2);
 
   // different contents
   vec = {1, 1, 1};
   v2 = Value::MakeBooleanArray(vec);
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
 
   // different size
   vec = {1, 0};
   v2 = Value::MakeBooleanArray(vec);
-  ASSERT_NE(*v1, *v2);
+  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);
+  ASSERT_EQ(v1, v2);
 
   // different contents
   vec = {0.5, 0.5, 0.5};
   v2 = Value::MakeDoubleArray(vec);
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
 
   // different size
   vec = {0.5, 0.25};
   v2 = Value::MakeDoubleArray(vec);
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
 }
 
 TEST_F(ValueTest, StringArrayComparison) {
@@ -362,7 +366,7 @@
   vec.push_back("goodbye");
   vec.push_back("string");
   auto v2 = Value::MakeStringArray(std::move(vec));
-  ASSERT_EQ(*v1, *v2);
+  ASSERT_EQ(v1, v2);
 
   // different contents
   vec.clear();
@@ -370,7 +374,7 @@
   vec.push_back("goodby2");
   vec.push_back("string");
   v2 = Value::MakeStringArray(std::move(vec));
-  ASSERT_NE(*v1, *v2);
+  ASSERT_NE(v1, v2);
 
   // different sized contents
   vec.clear();
@@ -378,14 +382,14 @@
   vec.push_back("goodbye2");
   vec.push_back("string");
   v2 = Value::MakeStringArray(vec);
-  ASSERT_NE(*v1, *v2);
+  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);
+  ASSERT_NE(v1, v2);
 }
 
 }  // namespace nt
diff --git a/ntcore/src/test/native/cpp/WireDecoderTest.cpp b/ntcore/src/test/native/cpp/WireDecoderTest.cpp
deleted file mode 100644
index 313fd98..0000000
--- a/ntcore/src/test/native/cpp/WireDecoderTest.cpp
+++ /dev/null
@@ -1,647 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include <stdint.h>
-
-#include <cfloat>
-#include <climits>
-#include <string>
-#include <string_view>
-
-#include "TestPrinters.h"
-#include "WireDecoder.h"
-#include "gtest/gtest.h"
-
-using namespace std::string_view_literals;
-
-namespace nt {
-
-class WireDecoderTest : public ::testing::Test {
- protected:
-  WireDecoderTest() {
-    v_boolean = Value::MakeBoolean(true);
-    v_double = Value::MakeDouble(1.0);
-    v_string = Value::MakeString("hello"sv);
-    v_raw = Value::MakeRaw("hello"sv);
-    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("bye"sv);
-  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("bye"sv);
-  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("bye"sv);
-  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
deleted file mode 100644
index b0cc664..0000000
--- a/ntcore/src/test/native/cpp/WireEncoderTest.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include <cfloat>
-#include <climits>
-#include <string>
-#include <string_view>
-
-#include <wpi/StringExtras.h>
-
-#include "TestPrinters.h"
-#include "WireEncoder.h"
-#include "gtest/gtest.h"
-
-#define BUFSIZE 1024
-
-using namespace std::string_view_literals;
-
-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("hello"sv);
-    v_raw = Value::MakeRaw("hello"sv);
-    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("\x05\x01\x00"sv, wpi::substr({e.data(), e.size()}, 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("\x00\x05\x00\x01\x45\x67\x00\x00"sv,
-            wpi::substr({e.data(), e.size()}, 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(std::string_view("\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\xab\xcd"
-                             "\x12\x34\x56\x78\x00\x00\x00\x00",
-                             20),
-            wpi::substr({e.data(), e.size()}, 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(std::string_view("\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::substr({e.data(), e.size()}, 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("\x00\x7f\x80\x01"sv, wpi::substr({e.data(), e.size()}, 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("\x00\x01\x02\x03\x10\x11\x12\x20"sv,
-            wpi::substr({e.data(), e.size()}, 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("\x01\x00"sv, std::string_view(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("\x3f\xf0\x00\x00\x00\x00\x00\x00"sv,
-            std::string_view(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("\x00\x05hello"sv, std::string_view(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("\x03\x00\x01\x00"sv, std::string_view(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("\xff\x00"sv, std::string_view(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(std::string_view("\x02\x3f\xe0\x00\x00\x00\x00\x00\x00"
-                             "\x3f\xd0\x00\x00\x00\x00\x00\x00",
-                             17),
-            std::string_view(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("\xff\x00"sv, std::string_view(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("\x02\x00\x05hello\x00\x07goodbye"sv,
-            std::string_view(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("\xff\x00\x01"sv, std::string_view(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("\x01\x00"sv, std::string_view(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("\x3f\xf0\x00\x00\x00\x00\x00\x00"sv,
-            std::string_view(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("\x05hello"sv, std::string_view(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("\x05hello"sv, std::string_view(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("\x03\x00\x01\x00"sv, std::string_view(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("\xff\x00"sv, std::string_view(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(std::string_view("\x02\x3f\xe0\x00\x00\x00\x00\x00\x00"
-                             "\x3f\xd0\x00\x00\x00\x00\x00\x00",
-                             17),
-            std::string_view(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("\xff\x00"sv, std::string_view(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("\x02\x05hello\x07goodbye"sv, std::string_view(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("\xff\x01"sv, std::string_view(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("\x00\x05hello"sv, std::string_view(e.data(), e.size()));
-
-  e.Reset();
-  e.WriteString(s_long);
-  EXPECT_EQ(nullptr, e.error());
-  ASSERT_EQ(130u, e.size());
-  EXPECT_EQ("\x00\x80**"sv, std::string_view(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("\xff\xff**"sv, std::string_view(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("\x05hello"sv, std::string_view(e.data(), e.size()));
-
-  e.Reset();
-  e.WriteString(s_long);
-  EXPECT_EQ(nullptr, e.error());
-  ASSERT_EQ(130u, e.size());
-  EXPECT_EQ("\x80\x01**"sv, std::string_view(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("\x81\x80\x04*"sv, std::string_view(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
index a3fec50..6d37027 100644
--- a/ntcore/src/test/native/cpp/main.cpp
+++ b/ntcore/src/test/native/cpp/main.cpp
@@ -8,14 +8,25 @@
 #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);
+  nt::AddLogger(nt::GetDefaultInstance(), 0, UINT_MAX, [](auto& event) {
+    if (auto msg = event.GetLogMessage()) {
+      std::fputs(msg->message.c_str(), stderr);
+      std::fputc('\n', stderr);
+    }
+  });
   ::testing::InitGoogleMock(&argc, argv);
   int ret = RUN_ALL_TESTS();
   return ret;
 }
+
+extern "C" {
+void __ubsan_on_report(void) {
+  FAIL() << "Encountered an undefined behavior sanitizer error";
+}
+void __asan_on_error(void) {
+  FAIL() << "Encountered an address sanitizer error";
+}
+void __tsan_on_report(void) {
+  FAIL() << "Encountered a thread sanitizer error";
+}
+}  // extern "C"
diff --git a/ntcore/src/test/native/cpp/net/MockNetworkInterface.h b/ntcore/src/test/native/cpp/net/MockNetworkInterface.h
new file mode 100644
index 0000000..b033436
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net/MockNetworkInterface.h
@@ -0,0 +1,69 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <string>
+
+#include <wpi/json.h>
+
+#include "PubSubOptions.h"
+#include "gmock/gmock.h"
+#include "net/NetworkInterface.h"
+
+namespace nt::net {
+
+class MockLocalInterface : public LocalInterface {
+ public:
+  MOCK_METHOD(NT_Topic, NetworkAnnounce,
+              (std::string_view name, std::string_view typeStr,
+               const wpi::json& properties, NT_Publisher pubHandle),
+              (override));
+  MOCK_METHOD(void, NetworkUnannounce, (std::string_view name), (override));
+  MOCK_METHOD(void, NetworkPropertiesUpdate,
+              (std::string_view name, const wpi::json& update, bool ack),
+              (override));
+  MOCK_METHOD(void, NetworkSetValue, (NT_Topic topicHandle, const Value& value),
+              (override));
+};
+
+class MockNetworkInterface : public NetworkInterface {
+ public:
+  MOCK_METHOD(void, Publish,
+              (NT_Publisher pubHandle, NT_Topic topicHandle,
+               std::string_view name, std::string_view typeStr,
+               const wpi::json& properties, const PubSubOptionsImpl& options),
+              (override));
+  MOCK_METHOD(void, Unpublish, (NT_Publisher pubHandle, NT_Topic topicHandle),
+              (override));
+  MOCK_METHOD(void, SetProperties,
+              (NT_Topic topicHandle, std::string_view name,
+               const wpi::json& update),
+              (override));
+  MOCK_METHOD(void, Subscribe,
+              (NT_Subscriber subHandle, std::span<const std::string> prefixes,
+               const PubSubOptionsImpl& options),
+              (override));
+  MOCK_METHOD(void, Unsubscribe, (NT_Subscriber subHandle), (override));
+  MOCK_METHOD(void, SetValue, (NT_Publisher pubHandle, const Value& value),
+              (override));
+};
+
+class MockLocalStorage : public ILocalStorage {
+ public:
+  MOCK_METHOD(NT_Topic, NetworkAnnounce,
+              (std::string_view name, std::string_view typeStr,
+               const wpi::json& properties, NT_Publisher pubHandle),
+              (override));
+  MOCK_METHOD(void, NetworkUnannounce, (std::string_view name), (override));
+  MOCK_METHOD(void, NetworkPropertiesUpdate,
+              (std::string_view name, const wpi::json& update, bool ack),
+              (override));
+  MOCK_METHOD(void, NetworkSetValue, (NT_Topic topicHandle, const Value& value),
+              (override));
+  MOCK_METHOD(void, StartNetwork, (NetworkInterface * network), (override));
+  MOCK_METHOD(void, ClearNetwork, (), (override));
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/test/native/cpp/net/MockWireConnection.cpp b/ntcore/src/test/native/cpp/net/MockWireConnection.cpp
new file mode 100644
index 0000000..a5ddb1f
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net/MockWireConnection.cpp
@@ -0,0 +1,26 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "MockWireConnection.h"
+
+using namespace nt::net;
+
+void MockWireConnection::StartSendText() {
+  if (m_in_text) {
+    m_text_os << ',';
+  } else {
+    m_text_os << '[';
+    m_in_text = true;
+  }
+}
+
+void MockWireConnection::FinishSendText() {
+  if (m_in_text) {
+    m_text_os << ']';
+    m_in_text = false;
+  }
+  m_text_os.flush();
+  Text(m_text);
+  m_text.clear();
+}
diff --git a/ntcore/src/test/native/cpp/net/MockWireConnection.h b/ntcore/src/test/native/cpp/net/MockWireConnection.h
new file mode 100644
index 0000000..3909cab
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net/MockWireConnection.h
@@ -0,0 +1,54 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include <wpi/raw_ostream.h>
+
+#include "gmock/gmock.h"
+#include "net/WireConnection.h"
+
+namespace nt::net {
+
+class MockWireConnection : public WireConnection {
+ public:
+  MockWireConnection() : m_text_os{m_text}, m_binary_os{m_binary} {}
+
+  MOCK_METHOD(bool, Ready, (), (const, override));
+
+  TextWriter SendText() override { return {m_text_os, *this}; }
+  BinaryWriter SendBinary() override { return {m_binary_os, *this}; }
+
+  MOCK_METHOD(void, Text, (std::string_view contents));
+  MOCK_METHOD(void, Binary, (std::span<const uint8_t> contents));
+
+  MOCK_METHOD(void, Flush, (), (override));
+
+  MOCK_METHOD(void, Disconnect, (std::string_view reason), (override));
+
+ protected:
+  void StartSendText() override;
+  void FinishSendText() override;
+  void StartSendBinary() override {}
+  void FinishSendBinary() override {
+    Binary(m_binary);
+    m_binary.resize(0);
+  }
+
+ private:
+  std::string m_text;
+  wpi::raw_string_ostream m_text_os;
+  std::vector<uint8_t> m_binary;
+  wpi::raw_uvector_ostream m_binary_os;
+  bool m_in_text{false};
+};
+
+}  // namespace nt::net
diff --git a/ntcore/src/test/native/cpp/net/WireDecoderTest.cpp b/ntcore/src/test/native/cpp/net/WireDecoderTest.cpp
new file mode 100644
index 0000000..f893302
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net/WireDecoderTest.cpp
@@ -0,0 +1,214 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <wpi/SmallString.h>
+#include <wpi/raw_ostream.h>
+
+#include "../MockLogger.h"
+#include "../TestPrinters.h"
+#include "Handle.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "net/Message.h"
+#include "net/WireDecoder.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace std::string_view_literals;
+using testing::_;
+using testing::MockFunction;
+using testing::StrictMock;
+
+namespace nt {
+
+class MockClientMessageHandler : public net::ClientMessageHandler {
+ public:
+  MOCK_METHOD4(ClientPublish,
+               void(int64_t pubuid, std::string_view name,
+                    std::string_view typeStr, const wpi::json& properties));
+  MOCK_METHOD1(ClientUnpublish, void(int64_t pubuid));
+  MOCK_METHOD2(ClientSetProperties,
+               void(std::string_view name, const wpi::json& update));
+  MOCK_METHOD3(ClientSubscribe,
+               void(int64_t subuid, std::span<const std::string> prefixes,
+                    const PubSubOptionsImpl& options));
+  MOCK_METHOD1(ClientUnsubscribe, void(int64_t subuid));
+};
+
+class MockServerMessageHandler : public net::ServerMessageHandler {
+ public:
+  MOCK_METHOD5(ServerAnnounce,
+               void(std::string_view name, int64_t id, std::string_view typeStr,
+                    const wpi::json& properties,
+                    std::optional<int64_t> pubuid));
+  MOCK_METHOD2(ServerUnannounce, void(std::string_view name, int64_t id));
+  MOCK_METHOD3(ServerPropertiesUpdate,
+               void(std::string_view name, const wpi::json& update, bool ack));
+};
+
+class WireDecodeTextClientTest : public ::testing::Test {
+ public:
+  StrictMock<MockClientMessageHandler> handler;
+  StrictMock<wpi::MockLogger> logger;
+};
+
+class WireDecodeTextServerTest : public ::testing::Test {
+ public:
+  StrictMock<MockServerMessageHandler> handler;
+  StrictMock<wpi::MockLogger> logger;
+};
+
+TEST_F(WireDecodeTextClientTest, EmptyArray) {
+  net::WireDecodeText("[]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorEmpty) {
+  EXPECT_CALL(
+      logger,
+      Call(_, _, _,
+           "could not decode JSON message: [json.exception.parse_error.101] "
+           "parse error at 1: syntax error - "
+           "unexpected end of input; expected '[', '{', or a literal"sv));
+  net::WireDecodeText("", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorBadJson1) {
+  EXPECT_CALL(
+      logger,
+      Call(_, _, _,
+           "could not decode JSON message: [json.exception.parse_error.101] "
+           "parse error at 2: syntax error - "
+           "unexpected end of input; expected '[', '{', or a literal"sv));
+  net::WireDecodeText("[", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorBadJson2) {
+  EXPECT_CALL(
+      logger,
+      Call(_, _, _,
+           "could not decode JSON message: [json.exception.parse_error.101] "
+           "parse error at 3: syntax error - "
+           "unexpected end of input; expected string literal"sv));
+  net::WireDecodeText("[{", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorNotArray) {
+  EXPECT_CALL(logger, Call(_, _, _, "expected JSON array at top level"sv));
+  net::WireDecodeText("{}", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorMessageNotObject) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: expected message to be an object"sv));
+  net::WireDecodeText("[5]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorNoMethodKey) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: no method key"sv));
+  net::WireDecodeText("[{}]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorMethodNotString) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: method must be a string"sv));
+  net::WireDecodeText("[{\"method\":5}]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorNoParamsKey) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: no params key"sv));
+  net::WireDecodeText("[{\"method\":\"a\"}]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorParamsNotObject) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: params must be an object"sv));
+  net::WireDecodeText("[{\"method\":\"a\",\"params\":5}]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, ErrorUnknownMethod) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: unrecognized method 'a'"sv));
+  net::WireDecodeText("[{\"method\":\"a\",\"params\":{}}]", handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, PublishPropsEmpty) {
+  EXPECT_CALL(handler,
+              ClientPublish(5, std::string_view{"test"},
+                            std::string_view{"double"}, wpi::json::object()));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"properties\":{},\"pubuid\":5,\"type\":\"double\"}}]",
+      handler, logger);
+
+  EXPECT_CALL(handler,
+              ClientPublish(5, std::string_view{"test"},
+                            std::string_view{"double"}, wpi::json::object()));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"pubuid\":5,\"type\":\"double\"}}]",
+      handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, PublishProps) {
+  wpi::json props = {{"k", 6}};
+  EXPECT_CALL(handler, ClientPublish(5, std::string_view{"test"},
+                                     std::string_view{"double"}, props));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"properties\":{\"k\":6},"
+      "\"pubuid\":5,\"type\":\"double\"}}]",
+      handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, PublishPropsError) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: properties must be an object"sv));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"properties\":[\"k\"],"
+      "\"pubuid\":5,\"type\":\"double\"}}]",
+      handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, PublishError) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: no name key"sv));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"pubuid\":5,\"type\":\"double\"}}]",
+      handler, logger);
+
+  EXPECT_CALL(logger, Call(_, _, _, "0: no type key"sv));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"pubuid\":5}}]",
+      handler, logger);
+
+  EXPECT_CALL(logger, Call(_, _, _, "0: no pubuid key"sv));
+  net::WireDecodeText(
+      "[{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"type\":\"double\"}}]",
+      handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, Unpublish) {
+  EXPECT_CALL(handler, ClientUnpublish(5));
+  net::WireDecodeText("[{\"method\":\"unpublish\",\"params\":{\"pubuid\":5}}]",
+                      handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, UnpublishMultiple) {
+  EXPECT_CALL(handler, ClientUnpublish(5));
+  EXPECT_CALL(handler, ClientUnpublish(6));
+  net::WireDecodeText(
+      "[{\"method\":\"unpublish\",\"params\":{\"pubuid\":5}},{\"method\":"
+      "\"unpublish\",\"params\":{\"pubuid\":6}}]",
+      handler, logger);
+}
+
+TEST_F(WireDecodeTextClientTest, UnpublishError) {
+  EXPECT_CALL(logger, Call(_, _, _, "0: no pubuid key"sv));
+  net::WireDecodeText("[{\"method\":\"unpublish\",\"params\":{}}]", handler,
+                      logger);
+
+  EXPECT_CALL(logger, Call(_, _, _, "0: pubuid must be a number"sv));
+  net::WireDecodeText(
+      "[{\"method\":\"unpublish\",\"params\":{\"pubuid\":\"5\"}}]", handler,
+      logger);
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/net/WireEncoderTest.cpp b/ntcore/src/test/native/cpp/net/WireEncoderTest.cpp
new file mode 100644
index 0000000..9cc3187
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net/WireEncoderTest.cpp
@@ -0,0 +1,293 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include <wpi/json.h>
+#include <wpi/raw_ostream.h>
+
+#include "../SpanMatcher.h"
+#include "../TestPrinters.h"
+#include "Handle.h"
+#include "PubSubOptions.h"
+#include "gmock/gmock-matchers.h"
+#include "gtest/gtest.h"
+#include "net/Message.h"
+#include "net/WireEncoder.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace std::string_view_literals;
+
+namespace nt {
+
+class WireEncoderTextTest : public ::testing::Test {
+ protected:
+  std::string out;
+  wpi::raw_string_ostream os{out};
+  wpi::json GetJson() { return wpi::json::parse(os.str()); }
+};
+
+class WireEncoderBinaryTest : public ::testing::Test {
+ protected:
+  std::vector<uint8_t> out;
+  wpi::raw_uvector_ostream os{out};
+};
+
+TEST_F(WireEncoderTextTest, PublishPropsEmpty) {
+  net::WireEncodePublish(os, 5, "test", "double", wpi::json::object());
+  ASSERT_EQ(
+      os.str(),
+      "{\"method\":\"publish\",\"params\":{"
+      "\"name\":\"test\",\"properties\":{},\"pubuid\":5,\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, PublishProps) {
+  net::WireEncodePublish(os, 5, "test", "double", {{"k", 6}});
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"publish\",\"params\":{"
+            "\"name\":\"test\",\"properties\":{\"k\":6},"
+            "\"pubuid\":5,\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, Unpublish) {
+  net::WireEncodeUnpublish(os, 5);
+  ASSERT_EQ(os.str(), "{\"method\":\"unpublish\",\"params\":{\"pubuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, SetProperties) {
+  net::WireEncodeSetProperties(os, "test", {{"k", 6}});
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"setproperties\",\"params\":{"
+            "\"name\":\"test\",\"update\":{\"k\":6}}}");
+}
+
+TEST_F(WireEncoderTextTest, Subscribe) {
+  net::WireEncodeSubscribe(os, 5, std::span<const std::string_view>{{"a", "b"}},
+                           PubSubOptions{});
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"subscribe\",\"params\":{"
+            "\"options\":{},\"topics\":[\"a\",\"b\"],\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, SubscribeSendAll) {
+  PubSubOptionsImpl options;
+  options.sendAll = true;
+  net::WireEncodeSubscribe(os, 5, std::span<const std::string_view>{{"a", "b"}},
+                           options);
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"subscribe\",\"params\":{"
+            "\"options\":{\"all\":true},\"topics\":[\"a\",\"b\"],"
+            "\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, SubscribePeriodic) {
+  PubSubOptionsImpl options;
+  options.periodicMs = 500u;
+  net::WireEncodeSubscribe(os, 5, std::span<const std::string_view>{{"a", "b"}},
+                           options);
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"subscribe\",\"params\":{"
+            "\"options\":{\"periodic\":0.5},\"topics\":[\"a\",\"b\"],"
+            "\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, SubscribeAllOptions) {
+  PubSubOptionsImpl options;
+  options.sendAll = true;
+  options.periodicMs = 500u;
+  net::WireEncodeSubscribe(os, 5, std::span<const std::string_view>{{"a", "b"}},
+                           options);
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"subscribe\",\"params\":{"
+            "\"options\":{\"all\":true,\"periodic\":0.5},"
+            "\"topics\":[\"a\",\"b\"],\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, Unsubscribe) {
+  net::WireEncodeUnsubscribe(os, 5);
+  ASSERT_EQ(os.str(), "{\"method\":\"unsubscribe\",\"params\":{\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, Announce) {
+  net::WireEncodeAnnounce(os, "test", 5, "double", wpi::json::object(),
+                          std::nullopt);
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"announce\",\"params\":{\"id\":5,\"name\":\"test\","
+            "\"properties\":{},\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, AnnounceProperties) {
+  net::WireEncodeAnnounce(os, "test", 5, "double", {{"k", 6}}, std::nullopt);
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"announce\",\"params\":{\"id\":5,\"name\":\"test\","
+            "\"properties\":{\"k\":6},\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, AnnouncePubuid) {
+  net::WireEncodeAnnounce(os, "test", 5, "double", wpi::json::object(), 6);
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"announce\",\"params\":{\"id\":5,\"name\":\"test\","
+            "\"properties\":{},\"pubuid\":6,\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, Unannounce) {
+  net::WireEncodeUnannounce(os, "test", 5);
+  ASSERT_EQ(
+      os.str(),
+      "{\"method\":\"unannounce\",\"params\":{\"id\":5,\"name\":\"test\"}}");
+}
+
+TEST_F(WireEncoderTextTest, MessagePublish) {
+  net::ClientMessage msg{net::PublishMsg{
+      Handle{0, 5, Handle::kPublisher}, 0, "test", "double", {{"k", 6}}, {}}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"publish\",\"params\":{"
+            "\"name\":\"test\",\"properties\":{\"k\":6},"
+            "\"pubuid\":5,\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageUnpublish) {
+  net::ClientMessage msg{
+      net::UnpublishMsg{Handle{0, 5, Handle::kPublisher}, 0}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(), "{\"method\":\"unpublish\",\"params\":{\"pubuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageSetProperties) {
+  net::ClientMessage msg{net::SetPropertiesMsg{0, "test", {{"k", 6}}}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"setproperties\",\"params\":{"
+            "\"name\":\"test\",\"update\":{\"k\":6}}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageSubscribe) {
+  net::ClientMessage msg{
+      net::SubscribeMsg{Handle{0, 5, Handle::kSubscriber}, {"a", "b"}, {}}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"subscribe\",\"params\":{"
+            "\"options\":{},\"topics\":[\"a\",\"b\"],\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageUnsubscribe) {
+  net::ClientMessage msg{
+      net::UnsubscribeMsg{Handle{0, 5, Handle::kSubscriber}}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(), "{\"method\":\"unsubscribe\",\"params\":{\"subuid\":5}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageAnnounce) {
+  net::ServerMessage msg{
+      net::AnnounceMsg{"test", 5, "double", std::nullopt, wpi::json::object()}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"announce\",\"params\":{\"id\":5,\"name\":\"test\","
+            "\"properties\":{},\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageAnnounceProperties) {
+  net::ServerMessage msg{
+      net::AnnounceMsg{"test", 5, "double", std::nullopt, {{"k", 6}}}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"announce\",\"params\":{\"id\":5,\"name\":\"test\","
+            "\"properties\":{\"k\":6},\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageAnnouncePubuid) {
+  net::ServerMessage msg{
+      net::AnnounceMsg{"test", 5, "double", 6, wpi::json::object()}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(os.str(),
+            "{\"method\":\"announce\",\"params\":{\"id\":5,\"name\":\"test\","
+            "\"properties\":{},\"pubuid\":6,\"type\":\"double\"}}");
+}
+
+TEST_F(WireEncoderTextTest, MessageUnannounce) {
+  net::ServerMessage msg{net::UnannounceMsg{"test", 5}};
+  ASSERT_TRUE(net::WireEncodeText(os, msg));
+  ASSERT_EQ(
+      os.str(),
+      "{\"method\":\"unannounce\",\"params\":{\"id\":5,\"name\":\"test\"}}");
+}
+
+TEST_F(WireEncoderTextTest, ServerMessageEmpty) {
+  ASSERT_FALSE(net::WireEncodeText(os, net::ServerMessage{}));
+}
+
+TEST_F(WireEncoderTextTest, ServerMessageValue) {
+  net::ServerMessage msg{net::ServerValueMsg{}};
+  ASSERT_FALSE(net::WireEncodeText(os, msg));
+}
+
+TEST_F(WireEncoderBinaryTest, Boolean) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeBoolean(true));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x00\xc3"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, Integer) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeInteger(7));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x02\x07"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, Float) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeFloat(2.5));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x03\xca\x40\x20\x00\x00"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, Double) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeDouble(2.5));
+  ASSERT_THAT(
+      out,
+      wpi::SpanEq("\x94\x05\x06\x01\xcb\x40\x04\x00\x00\x00\x00\x00\x00"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, String) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeString("hello"));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x04\xa5hello"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, Raw) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeRaw("hello"_us));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x05\xc4\x05hello"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, BooleanArray) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeBooleanArray({true, false, true}));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x10\x93\xc3\xc2\xc3"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, IntegerArray) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeIntegerArray({1, 2, 4}));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x12\x93\x01\x02\x04"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, FloatArray) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeFloatArray({1, 2, 3}));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x13\x93"
+                               "\xca\x3f\x80\x00\x00"
+                               "\xca\x40\x00\x00\x00"
+                               "\xca\x40\x40\x00\x00"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, DoubleArray) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeDoubleArray({1, 2, 3}));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x11\x93"
+                               "\xcb\x3f\xf0\x00\x00\x00\x00\x00\x00"
+                               "\xcb\x40\x00\x00\x00\x00\x00\x00\x00"
+                               "\xcb\x40\x08\x00\x00\x00\x00\x00\x00"_us));
+}
+
+TEST_F(WireEncoderBinaryTest, StringArray) {
+  net::WireEncodeBinary(os, 5, 6, Value::MakeStringArray({"hello", "bye"}));
+  ASSERT_THAT(out, wpi::SpanEq("\x94\x05\x06\x14\x92\xa5hello\xa3"
+                               "bye"_us));
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/net3/MessageMatcher3.cpp b/ntcore/src/test/native/cpp/net3/MessageMatcher3.cpp
new file mode 100644
index 0000000..d595c6a
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net3/MessageMatcher3.cpp
@@ -0,0 +1,45 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "MessageMatcher3.h"
+
+namespace nt::net3 {
+
+bool MessageMatcher::MatchAndExplain(
+    Message3 msg, ::testing::MatchResultListener* listener) const {
+  bool match = true;
+  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::net3
diff --git a/ntcore/src/test/native/cpp/net3/MessageMatcher3.h b/ntcore/src/test/native/cpp/net3/MessageMatcher3.h
new file mode 100644
index 0000000..6b1e770
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net3/MessageMatcher3.h
@@ -0,0 +1,34 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <memory>
+#include <ostream>
+#include <utility>
+
+#include "../TestPrinters.h"
+#include "gmock/gmock.h"
+#include "net3/Message3.h"
+
+namespace nt::net3 {
+
+class MessageMatcher : public ::testing::MatcherInterface<Message3> {
+ public:
+  explicit MessageMatcher(Message3 goodmsg_) : goodmsg(std::move(goodmsg_)) {}
+
+  bool MatchAndExplain(Message3 msg,
+                       ::testing::MatchResultListener* listener) const override;
+  void DescribeTo(::std::ostream* os) const override;
+  void DescribeNegationTo(::std::ostream* os) const override;
+
+ private:
+  Message3 goodmsg;
+};
+
+inline ::testing::Matcher<Message3> MessageEq(Message3 goodmsg) {
+  return ::testing::MakeMatcher(new MessageMatcher(std::move(goodmsg)));
+}
+
+}  // namespace nt::net3
diff --git a/ntcore/src/test/native/cpp/net3/MockWireConnection3.h b/ntcore/src/test/native/cpp/net3/MockWireConnection3.h
new file mode 100644
index 0000000..b7c785f
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net3/MockWireConnection3.h
@@ -0,0 +1,44 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <stdint.h>
+
+#include <span>
+#include <vector>
+
+#include <wpi/raw_ostream.h>
+
+#include "gmock/gmock.h"
+#include "net3/WireConnection3.h"
+
+namespace nt::net3 {
+
+class MockWireConnection3 : public WireConnection3 {
+ public:
+  MockWireConnection3() : m_os{m_data} {}
+
+  MOCK_METHOD(bool, Ready, (), (const, override));
+
+  Writer Send() override { return {m_os, *this}; }
+
+  MOCK_METHOD(void, Data, (std::span<const uint8_t> data));
+
+  MOCK_METHOD(void, Flush, (), (override));
+
+  MOCK_METHOD(void, Disconnect, (std::string_view reason), (override));
+
+ protected:
+  void FinishSend() override {
+    Data(m_data);
+    m_data.resize(0);
+  }
+
+ private:
+  std::vector<uint8_t> m_data;
+  wpi::raw_uvector_ostream m_os;
+};
+
+}  // namespace nt::net3
diff --git a/ntcore/src/test/native/cpp/net3/WireDecoder3Test.cpp b/ntcore/src/test/native/cpp/net3/WireDecoder3Test.cpp
new file mode 100644
index 0000000..1cd6ecb
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net3/WireDecoder3Test.cpp
@@ -0,0 +1,276 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <stdint.h>
+
+#include <cfloat>
+#include <climits>
+#include <string>
+#include <string_view>
+
+#include "../SpanMatcher.h"
+#include "../TestPrinters.h"
+#include "../ValueMatcher.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "net3/WireDecoder3.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace std::string_view_literals;
+using testing::_;
+using testing::MockFunction;
+using testing::StrictMock;
+
+namespace nt {
+
+class MockMessageHandler3 : public net3::MessageHandler3 {
+ public:
+  MOCK_METHOD0(KeepAlive, void());
+  MOCK_METHOD0(ServerHelloDone, void());
+  MOCK_METHOD0(ClientHelloDone, void());
+  MOCK_METHOD0(ClearEntries, void());
+  MOCK_METHOD1(ProtoUnsup, void(unsigned int proto_rev));
+  MOCK_METHOD2(ClientHello,
+               void(std::string_view self_id, unsigned int proto_rev));
+  MOCK_METHOD2(ServerHello, void(unsigned int flags, std::string_view self_id));
+  MOCK_METHOD5(EntryAssign, void(std::string_view name, unsigned int id,
+                                 unsigned int seq_num, const Value& value,
+                                 unsigned int flags));
+  MOCK_METHOD3(EntryUpdate,
+               void(unsigned int id, unsigned int seq_num, const Value& value));
+  MOCK_METHOD2(FlagsUpdate, void(unsigned int id, unsigned int flags));
+  MOCK_METHOD1(EntryDelete, void(unsigned int id));
+  MOCK_METHOD3(ExecuteRpc, void(unsigned int id, unsigned int uid,
+                                std::span<const uint8_t> params));
+  MOCK_METHOD3(RpcResponse, void(unsigned int id, unsigned int uid,
+                                 std::span<const uint8_t> result));
+};
+
+class WireDecoder3Test : public ::testing::Test {
+ protected:
+  StrictMock<MockMessageHandler3> handler;
+  net3::WireDecoder3 decoder{handler};
+
+  void DecodeComplete(std::span<const uint8_t> in) {
+    decoder.Execute(&in);
+    EXPECT_TRUE(in.empty());
+    ASSERT_EQ(decoder.GetError(), "");
+  }
+};
+
+TEST_F(WireDecoder3Test, KeepAlive) {
+  EXPECT_CALL(handler, KeepAlive());
+  DecodeComplete("\x00"_us);
+}
+
+TEST_F(WireDecoder3Test, ClientHello) {
+  EXPECT_CALL(handler, ClientHello(std::string_view{"hello"}, 0x0300u));
+  DecodeComplete("\x01\x03\x00\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, ProtoUnsup) {
+  EXPECT_CALL(handler, ProtoUnsup(0x0300u));
+  EXPECT_CALL(handler, ProtoUnsup(0x0200u));
+  DecodeComplete("\x02\x03\x00\x02\x02\x00"_us);
+}
+
+TEST_F(WireDecoder3Test, ServerHelloDone) {
+  EXPECT_CALL(handler, ServerHelloDone());
+  DecodeComplete("\x03"_us);
+}
+
+TEST_F(WireDecoder3Test, ServerHello) {
+  EXPECT_CALL(handler, ServerHello(0x03, std::string_view{"hello"}));
+  DecodeComplete("\x04\x03\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, ClientHelloDone) {
+  EXPECT_CALL(handler, ClientHelloDone());
+  DecodeComplete("\x05"_us);
+}
+
+TEST_F(WireDecoder3Test, FlagsUpdate) {
+  EXPECT_CALL(handler, FlagsUpdate(0x5678, 0x03));
+  DecodeComplete("\x12\x56\x78\x03"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryDelete) {
+  EXPECT_CALL(handler, EntryDelete(0x5678));
+  DecodeComplete("\x13\x56\x78"_us);
+}
+
+TEST_F(WireDecoder3Test, ClearEntries) {
+  EXPECT_CALL(handler, ClearEntries());
+  DecodeComplete("\x14\xd0\x6c\xb2\x7a"_us);
+}
+
+TEST_F(WireDecoder3Test, ClearEntriesInvalid) {
+  auto in = "\x14\xd0\x6c\xb2\x7b"_us;
+  decoder.Execute(&in);
+  EXPECT_EQ(decoder.GetError(), "received incorrect CLEAR_ENTRIES magic value");
+}
+
+TEST_F(WireDecoder3Test, ExecuteRpc) {
+  EXPECT_CALL(handler, ExecuteRpc(0x5678, 0x1234, wpi::SpanEq("hello"_us)));
+  DecodeComplete("\x20\x56\x78\x12\x34\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, RpcResponse) {
+  EXPECT_CALL(handler, RpcResponse(0x5678, 0x1234, wpi::SpanEq("hello"_us)));
+  DecodeComplete("\x21\x56\x78\x12\x34\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, UnknownMessage) {
+  auto in = "\x23"_us;
+  decoder.Execute(&in);
+  EXPECT_EQ(decoder.GetError(), "unrecognized message type: 35");
+}
+
+TEST_F(WireDecoder3Test, EntryAssignBoolean) {
+  EXPECT_CALL(handler, EntryAssign("test"sv, 0x5678, 0x1234,
+                                   Value::MakeBoolean(true), 0x9a));
+  DecodeComplete("\x10\x04test\x00\x56\x78\x12\x34\x9a\x01"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryAssignDouble) {
+  EXPECT_CALL(handler, EntryAssign("test"sv, 0x5678, 0x1234,
+                                   Value::MakeDouble(2.3e5), 0x9a));
+  DecodeComplete(
+      "\x10\x04test\x01\x56\x78\x12\x34"
+      "\x9a\x41\x0c\x13\x80\x00\x00\x00\x00"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateBoolean) {
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeBoolean(true)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x00\x01"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateDouble) {
+  // values except min and max from
+  // http://www.binaryconvert.com/result_double.html
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeDouble(0.0)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x01\x00\x00\x00\x00\x00\x00\x00\x00"_us);
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeDouble(2.3e5)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x01\x41\x0c\x13\x80\x00\x00\x00\x00"_us);
+  EXPECT_CALL(
+      handler,
+      EntryUpdate(0x5678, 0x1234,
+                  Value::MakeDouble(std::numeric_limits<double>::infinity())));
+  DecodeComplete("\x11\x56\x78\x12\x34\x01\x7f\xf0\x00\x00\x00\x00\x00\x00"_us);
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeDouble(DBL_MIN)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x01\x00\x10\x00\x00\x00\x00\x00\x00"_us);
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeDouble(DBL_MAX)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x01\x7f\xef\xff\xff\xff\xff\xff\xff"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateString) {
+  EXPECT_CALL(handler,
+              EntryUpdate(0x5678, 0x1234, Value::MakeString("hello"sv)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x02\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateString2) {
+  std::vector<uint8_t> in{0x11, 0x56, 0x78, 0x12, 0x34, 0x02, 0x7f};
+  in.insert(in.end(), 127, '*');
+  std::string out(127, '*');
+  EXPECT_CALL(handler,
+              EntryUpdate(0x5678, 0x1234, Value::MakeString(std::move(out))));
+  DecodeComplete(in);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateStringLarge) {
+  std::vector<uint8_t> in{0x11, 0x56, 0x78, 0x12, 0x34, 0x02, 0x80, 0x01};
+  in.insert(in.end(), 127, '*');
+  in.push_back('x');
+
+  std::string out(127, '*');
+  out.push_back('x');
+
+  EXPECT_CALL(handler,
+              EntryUpdate(0x5678, 0x1234, Value::MakeString(std::move(out))));
+  DecodeComplete(in);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateStringHuge) {
+  std::vector<uint8_t> in{0x11, 0x56, 0x78, 0x12, 0x34, 0x02, 0x81, 0x80, 0x04};
+  in.insert(in.end(), 65534, '*');
+  in.insert(in.end(), 3, 'x');
+
+  std::string out(65534, '*');
+  out.append(3, 'x');
+
+  EXPECT_CALL(handler,
+              EntryUpdate(0x5678, 0x1234, Value::MakeString(std::move(out))));
+  DecodeComplete(in);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateRaw) {
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeRaw("hello"_us)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x03\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateBooleanArray) {
+  EXPECT_CALL(handler,
+              EntryUpdate(0x5678, 0x1234,
+                          Value::MakeBooleanArray({false, true, false})));
+  DecodeComplete("\x11\x56\x78\x12\x34\x10\x03\x00\x01\x00"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateBooleanArrayLarge) {
+  std::vector<uint8_t> in{0x11, 0x56, 0x78, 0x12, 0x34, 0x10, 0xff};
+  in.insert(in.end(), 255, 0);
+  std::vector<int> out(255, 0);
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234,
+                                   Value::MakeBooleanArray(std::move(out))));
+  DecodeComplete(in);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateDoubleArray) {
+  EXPECT_CALL(handler,
+              EntryUpdate(0x5678, 0x1234, Value::MakeDoubleArray({0.5, 0.25})));
+  DecodeComplete(
+      "\x11\x56\x78\x12\x34\x11\x02"
+      "\x3f\xe0\x00\x00\x00\x00\x00\x00"
+      "\x3f\xd0\x00\x00\x00\x00\x00\x00"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateDoubleArrayLarge) {
+  std::vector<uint8_t> in{0x11, 0x56, 0x78, 0x12, 0x34, 0x11, 0xff};
+  in.insert(in.end(), 255 * 8, 0);
+  std::vector<double> out(255, 0.0);
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234,
+                                   Value::MakeDoubleArray(std::move(out))));
+  DecodeComplete(in);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateStringArray) {
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234,
+                                   Value::MakeStringArray({"hello", "bye"})));
+  DecodeComplete(
+      "\x11\x56\x78\x12\x34\x12\x02\x05hello\x03"
+      "bye"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateStringArrayLarge) {
+  std::vector<uint8_t> in{0x11, 0x56, 0x78, 0x12, 0x34, 0x12, 0xff};
+  in.insert(in.end(), 255, 0);
+  std::vector<std::string> out(255, "");
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234,
+                                   Value::MakeStringArray(std::move(out))));
+  DecodeComplete(in);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateRpc) {
+  // RPC values are decoded as raw
+  EXPECT_CALL(handler, EntryUpdate(0x5678, 0x1234, Value::MakeRaw("hello"_us)));
+  DecodeComplete("\x11\x56\x78\x12\x34\x20\x05hello"_us);
+}
+
+TEST_F(WireDecoder3Test, EntryUpdateTypeError) {
+  auto in = "\x11\x56\x78\x12\x34\x30\x11"_us;
+  decoder.Execute(&in);
+  ASSERT_EQ(decoder.GetError(), "unrecognized value type");
+}
+
+}  // namespace nt
diff --git a/ntcore/src/test/native/cpp/net3/WireEncoder3Test.cpp b/ntcore/src/test/native/cpp/net3/WireEncoder3Test.cpp
new file mode 100644
index 0000000..bb4bfd2
--- /dev/null
+++ b/ntcore/src/test/native/cpp/net3/WireEncoder3Test.cpp
@@ -0,0 +1,283 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <cfloat>
+#include <climits>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include <wpi/raw_ostream.h>
+
+#include "../SpanMatcher.h"
+#include "../TestPrinters.h"
+#include "gtest/gtest.h"
+#include "net3/Message3.h"
+#include "net3/WireEncoder3.h"
+#include "networktables/NetworkTableValue.h"
+
+using namespace std::string_view_literals;
+
+namespace nt {
+
+class WireEncoder3Test : public ::testing::Test {
+ protected:
+  std::vector<uint8_t> out;
+  wpi::raw_uvector_ostream os{out};
+};
+
+TEST_F(WireEncoder3Test, Unknown) {
+  net3::WireEncode(os, net3::Message3{});
+  ASSERT_TRUE(out.empty());
+}
+
+TEST_F(WireEncoder3Test, KeepAlive) {
+  net3::WireEncode(os, net3::Message3::KeepAlive());
+  ASSERT_THAT(out, wpi::SpanEq("\x00"_us));
+}
+
+TEST_F(WireEncoder3Test, ClientHello) {
+  net3::WireEncode(os, net3::Message3::ClientHello("hello"));
+  ASSERT_THAT(out, wpi::SpanEq("\x01\x03\x00\x05hello"_us));
+}
+
+TEST_F(WireEncoder3Test, ProtoUnsup) {
+  net3::WireEncode(os, net3::Message3::ProtoUnsup());
+  net3::WireEncode(os, net3::Message3::ProtoUnsup(0x0200u));
+  ASSERT_THAT(out, wpi::SpanEq("\x02\x03\x00\x02\x02\x00"_us));
+}
+
+TEST_F(WireEncoder3Test, ServerHelloDone) {
+  net3::WireEncode(os, net3::Message3::ServerHelloDone());
+  ASSERT_THAT(out, wpi::SpanEq("\x03"_us));
+}
+
+TEST_F(WireEncoder3Test, ServerHello) {
+  net3::WireEncode(os, net3::Message3::ServerHello(0x03, "hello"));
+  ASSERT_THAT(out, wpi::SpanEq("\x04\x03\x05hello"_us));
+}
+
+TEST_F(WireEncoder3Test, ClientHelloDone) {
+  net3::WireEncode(os, net3::Message3::ClientHelloDone());
+  ASSERT_THAT(out, wpi::SpanEq("\x05"_us));
+}
+
+TEST_F(WireEncoder3Test, FlagsUpdate) {
+  net3::WireEncode(os, net3::Message3::FlagsUpdate(0x5678, 0x03));
+  ASSERT_THAT(out, wpi::SpanEq("\x12\x56\x78\x03"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryDelete) {
+  net3::WireEncode(os, net3::Message3::EntryDelete(0x5678));
+  ASSERT_THAT(out, wpi::SpanEq("\x13\x56\x78"_us));
+}
+
+TEST_F(WireEncoder3Test, ClearEntries) {
+  net3::WireEncode(os, net3::Message3::ClearEntries());
+  ASSERT_THAT(out, wpi::SpanEq("\x14\xd0\x6c\xb2\x7a"_us));
+}
+
+TEST_F(WireEncoder3Test, ExecuteRpc) {
+  net3::WireEncode(os, net3::Message3::ExecuteRpc(0x5678, 0x1234, "hello"_us));
+  ASSERT_THAT(out, wpi::SpanEq("\x20\x56\x78\x12\x34\x05hello"_us));
+}
+
+TEST_F(WireEncoder3Test, RpcResponse) {
+  net3::WireEncode(os, net3::Message3::RpcResponse(0x5678, 0x1234, "hello"_us));
+  ASSERT_THAT(out, wpi::SpanEq("\x21\x56\x78\x12\x34\x05hello"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryAssignBoolean) {
+  net3::WireEncode(os,
+                   net3::Message3::EntryAssign("test"sv, 0x5678, 0x1234,
+                                               Value::MakeBoolean(true), 0x9a));
+  ASSERT_THAT(out, wpi::SpanEq("\x10\x04test\x00\x56\x78\x12\x34\x9a\x01"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryAssignDouble) {
+  net3::WireEncode(os,
+                   net3::Message3::EntryAssign("test"sv, 0x5678, 0x1234,
+                                               Value::MakeDouble(2.3e5), 0x9a));
+  ASSERT_THAT(out, wpi::SpanEq("\x10\x04test\x01\x56\x78\x12\x34"
+                               "\x9a\x41\x0c\x13\x80\x00\x00\x00\x00"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateBoolean) {
+  net3::WireEncode(os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                                   Value::MakeBoolean(true)));
+  ASSERT_THAT(out, wpi::SpanEq("\x11\x56\x78\x12\x34\x00\x01"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateDouble) {
+  // values except min and max from
+  // http://www.binaryconvert.com/result_double.html
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234, Value::MakeDouble(0.0)));
+  ASSERT_THAT(
+      out, wpi::SpanEq(
+               "\x11\x56\x78\x12\x34\x01\x00\x00\x00\x00\x00\x00\x00\x00"_us));
+
+  out.clear();
+  net3::WireEncode(os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                                   Value::MakeDouble(2.3e5)));
+  ASSERT_THAT(
+      out, wpi::SpanEq(
+               "\x11\x56\x78\x12\x34\x01\x41\x0c\x13\x80\x00\x00\x00\x00"_us));
+
+  out.clear();
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(
+              0x5678, 0x1234,
+              Value::MakeDouble(std::numeric_limits<double>::infinity())));
+  ASSERT_THAT(
+      out, wpi::SpanEq(
+               "\x11\x56\x78\x12\x34\x01\x7f\xf0\x00\x00\x00\x00\x00\x00"_us));
+
+  out.clear();
+  net3::WireEncode(os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                                   Value::MakeDouble(DBL_MIN)));
+  ASSERT_THAT(
+      out, wpi::SpanEq(
+               "\x11\x56\x78\x12\x34\x01\x00\x10\x00\x00\x00\x00\x00\x00"_us));
+
+  out.clear();
+  net3::WireEncode(os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                                   Value::MakeDouble(DBL_MAX)));
+  ASSERT_THAT(
+      out, wpi::SpanEq(
+               "\x11\x56\x78\x12\x34\x01\x7f\xef\xff\xff\xff\xff\xff\xff"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateString) {
+  net3::WireEncode(os, net3::Message3::EntryUpdate(
+                           0x5678, 0x1234, Value::MakeString("hello"sv)));
+  ASSERT_THAT(out, wpi::SpanEq("\x11\x56\x78\x12\x34\x02\x05hello"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateString2) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x02, 0x7f};
+  ex.insert(ex.end(), 127, '*');
+  std::string in(127, '*');
+  net3::WireEncode(os, net3::Message3::EntryUpdate(
+                           0x5678, 0x1234, Value::MakeString(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateStringLarge) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x02, 0x80, 0x01};
+  ex.insert(ex.end(), 127, '*');
+  ex.push_back('x');
+
+  std::string in(127, '*');
+  in.push_back('x');
+
+  net3::WireEncode(os, net3::Message3::EntryUpdate(
+                           0x5678, 0x1234, Value::MakeString(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateStringHuge) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x02, 0x81, 0x80, 0x04};
+  ex.insert(ex.end(), 65534, '*');
+  ex.insert(ex.end(), 3, 'x');
+
+  std::string in(65534, '*');
+  in.append(3, 'x');
+
+  net3::WireEncode(os, net3::Message3::EntryUpdate(
+                           0x5678, 0x1234, Value::MakeString(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateRaw) {
+  net3::WireEncode(os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                                   Value::MakeRaw("hello"_us)));
+  ASSERT_THAT(out, wpi::SpanEq("\x11\x56\x78\x12\x34\x03\x05hello"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateBooleanArray) {
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(
+              0x5678, 0x1234, Value::MakeBooleanArray({false, true, false})));
+  ASSERT_THAT(out, wpi::SpanEq("\x11\x56\x78\x12\x34\x10\x03\x00\x01\x00"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateBooleanArrayLarge) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x10, 0xff};
+  ex.insert(ex.end(), 255, 0);
+  std::vector<int> in(255, 0);
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeBooleanArray(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateBooleanArrayTrunc) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x10, 0xff};
+  ex.insert(ex.end(), 255, 0);
+  std::vector<int> in(256, 0);
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeBooleanArray(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateDoubleArray) {
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeDoubleArray({0.5, 0.25})));
+  ASSERT_THAT(out, wpi::SpanEq("\x11\x56\x78\x12\x34\x11\x02"
+                               "\x3f\xe0\x00\x00\x00\x00\x00\x00"
+                               "\x3f\xd0\x00\x00\x00\x00\x00\x00"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateDoubleArrayLarge) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x11, 0xff};
+  ex.insert(ex.end(), 255 * 8, 0);
+  std::vector<double> in(255, 0.0);
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeDoubleArray(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateDoubleArrayTrunc) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x11, 0xff};
+  ex.insert(ex.end(), 255 * 8, 0);
+  std::vector<double> in(256, 0.0);
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeDoubleArray(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateStringArray) {
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(
+              0x5678, 0x1234, Value::MakeStringArray({"hello", "bye"})));
+  ASSERT_THAT(out, wpi::SpanEq("\x11\x56\x78\x12\x34\x12\x02\x05hello\x03"
+                               "bye"_us));
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateStringArrayLarge) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x12, 0xff};
+  ex.insert(ex.end(), 255, 0);
+  std::vector<std::string> in(255, "");
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeStringArray(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+TEST_F(WireEncoder3Test, EntryUpdateStringArrayTrunc) {
+  std::vector<uint8_t> ex{0x11, 0x56, 0x78, 0x12, 0x34, 0x12, 0xff};
+  ex.insert(ex.end(), 255, 0);
+  std::vector<std::string> in(256, "");
+  net3::WireEncode(
+      os, net3::Message3::EntryUpdate(0x5678, 0x1234,
+                                      Value::MakeStringArray(std::move(in))));
+  ASSERT_THAT(out, ex);
+}
+
+}  // namespace nt
