Squashed 'third_party/allwpilib_2019/' changes from 99e4f7dd2..c36bbcc9a

936627bd9 wpilibc: Remove direct CameraServer dependency (#1989)
8e333c0aa Use FPGA Time instead of wall clock time for odometry (#1996)
d4430b765 Gearsbot example: Use standard argument order (#1995)
75438ab2c Add RamseteCommand (#1951)
989df1b46 Bump Native Utils and OpenCV dependencies (#1993)
dbc33b61e Fix Timer usage in TrapezoidProfileCommand (#1992)
79f8c5644 Add TrapezoidProfileCommand (#1962)
9440edf2b Refactor TrajectoryGenerator (#1972)
73a30182c Add frc2::Timer (#1968)
36ea865ed Add toString for geometry and trajectory classes (#1991)
cbe05e7e8 Update ProfiledPIDController API (#1967)
d04eb3546 Deprecate old PID classes (#1964)
02264db69 Add JNI dependencies to myRobotCpp (#1980)
2a76c996e Use VID/PID detection for PS3Eye (#1977)
a3820bbdf Remove HAL_BaseInitialize (#1981)
a83fb4793 Update to 2020v5 image (#1983)
4b0ed910e Make SwerveDriveKinematics.toChassisSpeeds() public (#1976)
103c1b121 Remove DS caching from the HAL level (#1971)
6635ea75e Fix NPE in SendableRegistry.foreachLiveWindow() (#1974)
cfe23c5cd Fix grammar error in comment for configureButtonBindings (#1969)
4bde2654e Fix mac azure build (#1973)
4f034e6c1 generateTrajectory: default reversed param to false (#1953)
acf960f72 Sim GUI: Add option to disable outputs on DS disable
2d3dac99f Sim GUI: Handle low resolutions and scale default window positions
07c86e0cd Sim GUI: Support High DPI monitors
46ad95512 SimDeviceData: Add missing null check
5bce489b9 Add ProggyDotted font to imgui (both cmake and gradle)
55af553ac Simulation GUI: Map gamepad the same way as DS
c59f9cea5 CameraServer: Add VID/PID support for Linux USB devices (#1960)
3fc89c84d Make splinePointsFromSplines public (#1963)
2c5093797 Fix implicitly deleted move constructors (#1954)
f3ad927f4 Update Java SmartDashboard and LiveWindow to match C++
05c25deb7 Fix move handling of C++ Sendable in SmartDashboard and LiveWindow
d726591ce Fix Gazebo sim plugin build (#1959)
2ff694fa4 Unbreak gradle build when other compilers installed (#1958)
53816155b Improve command decorator names (#1945)
a38f183a9 Fix GenResources.cmake so it's usable in a submodule (#1956)
b3398dca3 Set gradlebase correctly for all examples (#1950)
2c311013d Add Aarch64Bionic platform detection (#1922)
c10f2003c Add generateTrajectory overload (#1944)
63cfa64fb Add getters for pose in odometry classes (#1943)
2402c2bad Fix C++ command group recursive constructor bug (#1941)
f4eedf597 Fix ConcurrentModificationException in CommandScheduler (#1938)
bb0b207d2 Fix array out of bounds exception caused by parallel race group (#1935)
7bd69e591 Fix typo in temperature (#1940)
ec9738245 Bump to 2020 v4 image (#1931)
46303a822 Add messaging to extension loading in the HAL (#1926)
d169d6be9 Set extract_static for Doxygen config so that static members show up (#1930)
4e183eb10 Bump to 2020 v3 image (#1929)
84c185803 LiveWindow: catch errors in callback/builder functions (#1921)
0e3b0f3da Remove deprecated free() calls (#1925)
7f839b87c Remove timeouts from azure builds (#1924)
45b766a5d Fix main thread ID being potentially incorrect for simulation (#1923)
56d782b16 Add secondary camera name for PS3Eye (#1920)
2b4894038 Add simulation GUI plugin
f97d16073 Add imgui build to cmake
55a844a3e HAL sim: Add encoder channel B access
10deba854 Remove sendables from SendableRegistry when close() is called (#1917)
a9f0e4668 Implement sim devices for ADXL345, ADXL362, ADXRS450, Ultrasonic
aa9064586 Add ability to associate other devices with a SimDevice
81c2c8a7d Add simulation generic device/value support
e8d6f8a2c Move mockdata/HAL_Value.h to hal/Value.h
1b266717a Add simulation module support to cmake build (#1906)
fb8f3bd06 Add testbench yaml file (#1915)
846d8def0 Update to 2020 v2 image (#1913)
d6ac6e512 Fix PortForwarder package declaration (#1912)
227157086 Fix PS3Eye exposure setting (#1911)
885744d7e Add myRobot C++ version to cmake build (#1907)
366091fa8 Document that ConditionalCommand requires all subsystems (#1909)
c58b072c8 Fix Drive usage reporting order (#1908)
762c88adb Update compiler versions in readme (#1905)
af8ce568d Add Ramsete unicycle controller (#1790)
b2c2934d0 Fix javadoc warnings about invalid usage of ">" (#1904)
cce26ec78 Replace CRLF line endings with LF (#1902)
cb54602d4 Add support for writing RTR CAN Frames to the CAN API (#1900)
9f740e590 Use OS for serial port instead of NI VISA (#1875)
b23baf611 Add ability to run robot main loop in a separate thread (#1895)
457f94ba2 Add trajectory generation using hermite splines (#1843)
fd612052f Update native utils to use new frchome directory (#1884)
8858ec55c Remove periodic can read call (#1868)
41efb8015 Update CANAPITypes.h (#1860)
c93be1b2d Remove LabVIEW HAL support (#1901)
680f8919e Remove eigen, units and libuv from doxygen generation (#1898)
c5812524f Bump GradleJNI plugin version (#1899)
971303da8 Add PortForwarder class (#1890)
50db77bf2 Fix wpiutil cmake eigen install source directory (#1891)
85d42c199 C++ PIDCommand: Add GetMeasurement() and UseOutput() (#1892)
2dfbb855d wpilibj: Fix SwerveDriveKinematics ctor parameter name (#1889)
471f375a3 Simplify Sendable interface (#1864)
1d8c4d016 Replace ::value and ::type with _v and _t suffixes (#1885)
a5650b943 Add Units Utility class for Java (#1829)
904479ad4 Deprecate GearTooth class for removal (#1878)
86b666bba Add equality comparator to geometry classes (#1882)
62f07c182 Make one-arg Rotation2d constructor implicit (#1883)
f405582f8 Add kinematics suite (#1787)
561cbbd14 Deprecate Filter class for removal (#1876)
84e2973aa Remove unused include from Filesystem.h (#1877)
f49859ebf Remove NI VISA headers, as they are now included in NI Libraries (#1879)
bc59db5e6 Rename DEBUG macro to DEBUG0 (#1871)
dd928b4cb Remove JNI logging (#1872)
3e0f7d099 Use units for new NotifierCommand (#1869)
5ffe15d5f Remove ability to build all combined artifacts (#1867)
516cbef2c  Remove RoboRIO ifdef from simulation headers (#1859)
9b6ffc201 Replace SetOutputRange() with SetIntegratorRange()
ff8b8f0a8 Remove percent tolerance from PID controller
0ca8d667d Clean up AutoCloseable and other Java warnings (#1866)
7112add67 Watchdog: use units::second_t instead of double (#1863)
761bc3ef8 Change C++ WaitCommand to use units (#1865)
1fb301123 Add MathUtils.clamp() for Java (#1861)
eb3e0c9c9 Fix cmake Eigen include directory (#1862)
2250b7fbe Rename GearsBotNew example to GearsBot
c9f9feff1 Replace deprecated API usage in C++ examples
d6b9c7e14 CONTRIBUTING.md: Point to frc-docs instead of screensteps (#1858)
d10a1a797 Fix eigen build in vcpkg (#1856)
2bdb44325 Add frc2 includes to list of "other lib" regexes (#1855)
4b2b21d24 Replace outdated Java collections (#508)
8993ce5bf Move Eigen headers out of main include folder (#1854)
0f532a117 Add PWMSparkMax (#1751)
f7ad363d8 Add jni cross compile options for aarch64 (#1853)
9afea3340 Add support for aarch64 jetson bionic builds (#1844)
d787b5d60 Add more items to .gitignore (#1850)
5dd0d1b7d Use units in SPI
07ac711b3 Fix units deprecated warning in IterativeRobot
decfd858b Correctly report -1 for POV on disconnected joystick (#1852)
076ed7770 Add new C++ Command framework (#1785)
a0be07c37 Refactor HAL handle move construction/assignment (#1845)
558c38308 Add new Java Command framework (#1682)
1379735af Delete RobotState and SensorUtil constructors (#1847)
e3d86fee4 Move circular buffer class from wpilib to wpiutil (#1840)
4cd8a5667 TimedRobot.cpp: Fix deprecation warning (#1846)
b2861f894 Use 2020 artifacts and artifactory server (#1838)
98cc32703 Update to use artifactory to publish artifacts (#1833)
fa0640300 Move drive integration tests into wpilibj/src/test (#1836)
e716c36b8 Fix Nat.java generation to be incremental (#1831)
9fd2b5e3f Fix MSVC builds on cmake windows in vcpkg (#1835)
7e95010a2 Add compile-time EJML matrix wrapper to wpiutil (#1804)
3ebc5a6d3 Add ProfiledPIDController
fc98a79db Clean up PIDController interface in preparation for ProfiledPIDController
fdc098267 Fix compilation error in elevator trapezoid profile example (#1826)
a3dd84e85 Make XBoxController Button enum public (#1823)
a216b9e9e Add TrapezoidProfile example (#1814)
8f386f6bb wpilibc: Add unit-safety to C++ geometry classes (#1811)
c07ac2353 wpilibc: Add overloads for units (#1815)
f1d71da8a Move GetStackTrace and Demangle to wpiutil, add Windows support (#1819)
ef037457e Make LinearFilter copyable and moveable (#1789)
76930250c Remove objective-cpp support (#1816)
1c246418f Move TrapezoidProfileTest to trajectory folder (#1812)
95a54a0f2 Add java arcade drive example (#1810)
a4530243e HAL sim: Fix incorrectly setting dio port to initialized on cleanup (#1813)
09d00a622 Update Java examples to use new PIDController (#1809)
ba9b51742 Add missing Java examples (#841)
6411bd79c InterruptableSensorBase: Fix callback function deletion (#1807)
810e58ea8 I2C: Add tip about writeBulk() to transaction() (#1806)
607d6c148 Fix wpilibj integration tests jar name (#1808)
c9873e81b Remove PIDControllerRunner and mutex from new PIDController (#1795)
98d0706de Fix cscore build with OpenCV 4 (#1803)
fbe67c90c Make Sendable setters synchronous (#1799)
c67a488a0 Format SendableBuilderImpl javadocs (#1802)
8e93ce892 Fix PIDControllerRunner member destruction order (#1801)
c98ca7310 Add EJML dependency to wpiutil (#1769)
3b12276bc SendableBase: remove unnecessary synchronization (#1797)
e6d348f38 Fix missing default name in Java PIDController (#1792)
df12fc2a8 Java cleanups (#1776)
39561751f Update GradleVSCode version (#1786)
37d316aa0 Add C++20 std::math constants shim (#1788)
dd4310959 Deprecate frc/WPILib.h (#1779)
823174f30 Update native utils to 2020.0.4 (#1783)
37c695266 Squelch -Wdeprecated-copy for Eigen with GCC >= 9
04c9b000f Revert "Fix build of Eigen 3.3.7 with GCC 9"
ca3e71e21 wpiutil: Fix Process::Spawn() (#1778)
d946d5a2b Fix Eigen compilation errors and add tests (#1777)
8b1b9ac75 Fix build of Eigen 3.3.7 with GCC 9
2f680ba99 Add Eigen linear algebra library
a885db7d4 Make MotorEncoderTest use LinearFilter (#1775)
ee2410169 Add geometry classes (#1766)
48fe54271 Add HALSIM_SetSendError implementation (#1773)
dff58c87f Fix unused warning in release build (#1771)
dde61aad3 Remove TimerEventHandler typedef from Notifier class (#1767)
0f6ef80ab Add RobotState#IsEStopped and DriverStation#IsEStopped (#952)
e48886187 Move unit tests from integration test suite (#1170)
dffa1a5cb Make null checks more descriptive (#1688)
fe59d854d Notifier: add null check (#1684)
10731f3d6 Update uv Udp wrapper for latest features
89f7b72b6 Update libuv to 1.30.1 release
85f2f8740 wpiutil: Add unique_function (#1761)
73ec94078 Remove SampleRobot (#1658)
62be0392b Replace std::lock_guard and std::lock with std::scoped_lock (#1758)
24d31df55 Make sure move constructor is generated for TrapezoidProfile (#1757)
841ef5d73 Remove template types from lock RAII wrapper usages (#1756)
e582518ba Fix some move constructors (#1754)
8757bc471 Remove pre-C++17 shims (#1752)
ea9512977 Add replacement PIDController class (#1300)
9b798d228 Add TrapezoidProfile class (#1673)
804926fb5 Unconditionally skip athena builds for sim (#1748)
118e9d29d Add C++14 units library (#1749)
c705953d7 Add usage reporting to LinearFilter (#1750)
852d1b9ca Don't cross-build gazebo for raspbian (#1747)
eedb3a1ad Fix GCC 9 warnings (#1730)
60dce66a4 Remove wpi::ArrayRef std::initializer_list constructor (#1745)
9e19b29c3 Use base azure image for primary wpilib build (#1744)
299425071 Update jni library, fix cross builds of the jni symbol check (#1742)
a6b0e9b85 Only disable execution of cross compile google tests (#1741)
3c2093119 Use docker container to run wpiformat (#1740)
5fe2eebce Revert "Don't build halsim_gazebo on raspbian (#1737)" (#1743)
4b1b92bb7 Replace wpi::optional with C++17 std::optional (#1732)
0fbb0d989 Update to 2020 compilers (#1733)
2dc94e605 Disable google tests on cross compilers (#1738)
d9cb57a42 Don't build halsim_gazebo on raspbian (#1737)
f7cfdd7ce Replace crlf line endings with lf (#1731)
b6d5d90d9 Add JaCoCo Support (#1734)
c7ab2baa6 Add way to disable the jni check tasks from a property (#1736)
0c45c5b7e Fix skip athena and skip raspbian flags (#1735)
3dfb01d45 Update to new Native Utils (#1696)
30e936837 Clean up LinearDigitalFilter class (#782)
311e2de4c Remove deprecated Joystick constants (#1715)
c08fd6682 Update CAN manufacturer list (#1706)
258bba0c2 ErrorBase and WPIError improvements (#1727)
372ca4f45 cmake: Enable googletest unit tests (#1720)
223d47af0 HALSIM: support mocking of HAL_SendError() (#1728)
55cb683db Change compiler flags to C++17 (#1723)
ee8a33c56 wpiutil: SafeThread: Add thread id, support getting shared_ptr (#1722)
61426d08d wpiutil: Signal: make operator() const (#1721)
b630b63ef Remove functions in LiveWindow deprecated since 2018 (#1716)
1d0c05d4f Styleguide fixes for #1718 (#1719)
f07569df1 Fix newer GCC/clang compiler warnings (#1718)
0120f3124 C++ SPI: Fix SetClockRate to take int (#1717)
c2829ed98 Configure gradle to ignore unresolved headers (#1711)
221e66f46 Allow disabling static init of JNI libraries (#1672)
738852e11 cmake: Add cross toolchain files for Rio and Pi (#1710)
27b697b08 Remove frc directory include shims (#1714)
9e45373a7 Remove functions and classes deprecated for 2018 season (#1059)
eeb1025ac SPI: Report port as instance for usage reporting (#1704)
bc6f1e246 Windows compiler options improvements (#1709)
bb48ae391 cmake: Move example programs into folders (#1654)
221011494 Update for C++17 and fix MSVC warnings (#1694)
fb1239a2a Add raw sources and sinks to cscore (#1670)
7de947734 Add lambda overloads for interrupts (#1636)
90957aeea Move libuv to its own subfolder in build (#1661)
47aae502a Styleguide fixes (#1702)
0bff98b5e Correct DifferentialDrive::ArcadeDrive param docs (#1698)
b52e40b80 Allow widgets to be added by passing value suppliers (#1690)
4a00cd77b Add usage reporting for the Shuffleboard API (#1685)
e25e515f2  Publish artifacts on azure (#1678)
322ef9b96 Force Java 11, fix javadoc generation (#1695)
d42ef5df0 Fix Watchdog print formatting (#1693)
f432f65be Update copyright year in license to 2019 (#1524)
1726b77ac wpiutil: uv: Remove copy from SimpleBufferPool (#1680)
620bec9ca wpiutil: uv: Add LoopClosing status to Handle (#1647)
7cd6e2e7f UsbCamera: Solve race in windows initialization (#1638)
7732836bd Completely disable watchdog tests on mac (#1679)
698edfda9 Remove framework load, disable mac timeout test (#1676)
1c454b000 Add Shuffleboard calls to IterativeRobotBase in C++ (#1607)
f42905b32 Include missing headers in HAL.h (#1660)
bdc822fad Only generate passthrough URLs for RoboRIO (#1624)
d3affb16b Make failure of HAL_GetFPGATime() more descriptive (#1633)
2de3bf7f5 Update LLVM from stable upstream (#1653)
3cf4f38f5 Fix build on macos10.14.4 (#1648)
4e0c10f48 Fix CAN Clean using wrong ID (#1668)
3b0631324 Fix Gray to BGR conversion in CameraServer (#1665)
6cd1c73ef Fix GUID comparison creating weird symbol (#1659)
063bbab6f MavenArtifacts.md: update links to HTTPS (#1674)
aab4c494d Fix type in build.gradle (#1604)
bf46af260 Disable extraneous data warnings in libjpeg (#1630)
655763a9a Limit length of message sent to DS SendError call (#1618)
a095ec2d8 Fix linker errors with free functions in Threads.h (#1625)
12ab035aa Fix receive side of LabVIEW USB streams (#1621)

Change-Id: Ibd382e1a48925c200850cf90a8121e35c0fcffe3
git-subtree-dir: third_party/allwpilib_2019
git-subtree-split: c36bbcc9a9095489fc078229db4fba3ecd0f9b78
diff --git a/hal/src/main/native/cpp/Main.cpp b/hal/src/main/native/cpp/Main.cpp
new file mode 100644
index 0000000..a37c2b0
--- /dev/null
+++ b/hal/src/main/native/cpp/Main.cpp
@@ -0,0 +1,64 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Main.h"
+
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+
+static void DefaultMain(void*);
+static void DefaultExit(void*);
+
+static bool gHasMain = false;
+static void* gMainParam = nullptr;
+static void (*gMainFunc)(void*) = DefaultMain;
+static void (*gExitFunc)(void*) = DefaultExit;
+static bool gExited = false;
+struct MainObj {
+  wpi::mutex gExitMutex;
+  wpi::condition_variable gExitCv;
+};
+
+static MainObj* mainObj;
+
+static void DefaultMain(void*) {
+  std::unique_lock lock{mainObj->gExitMutex};
+  mainObj->gExitCv.wait(lock, [] { return gExited; });
+}
+
+static void DefaultExit(void*) {
+  std::lock_guard lock{mainObj->gExitMutex};
+  gExited = true;
+  mainObj->gExitCv.notify_all();
+}
+
+namespace hal {
+namespace init {
+void InitializeMain() {
+  static MainObj mO;
+  mainObj = &mO;
+}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+
+void HAL_SetMain(void* param, void (*mainFunc)(void*),
+                 void (*exitFunc)(void*)) {
+  gHasMain = true;
+  gMainParam = param;
+  gMainFunc = mainFunc;
+  gExitFunc = exitFunc;
+}
+
+HAL_Bool HAL_HasMain(void) { return gHasMain; }
+
+void HAL_RunMain(void) { gMainFunc(gMainParam); }
+
+void HAL_ExitMain(void) { gExitFunc(gMainParam); }
+
+}  // extern "C"
diff --git a/hal/src/main/native/cpp/cpp/fpga_clock.cpp b/hal/src/main/native/cpp/cpp/fpga_clock.cpp
index 751eae1..bcec155 100644
--- a/hal/src/main/native/cpp/cpp/fpga_clock.cpp
+++ b/hal/src/main/native/cpp/cpp/fpga_clock.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -21,8 +21,9 @@
   uint64_t currentTime = HAL_GetFPGATime(&status);
   if (status != 0) {
     wpi::errs()
-        << "Call to HAL_GetFPGATime failed."
-        << "Initialization might have failed. Time will not be correct\n";
+        << "Call to HAL_GetFPGATime failed in fpga_clock::now() with status "
+        << status
+        << ". Initialization might have failed. Time will not be correct\n";
     wpi::errs().flush();
     return epoch();
   }
diff --git a/hal/src/main/native/cpp/handles/HandlesInternal.cpp b/hal/src/main/native/cpp/handles/HandlesInternal.cpp
index 45ffb31..5e66ce1 100644
--- a/hal/src/main/native/cpp/handles/HandlesInternal.cpp
+++ b/hal/src/main/native/cpp/handles/HandlesInternal.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -17,7 +17,7 @@
 static wpi::mutex globalHandleMutex;
 HandleBase::HandleBase() {
   static wpi::SmallVector<HandleBase*, 32> gH;
-  std::lock_guard<wpi::mutex> lock(globalHandleMutex);
+  std::scoped_lock lock(globalHandleMutex);
   if (!globalHandles) {
     globalHandles = &gH;
   }
@@ -30,7 +30,7 @@
   }
 }
 HandleBase::~HandleBase() {
-  std::lock_guard<wpi::mutex> lock(globalHandleMutex);
+  std::scoped_lock lock(globalHandleMutex);
   auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
   if (index != globalHandles->end()) {
     *index = nullptr;
@@ -43,7 +43,7 @@
   }
 }
 void HandleBase::ResetGlobalHandles() {
-  std::unique_lock<wpi::mutex> lock(globalHandleMutex);
+  std::unique_lock lock(globalHandleMutex);
   for (auto&& i : *globalHandles) {
     if (i != nullptr) {
       lock.unlock();
diff --git a/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp b/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp
index 74c1b49..35b7414 100644
--- a/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp
+++ b/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -12,20 +12,10 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_AnalogGyroJNI.h"
 #include "hal/AnalogGyro.h"
-#include "hal/cpp/Log.h"
 #include "hal/handles/HandlesInternal.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel analogGyroJNILogLevel = logWARNING;
-
-#define ANALOGGYROJNI_LOG(level)     \
-  if (level > analogGyroJNILogLevel) \
-    ;                                \
-  else                               \
-    Log().Get(level)
-
 extern "C" {
 /*
  * Class:     edu_wpi_first_hal_AnalogGyroJNI
@@ -36,14 +26,9 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_initializeAnalogGyro
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI initializeAnalogGyro";
-  ANALOGGYROJNI_LOG(logDEBUG)
-      << "Analog Input Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_GyroHandle handle =
       HAL_InitializeAnalogGyro((HAL_AnalogInputHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << handle;
   // Analog input does range checking, so we don't need to do so.
   CheckStatusForceThrow(env, status);
   return (jint)handle;
@@ -58,11 +43,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_setupAnalogGyro
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI setupAnalogGyro";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   HAL_SetupAnalogGyro((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -75,8 +57,6 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_freeAnalogGyro
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI freeAnalogGyro";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   HAL_FreeAnalogGyro((HAL_GyroHandle)id);
 }
 
@@ -89,13 +69,9 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_setAnalogGyroParameters
   (JNIEnv* env, jclass, jint id, jdouble vPDPS, jdouble offset, jint center)
 {
-  ANALOGGYROJNI_LOG(logDEBUG)
-      << "Calling ANALOGGYROJNI setAnalogGyroParameters";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   HAL_SetAnalogGyroParameters((HAL_GyroHandle)id, vPDPS, offset, center,
                               &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -108,13 +84,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_setAnalogGyroVoltsPerDegreePerSecond
   (JNIEnv* env, jclass, jint id, jdouble vPDPS)
 {
-  ANALOGGYROJNI_LOG(logDEBUG)
-      << "Calling ANALOGGYROJNI setAnalogGyroVoltsPerDegreePerSecond";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
-  ANALOGGYROJNI_LOG(logDEBUG) << "vPDPS = " << vPDPS;
   int32_t status = 0;
   HAL_SetAnalogGyroVoltsPerDegreePerSecond((HAL_GyroHandle)id, vPDPS, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -127,11 +98,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_resetAnalogGyro
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI resetAnalogGyro";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   HAL_ResetAnalogGyro((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -144,11 +112,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_calibrateAnalogGyro
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI calibrateAnalogGyro";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   HAL_CalibrateAnalogGyro((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -161,11 +126,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_setAnalogGyroDeadband
   (JNIEnv* env, jclass, jint id, jdouble deadband)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI setAnalogGyroDeadband";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   HAL_SetAnalogGyroDeadband((HAL_GyroHandle)id, deadband, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -178,12 +140,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroAngle
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroAngle";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   jdouble value = HAL_GetAnalogGyroAngle((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
   CheckStatus(env, status);
   return value;
 }
@@ -197,12 +155,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroRate
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroRate";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   jdouble value = HAL_GetAnalogGyroRate((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
   CheckStatus(env, status);
   return value;
 }
@@ -216,12 +170,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroOffset
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroOffset";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   jdouble value = HAL_GetAnalogGyroOffset((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
   CheckStatus(env, status);
   return value;
 }
@@ -235,12 +185,8 @@
 Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroCenter
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroCenter";
-  ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
   int32_t status = 0;
   jint value = HAL_GetAnalogGyroCenter((HAL_GyroHandle)id, &status);
-  ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
   CheckStatus(env, status);
   return value;
 }
diff --git a/hal/src/main/native/cpp/jni/AnalogJNI.cpp b/hal/src/main/native/cpp/jni/AnalogJNI.cpp
index 3b2aa2d..abd614f 100644
--- a/hal/src/main/native/cpp/jni/AnalogJNI.cpp
+++ b/hal/src/main/native/cpp/jni/AnalogJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -16,20 +16,10 @@
 #include "hal/AnalogOutput.h"
 #include "hal/AnalogTrigger.h"
 #include "hal/Ports.h"
-#include "hal/cpp/Log.h"
 #include "hal/handles/HandlesInternal.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel analogJNILogLevel = logWARNING;
-
-#define ANALOGJNI_LOG(level)     \
-  if (level > analogJNILogLevel) \
-    ;                            \
-  else                           \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -41,11 +31,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_initializeAnalogInputPort
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
   int32_t status = 0;
   auto analog = HAL_InitializeAnalogInputPort((HAL_PortHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << analog;
   CheckStatusRange(env, status, 0, HAL_GetNumAnalogInputs(),
                    hal::getPortHandleChannel((HAL_PortHandle)id));
   return (jint)analog;
@@ -60,7 +47,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_freeAnalogInputPort
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_AnalogInputHandle)id;
   HAL_FreeAnalogInputPort((HAL_AnalogInputHandle)id);
 }
 
@@ -73,12 +59,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_initializeAnalogOutputPort
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
   int32_t status = 0;
   HAL_AnalogOutputHandle analog =
       HAL_InitializeAnalogOutputPort((HAL_PortHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << analog;
   CheckStatusRange(env, status, 0, HAL_GetNumAnalogOutputs(),
                    hal::getPortHandleChannel((HAL_PortHandle)id));
   return (jlong)analog;
@@ -93,7 +76,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_freeAnalogOutputPort
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << id;
   HAL_FreeAnalogOutputPort((HAL_AnalogOutputHandle)id);
 }
 
@@ -106,10 +88,7 @@
 Java_edu_wpi_first_hal_AnalogJNI_checkAnalogModule
   (JNIEnv*, jclass, jbyte value)
 {
-  // ANALOGJNI_LOG(logDEBUG) << "Module = " << (jint)value;
   jboolean returnValue = HAL_CheckAnalogModule(value);
-  // ANALOGJNI_LOG(logDEBUG) << "checkAnalogModuleResult = " <<
-  // (jint)returnValue;
   return returnValue;
 }
 
@@ -122,10 +101,7 @@
 Java_edu_wpi_first_hal_AnalogJNI_checkAnalogInputChannel
   (JNIEnv*, jclass, jint value)
 {
-  // ANALOGJNI_LOG(logDEBUG) << "Channel = " << value;
   jboolean returnValue = HAL_CheckAnalogInputChannel(value);
-  // ANALOGJNI_LOG(logDEBUG) << "checkAnalogChannelResult = " <<
-  // (jint)returnValue;
   return returnValue;
 }
 
@@ -138,15 +114,25 @@
 Java_edu_wpi_first_hal_AnalogJNI_checkAnalogOutputChannel
   (JNIEnv*, jclass, jint value)
 {
-  // ANALOGJNI_LOG(logDEBUG) << "Channel = " << value;
   jboolean returnValue = HAL_CheckAnalogOutputChannel(value);
-  // ANALOGJNI_LOG(logDEBUG) << "checkAnalogChannelResult = " <<
-  // (jint)returnValue;
   return returnValue;
 }
 
 /*
  * Class:     edu_wpi_first_hal_AnalogJNI
+ * Method:    setAnalogInputSimDevice
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogInputSimDevice
+  (JNIEnv* env, jclass, jint handle, jint device)
+{
+  HAL_SetAnalogInputSimDevice((HAL_AnalogInputHandle)handle,
+                              (HAL_SimDeviceHandle)device);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_AnalogJNI
  * Method:    setAnalogOutput
  * Signature: (ID)V
  */
@@ -154,9 +140,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogOutput
   (JNIEnv* env, jclass, jint id, jdouble voltage)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Calling setAnalogOutput";
-  ANALOGJNI_LOG(logDEBUG) << "Voltage = " << voltage;
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << id;
   int32_t status = 0;
   HAL_SetAnalogOutput((HAL_AnalogOutputHandle)id, voltage, &status);
   CheckStatus(env, status);
@@ -186,10 +169,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogSampleRate
   (JNIEnv* env, jclass, jdouble value)
 {
-  ANALOGJNI_LOG(logDEBUG) << "SampleRate = " << value;
   int32_t status = 0;
   HAL_SetAnalogSampleRate(value, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -204,8 +185,6 @@
 {
   int32_t status = 0;
   double returnValue = HAL_GetAnalogSampleRate(&status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "SampleRate = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -219,11 +198,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogAverageBits
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  ANALOGJNI_LOG(logDEBUG) << "AverageBits = " << value;
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_SetAnalogAverageBits((HAL_AnalogInputHandle)id, value, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -236,12 +212,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogAverageBits
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetAnalogAverageBits((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AverageBits = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -255,11 +228,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogOversampleBits
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  ANALOGJNI_LOG(logDEBUG) << "OversampleBits = " << value;
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_SetAnalogOversampleBits((HAL_AnalogInputHandle)id, value, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -272,12 +242,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogOversampleBits
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetAnalogOversampleBits((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "OversampleBits = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -291,11 +258,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogValue
   (JNIEnv* env, jclass, jint id)
 {
-  // ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (void*)id;
   int32_t status = 0;
   jshort returnValue = HAL_GetAnalogValue((HAL_AnalogInputHandle)id, &status);
-  // ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  // ANALOGJNI_LOG(logDEBUG) << "Value = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -309,12 +273,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogAverageValue
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetAnalogAverageValue((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AverageValue = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -328,13 +289,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogVoltsToValue
   (JNIEnv* env, jclass, jint id, jdouble voltageValue)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
-  ANALOGJNI_LOG(logDEBUG) << "VoltageValue = " << voltageValue;
   int32_t status = 0;
   jint returnValue = HAL_GetAnalogVoltsToValue((HAL_AnalogInputHandle)id,
                                                voltageValue, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "Value = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -348,12 +305,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogVoltage
   (JNIEnv* env, jclass, jint id)
 {
-  // ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (void*)id;
   int32_t status = 0;
   jdouble returnValue =
       HAL_GetAnalogVoltage((HAL_AnalogInputHandle)id, &status);
-  // ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  // ANALOGJNI_LOG(logDEBUG) << "Voltage = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -367,12 +321,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogAverageVoltage
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   jdouble returnValue =
       HAL_GetAnalogAverageVoltage((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AverageVoltage = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -386,12 +337,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogLSBWeight
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
 
   jint returnValue = HAL_GetAnalogLSBWeight((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AnalogLSBWeight = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -405,12 +353,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogOffset
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
 
   jint returnValue = HAL_GetAnalogOffset((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AnalogOffset = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -424,14 +369,10 @@
 Java_edu_wpi_first_hal_AnalogJNI_isAccumulatorChannel
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "isAccumulatorChannel";
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
 
   jboolean returnValue =
       HAL_IsAccumulatorChannel((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AnalogOffset = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -445,10 +386,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_initAccumulator
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_InitAccumulator((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -461,10 +400,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_resetAccumulator
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_ResetAccumulator((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -477,10 +414,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAccumulatorCenter
   (JNIEnv* env, jclass, jint id, jint center)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_SetAccumulatorCenter((HAL_AnalogInputHandle)id, center, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -493,10 +428,8 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAccumulatorDeadband
   (JNIEnv* env, jclass, jint id, jint deadband)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   HAL_SetAccumulatorDeadband((HAL_AnalogInputHandle)id, deadband, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -509,12 +442,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAccumulatorValue
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   jlong returnValue =
       HAL_GetAccumulatorValue((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AccumulatorValue = " << returnValue;
   CheckStatus(env, status);
 
   return returnValue;
@@ -529,12 +459,9 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAccumulatorCount
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetAccumulatorCount((HAL_AnalogInputHandle)id, &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AccumulatorCount = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -548,15 +475,11 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAccumulatorOutput
   (JNIEnv* env, jclass, jint id, jobject accumulatorResult)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
   int32_t status = 0;
   int64_t value = 0;
   int64_t count = 0;
   HAL_GetAccumulatorOutput((HAL_AnalogInputHandle)id, &value, &count, &status);
   SetAccumulatorResultObject(env, accumulatorResult, value, count);
-  ANALOGJNI_LOG(logDEBUG) << "Value = " << value;
-  ANALOGJNI_LOG(logDEBUG) << "Count = " << count;
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -569,16 +492,12 @@
 Java_edu_wpi_first_hal_AnalogJNI_initializeAnalogTrigger
   (JNIEnv* env, jclass, jint id, jobject index)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_AnalogInputHandle)id;
   jint* indexHandle =
       reinterpret_cast<jint*>(env->GetDirectBufferAddress(index));
-  ANALOGJNI_LOG(logDEBUG) << "Index Ptr = " << indexHandle;
   int32_t status = 0;
   HAL_AnalogTriggerHandle analogTrigger = HAL_InitializeAnalogTrigger(
       (HAL_AnalogInputHandle)id, reinterpret_cast<int32_t*>(indexHandle),
       &status);
-  ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
-  ANALOGJNI_LOG(logDEBUG) << "AnalogTrigger Handle = " << analogTrigger;
   CheckStatus(env, status);
   return (jint)analogTrigger;
 }
@@ -592,8 +511,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_cleanAnalogTrigger
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   HAL_CleanAnalogTrigger((HAL_AnalogTriggerHandle)id, &status);
   CheckStatus(env, status);
@@ -608,8 +525,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerLimitsRaw
   (JNIEnv* env, jclass, jint id, jint lower, jint upper)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   HAL_SetAnalogTriggerLimitsRaw((HAL_AnalogTriggerHandle)id, lower, upper,
                                 &status);
@@ -625,8 +540,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerLimitsVoltage
   (JNIEnv* env, jclass, jint id, jdouble lower, jdouble upper)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   HAL_SetAnalogTriggerLimitsVoltage((HAL_AnalogTriggerHandle)id, lower, upper,
                                     &status);
@@ -642,8 +555,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerAveraged
   (JNIEnv* env, jclass, jint id, jboolean averaged)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   HAL_SetAnalogTriggerAveraged((HAL_AnalogTriggerHandle)id, averaged, &status);
   CheckStatus(env, status);
@@ -658,8 +569,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerFiltered
   (JNIEnv* env, jclass, jint id, jboolean filtered)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   HAL_SetAnalogTriggerFiltered((HAL_AnalogTriggerHandle)id, filtered, &status);
   CheckStatus(env, status);
@@ -674,8 +583,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogTriggerInWindow
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   jboolean val =
       HAL_GetAnalogTriggerInWindow((HAL_AnalogTriggerHandle)id, &status);
@@ -692,8 +599,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogTriggerTriggerState
   (JNIEnv* env, jclass, jint id)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   jboolean val =
       HAL_GetAnalogTriggerTriggerState((HAL_AnalogTriggerHandle)id, &status);
@@ -710,8 +615,6 @@
 Java_edu_wpi_first_hal_AnalogJNI_getAnalogTriggerOutput
   (JNIEnv* env, jclass, jint id, jint type)
 {
-  ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
-                          << (HAL_AnalogTriggerHandle)id;
   int32_t status = 0;
   jboolean val = HAL_GetAnalogTriggerOutput(
       (HAL_AnalogTriggerHandle)id, (HAL_AnalogTriggerType)type, &status);
diff --git a/hal/src/main/native/cpp/jni/CANAPIJNI.cpp b/hal/src/main/native/cpp/jni/CANAPIJNI.cpp
index bcb285c..7ac7cf6 100644
--- a/hal/src/main/native/cpp/jni/CANAPIJNI.cpp
+++ b/hal/src/main/native/cpp/jni/CANAPIJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -18,7 +18,6 @@
 #include "hal/CAN.h"
 #include "hal/CANAPI.h"
 #include "hal/Errors.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 using namespace wpi::java;
@@ -95,6 +94,21 @@
 
 /*
  * Class:     edu_wpi_first_hal_CANAPIJNI
+ * Method:    writeCANRTRFrame
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_writeCANRTRFrame
+  (JNIEnv* env, jclass, jint handle, jint length, jint apiId)
+{
+  auto halHandle = static_cast<HAL_CANHandle>(handle);
+  int32_t status = 0;
+  HAL_WriteCANRTRFrame(halHandle, static_cast<int32_t>(length), apiId, &status);
+  CheckStatus(env, status);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_CANAPIJNI
  * Method:    stopCANPacketRepeating
  * Signature: (II)V
  */
@@ -204,38 +218,4 @@
                           reinterpret_cast<jbyte*>(dataTemp));
   return true;
 }
-
-/*
- * Class:     edu_wpi_first_hal_CANAPIJNI
- * Method:    readCANPeriodicPacket
- * Signature: (IIIILjava/lang/Object;)Z
- */
-JNIEXPORT jboolean JNICALL
-Java_edu_wpi_first_hal_CANAPIJNI_readCANPeriodicPacket
-  (JNIEnv* env, jclass, jint handle, jint apiId, jint timeoutMs, jint periodMs,
-   jobject data)
-{
-  auto halHandle = static_cast<HAL_CANHandle>(handle);
-  uint8_t dataTemp[8];
-  int32_t dataLength = 0;
-  uint64_t timestamp = 0;
-  int32_t status = 0;
-  HAL_ReadCANPeriodicPacket(halHandle, apiId, dataTemp, &dataLength, &timestamp,
-                            timeoutMs, periodMs, &status);
-  if (status == HAL_CAN_TIMEOUT ||
-      status == HAL_ERR_CANSessionMux_MessageNotFound) {
-    return false;
-  }
-  if (!CheckStatus(env, status)) {
-    return false;
-  }
-  if (dataLength > 8) dataLength = 8;
-
-  jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
-  auto javaLen = env->GetArrayLength(toSetArray);
-  if (javaLen < dataLength) dataLength = javaLen;
-  env->SetByteArrayRegion(toSetArray, 0, dataLength,
-                          reinterpret_cast<jbyte*>(dataTemp));
-  return true;
-}
 }  // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CANJNI.cpp b/hal/src/main/native/cpp/jni/CANJNI.cpp
index 0f46d15..9278c24 100644
--- a/hal/src/main/native/cpp/jni/CANJNI.cpp
+++ b/hal/src/main/native/cpp/jni/CANJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -16,21 +16,10 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_can_CANJNI.h"
 #include "hal/CAN.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 using namespace wpi::java;
 
-// set the logging level
-// TLogLevel canJNILogLevel = logDEBUG;
-TLogLevel canJNILogLevel = logERROR;
-
-#define CANJNI_LOG(level)     \
-  if (level > canJNILogLevel) \
-    ;                         \
-  else                        \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -42,37 +31,14 @@
 Java_edu_wpi_first_hal_can_CANJNI_FRCNetCommCANSessionMuxSendMessage
   (JNIEnv* env, jclass, jint messageID, jbyteArray data, jint periodMs)
 {
-  CANJNI_LOG(logDEBUG) << "Calling CANJNI FRCNetCommCANSessionMuxSendMessage";
-
   JByteArrayRef dataArray{env, data};
 
   const uint8_t* dataBuffer =
       reinterpret_cast<const uint8_t*>(dataArray.array().data());
   uint8_t dataSize = dataArray.array().size();
 
-  CANJNI_LOG(logDEBUG) << "Message ID ";
-  CANJNI_LOG(logDEBUG).write_hex(messageID);
-
-  if (logDEBUG <= canJNILogLevel) {
-    if (dataBuffer) {
-      wpi::SmallString<128> buf;
-      wpi::raw_svector_ostream str(buf);
-      for (int32_t i = 0; i < dataSize; i++) {
-        str.write_hex(dataBuffer[i]) << ' ';
-      }
-
-      Log().Get(logDEBUG) << "Data: " << str.str();
-    } else {
-      CANJNI_LOG(logDEBUG) << "Data: null";
-    }
-  }
-
-  CANJNI_LOG(logDEBUG) << "Period: " << periodMs;
-
   int32_t status = 0;
   HAL_CAN_SendMessage(messageID, dataBuffer, dataSize, periodMs, &status);
-
-  CANJNI_LOG(logDEBUG) << "Status: " << status;
   CheckCANStatus(env, status, messageID);
 }
 
@@ -86,9 +52,6 @@
   (JNIEnv* env, jclass, jobject messageID, jint messageIDMask,
    jobject timeStamp)
 {
-  CANJNI_LOG(logDEBUG)
-      << "Calling CANJNI FRCNetCommCANSessionMuxReceiveMessage";
-
   uint32_t* messageIDPtr =
       reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(messageID));
   uint32_t* timeStampPtr =
@@ -101,28 +64,6 @@
   HAL_CAN_ReceiveMessage(messageIDPtr, messageIDMask, buffer, &dataSize,
                          timeStampPtr, &status);
 
-  CANJNI_LOG(logDEBUG) << "Message ID ";
-  CANJNI_LOG(logDEBUG).write_hex(*messageIDPtr);
-
-  if (logDEBUG <= canJNILogLevel) {
-    wpi::SmallString<128> buf;
-    wpi::raw_svector_ostream str(buf);
-
-    for (int32_t i = 0; i < dataSize; i++) {
-      // Pad one-digit data with a zero
-      if (buffer[i] <= 16) {
-        str << '0';
-      }
-
-      str.write_hex(buffer[i]) << ' ';
-    }
-
-    Log().Get(logDEBUG) << "Data: " << str.str();
-  }
-
-  CANJNI_LOG(logDEBUG) << "Timestamp: " << *timeStampPtr;
-  CANJNI_LOG(logDEBUG) << "Status: " << status;
-
   if (!CheckCANStatus(env, status, *messageIDPtr)) return nullptr;
   return MakeJByteArray(env,
                         wpi::StringRef{reinterpret_cast<const char*>(buffer),
@@ -138,8 +79,6 @@
 Java_edu_wpi_first_hal_can_CANJNI_GetCANStatus
   (JNIEnv* env, jclass, jobject canStatus)
 {
-  CANJNI_LOG(logDEBUG) << "Calling CANJNI HAL_CAN_GetCANStatus";
-
   float percentBusUtilization = 0;
   uint32_t busOffCount = 0;
   uint32_t txFullCount = 0;
diff --git a/hal/src/main/native/cpp/jni/CompressorJNI.cpp b/hal/src/main/native/cpp/jni/CompressorJNI.cpp
index e38abb5..75a5e0a 100644
--- a/hal/src/main/native/cpp/jni/CompressorJNI.cpp
+++ b/hal/src/main/native/cpp/jni/CompressorJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -10,7 +10,6 @@
 #include "hal/Compressor.h"
 #include "hal/Ports.h"
 #include "hal/Solenoid.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
diff --git a/hal/src/main/native/cpp/jni/ConstantsJNI.cpp b/hal/src/main/native/cpp/jni/ConstantsJNI.cpp
index 3db8f5a..fb1ae0b 100644
--- a/hal/src/main/native/cpp/jni/ConstantsJNI.cpp
+++ b/hal/src/main/native/cpp/jni/ConstantsJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -12,19 +12,9 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_ConstantsJNI.h"
 #include "hal/Constants.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel constantsJNILogLevel = logWARNING;
-
-#define CONSTANTSJNI_LOG(level)     \
-  if (level > constantsJNILogLevel) \
-    ;                               \
-  else                              \
-    Log().Get(level)
-
 extern "C" {
 /*
  * Class:     edu_wpi_first_hal_ConstantsJNI
@@ -35,10 +25,7 @@
 Java_edu_wpi_first_hal_ConstantsJNI_getSystemClockTicksPerMicrosecond
   (JNIEnv* env, jclass)
 {
-  CONSTANTSJNI_LOG(logDEBUG)
-      << "Calling ConstantsJNI getSystemClockTicksPerMicrosecond";
   jint value = HAL_GetSystemClockTicksPerMicrosecond();
-  CONSTANTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 }  // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CounterJNI.cpp b/hal/src/main/native/cpp/jni/CounterJNI.cpp
index 70ec5be..41dedab 100644
--- a/hal/src/main/native/cpp/jni/CounterJNI.cpp
+++ b/hal/src/main/native/cpp/jni/CounterJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -13,19 +13,9 @@
 #include "edu_wpi_first_hal_CounterJNI.h"
 #include "hal/Counter.h"
 #include "hal/Errors.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel counterJNILogLevel = logWARNING;
-
-#define COUNTERJNI_LOG(level)     \
-  if (level > counterJNILogLevel) \
-    ;                             \
-  else                            \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -37,17 +27,10 @@
 Java_edu_wpi_first_hal_CounterJNI_initializeCounter
   (JNIEnv* env, jclass, jint mode, jobject index)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI initializeCounter";
-  COUNTERJNI_LOG(logDEBUG) << "Mode = " << mode;
   jint* indexPtr = reinterpret_cast<jint*>(env->GetDirectBufferAddress(index));
-  COUNTERJNI_LOG(logDEBUG) << "Index Ptr = "
-                           << reinterpret_cast<int32_t*>(indexPtr);
   int32_t status = 0;
   auto counter = HAL_InitializeCounter(
       (HAL_Counter_Mode)mode, reinterpret_cast<int32_t*>(indexPtr), &status);
-  COUNTERJNI_LOG(logDEBUG) << "Index = " << *indexPtr;
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
-  COUNTERJNI_LOG(logDEBUG) << "COUNTER Handle = " << counter;
   CheckStatusForceThrow(env, status);
   return (jint)counter;
 }
@@ -61,11 +44,8 @@
 Java_edu_wpi_first_hal_CounterJNI_freeCounter
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI freeCounter";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   HAL_FreeCounter((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -78,12 +58,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterAverageSize
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterAverageSize";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "AverageSize = " << value;
   int32_t status = 0;
   HAL_SetCounterAverageSize((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -97,14 +73,9 @@
   (JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
    jint analogTriggerType)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterUpSource";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "digitalSourceHandle = " << digitalSourceHandle;
-  COUNTERJNI_LOG(logDEBUG) << "analogTriggerType = " << analogTriggerType;
   int32_t status = 0;
   HAL_SetCounterUpSource((HAL_CounterHandle)id, (HAL_Handle)digitalSourceHandle,
                          (HAL_AnalogTriggerType)analogTriggerType, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -117,14 +88,9 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterUpSourceEdge
   (JNIEnv* env, jclass, jint id, jboolean valueRise, jboolean valueFall)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterUpSourceEdge";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "Rise = " << (jint)valueRise;
-  COUNTERJNI_LOG(logDEBUG) << "Fall = " << (jint)valueFall;
   int32_t status = 0;
   HAL_SetCounterUpSourceEdge((HAL_CounterHandle)id, valueRise, valueFall,
                              &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -137,11 +103,8 @@
 Java_edu_wpi_first_hal_CounterJNI_clearCounterUpSource
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI clearCounterUpSource";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   HAL_ClearCounterUpSource((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -155,15 +118,10 @@
   (JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
    jint analogTriggerType)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterDownSource";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "digitalSourceHandle = " << digitalSourceHandle;
-  COUNTERJNI_LOG(logDEBUG) << "analogTriggerType = " << analogTriggerType;
   int32_t status = 0;
   HAL_SetCounterDownSource((HAL_CounterHandle)id,
                            (HAL_Handle)digitalSourceHandle,
                            (HAL_AnalogTriggerType)analogTriggerType, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   if (status == PARAMETER_OUT_OF_RANGE) {
     ThrowIllegalArgumentException(env,
                                   "Counter only supports DownSource in "
@@ -182,14 +140,9 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterDownSourceEdge
   (JNIEnv* env, jclass, jint id, jboolean valueRise, jboolean valueFall)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterDownSourceEdge";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "Rise = " << (jint)valueRise;
-  COUNTERJNI_LOG(logDEBUG) << "Fall = " << (jint)valueFall;
   int32_t status = 0;
   HAL_SetCounterDownSourceEdge((HAL_CounterHandle)id, valueRise, valueFall,
                                &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -202,11 +155,8 @@
 Java_edu_wpi_first_hal_CounterJNI_clearCounterDownSource
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI clearCounterDownSource";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   HAL_ClearCounterDownSource((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -219,11 +169,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterUpDownMode
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterUpDownMode";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   HAL_SetCounterUpDownMode((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -236,12 +183,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterExternalDirectionMode
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG)
-      << "Calling COUNTERJNI setCounterExternalDirectionMode";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   HAL_SetCounterExternalDirectionMode((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -254,12 +197,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterSemiPeriodMode
   (JNIEnv* env, jclass, jint id, jboolean value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterSemiPeriodMode";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "SemiPeriodMode = " << (jint)value;
   int32_t status = 0;
   HAL_SetCounterSemiPeriodMode((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -272,12 +211,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterPulseLengthMode
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterPulseLengthMode";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "PulseLengthMode = " << value;
   int32_t status = 0;
   HAL_SetCounterPulseLengthMode((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -290,14 +225,9 @@
 Java_edu_wpi_first_hal_CounterJNI_getCounterSamplesToAverage
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterSamplesToAverage";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetCounterSamplesToAverage((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
-  COUNTERJNI_LOG(logDEBUG) << "getCounterSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -311,12 +241,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterSamplesToAverage
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterSamplesToAverage";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "SamplesToAverage = " << value;
   int32_t status = 0;
   HAL_SetCounterSamplesToAverage((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   if (status == PARAMETER_OUT_OF_RANGE) {
     ThrowBoundaryException(env, value, 1, 127);
     return;
@@ -333,11 +259,8 @@
 Java_edu_wpi_first_hal_CounterJNI_resetCounter
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI resetCounter";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   HAL_ResetCounter((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -350,12 +273,8 @@
 Java_edu_wpi_first_hal_CounterJNI_getCounter
   (JNIEnv* env, jclass, jint id)
 {
-  // COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounter";
-  // COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   jint returnValue = HAL_GetCounter((HAL_CounterHandle)id, &status);
-  // COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
-  // COUNTERJNI_LOG(logDEBUG) << "getCounterResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -369,12 +288,8 @@
 Java_edu_wpi_first_hal_CounterJNI_getCounterPeriod
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterPeriod";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   jdouble returnValue = HAL_GetCounterPeriod((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
-  COUNTERJNI_LOG(logDEBUG) << "getCounterPeriodResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -388,12 +303,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterMaxPeriod
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterMaxPeriod";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "MaxPeriod = " << value;
   int32_t status = 0;
   HAL_SetCounterMaxPeriod((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -406,12 +317,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterUpdateWhenEmpty
   (JNIEnv* env, jclass, jint id, jboolean value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterMaxPeriod";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "UpdateWhenEmpty = " << (jint)value;
   int32_t status = 0;
   HAL_SetCounterUpdateWhenEmpty((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -424,12 +331,8 @@
 Java_edu_wpi_first_hal_CounterJNI_getCounterStopped
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterStopped";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   jboolean returnValue = HAL_GetCounterStopped((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
-  COUNTERJNI_LOG(logDEBUG) << "getCounterStoppedResult = " << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -443,14 +346,9 @@
 Java_edu_wpi_first_hal_CounterJNI_getCounterDirection
   (JNIEnv* env, jclass, jint id)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterDirection";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
   int32_t status = 0;
   jboolean returnValue =
       HAL_GetCounterDirection((HAL_CounterHandle)id, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
-  COUNTERJNI_LOG(logDEBUG) << "getCounterDirectionResult = "
-                           << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -464,12 +362,8 @@
 Java_edu_wpi_first_hal_CounterJNI_setCounterReverseDirection
   (JNIEnv* env, jclass, jint id, jboolean value)
 {
-  COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterReverseDirection";
-  COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
-  COUNTERJNI_LOG(logDEBUG) << "ReverseDirection = " << (jint)value;
   int32_t status = 0;
   HAL_SetCounterReverseDirection((HAL_CounterHandle)id, value, &status);
-  COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
diff --git a/hal/src/main/native/cpp/jni/DIOJNI.cpp b/hal/src/main/native/cpp/jni/DIOJNI.cpp
index e21edcf..9c44b4c 100644
--- a/hal/src/main/native/cpp/jni/DIOJNI.cpp
+++ b/hal/src/main/native/cpp/jni/DIOJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -14,20 +14,10 @@
 #include "hal/DIO.h"
 #include "hal/PWM.h"
 #include "hal/Ports.h"
-#include "hal/cpp/Log.h"
 #include "hal/handles/HandlesInternal.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel dioJNILogLevel = logWARNING;
-
-#define DIOJNI_LOG(level)     \
-  if (level > dioJNILogLevel) \
-    ;                         \
-  else                        \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -39,14 +29,9 @@
 Java_edu_wpi_first_hal_DIOJNI_initializeDIOPort
   (JNIEnv* env, jclass, jint id, jboolean input)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI initializeDIOPort";
-  DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
-  DIOJNI_LOG(logDEBUG) << "Input = " << (jint)input;
   int32_t status = 0;
   auto dio = HAL_InitializeDIOPort((HAL_PortHandle)id,
                                    static_cast<uint8_t>(input), &status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  DIOJNI_LOG(logDEBUG) << "DIO Handle = " << dio;
   CheckStatusRange(env, status, 0, HAL_GetNumDigitalChannels(),
                    hal::getPortHandleChannel((HAL_PortHandle)id));
   return (jint)dio;
@@ -61,8 +46,6 @@
 Java_edu_wpi_first_hal_DIOJNI_checkDIOChannel
   (JNIEnv* env, jclass, jint channel)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI checkDIOChannel";
-  DIOJNI_LOG(logDEBUG) << "Channel = " << channel;
   return HAL_CheckDIOChannel(channel);
 }
 
@@ -75,13 +58,23 @@
 Java_edu_wpi_first_hal_DIOJNI_freeDIOPort
   (JNIEnv* env, jclass, jint id)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDIOPort";
-  DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   HAL_FreeDIOPort((HAL_DigitalHandle)id);
 }
 
 /*
  * Class:     edu_wpi_first_hal_DIOJNI
+ * Method:    setDIOSimDevice
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDIOSimDevice
+  (JNIEnv* env, jclass, jint handle, jint device)
+{
+  HAL_SetDIOSimDevice((HAL_DigitalHandle)handle, (HAL_SimDeviceHandle)device);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_DIOJNI
  * Method:    setDIO
  * Signature: (IS)V
  */
@@ -89,12 +82,8 @@
 Java_edu_wpi_first_hal_DIOJNI_setDIO
   (JNIEnv* env, jclass, jint id, jshort value)
 {
-  // DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDIO";
-  // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
-  // DIOJNI_LOG(logDEBUG) << "Value = " << value;
   int32_t status = 0;
   HAL_SetDIO((HAL_DigitalHandle)id, value, &status);
-  // DIOJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -107,12 +96,8 @@
 Java_edu_wpi_first_hal_DIOJNI_setDIODirection
   (JNIEnv* env, jclass, jint id, jboolean input)
 {
-  // DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDIO";
-  // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
-  // DIOJNI_LOG(logDEBUG) << "IsInput = " << input;
   int32_t status = 0;
   HAL_SetDIODirection((HAL_DigitalHandle)id, input, &status);
-  // DIOJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -125,12 +110,8 @@
 Java_edu_wpi_first_hal_DIOJNI_getDIO
   (JNIEnv* env, jclass, jint id)
 {
-  // DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getDIO";
-  // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   jboolean returnValue = HAL_GetDIO((HAL_DigitalHandle)id, &status);
-  // DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  // DIOJNI_LOG(logDEBUG) << "getDIOResult = " << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -144,12 +125,8 @@
 Java_edu_wpi_first_hal_DIOJNI_getDIODirection
   (JNIEnv* env, jclass, jint id)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getDIODirection (RR upd)";
-  // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   jboolean returnValue = HAL_GetDIODirection((HAL_DigitalHandle)id, &status);
-  // DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  DIOJNI_LOG(logDEBUG) << "getDIODirectionResult = " << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -163,12 +140,8 @@
 Java_edu_wpi_first_hal_DIOJNI_pulse
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI pulse (RR upd)";
-  // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
-  // DIOJNI_LOG(logDEBUG) << "Value = " << value;
   int32_t status = 0;
   HAL_Pulse((HAL_DigitalHandle)id, value, &status);
-  DIOJNI_LOG(logDEBUG) << "Did it work? Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -181,12 +154,8 @@
 Java_edu_wpi_first_hal_DIOJNI_isPulsing
   (JNIEnv* env, jclass, jint id)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI isPulsing (RR upd)";
-  // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   jboolean returnValue = HAL_IsPulsing((HAL_DigitalHandle)id, &status);
-  // DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  DIOJNI_LOG(logDEBUG) << "isPulsingResult = " << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -200,11 +169,8 @@
 Java_edu_wpi_first_hal_DIOJNI_isAnyPulsing
   (JNIEnv* env, jclass)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI isAnyPulsing (RR upd)";
   int32_t status = 0;
   jboolean returnValue = HAL_IsAnyPulsing(&status);
-  // DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  DIOJNI_LOG(logDEBUG) << "isAnyPulsingResult = " << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -218,11 +184,8 @@
 Java_edu_wpi_first_hal_DIOJNI_getLoopTiming
   (JNIEnv* env, jclass)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getLoopTimeing";
   int32_t status = 0;
   jshort returnValue = HAL_GetPWMLoopTiming(&status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  DIOJNI_LOG(logDEBUG) << "LoopTiming = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -236,11 +199,8 @@
 Java_edu_wpi_first_hal_DIOJNI_allocateDigitalPWM
   (JNIEnv* env, jclass)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI allocateDigitalPWM";
   int32_t status = 0;
   auto pwm = HAL_AllocateDigitalPWM(&status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
-  DIOJNI_LOG(logDEBUG) << "PWM Handle = " << pwm;
   CheckStatus(env, status);
   return (jint)pwm;
 }
@@ -254,11 +214,8 @@
 Java_edu_wpi_first_hal_DIOJNI_freeDigitalPWM
   (JNIEnv* env, jclass, jint id)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDigitalPWM";
-  DIOJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalPWMHandle)id;
   int32_t status = 0;
   HAL_FreeDigitalPWM((HAL_DigitalPWMHandle)id, &status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -271,11 +228,8 @@
 Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMRate
   (JNIEnv* env, jclass, jdouble value)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDigitalPWMRate";
-  DIOJNI_LOG(logDEBUG) << "Rate= " << value;
   int32_t status = 0;
   HAL_SetDigitalPWMRate(value, &status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -288,12 +242,8 @@
 Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMDutyCycle
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDigitalPWMDutyCycle";
-  DIOJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalPWMHandle)id;
-  DIOJNI_LOG(logDEBUG) << "DutyCycle= " << value;
   int32_t status = 0;
   HAL_SetDigitalPWMDutyCycle((HAL_DigitalPWMHandle)id, value, &status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -306,13 +256,9 @@
 Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMOutputChannel
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDigitalPWMOutputChannel";
-  DIOJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalPWMHandle)id;
-  DIOJNI_LOG(logDEBUG) << "Channel= " << value;
   int32_t status = 0;
   HAL_SetDigitalPWMOutputChannel((HAL_DigitalPWMHandle)id,
                                  static_cast<uint32_t>(value), &status);
-  DIOJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
diff --git a/hal/src/main/native/cpp/jni/EncoderJNI.cpp b/hal/src/main/native/cpp/jni/EncoderJNI.cpp
index 10c4332..e5aa7e8 100644
--- a/hal/src/main/native/cpp/jni/EncoderJNI.cpp
+++ b/hal/src/main/native/cpp/jni/EncoderJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -13,19 +13,9 @@
 #include "edu_wpi_first_hal_EncoderJNI.h"
 #include "hal/Encoder.h"
 #include "hal/Errors.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel encoderJNILogLevel = logWARNING;
-
-#define ENCODERJNI_LOG(level)     \
-  if (level > encoderJNILogLevel) \
-    ;                             \
-  else                            \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -39,13 +29,6 @@
    jint digitalSourceHandleB, jint analogTriggerTypeB,
    jboolean reverseDirection, jint encodingType)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI initializeEncoder";
-  ENCODERJNI_LOG(logDEBUG) << "Source Handle A = " << digitalSourceHandleA;
-  ENCODERJNI_LOG(logDEBUG) << "Analog Trigger Type A = " << analogTriggerTypeA;
-  ENCODERJNI_LOG(logDEBUG) << "Source Handle B = " << digitalSourceHandleB;
-  ENCODERJNI_LOG(logDEBUG) << "Analog Trigger Type B = " << analogTriggerTypeB;
-  ENCODERJNI_LOG(logDEBUG) << "Reverse direction = " << (jint)reverseDirection;
-  ENCODERJNI_LOG(logDEBUG) << "EncodingType = " << encodingType;
   int32_t status = 0;
   auto encoder = HAL_InitializeEncoder(
       (HAL_Handle)digitalSourceHandleA,
@@ -53,9 +36,6 @@
       (HAL_Handle)digitalSourceHandleB,
       (HAL_AnalogTriggerType)analogTriggerTypeB, reverseDirection,
       (HAL_EncoderEncodingType)encodingType, &status);
-
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "ENCODER Handle = " << encoder;
   CheckStatusForceThrow(env, status);
   return (jint)encoder;
 }
@@ -69,16 +49,26 @@
 Java_edu_wpi_first_hal_EncoderJNI_freeEncoder
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI freeEncoder";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_FreeEncoder((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_EncoderJNI
+ * Method:    setEncoderSimDevice
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderSimDevice
+  (JNIEnv* env, jclass, jint handle, jint device)
+{
+  HAL_SetEncoderSimDevice((HAL_EncoderHandle)handle,
+                          (HAL_SimDeviceHandle)device);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_EncoderJNI
  * Method:    getEncoder
  * Signature: (I)I
  */
@@ -86,12 +76,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoder
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoder";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue = HAL_GetEncoder((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -105,12 +91,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderRaw
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderRaw";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue = HAL_GetEncoderRaw((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getRawEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -124,13 +106,9 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncodingScaleFactor
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncodingScaleFactor";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetEncoderEncodingScale((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncodingScaleFactorResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -144,11 +122,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_resetEncoder
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI resetEncoder";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_ResetEncoder((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -161,12 +136,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderPeriod
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderPeriod";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   double returnValue = HAL_GetEncoderPeriod((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderPeriodEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -180,11 +151,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_setEncoderMaxPeriod
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderMaxPeriod";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_SetEncoderMaxPeriod((HAL_EncoderHandle)id, value, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -197,12 +165,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderStopped
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderStopped";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jboolean returnValue = HAL_GetEncoderStopped((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getStoppedEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -216,13 +180,9 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderDirection
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderDirection";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jboolean returnValue =
       HAL_GetEncoderDirection((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getDirectionEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -236,12 +196,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderDistance
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderDistance";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jdouble returnValue = HAL_GetEncoderDistance((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getDistanceEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -255,12 +211,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderRate
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderRate";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jdouble returnValue = HAL_GetEncoderRate((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getRateEncoderResult = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -274,11 +226,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_setEncoderMinRate
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderMinRate";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_SetEncoderMinRate((HAL_EncoderHandle)id, value, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -291,11 +240,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_setEncoderDistancePerPulse
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderDistancePerPulse";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_SetEncoderDistancePerPulse((HAL_EncoderHandle)id, value, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -308,11 +254,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_setEncoderReverseDirection
   (JNIEnv* env, jclass, jint id, jboolean value)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderReverseDirection";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_SetEncoderReverseDirection((HAL_EncoderHandle)id, value, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -325,11 +268,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_setEncoderSamplesToAverage
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   HAL_SetEncoderSamplesToAverage((HAL_EncoderHandle)id, value, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   if (status == PARAMETER_OUT_OF_RANGE) {
     ThrowBoundaryException(env, value, 1, 127);
     return;
@@ -346,14 +286,9 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderSamplesToAverage
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetEncoderSamplesToAverage((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -368,17 +303,11 @@
   (JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
    jint analogTriggerType, jint type)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderIndexSource";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
-  ENCODERJNI_LOG(logDEBUG) << "Source Handle = " << digitalSourceHandle;
-  ENCODERJNI_LOG(logDEBUG) << "Analog Trigger Type = " << analogTriggerType;
-  ENCODERJNI_LOG(logDEBUG) << "IndexingType = " << type;
   int32_t status = 0;
   HAL_SetEncoderIndexSource((HAL_EncoderHandle)id,
                             (HAL_Handle)digitalSourceHandle,
                             (HAL_AnalogTriggerType)analogTriggerType,
                             (HAL_EncoderIndexingType)type, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -391,13 +320,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderFPGAIndex
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue = HAL_GetEncoderFPGAIndex((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -411,14 +335,9 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderEncodingScale
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue =
       HAL_GetEncoderEncodingScale((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -432,14 +351,9 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderDecodingScaleFactor
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jdouble returnValue =
       HAL_GetEncoderDecodingScaleFactor((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -453,14 +367,9 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderDistancePerPulse
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jdouble returnValue =
       HAL_GetEncoderDistancePerPulse((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -474,13 +383,8 @@
 Java_edu_wpi_first_hal_EncoderJNI_getEncoderEncodingType
   (JNIEnv* env, jclass, jint id)
 {
-  ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
-  ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
   int32_t status = 0;
   jint returnValue = HAL_GetEncoderEncodingType((HAL_EncoderHandle)id, &status);
-  ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
-  ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
-                           << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
diff --git a/hal/src/main/native/cpp/jni/HAL.cpp b/hal/src/main/native/cpp/jni/HAL.cpp
index cc5f7cf..393b0b4 100644
--- a/hal/src/main/native/cpp/jni/HAL.cpp
+++ b/hal/src/main/native/cpp/jni/HAL.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -17,20 +17,11 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_HAL.h"
 #include "hal/DriverStation.h"
-#include "hal/cpp/Log.h"
+#include "hal/Main.h"
 
 using namespace frc;
 using namespace wpi::java;
 
-// set the logging level
-static TLogLevel netCommLogLevel = logWARNING;
-
-#define NETCOMM_LOG(level)     \
-  if (level > netCommLogLevel) \
-    ;                          \
-  else                         \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -47,6 +38,42 @@
 
 /*
  * Class:     edu_wpi_first_hal_HAL
+ * Method:    hasMain
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HAL_hasMain
+  (JNIEnv*, jclass)
+{
+  return HAL_HasMain();
+}
+
+/*
+ * Class:     edu_wpi_first_hal_HAL
+ * Method:    runMain
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_runMain
+  (JNIEnv*, jclass)
+{
+  HAL_RunMain();
+}
+
+/*
+ * Class:     edu_wpi_first_hal_HAL
+ * Method:    exitMain
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_exitMain
+  (JNIEnv*, jclass)
+{
+  HAL_ExitMain();
+}
+
+/*
+ * Class:     edu_wpi_first_hal_HAL
  * Method:    observeUserProgramStarting
  * Signature: ()V
  */
@@ -116,11 +143,6 @@
    jint paramContext, jstring paramFeature)
 {
   JStringRef featureStr{paramEnv, paramFeature};
-  NETCOMM_LOG(logDEBUG) << "Calling HAL report "
-                        << "res:" << paramResource
-                        << " instance:" << paramInstanceNumber
-                        << " context:" << paramContext
-                        << " feature:" << featureStr.c_str();
   jint returnValue = HAL_Report(paramResource, paramInstanceNumber,
                                 paramContext, featureStr.c_str());
   return returnValue;
@@ -135,7 +157,6 @@
 Java_edu_wpi_first_hal_HAL_nativeGetControlWord
   (JNIEnv*, jclass)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL Control Word";
   static_assert(sizeof(HAL_ControlWord) == sizeof(jint),
                 "Java int must match the size of control word");
   HAL_ControlWord controlWord;
@@ -155,7 +176,6 @@
 Java_edu_wpi_first_hal_HAL_nativeGetAllianceStation
   (JNIEnv*, jclass)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL Alliance Station";
   int32_t status = 0;
   auto allianceStation = HAL_GetAllianceStation(&status);
   return static_cast<jint>(allianceStation);
@@ -170,7 +190,6 @@
 Java_edu_wpi_first_hal_HAL_getJoystickAxes
   (JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HALJoystickAxes";
   HAL_JoystickAxes axes;
   HAL_GetJoystickAxes(joystickNum, &axes);
 
@@ -200,7 +219,6 @@
 Java_edu_wpi_first_hal_HAL_getJoystickPOVs
   (JNIEnv* env, jclass, jbyte joystickNum, jshortArray povsArray)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HALJoystickPOVs";
   HAL_JoystickPOVs povs;
   HAL_GetJoystickPOVs(joystickNum, &povs);
 
@@ -230,15 +248,11 @@
 Java_edu_wpi_first_hal_HAL_getJoystickButtons
   (JNIEnv* env, jclass, jbyte joystickNum, jobject count)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HALJoystickButtons";
   HAL_JoystickButtons joystickButtons;
   HAL_GetJoystickButtons(joystickNum, &joystickButtons);
   jbyte* countPtr =
       reinterpret_cast<jbyte*>(env->GetDirectBufferAddress(count));
-  NETCOMM_LOG(logDEBUG) << "Buttons = " << joystickButtons.buttons;
-  NETCOMM_LOG(logDEBUG) << "Count = " << (jint)joystickButtons.count;
   *countPtr = joystickButtons.count;
-  NETCOMM_LOG(logDEBUG) << "CountBuffer = " << (jint)*countPtr;
   return joystickButtons.buttons;
 }
 
@@ -252,10 +266,6 @@
   (JNIEnv*, jclass, jbyte port, jint outputs, jshort leftRumble,
    jshort rightRumble)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL_SetJoystickOutputs on port " << port;
-  NETCOMM_LOG(logDEBUG) << "Outputs: " << outputs;
-  NETCOMM_LOG(logDEBUG) << "Left Rumble: " << leftRumble
-                        << " Right Rumble: " << rightRumble;
   return HAL_SetJoystickOutputs(port, outputs, leftRumble, rightRumble);
 }
 
@@ -268,7 +278,6 @@
 Java_edu_wpi_first_hal_HAL_getJoystickIsXbox
   (JNIEnv*, jclass, jbyte port)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickIsXbox";
   return HAL_GetJoystickIsXbox(port);
 }
 
@@ -281,7 +290,6 @@
 Java_edu_wpi_first_hal_HAL_getJoystickType
   (JNIEnv*, jclass, jbyte port)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickType";
   return HAL_GetJoystickType(port);
 }
 
@@ -294,7 +302,6 @@
 Java_edu_wpi_first_hal_HAL_getJoystickName
   (JNIEnv* env, jclass, jbyte port)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickName";
   char* joystickName = HAL_GetJoystickName(port);
   jstring str = MakeJString(env, joystickName);
   HAL_FreeJoystickName(joystickName);
@@ -310,7 +317,6 @@
 Java_edu_wpi_first_hal_HAL_getJoystickAxisType
   (JNIEnv*, jclass, jbyte joystickNum, jbyte axis)
 {
-  NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickAxisType";
   return HAL_GetJoystickAxisType(joystickNum, axis);
 }
 
@@ -436,9 +442,6 @@
   JStringRef locationStr{env, location};
   JStringRef callStackStr{env, callStack};
 
-  NETCOMM_LOG(logDEBUG) << "Send Error: " << detailsStr.c_str();
-  NETCOMM_LOG(logDEBUG) << "Location: " << locationStr.c_str();
-  NETCOMM_LOG(logDEBUG) << "Call Stack: " << callStackStr.c_str();
   jint returnValue =
       HAL_SendError(isError, errorCode, isLVCode, detailsStr.c_str(),
                     locationStr.c_str(), callStackStr.c_str(), printMsg);
@@ -454,11 +457,7 @@
 Java_edu_wpi_first_hal_HAL_getPortWithModule
   (JNIEnv* env, jclass, jbyte module, jbyte channel)
 {
-  // FILE_LOG(logDEBUG) << "Calling HAL getPortWithModlue";
-  // FILE_LOG(logDEBUG) << "Module = " << (jint)module;
-  // FILE_LOG(logDEBUG) << "Channel = " << (jint)channel;
   HAL_PortHandle port = HAL_GetPortWithModule(module, channel);
-  // FILE_LOG(logDEBUG) << "Port Handle = " << port;
   return (jint)port;
 }
 
@@ -471,11 +470,7 @@
 Java_edu_wpi_first_hal_HAL_getPort
   (JNIEnv* env, jclass, jbyte channel)
 {
-  // FILE_LOG(logDEBUG) << "Calling HAL getPortWithModlue";
-  // FILE_LOG(logDEBUG) << "Module = " << (jint)module;
-  // FILE_LOG(logDEBUG) << "Channel = " << (jint)channel;
   HAL_PortHandle port = HAL_GetPort(channel);
-  // FILE_LOG(logDEBUG) << "Port Handle = " << port;
   return (jint)port;
 }
 
diff --git a/hal/src/main/native/cpp/jni/HALUtil.cpp b/hal/src/main/native/cpp/jni/HALUtil.cpp
index 92d09b4..26b7919 100644
--- a/hal/src/main/native/cpp/jni/HALUtil.cpp
+++ b/hal/src/main/native/cpp/jni/HALUtil.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -24,19 +24,9 @@
 #include "hal/DriverStation.h"
 #include "hal/Errors.h"
 #include "hal/HAL.h"
-#include "hal/cpp/Log.h"
 
 using namespace wpi::java;
 
-// set the logging level
-TLogLevel halUtilLogLevel = logWARNING;
-
-#define HALUTIL_LOG(level)     \
-  if (level > halUtilLogLevel) \
-    ;                          \
-  else                         \
-    Log().Get(level)
-
 #define kRioStatusOffset -63000
 #define kRioStatusSuccess 0
 #define kRIOStatusBufferInvalidSize (kRioStatusOffset - 80)
@@ -59,13 +49,15 @@
 static JClass matchInfoDataCls;
 static JClass accumulatorResultCls;
 static JClass canDataCls;
+static JClass halValueCls;
 
 static const JClassInit classes[] = {
     {"edu/wpi/first/hal/PWMConfigDataResult", &pwmConfigDataResultCls},
     {"edu/wpi/first/hal/can/CANStatus", &canStatusCls},
     {"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
     {"edu/wpi/first/hal/AccumulatorResult", &accumulatorResultCls},
-    {"edu/wpi/first/hal/CANData", &canDataCls}};
+    {"edu/wpi/first/hal/CANData", &canDataCls},
+    {"edu/wpi/first/hal/HALValue", &halValueCls}};
 
 static const JExceptionInit exceptions[] = {
     {"java/lang/IllegalArgumentException", &illegalArgExCls},
@@ -234,8 +226,9 @@
                                   int32_t deadbandMinPwm, int32_t minPwm) {
   static jmethodID constructor =
       env->GetMethodID(pwmConfigDataResultCls, "<init>", "(IIIII)V");
-  return env->NewObject(pwmConfigDataResultCls, constructor, maxPwm,
-                        deadbandMaxPwm, centerPwm, deadbandMinPwm, minPwm);
+  return env->NewObject(pwmConfigDataResultCls, constructor, (jint)maxPwm,
+                        (jint)deadbandMaxPwm, (jint)centerPwm,
+                        (jint)deadbandMinPwm, (jint)minPwm);
 }
 
 void SetCanStatusObject(JNIEnv* env, jobject canStatus,
@@ -281,6 +274,34 @@
   return retVal;
 }
 
+jobject CreateHALValue(JNIEnv* env, const HAL_Value& value) {
+  static jmethodID fromNative = env->GetStaticMethodID(
+      halValueCls, "fromNative", "(IJD)Ledu/wpi/first/hal/HALValue;");
+  jlong value1 = 0;
+  jdouble value2 = 0.0;
+  switch (value.type) {
+    case HAL_BOOLEAN:
+      value1 = value.data.v_boolean;
+      break;
+    case HAL_DOUBLE:
+      value2 = value.data.v_double;
+      break;
+    case HAL_ENUM:
+      value1 = value.data.v_enum;
+      break;
+    case HAL_INT:
+      value1 = value.data.v_int;
+      break;
+    case HAL_LONG:
+      value1 = value.data.v_long;
+      break;
+    default:
+      break;
+  }
+  return env->CallStaticObjectMethod(halValueCls, fromNative, (jint)value.type,
+                                     value1, value2);
+}
+
 JavaVM* GetJVM() { return jvm; }
 
 }  // namespace frc
@@ -300,9 +321,6 @@
 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
   jvm = vm;
 
-  // set our logging level
-  Log::ReportingLevel() = logDEBUG;
-
   JNIEnv* env;
   if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
     return JNI_ERR;
@@ -346,11 +364,8 @@
 Java_edu_wpi_first_hal_HALUtil_getFPGAVersion
   (JNIEnv* env, jclass)
 {
-  HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGAVersion";
   int32_t status = 0;
   jshort returnValue = HAL_GetFPGAVersion(&status);
-  HALUTIL_LOG(logDEBUG) << "Status = " << status;
-  HALUTIL_LOG(logDEBUG) << "FPGAVersion = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -364,11 +379,8 @@
 Java_edu_wpi_first_hal_HALUtil_getFPGARevision
   (JNIEnv* env, jclass)
 {
-  HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGARevision";
   int32_t status = 0;
   jint returnValue = HAL_GetFPGARevision(&status);
-  HALUTIL_LOG(logDEBUG) << "Status = " << status;
-  HALUTIL_LOG(logDEBUG) << "FPGARevision = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -382,11 +394,8 @@
 Java_edu_wpi_first_hal_HALUtil_getFPGATime
   (JNIEnv* env, jclass)
 {
-  // HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGATime";
   int32_t status = 0;
   jlong returnValue = HAL_GetFPGATime(&status);
-  // HALUTIL_LOG(logDEBUG) << "Status = " << status;
-  // HALUTIL_LOG(logDEBUG) << "FPGATime = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -400,9 +409,7 @@
 Java_edu_wpi_first_hal_HALUtil_getHALRuntimeType
   (JNIEnv* env, jclass)
 {
-  // HALUTIL_LOG(logDEBUG) << "Calling HALUtil getHALRuntimeType";
   jint returnValue = HAL_GetRuntimeType();
-  // HALUTIL_LOG(logDEBUG) << "RuntimeType = " << returnValue;
   return returnValue;
 }
 
@@ -415,11 +422,8 @@
 Java_edu_wpi_first_hal_HALUtil_getFPGAButton
   (JNIEnv* env, jclass)
 {
-  // HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGATime";
   int32_t status = 0;
   jboolean returnValue = HAL_GetFPGAButton(&status);
-  // HALUTIL_LOG(logDEBUG) << "Status = " << status;
-  // HALUTIL_LOG(logDEBUG) << "FPGATime = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -434,8 +438,6 @@
   (JNIEnv* paramEnv, jclass, jint paramId)
 {
   const char* msg = HAL_GetErrorMessage(paramId);
-  HALUTIL_LOG(logDEBUG) << "Calling HALUtil HAL_GetErrorMessage id=" << paramId
-                        << " msg=" << msg;
   return MakeJString(paramEnv, msg);
 }
 
@@ -461,8 +463,6 @@
   (JNIEnv* env, jclass, jint errorCode)
 {
   const char* msg = std::strerror(errno);
-  HALUTIL_LOG(logDEBUG) << "Calling HALUtil getHALstrerror errorCode="
-                        << errorCode << " msg=" << msg;
   return MakeJString(env, msg);
 }
 
diff --git a/hal/src/main/native/cpp/jni/HALUtil.h b/hal/src/main/native/cpp/jni/HALUtil.h
index 8197e1a..c035f75 100644
--- a/hal/src/main/native/cpp/jni/HALUtil.h
+++ b/hal/src/main/native/cpp/jni/HALUtil.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -14,6 +14,7 @@
 #include <wpi/StringRef.h>
 
 struct HAL_MatchInfo;
+struct HAL_Value;
 
 namespace frc {
 
@@ -67,6 +68,8 @@
 jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
                             uint64_t timestamp);
 
+jobject CreateHALValue(JNIEnv* env, const HAL_Value& value);
+
 JavaVM* GetJVM();
 
 }  // namespace frc
diff --git a/hal/src/main/native/cpp/jni/I2CJNI.cpp b/hal/src/main/native/cpp/jni/I2CJNI.cpp
index 9dafd4a..7812bdb 100644
--- a/hal/src/main/native/cpp/jni/I2CJNI.cpp
+++ b/hal/src/main/native/cpp/jni/I2CJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -14,20 +14,10 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_I2CJNI.h"
 #include "hal/I2C.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 using namespace wpi::java;
 
-// set the logging level
-TLogLevel i2cJNILogLevel = logWARNING;
-
-#define I2CJNI_LOG(level)     \
-  if (level > i2cJNILogLevel) \
-    ;                         \
-  else                        \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -39,11 +29,8 @@
 Java_edu_wpi_first_hal_I2CJNI_i2CInitialize
   (JNIEnv* env, jclass, jint port)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CInititalize";
-  I2CJNI_LOG(logDEBUG) << "Port: " << port;
   int32_t status = 0;
   HAL_InitializeI2C(static_cast<HAL_I2CPort>(port), &status);
-  I2CJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatusForceThrow(env, status);
 }
 
@@ -57,26 +44,16 @@
   (JNIEnv* env, jclass, jint port, jbyte address, jobject dataToSend,
    jbyte sendSize, jobject dataReceived, jbyte receiveSize)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CTransaction";
-  I2CJNI_LOG(logDEBUG) << "Port = " << port;
-  I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
   uint8_t* dataToSendPtr = nullptr;
   if (dataToSend != 0) {
     dataToSendPtr =
         reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
   }
-  I2CJNI_LOG(logDEBUG) << "DataToSendPtr = "
-                       << reinterpret_cast<jint*>(dataToSendPtr);
-  I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
   uint8_t* dataReceivedPtr =
       reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
-  I2CJNI_LOG(logDEBUG) << "DataReceivedPtr = "
-                       << reinterpret_cast<jint*>(dataReceivedPtr);
-  I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << (jint)receiveSize;
   jint returnValue =
       HAL_TransactionI2C(static_cast<HAL_I2CPort>(port), address, dataToSendPtr,
                          sendSize, dataReceivedPtr, receiveSize);
-  I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
   return returnValue;
 }
 
@@ -90,13 +67,8 @@
   (JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataToSend,
    jbyte sendSize, jbyteArray dataReceived, jbyte receiveSize)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CTransactionB";
-  I2CJNI_LOG(logDEBUG) << "Port = " << port;
-  I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
-  I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
   wpi::SmallVector<uint8_t, 128> recvBuf;
   recvBuf.resize(receiveSize);
-  I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << (jint)receiveSize;
   jint returnValue =
       HAL_TransactionI2C(static_cast<HAL_I2CPort>(port), address,
                          reinterpret_cast<const uint8_t*>(
@@ -104,7 +76,6 @@
                          sendSize, recvBuf.data(), receiveSize);
   env->SetByteArrayRegion(dataReceived, 0, receiveSize,
                           reinterpret_cast<const jbyte*>(recvBuf.data()));
-  I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
   return returnValue;
 }
 
@@ -118,20 +89,14 @@
   (JNIEnv* env, jclass, jint port, jbyte address, jobject dataToSend,
    jbyte sendSize)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CWrite";
-  I2CJNI_LOG(logDEBUG) << "Port = " << port;
-  I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
   uint8_t* dataToSendPtr = nullptr;
 
   if (dataToSend != 0) {
     dataToSendPtr =
         reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
   }
-  I2CJNI_LOG(logDEBUG) << "DataToSendPtr = " << dataToSendPtr;
-  I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
   jint returnValue = HAL_WriteI2C(static_cast<HAL_I2CPort>(port), address,
                                   dataToSendPtr, sendSize);
-  I2CJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)returnValue;
   return returnValue;
 }
 
@@ -145,16 +110,11 @@
   (JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataToSend,
    jbyte sendSize)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CWrite";
-  I2CJNI_LOG(logDEBUG) << "Port = " << port;
-  I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
-  I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
   jint returnValue =
       HAL_WriteI2C(static_cast<HAL_I2CPort>(port), address,
                    reinterpret_cast<const uint8_t*>(
                        JByteArrayRef(env, dataToSend).array().data()),
                    sendSize);
-  I2CJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)returnValue;
   return returnValue;
 }
 
@@ -168,16 +128,10 @@
   (JNIEnv* env, jclass, jint port, jbyte address, jobject dataReceived,
    jbyte receiveSize)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CRead";
-  I2CJNI_LOG(logDEBUG) << "Port = " << port;
-  I2CJNI_LOG(logDEBUG) << "Address = " << address;
   uint8_t* dataReceivedPtr =
       reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
-  I2CJNI_LOG(logDEBUG) << "DataReceivedPtr = " << dataReceivedPtr;
-  I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << receiveSize;
   jint returnValue = HAL_ReadI2C(static_cast<HAL_I2CPort>(port), address,
                                  dataReceivedPtr, receiveSize);
-  I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
   return returnValue;
 }
 
@@ -191,17 +145,12 @@
   (JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataReceived,
    jbyte receiveSize)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CRead";
-  I2CJNI_LOG(logDEBUG) << "Port = " << port;
-  I2CJNI_LOG(logDEBUG) << "Address = " << address;
-  I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << receiveSize;
   wpi::SmallVector<uint8_t, 128> recvBuf;
   recvBuf.resize(receiveSize);
   jint returnValue = HAL_ReadI2C(static_cast<HAL_I2CPort>(port), address,
                                  recvBuf.data(), receiveSize);
   env->SetByteArrayRegion(dataReceived, 0, receiveSize,
                           reinterpret_cast<const jbyte*>(recvBuf.data()));
-  I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
   return returnValue;
 }
 
@@ -214,7 +163,6 @@
 Java_edu_wpi_first_hal_I2CJNI_i2CClose
   (JNIEnv*, jclass, jint port)
 {
-  I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CClose";
   HAL_CloseI2C(static_cast<HAL_I2CPort>(port));
 }
 
diff --git a/hal/src/main/native/cpp/jni/InterruptJNI.cpp b/hal/src/main/native/cpp/jni/InterruptJNI.cpp
index 2dd4abf..e3a783d 100644
--- a/hal/src/main/native/cpp/jni/InterruptJNI.cpp
+++ b/hal/src/main/native/cpp/jni/InterruptJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -17,18 +17,9 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_InterruptJNI.h"
 #include "hal/Interrupts.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-TLogLevel interruptJNILogLevel = logERROR;
-
-#define INTERRUPTJNI_LOG(level)     \
-  if (level > interruptJNILogLevel) \
-    ;                               \
-  else                              \
-    Log().Get(level)
-
 // Thread where callbacks are actually performed.
 //
 // JNI's AttachCurrentThread() creates a Java Thread object on every
@@ -88,7 +79,7 @@
       reinterpret_cast<void**>(&env), &args);
   if (rs != JNI_OK) return;
 
-  std::unique_lock<wpi::mutex> lock(m_mutex);
+  std::unique_lock lock(m_mutex);
   while (m_active) {
     m_cond.wait(lock, [&] { return !m_active || m_notify; });
     if (!m_active) break;
@@ -129,15 +120,9 @@
 Java_edu_wpi_first_hal_InterruptJNI_initializeInterrupts
   (JNIEnv* env, jclass, jboolean watcher)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI initializeInterrupts";
-  INTERRUPTJNI_LOG(logDEBUG) << "watcher = " << static_cast<bool>(watcher);
-
   int32_t status = 0;
   HAL_InterruptHandle interrupt = HAL_InitializeInterrupts(watcher, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << interrupt;
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
-
   CheckStatusForceThrow(env, status);
   return (jint)interrupt;
 }
@@ -151,10 +136,6 @@
 Java_edu_wpi_first_hal_InterruptJNI_cleanInterrupts
   (JNIEnv* env, jclass, jint interruptHandle)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI cleanInterrupts";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   int32_t status = 0;
   auto param =
       HAL_CleanInterrupts((HAL_InterruptHandle)interruptHandle, &status);
@@ -162,8 +143,6 @@
     delete static_cast<InterruptJNI*>(param);
   }
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
-
   // ignore status, as an invalid handle just needs to be ignored.
 }
 
@@ -177,16 +156,10 @@
   (JNIEnv* env, jclass, jint interruptHandle, jdouble timeout,
    jboolean ignorePrevious)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI waitForInterrupt";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   int32_t status = 0;
   int32_t result = HAL_WaitForInterrupt((HAL_InterruptHandle)interruptHandle,
                                         timeout, ignorePrevious, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
-
   CheckStatus(env, status);
   return result;
 }
@@ -200,15 +173,9 @@
 Java_edu_wpi_first_hal_InterruptJNI_enableInterrupts
   (JNIEnv* env, jclass, jint interruptHandle)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI enableInterrupts";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   int32_t status = 0;
   HAL_EnableInterrupts((HAL_InterruptHandle)interruptHandle, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
-
   CheckStatus(env, status);
 }
 
@@ -221,15 +188,9 @@
 Java_edu_wpi_first_hal_InterruptJNI_disableInterrupts
   (JNIEnv* env, jclass, jint interruptHandle)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI disableInterrupts";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   int32_t status = 0;
   HAL_DisableInterrupts((HAL_InterruptHandle)interruptHandle, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
-
   CheckStatus(env, status);
 }
 
@@ -242,16 +203,10 @@
 Java_edu_wpi_first_hal_InterruptJNI_readInterruptRisingTimestamp
   (JNIEnv* env, jclass, jint interruptHandle)
 {
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Calling INTERRUPTJNI readInterruptRisingTimestamp";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   int32_t status = 0;
   jlong timeStamp = HAL_ReadInterruptRisingTimestamp(
       (HAL_InterruptHandle)interruptHandle, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
   return timeStamp;
 }
@@ -265,16 +220,10 @@
 Java_edu_wpi_first_hal_InterruptJNI_readInterruptFallingTimestamp
   (JNIEnv* env, jclass, jint interruptHandle)
 {
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Calling INTERRUPTJNI readInterruptFallingTimestamp";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   int32_t status = 0;
   jlong timeStamp = HAL_ReadInterruptFallingTimestamp(
       (HAL_InterruptHandle)interruptHandle, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
   return timeStamp;
 }
@@ -289,18 +238,11 @@
   (JNIEnv* env, jclass, jint interruptHandle, jint digitalSourceHandle,
    jint analogTriggerType)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI requestInterrupts";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-  INTERRUPTJNI_LOG(logDEBUG) << "digitalSourceHandle = " << digitalSourceHandle;
-  INTERRUPTJNI_LOG(logDEBUG) << "analogTriggerType = " << analogTriggerType;
-
   int32_t status = 0;
   HAL_RequestInterrupts((HAL_InterruptHandle)interruptHandle,
                         (HAL_Handle)digitalSourceHandle,
                         (HAL_AnalogTriggerType)analogTriggerType, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -313,21 +255,13 @@
 Java_edu_wpi_first_hal_InterruptJNI_attachInterruptHandler
   (JNIEnv* env, jclass, jint interruptHandle, jobject handler, jobject param)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI attachInterruptHandler";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-
   jclass cls = env->GetObjectClass(handler);
-  INTERRUPTJNI_LOG(logDEBUG) << "class = " << cls;
   if (cls == 0) {
-    INTERRUPTJNI_LOG(logERROR) << "Error getting java class";
     assert(false);
     return;
   }
   jmethodID mid = env->GetMethodID(cls, "apply", "(ILjava/lang/Object;)V");
-  INTERRUPTJNI_LOG(logDEBUG) << "method = " << mid;
   if (mid == 0) {
-    INTERRUPTJNI_LOG(logERROR) << "Error getting java method ID";
     assert(false);
     return;
   }
@@ -336,13 +270,10 @@
   intr->Start();
   intr->SetFunc(env, handler, mid, param);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "InterruptThreadJNI Ptr = " << intr;
-
   int32_t status = 0;
   HAL_AttachInterruptHandler((HAL_InterruptHandle)interruptHandle,
                              interruptHandler, intr, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -356,19 +287,10 @@
   (JNIEnv* env, jclass, jint interruptHandle, jboolean risingEdge,
    jboolean fallingEdge)
 {
-  INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI setInterruptUpSourceEdge";
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Rising Edge = " << static_cast<bool>(risingEdge);
-  INTERRUPTJNI_LOG(logDEBUG)
-      << "Falling Edge = " << static_cast<bool>(fallingEdge);
-
   int32_t status = 0;
   HAL_SetInterruptUpSourceEdge((HAL_InterruptHandle)interruptHandle, risingEdge,
                                fallingEdge, &status);
 
-  INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
diff --git a/hal/src/main/native/cpp/jni/NotifierJNI.cpp b/hal/src/main/native/cpp/jni/NotifierJNI.cpp
index 61fe32f..588614e 100644
--- a/hal/src/main/native/cpp/jni/NotifierJNI.cpp
+++ b/hal/src/main/native/cpp/jni/NotifierJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -13,19 +13,9 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_NotifierJNI.h"
 #include "hal/Notifier.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel notifierJNILogLevel = logWARNING;
-
-#define NOTIFIERJNI_LOG(level)     \
-  if (level > notifierJNILogLevel) \
-    ;                              \
-  else                             \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -37,14 +27,9 @@
 Java_edu_wpi_first_hal_NotifierJNI_initializeNotifier
   (JNIEnv* env, jclass)
 {
-  NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI initializeNotifier";
-
   int32_t status = 0;
   HAL_NotifierHandle notifierHandle = HAL_InitializeNotifier(&status);
 
-  NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
-  NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
-
   if (notifierHandle <= 0 || !CheckStatusForceThrow(env, status)) {
     return 0;  // something went wrong in HAL
   }
@@ -61,13 +46,8 @@
 Java_edu_wpi_first_hal_NotifierJNI_stopNotifier
   (JNIEnv* env, jclass cls, jint notifierHandle)
 {
-  NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI stopNotifier";
-
-  NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
-
   int32_t status = 0;
   HAL_StopNotifier((HAL_NotifierHandle)notifierHandle, &status);
-  NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -80,13 +60,8 @@
 Java_edu_wpi_first_hal_NotifierJNI_cleanNotifier
   (JNIEnv* env, jclass, jint notifierHandle)
 {
-  NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI cleanNotifier";
-
-  NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
-
   int32_t status = 0;
   HAL_CleanNotifier((HAL_NotifierHandle)notifierHandle, &status);
-  NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -99,16 +74,9 @@
 Java_edu_wpi_first_hal_NotifierJNI_updateNotifierAlarm
   (JNIEnv* env, jclass cls, jint notifierHandle, jlong triggerTime)
 {
-  NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI updateNotifierAlarm";
-
-  NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
-
-  NOTIFIERJNI_LOG(logDEBUG) << "triggerTime = " << triggerTime;
-
   int32_t status = 0;
   HAL_UpdateNotifierAlarm((HAL_NotifierHandle)notifierHandle,
                           static_cast<uint64_t>(triggerTime), &status);
-  NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -121,13 +89,8 @@
 Java_edu_wpi_first_hal_NotifierJNI_cancelNotifierAlarm
   (JNIEnv* env, jclass cls, jint notifierHandle)
 {
-  NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI cancelNotifierAlarm";
-
-  NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
-
   int32_t status = 0;
   HAL_CancelNotifierAlarm((HAL_NotifierHandle)notifierHandle, &status);
-  NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -140,15 +103,10 @@
 Java_edu_wpi_first_hal_NotifierJNI_waitForNotifierAlarm
   (JNIEnv* env, jclass cls, jint notifierHandle)
 {
-  NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI waitForNotifierAlarm";
-
-  NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
-
   int32_t status = 0;
   uint64_t time =
       HAL_WaitForNotifierAlarm((HAL_NotifierHandle)notifierHandle, &status);
-  NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
-  NOTIFIERJNI_LOG(logDEBUG) << "Time = " << time;
+
   CheckStatus(env, status);
 
   return (jlong)time;
diff --git a/hal/src/main/native/cpp/jni/PWMJNI.cpp b/hal/src/main/native/cpp/jni/PWMJNI.cpp
index 1509f94..80293c4 100644
--- a/hal/src/main/native/cpp/jni/PWMJNI.cpp
+++ b/hal/src/main/native/cpp/jni/PWMJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -14,20 +14,10 @@
 #include "hal/DIO.h"
 #include "hal/PWM.h"
 #include "hal/Ports.h"
-#include "hal/cpp/Log.h"
 #include "hal/handles/HandlesInternal.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel pwmJNILogLevel = logWARNING;
-
-#define PWMJNI_LOG(level)     \
-  if (level > pwmJNILogLevel) \
-    ;                         \
-  else                        \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -39,12 +29,8 @@
 Java_edu_wpi_first_hal_PWMJNI_initializePWMPort
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "Calling PWMJNI initializePWMPort";
-  PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
   int32_t status = 0;
   auto pwm = HAL_InitializePWMPort((HAL_PortHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << pwm;
   CheckStatusRange(env, status, 0, HAL_GetNumPWMChannels(),
                    hal::getPortHandleChannel((HAL_PortHandle)id));
   return (jint)pwm;
@@ -59,8 +45,6 @@
 Java_edu_wpi_first_hal_PWMJNI_checkPWMChannel
   (JNIEnv* env, jclass, jint channel)
 {
-  PWMJNI_LOG(logDEBUG) << "Calling PWMJNI checkPWMChannel";
-  PWMJNI_LOG(logDEBUG) << "Channel = " << channel;
   return HAL_CheckPWMChannel(channel);
 }
 
@@ -73,8 +57,6 @@
 Java_edu_wpi_first_hal_PWMJNI_freePWMPort
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "Calling PWMJNI freePWMPort";
-  PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   HAL_FreePWMPort((HAL_DigitalHandle)id, &status);
   CheckStatus(env, status);
@@ -90,8 +72,6 @@
   (JNIEnv* env, jclass, jint id, jint maxPwm, jint deadbandMaxPwm,
    jint centerPwm, jint deadbandMinPwm, jint minPwm)
 {
-  PWMJNI_LOG(logDEBUG) << "Calling PWMJNI setPWMConfigRaw";
-  PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   HAL_SetPWMConfigRaw((HAL_DigitalHandle)id, maxPwm, deadbandMaxPwm, centerPwm,
                       deadbandMinPwm, minPwm, &status);
@@ -108,8 +88,6 @@
   (JNIEnv* env, jclass, jint id, jdouble maxPwm, jdouble deadbandMaxPwm,
    jdouble centerPwm, jdouble deadbandMinPwm, jdouble minPwm)
 {
-  PWMJNI_LOG(logDEBUG) << "Calling PWMJNI setPWMConfig";
-  PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   HAL_SetPWMConfig((HAL_DigitalHandle)id, maxPwm, deadbandMaxPwm, centerPwm,
                    deadbandMinPwm, minPwm, &status);
@@ -125,8 +103,6 @@
 Java_edu_wpi_first_hal_PWMJNI_getPWMConfigRaw
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "Calling PWMJNI getPWMConfigRaw";
-  PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   int32_t maxPwm = 0;
   int32_t deadbandMaxPwm = 0;
@@ -149,10 +125,8 @@
 Java_edu_wpi_first_hal_PWMJNI_setPWMEliminateDeadband
   (JNIEnv* env, jclass, jint id, jboolean value)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   HAL_SetPWMEliminateDeadband((HAL_DigitalHandle)id, value, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -165,10 +139,8 @@
 Java_edu_wpi_first_hal_PWMJNI_getPWMEliminateDeadband
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   auto val = HAL_GetPWMEliminateDeadband((HAL_DigitalHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
   return (jboolean)val;
 }
@@ -182,11 +154,8 @@
 Java_edu_wpi_first_hal_PWMJNI_setPWMRaw
   (JNIEnv* env, jclass, jint id, jshort value)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
-  PWMJNI_LOG(logDEBUG) << "PWM Value = " << value;
   int32_t status = 0;
   HAL_SetPWMRaw((HAL_DigitalHandle)id, value, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -199,11 +168,8 @@
 Java_edu_wpi_first_hal_PWMJNI_setPWMSpeed
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
-  PWMJNI_LOG(logDEBUG) << "PWM Value = " << value;
   int32_t status = 0;
   HAL_SetPWMSpeed((HAL_DigitalHandle)id, value, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -216,11 +182,8 @@
 Java_edu_wpi_first_hal_PWMJNI_setPWMPosition
   (JNIEnv* env, jclass, jint id, jdouble value)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
-  PWMJNI_LOG(logDEBUG) << "PWM Value = " << value;
   int32_t status = 0;
   HAL_SetPWMPosition((HAL_DigitalHandle)id, value, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -233,11 +196,8 @@
 Java_edu_wpi_first_hal_PWMJNI_getPWMRaw
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   jshort returnValue = HAL_GetPWMRaw((HAL_DigitalHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
-  PWMJNI_LOG(logDEBUG) << "Value = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -251,11 +211,8 @@
 Java_edu_wpi_first_hal_PWMJNI_getPWMSpeed
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   jdouble returnValue = HAL_GetPWMSpeed((HAL_DigitalHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
-  PWMJNI_LOG(logDEBUG) << "Value = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -269,11 +226,8 @@
 Java_edu_wpi_first_hal_PWMJNI_getPWMPosition
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   jdouble returnValue = HAL_GetPWMPosition((HAL_DigitalHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
-  PWMJNI_LOG(logDEBUG) << "Value = " << returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
@@ -287,10 +241,8 @@
 Java_edu_wpi_first_hal_PWMJNI_setPWMDisabled
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   HAL_SetPWMDisabled((HAL_DigitalHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -303,10 +255,8 @@
 Java_edu_wpi_first_hal_PWMJNI_latchPWMZero
   (JNIEnv* env, jclass, jint id)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
   int32_t status = 0;
   HAL_LatchPWMZero((HAL_DigitalHandle)id, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -319,11 +269,8 @@
 Java_edu_wpi_first_hal_PWMJNI_setPWMPeriodScale
   (JNIEnv* env, jclass, jint id, jint value)
 {
-  PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
-  PWMJNI_LOG(logDEBUG) << "PeriodScale Value = " << value;
   int32_t status = 0;
   HAL_SetPWMPeriodScale((HAL_DigitalHandle)id, value, &status);
-  PWMJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
diff --git a/hal/src/main/native/cpp/jni/PortsJNI.cpp b/hal/src/main/native/cpp/jni/PortsJNI.cpp
index 4e14984..1adb7fb 100644
--- a/hal/src/main/native/cpp/jni/PortsJNI.cpp
+++ b/hal/src/main/native/cpp/jni/PortsJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -12,19 +12,9 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_PortsJNI.h"
 #include "hal/Ports.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel portsJNILogLevel = logWARNING;
-
-#define PORTSJNI_LOG(level)     \
-  if (level > portsJNILogLevel) \
-    ;                           \
-  else                          \
-    Log().Get(level)
-
 extern "C" {
 /*
  * Class:     edu_wpi_first_hal_PortsJNI
@@ -35,9 +25,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumAccumulators
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAccumulators";
   jint value = HAL_GetNumAccumulators();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -50,9 +38,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumAnalogTriggers
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAnalogTriggers";
   jint value = HAL_GetNumAnalogTriggers();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -65,9 +51,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumAnalogInputs
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAnalogInputs";
   jint value = HAL_GetNumAnalogInputs();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -80,9 +64,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumAnalogOutputs
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAnalogOutputs";
   jint value = HAL_GetNumAnalogOutputs();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -95,9 +77,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumCounters
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumCounters";
   jint value = HAL_GetNumCounters();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -110,9 +90,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumDigitalHeaders
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumDigitalHeaders";
   jint value = HAL_GetNumDigitalHeaders();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -125,9 +103,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumPWMHeaders
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPWMHeaders";
   jint value = HAL_GetNumPWMHeaders();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -140,9 +116,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumDigitalChannels
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumDigitalChannels";
   jint value = HAL_GetNumDigitalChannels();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -155,9 +129,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumPWMChannels
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPWMChannels";
   jint value = HAL_GetNumPWMChannels();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -170,9 +142,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumDigitalPWMOutputs
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumDigitalPWMOutputs";
   jint value = HAL_GetNumDigitalPWMOutputs();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -185,9 +155,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumEncoders
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumEncoders";
   jint value = HAL_GetNumEncoders();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -200,9 +168,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumInterrupts
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumInterrupts";
   jint value = HAL_GetNumInterrupts();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -215,9 +181,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumRelayChannels
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumRelayChannels";
   jint value = HAL_GetNumRelayChannels();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -230,9 +194,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumRelayHeaders
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumRelayHeaders";
   jint value = HAL_GetNumRelayHeaders();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -245,9 +207,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumPCMModules
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPCMModules";
   jint value = HAL_GetNumPCMModules();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -260,9 +220,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumSolenoidChannels
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumSolenoidChannels";
   jint value = HAL_GetNumSolenoidChannels();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -275,9 +233,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumPDPModules
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPDPModules";
   jint value = HAL_GetNumPDPModules();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 
@@ -290,9 +246,7 @@
 Java_edu_wpi_first_hal_PortsJNI_getNumPDPChannels
   (JNIEnv* env, jclass)
 {
-  PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPDPChannels";
   jint value = HAL_GetNumPDPChannels();
-  PORTSJNI_LOG(logDEBUG) << "Value = " << value;
   return value;
 }
 }  // extern "C"
diff --git a/hal/src/main/native/cpp/jni/RelayJNI.cpp b/hal/src/main/native/cpp/jni/RelayJNI.cpp
index 0cc70fb..c058435 100644
--- a/hal/src/main/native/cpp/jni/RelayJNI.cpp
+++ b/hal/src/main/native/cpp/jni/RelayJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -13,20 +13,10 @@
 #include "edu_wpi_first_hal_RelayJNI.h"
 #include "hal/Ports.h"
 #include "hal/Relay.h"
-#include "hal/cpp/Log.h"
 #include "hal/handles/HandlesInternal.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel relayJNILogLevel = logWARNING;
-
-#define RELAYJNI_LOG(level)     \
-  if (level > relayJNILogLevel) \
-    ;                           \
-  else                          \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -38,14 +28,9 @@
 Java_edu_wpi_first_hal_RelayJNI_initializeRelayPort
   (JNIEnv* env, jclass, jint id, jboolean fwd)
 {
-  RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI initializeRelayPort";
-  RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
-  RELAYJNI_LOG(logDEBUG) << "Forward = " << (jint)fwd;
   int32_t status = 0;
   HAL_RelayHandle handle = HAL_InitializeRelayPort(
       (HAL_PortHandle)id, static_cast<uint8_t>(fwd), &status);
-  RELAYJNI_LOG(logDEBUG) << "Status = " << status;
-  RELAYJNI_LOG(logDEBUG) << "Relay Handle = " << handle;
   CheckStatusRange(env, status, 0, HAL_GetNumRelayChannels(),
                    hal::getPortHandleChannel((HAL_PortHandle)id));
   return (jint)handle;
@@ -60,8 +45,6 @@
 Java_edu_wpi_first_hal_RelayJNI_freeRelayPort
   (JNIEnv* env, jclass, jint id)
 {
-  RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI freeRelayPort";
-  RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_RelayHandle)id;
   HAL_FreeRelayPort((HAL_RelayHandle)id);
 }
 
@@ -74,8 +57,6 @@
 Java_edu_wpi_first_hal_RelayJNI_checkRelayChannel
   (JNIEnv* env, jclass, jint channel)
 {
-  RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI checkRelayChannel";
-  RELAYJNI_LOG(logDEBUG) << "Channel = " << channel;
   return (jboolean)HAL_CheckRelayChannel(static_cast<uint8_t>(channel));
 }
 
@@ -88,12 +69,8 @@
 Java_edu_wpi_first_hal_RelayJNI_setRelay
   (JNIEnv* env, jclass, jint id, jboolean value)
 {
-  RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI setRelay";
-  RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_RelayHandle)id;
-  RELAYJNI_LOG(logDEBUG) << "Flag = " << (jint)value;
   int32_t status = 0;
   HAL_SetRelay((HAL_RelayHandle)id, value, &status);
-  RELAYJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -106,12 +83,8 @@
 Java_edu_wpi_first_hal_RelayJNI_getRelay
   (JNIEnv* env, jclass, jint id)
 {
-  RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI getRelay";
-  RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_RelayHandle)id;
   int32_t status = 0;
   jboolean returnValue = HAL_GetRelay((HAL_RelayHandle)id, &status);
-  RELAYJNI_LOG(logDEBUG) << "Status = " << status;
-  RELAYJNI_LOG(logDEBUG) << "getRelayResult = " << (jint)returnValue;
   CheckStatus(env, status);
   return returnValue;
 }
diff --git a/hal/src/main/native/cpp/jni/SPIJNI.cpp b/hal/src/main/native/cpp/jni/SPIJNI.cpp
index d594058..27078fd 100644
--- a/hal/src/main/native/cpp/jni/SPIJNI.cpp
+++ b/hal/src/main/native/cpp/jni/SPIJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -14,20 +14,10 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_SPIJNI.h"
 #include "hal/SPI.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 using namespace wpi::java;
 
-// set the logging level
-TLogLevel spiJNILogLevel = logWARNING;
-
-#define SPIJNI_LOG(level)     \
-  if (level > spiJNILogLevel) \
-    ;                         \
-  else                        \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -39,11 +29,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiInitialize
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiInitialize";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   int32_t status = 0;
   HAL_InitializeSPI(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatusForceThrow(env, status);
 }
 
@@ -57,8 +44,6 @@
   (JNIEnv* env, jclass, jint port, jobject dataToSend, jobject dataReceived,
    jbyte size)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiTransaction";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   uint8_t* dataToSendPtr = nullptr;
   if (dataToSend != 0) {
     dataToSendPtr =
@@ -66,12 +51,8 @@
   }
   uint8_t* dataReceivedPtr =
       reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
-  SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
-  SPIJNI_LOG(logDEBUG) << "DataToSendPtr = " << dataToSendPtr;
-  SPIJNI_LOG(logDEBUG) << "DataReceivedPtr = " << dataReceivedPtr;
   jint retVal = HAL_TransactionSPI(static_cast<HAL_SPIPort>(port),
                                    dataToSendPtr, dataReceivedPtr, size);
-  SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
   return retVal;
 }
 
@@ -85,9 +66,6 @@
   (JNIEnv* env, jclass, jint port, jbyteArray dataToSend,
    jbyteArray dataReceived, jbyte size)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiTransactionB";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
-  SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
   wpi::SmallVector<uint8_t, 128> recvBuf;
   recvBuf.resize(size);
   jint retVal =
@@ -97,7 +75,6 @@
                          recvBuf.data(), size);
   env->SetByteArrayRegion(dataReceived, 0, size,
                           reinterpret_cast<const jbyte*>(recvBuf.data()));
-  SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
   return retVal;
 }
 
@@ -110,18 +87,13 @@
 Java_edu_wpi_first_hal_SPIJNI_spiWrite
   (JNIEnv* env, jclass, jint port, jobject dataToSend, jbyte size)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiWrite";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   uint8_t* dataToSendPtr = nullptr;
   if (dataToSend != 0) {
     dataToSendPtr =
         reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
   }
-  SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
-  SPIJNI_LOG(logDEBUG) << "DataToSendPtr = " << dataToSendPtr;
   jint retVal =
       HAL_WriteSPI(static_cast<HAL_SPIPort>(port), dataToSendPtr, size);
-  SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
   return retVal;
 }
 
@@ -134,14 +106,10 @@
 Java_edu_wpi_first_hal_SPIJNI_spiWriteB
   (JNIEnv* env, jclass, jint port, jbyteArray dataToSend, jbyte size)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiWriteB";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
-  SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
   jint retVal = HAL_WriteSPI(static_cast<HAL_SPIPort>(port),
                              reinterpret_cast<const uint8_t*>(
                                  JByteArrayRef(env, dataToSend).array().data()),
                              size);
-  SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
   return retVal;
 }
 
@@ -155,13 +123,8 @@
   (JNIEnv* env, jclass, jint port, jboolean initiate, jobject dataReceived,
    jbyte size)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiRead";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
-  SPIJNI_LOG(logDEBUG) << "Initiate = " << (jboolean)initiate;
   uint8_t* dataReceivedPtr =
       reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
-  SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
-  SPIJNI_LOG(logDEBUG) << "DataReceivedPtr = " << dataReceivedPtr;
   jint retVal;
   if (initiate) {
     wpi::SmallVector<uint8_t, 128> sendBuf;
@@ -172,7 +135,6 @@
     retVal = HAL_ReadSPI(static_cast<HAL_SPIPort>(port),
                          reinterpret_cast<uint8_t*>(dataReceivedPtr), size);
   }
-  SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
   return retVal;
 }
 
@@ -186,10 +148,6 @@
   (JNIEnv* env, jclass, jint port, jboolean initiate, jbyteArray dataReceived,
    jbyte size)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadB";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
-  SPIJNI_LOG(logDEBUG) << "Initiate = " << (jboolean)initiate;
-  SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
   jint retVal;
   wpi::SmallVector<uint8_t, 128> recvBuf;
   recvBuf.resize(size);
@@ -203,7 +161,6 @@
   }
   env->SetByteArrayRegion(dataReceived, 0, size,
                           reinterpret_cast<const jbyte*>(recvBuf.data()));
-  SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
   return retVal;
 }
 
@@ -216,8 +173,6 @@
 Java_edu_wpi_first_hal_SPIJNI_spiClose
   (JNIEnv*, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiClose";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   HAL_CloseSPI(static_cast<HAL_SPIPort>(port));
 }
 
@@ -230,9 +185,6 @@
 Java_edu_wpi_first_hal_SPIJNI_spiSetSpeed
   (JNIEnv*, jclass, jint port, jint speed)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetSpeed";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
-  SPIJNI_LOG(logDEBUG) << "Speed = " << (jint)speed;
   HAL_SetSPISpeed(static_cast<HAL_SPIPort>(port), speed);
 }
 
@@ -246,11 +198,6 @@
   (JNIEnv*, jclass, jint port, jint msb_first, jint sample_on_trailing,
    jint clk_idle_high)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetOpts";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
-  SPIJNI_LOG(logDEBUG) << "msb_first = " << msb_first;
-  SPIJNI_LOG(logDEBUG) << "sample_on_trailing = " << sample_on_trailing;
-  SPIJNI_LOG(logDEBUG) << "clk_idle_high = " << clk_idle_high;
   HAL_SetSPIOpts(static_cast<HAL_SPIPort>(port), msb_first, sample_on_trailing,
                  clk_idle_high);
 }
@@ -264,11 +211,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiSetChipSelectActiveHigh
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetCSActiveHigh";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   int32_t status = 0;
   HAL_SetSPIChipSelectActiveHigh(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -281,11 +225,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiSetChipSelectActiveLow
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetCSActiveLow";
-  SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   int32_t status = 0;
   HAL_SetSPIChipSelectActiveLow(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -298,12 +239,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiInitAuto
   (JNIEnv* env, jclass, jint port, jint bufferSize)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiInitAuto";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
-  SPIJNI_LOG(logDEBUG) << "BufferSize = " << bufferSize;
   int32_t status = 0;
   HAL_InitSPIAuto(static_cast<HAL_SPIPort>(port), bufferSize, &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -316,11 +253,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiFreeAuto
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiFreeAuto";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
   int32_t status = 0;
   HAL_FreeSPIAuto(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -333,12 +267,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiStartAutoRate
   (JNIEnv* env, jclass, jint port, jdouble period)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiStartAutoRate";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
-  SPIJNI_LOG(logDEBUG) << "Period = " << period;
   int32_t status = 0;
   HAL_StartSPIAutoRate(static_cast<HAL_SPIPort>(port), period, &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -352,17 +282,10 @@
   (JNIEnv* env, jclass, jint port, jint digitalSourceHandle,
    jint analogTriggerType, jboolean triggerRising, jboolean triggerFalling)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiStartAutoTrigger";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
-  SPIJNI_LOG(logDEBUG) << "DigitalSourceHandle = " << digitalSourceHandle;
-  SPIJNI_LOG(logDEBUG) << "AnalogTriggerType = " << analogTriggerType;
-  SPIJNI_LOG(logDEBUG) << "TriggerRising = " << (jint)triggerRising;
-  SPIJNI_LOG(logDEBUG) << "TriggerFalling = " << (jint)triggerFalling;
   int32_t status = 0;
   HAL_StartSPIAutoTrigger(static_cast<HAL_SPIPort>(port), digitalSourceHandle,
                           static_cast<HAL_AnalogTriggerType>(analogTriggerType),
                           triggerRising, triggerFalling, &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -375,11 +298,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiStopAuto
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiStopAuto";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
   int32_t status = 0;
   HAL_StopSPIAuto(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -392,16 +312,12 @@
 Java_edu_wpi_first_hal_SPIJNI_spiSetAutoTransmitData
   (JNIEnv* env, jclass, jint port, jbyteArray dataToSend, jint zeroSize)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetAutoTransmitData";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
-  SPIJNI_LOG(logDEBUG) << "ZeroSize = " << zeroSize;
   JByteArrayRef jarr(env, dataToSend);
   int32_t status = 0;
   HAL_SetSPIAutoTransmitData(
       static_cast<HAL_SPIPort>(port),
       reinterpret_cast<const uint8_t*>(jarr.array().data()),
       jarr.array().size(), zeroSize, &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -414,11 +330,8 @@
 Java_edu_wpi_first_hal_SPIJNI_spiForceAutoRead
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiForceAutoRead";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
   int32_t status = 0;
   HAL_ForceSPIAutoRead(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
@@ -432,17 +345,11 @@
   (JNIEnv* env, jclass, jint port, jobject buffer, jint numToRead,
    jdouble timeout)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadAutoReceivedData";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
-  SPIJNI_LOG(logDEBUG) << "NumToRead = " << numToRead;
-  SPIJNI_LOG(logDEBUG) << "Timeout = " << timeout;
   uint32_t* recvBuf =
       reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(buffer));
   int32_t status = 0;
   jint retval = HAL_ReadSPIAutoReceivedData(
       static_cast<HAL_SPIPort>(port), recvBuf, numToRead, timeout, &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
-  SPIJNI_LOG(logDEBUG) << "Return = " << retval;
   CheckStatus(env, status);
   return retval;
 }
@@ -457,18 +364,12 @@
   (JNIEnv* env, jclass, jint port, jintArray buffer, jint numToRead,
    jdouble timeout)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadAutoReceivedData";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
-  SPIJNI_LOG(logDEBUG) << "NumToRead = " << numToRead;
-  SPIJNI_LOG(logDEBUG) << "Timeout = " << timeout;
   wpi::SmallVector<uint32_t, 128> recvBuf;
   recvBuf.resize(numToRead);
   int32_t status = 0;
   jint retval =
       HAL_ReadSPIAutoReceivedData(static_cast<HAL_SPIPort>(port),
                                   recvBuf.data(), numToRead, timeout, &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
-  SPIJNI_LOG(logDEBUG) << "Return = " << retval;
   if (!CheckStatus(env, status)) return retval;
   if (numToRead > 0) {
     env->SetIntArrayRegion(buffer, 0, numToRead,
@@ -486,13 +387,9 @@
 Java_edu_wpi_first_hal_SPIJNI_spiGetAutoDroppedCount
   (JNIEnv* env, jclass, jint port)
 {
-  SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiGetAutoDroppedCount";
-  SPIJNI_LOG(logDEBUG) << "Port = " << port;
   int32_t status = 0;
   auto retval =
       HAL_GetSPIAutoDroppedCount(static_cast<HAL_SPIPort>(port), &status);
-  SPIJNI_LOG(logDEBUG) << "Status = " << status;
-  SPIJNI_LOG(logDEBUG) << "Return = " << retval;
   CheckStatus(env, status);
   return retval;
 }
diff --git a/hal/src/main/native/cpp/jni/SerialPortJNI.cpp b/hal/src/main/native/cpp/jni/SerialPortJNI.cpp
index 4524fe6..9fe9d92 100644
--- a/hal/src/main/native/cpp/jni/SerialPortJNI.cpp
+++ b/hal/src/main/native/cpp/jni/SerialPortJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -14,261 +14,222 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_SerialPortJNI.h"
 #include "hal/SerialPort.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 using namespace wpi::java;
 
-// set the logging level
-TLogLevel serialJNILogLevel = logWARNING;
-
-#define SERIALJNI_LOG(level)     \
-  if (level > serialJNILogLevel) \
-    ;                            \
-  else                           \
-    Log().Get(level)
-
 extern "C" {
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialInitializePort
- * Signature: (B)V
+ * Signature: (B)I
  */
-JNIEXPORT void JNICALL
+JNIEXPORT jint JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialInitializePort
   (JNIEnv* env, jclass, jbyte port)
 {
-  SERIALJNI_LOG(logDEBUG) << "Calling Serial Initialize";
-  SERIALJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   int32_t status = 0;
-  HAL_InitializeSerialPort(static_cast<HAL_SerialPort>(port), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  auto handle =
+      HAL_InitializeSerialPort(static_cast<HAL_SerialPort>(port), &status);
   CheckStatusForceThrow(env, status);
+  return static_cast<jint>(handle);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialInitializePortDirect
- * Signature: (BLjava/lang/String;)V
+ * Signature: (BLjava/lang/String;)I
  */
-JNIEXPORT void JNICALL
+JNIEXPORT jint JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialInitializePortDirect
   (JNIEnv* env, jclass, jbyte port, jstring portName)
 {
-  SERIALJNI_LOG(logDEBUG) << "Calling Serial Initialize Direct";
-  SERIALJNI_LOG(logDEBUG) << "Port = " << (jint)port;
   JStringRef portNameRef{env, portName};
-  SERIALJNI_LOG(logDEBUG) << "PortName = " << portNameRef.c_str();
   int32_t status = 0;
-  HAL_InitializeSerialPortDirect(static_cast<HAL_SerialPort>(port),
-                                 portNameRef.c_str(), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  auto handle = HAL_InitializeSerialPortDirect(
+      static_cast<HAL_SerialPort>(port), portNameRef.c_str(), &status);
   CheckStatusForceThrow(env, status);
+  return static_cast<jint>(handle);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetBaudRate
- * Signature: (BI)V
+ * Signature: (II)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetBaudRate
-  (JNIEnv* env, jclass, jbyte port, jint rate)
+  (JNIEnv* env, jclass, jint handle, jint rate)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Baud Rate";
-  SERIALJNI_LOG(logDEBUG) << "Baud: " << rate;
   int32_t status = 0;
-  HAL_SetSerialBaudRate(static_cast<HAL_SerialPort>(port), rate, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialBaudRate(static_cast<HAL_SerialPortHandle>(handle), rate,
+                        &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetDataBits
- * Signature: (BB)V
+ * Signature: (IB)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetDataBits
-  (JNIEnv* env, jclass, jbyte port, jbyte bits)
+  (JNIEnv* env, jclass, jint handle, jbyte bits)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Data Bits";
-  SERIALJNI_LOG(logDEBUG) << "Data Bits: " << bits;
   int32_t status = 0;
-  HAL_SetSerialDataBits(static_cast<HAL_SerialPort>(port), bits, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialDataBits(static_cast<HAL_SerialPortHandle>(handle), bits,
+                        &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetParity
- * Signature: (BB)V
+ * Signature: (IB)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetParity
-  (JNIEnv* env, jclass, jbyte port, jbyte parity)
+  (JNIEnv* env, jclass, jint handle, jbyte parity)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Parity";
-  SERIALJNI_LOG(logDEBUG) << "Parity: " << parity;
   int32_t status = 0;
-  HAL_SetSerialParity(static_cast<HAL_SerialPort>(port), parity, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialParity(static_cast<HAL_SerialPortHandle>(handle), parity,
+                      &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetStopBits
- * Signature: (BB)V
+ * Signature: (IB)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetStopBits
-  (JNIEnv* env, jclass, jbyte port, jbyte bits)
+  (JNIEnv* env, jclass, jint handle, jbyte bits)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Stop Bits";
-  SERIALJNI_LOG(logDEBUG) << "Stop Bits: " << bits;
   int32_t status = 0;
-  HAL_SetSerialStopBits(static_cast<HAL_SerialPort>(port), bits, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialStopBits(static_cast<HAL_SerialPortHandle>(handle), bits,
+                        &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetWriteMode
- * Signature: (BB)V
+ * Signature: (IB)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteMode
-  (JNIEnv* env, jclass, jbyte port, jbyte mode)
+  (JNIEnv* env, jclass, jint handle, jbyte mode)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Write Mode";
-  SERIALJNI_LOG(logDEBUG) << "Write mode: " << mode;
   int32_t status = 0;
-  HAL_SetSerialWriteMode(static_cast<HAL_SerialPort>(port), mode, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialWriteMode(static_cast<HAL_SerialPortHandle>(handle), mode,
+                         &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetFlowControl
- * Signature: (BB)V
+ * Signature: (IB)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetFlowControl
-  (JNIEnv* env, jclass, jbyte port, jbyte flow)
+  (JNIEnv* env, jclass, jint handle, jbyte flow)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Flow Control";
-  SERIALJNI_LOG(logDEBUG) << "Flow Control: " << flow;
   int32_t status = 0;
-  HAL_SetSerialFlowControl(static_cast<HAL_SerialPort>(port), flow, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialFlowControl(static_cast<HAL_SerialPortHandle>(handle), flow,
+                           &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetTimeout
- * Signature: (BD)V
+ * Signature: (ID)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetTimeout
-  (JNIEnv* env, jclass, jbyte port, jdouble timeout)
+  (JNIEnv* env, jclass, jint handle, jdouble timeout)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Timeout";
-  SERIALJNI_LOG(logDEBUG) << "Timeout: " << timeout;
   int32_t status = 0;
-  HAL_SetSerialTimeout(static_cast<HAL_SerialPort>(port), timeout, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialTimeout(static_cast<HAL_SerialPortHandle>(handle), timeout,
+                       &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialEnableTermination
- * Signature: (BC)V
+ * Signature: (IC)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialEnableTermination
-  (JNIEnv* env, jclass, jbyte port, jchar terminator)
+  (JNIEnv* env, jclass, jint handle, jchar terminator)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Enable Termination";
-  SERIALJNI_LOG(logDEBUG) << "Terminator: " << terminator;
   int32_t status = 0;
-  HAL_EnableSerialTermination(static_cast<HAL_SerialPort>(port), terminator,
-                              &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_EnableSerialTermination(static_cast<HAL_SerialPortHandle>(handle),
+                              terminator, &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialDisableTermination
- * Signature: (B)V
+ * Signature: (I)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialDisableTermination
-  (JNIEnv* env, jclass, jbyte port)
+  (JNIEnv* env, jclass, jint handle)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Disable termination";
   int32_t status = 0;
-  HAL_DisableSerialTermination(static_cast<HAL_SerialPort>(port), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_DisableSerialTermination(static_cast<HAL_SerialPortHandle>(handle),
+                               &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetReadBufferSize
- * Signature: (BI)V
+ * Signature: (II)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetReadBufferSize
-  (JNIEnv* env, jclass, jbyte port, jint size)
+  (JNIEnv* env, jclass, jint handle, jint size)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Read Buffer Size";
-  SERIALJNI_LOG(logDEBUG) << "Size: " << size;
   int32_t status = 0;
-  HAL_SetSerialReadBufferSize(static_cast<HAL_SerialPort>(port), size, &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_SetSerialReadBufferSize(static_cast<HAL_SerialPortHandle>(handle), size,
+                              &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialSetWriteBufferSize
- * Signature: (BI)V
+ * Signature: (II)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteBufferSize
-  (JNIEnv* env, jclass, jbyte port, jint size)
+  (JNIEnv* env, jclass, jint handle, jint size)
 {
-  SERIALJNI_LOG(logDEBUG) << "Setting Serial Write Buffer Size";
-  SERIALJNI_LOG(logDEBUG) << "Size: " << size;
   int32_t status = 0;
-  HAL_SetSerialWriteBufferSize(static_cast<HAL_SerialPort>(port), size,
+  HAL_SetSerialWriteBufferSize(static_cast<HAL_SerialPortHandle>(handle), size,
                                &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialGetBytesReceived
- * Signature: (B)I
+ * Signature: (I)I
  */
 JNIEXPORT jint JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialGetBytesReceived
-  (JNIEnv* env, jclass, jbyte port)
+  (JNIEnv* env, jclass, jint handle)
 {
-  SERIALJNI_LOG(logDEBUG) << "Serial Get Bytes Received";
   int32_t status = 0;
-  jint retVal =
-      HAL_GetSerialBytesReceived(static_cast<HAL_SerialPort>(port), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  jint retVal = HAL_GetSerialBytesReceived(
+      static_cast<HAL_SerialPortHandle>(handle), &status);
   CheckStatus(env, status);
   return retVal;
 }
@@ -276,22 +237,19 @@
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialRead
- * Signature: (B[BI)I
+ * Signature: (I[BI)I
  */
 JNIEXPORT jint JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialRead
-  (JNIEnv* env, jclass, jbyte port, jbyteArray dataReceived, jint size)
+  (JNIEnv* env, jclass, jint handle, jbyteArray dataReceived, jint size)
 {
-  SERIALJNI_LOG(logDEBUG) << "Serial Read";
   wpi::SmallVector<char, 128> recvBuf;
   recvBuf.resize(size);
   int32_t status = 0;
-  jint retVal = HAL_ReadSerial(static_cast<HAL_SerialPort>(port),
+  jint retVal = HAL_ReadSerial(static_cast<HAL_SerialPortHandle>(handle),
                                recvBuf.data(), size, &status);
   env->SetByteArrayRegion(dataReceived, 0, size,
                           reinterpret_cast<const jbyte*>(recvBuf.data()));
-  SERIALJNI_LOG(logDEBUG) << "ReturnValue = " << retVal;
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
   return retVal;
 }
@@ -299,21 +257,18 @@
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialWrite
- * Signature: (B[BI)I
+ * Signature: (I[BI)I
  */
 JNIEXPORT jint JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialWrite
-  (JNIEnv* env, jclass, jbyte port, jbyteArray dataToSend, jint size)
+  (JNIEnv* env, jclass, jint handle, jbyteArray dataToSend, jint size)
 {
-  SERIALJNI_LOG(logDEBUG) << "Serial Write";
   int32_t status = 0;
   jint retVal =
-      HAL_WriteSerial(static_cast<HAL_SerialPort>(port),
+      HAL_WriteSerial(static_cast<HAL_SerialPortHandle>(handle),
                       reinterpret_cast<const char*>(
                           JByteArrayRef(env, dataToSend).array().data()),
                       size, &status);
-  SERIALJNI_LOG(logDEBUG) << "ReturnValue = " << retVal;
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
   CheckStatus(env, status);
   return retVal;
 }
@@ -321,48 +276,42 @@
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialFlush
- * Signature: (B)V
+ * Signature: (I)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialFlush
-  (JNIEnv* env, jclass, jbyte port)
+  (JNIEnv* env, jclass, jint handle)
 {
-  SERIALJNI_LOG(logDEBUG) << "Serial Flush";
   int32_t status = 0;
-  HAL_FlushSerial(static_cast<HAL_SerialPort>(port), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_FlushSerial(static_cast<HAL_SerialPortHandle>(handle), &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialClear
- * Signature: (B)V
+ * Signature: (I)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialClear
-  (JNIEnv* env, jclass, jbyte port)
+  (JNIEnv* env, jclass, jint handle)
 {
-  SERIALJNI_LOG(logDEBUG) << "Serial Clear";
   int32_t status = 0;
-  HAL_ClearSerial(static_cast<HAL_SerialPort>(port), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_ClearSerial(static_cast<HAL_SerialPortHandle>(handle), &status);
   CheckStatus(env, status);
 }
 
 /*
  * Class:     edu_wpi_first_hal_SerialPortJNI
  * Method:    serialClose
- * Signature: (B)V
+ * Signature: (I)V
  */
 JNIEXPORT void JNICALL
 Java_edu_wpi_first_hal_SerialPortJNI_serialClose
-  (JNIEnv* env, jclass, jbyte port)
+  (JNIEnv* env, jclass, jint handle)
 {
-  SERIALJNI_LOG(logDEBUG) << "Serial Close";
   int32_t status = 0;
-  HAL_CloseSerial(static_cast<HAL_SerialPort>(port), &status);
-  SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+  HAL_CloseSerial(static_cast<HAL_SerialPortHandle>(handle), &status);
   CheckStatus(env, status);
 }
 
diff --git a/hal/src/main/native/cpp/jni/SimDeviceJNI.cpp b/hal/src/main/native/cpp/jni/SimDeviceJNI.cpp
new file mode 100644
index 0000000..d9652cc
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/SimDeviceJNI.cpp
@@ -0,0 +1,168 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_SimDeviceJNI.h"
+#include "hal/SimDevice.h"
+
+using namespace wpi::java;
+
+static HAL_Value ValueFromJava(jint type, jlong value1, jdouble value2) {
+  HAL_Value value;
+  value.type = static_cast<HAL_Type>(type);
+  switch (value.type) {
+    case HAL_BOOLEAN:
+      value.data.v_boolean = value1;
+      break;
+    case HAL_DOUBLE:
+      value.data.v_double = value2;
+      break;
+    case HAL_ENUM:
+      value.data.v_enum = value1;
+      break;
+    case HAL_INT:
+      value.data.v_int = value1;
+      break;
+    case HAL_LONG:
+      value.data.v_long = value1;
+      break;
+    default:
+      break;
+  }
+  return value;
+}
+
+extern "C" {
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    createSimDevice
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_createSimDevice
+  (JNIEnv* env, jclass, jstring name)
+{
+  return HAL_CreateSimDevice(JStringRef{env, name}.c_str());
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    freeSimDevice
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_freeSimDevice
+  (JNIEnv*, jclass, jint handle)
+{
+  HAL_FreeSimDevice(handle);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    createSimValueNative
+ * Signature: (ILjava/lang/String;ZIJD)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_createSimValueNative
+  (JNIEnv* env, jclass, jint device, jstring name, jboolean readonly, jint type,
+   jlong value1, jdouble value2)
+{
+  return HAL_CreateSimValue(device, JStringRef{env, name}.c_str(), readonly,
+                            ValueFromJava(type, value1, value2));
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    createSimValueEnum
+ * Signature: (ILjava/lang/String;Z[Ljava/lang/Object;I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_createSimValueEnum
+  (JNIEnv* env, jclass, jint device, jstring name, jboolean readonly,
+   jobjectArray options, jint initialValue)
+{
+  size_t len = env->GetArrayLength(options);
+  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(options, i))};
+    if (!elem) return 0;
+    arr.push_back(JStringRef{env, elem}.str());
+  }
+  wpi::SmallVector<const char*, 8> carr;
+  for (auto&& val : arr) carr.push_back(val.c_str());
+  return HAL_CreateSimValueEnum(device, JStringRef{env, name}.c_str(), readonly,
+                                len, carr.data(), initialValue);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    getSimValue
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_getSimValue
+  (JNIEnv* env, jclass, jint handle)
+{
+  return frc::CreateHALValue(env, HAL_GetSimValue(handle));
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    getSimValueDouble
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_getSimValueDouble
+  (JNIEnv*, jclass, jint handle)
+{
+  return HAL_GetSimValueDouble(handle);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    getSimValueEnum
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_getSimValueEnum
+  (JNIEnv*, jclass, jint handle)
+{
+  return HAL_GetSimValueEnum(handle);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    getSimValueBoolean
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_getSimValueBoolean
+  (JNIEnv*, jclass, jint handle)
+{
+  return HAL_GetSimValueBoolean(handle);
+}
+
+/*
+ * Class:     edu_wpi_first_hal_SimDeviceJNI
+ * Method:    setSimValueNative
+ * Signature: (IIJD)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SimDeviceJNI_setSimValueNative
+  (JNIEnv*, jclass, jint handle, jint type, jlong value1, jdouble value2)
+{
+  HAL_SetSimValue(handle, ValueFromJava(type, value1, value2));
+}
+
+}  // extern "C"
diff --git a/hal/src/main/native/cpp/jni/SolenoidJNI.cpp b/hal/src/main/native/cpp/jni/SolenoidJNI.cpp
index 524b70e..4e6f139 100644
--- a/hal/src/main/native/cpp/jni/SolenoidJNI.cpp
+++ b/hal/src/main/native/cpp/jni/SolenoidJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -11,19 +11,10 @@
 #include "edu_wpi_first_hal_SolenoidJNI.h"
 #include "hal/Ports.h"
 #include "hal/Solenoid.h"
-#include "hal/cpp/Log.h"
 #include "hal/handles/HandlesInternal.h"
 
 using namespace frc;
 
-TLogLevel solenoidJNILogLevel = logERROR;
-
-#define SOLENOIDJNI_LOG(level)     \
-  if (level > solenoidJNILogLevel) \
-    ;                              \
-  else                             \
-    Log().Get(level)
-
 extern "C" {
 
 /*
@@ -35,17 +26,10 @@
 Java_edu_wpi_first_hal_SolenoidJNI_initializeSolenoidPort
   (JNIEnv* env, jclass, jint id)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort";
-
-  SOLENOIDJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
-
   int32_t status = 0;
   HAL_SolenoidHandle handle =
       HAL_InitializeSolenoidPort((HAL_PortHandle)id, &status);
 
-  SOLENOIDJNI_LOG(logDEBUG) << "Status = " << status;
-  SOLENOIDJNI_LOG(logDEBUG) << "Solenoid Port Handle = " << handle;
-
   // Use solenoid channels, as we have to pick one.
   CheckStatusRange(env, status, 0, HAL_GetNumSolenoidChannels(),
                    hal::getPortHandleChannel((HAL_PortHandle)id));
@@ -61,8 +45,6 @@
 Java_edu_wpi_first_hal_SolenoidJNI_checkSolenoidChannel
   (JNIEnv* env, jclass, jint channel)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI checkSolenoidChannel";
-  SOLENOIDJNI_LOG(logDEBUG) << "Channel = " << channel;
   return HAL_CheckSolenoidChannel(channel);
 }
 
@@ -75,8 +57,6 @@
 Java_edu_wpi_first_hal_SolenoidJNI_checkSolenoidModule
   (JNIEnv* env, jclass, jint module)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI checkSolenoidModule";
-  SOLENOIDJNI_LOG(logDEBUG) << "Module = " << module;
   return HAL_CheckSolenoidModule(module);
 }
 
@@ -89,9 +69,6 @@
 Java_edu_wpi_first_hal_SolenoidJNI_freeSolenoidPort
   (JNIEnv* env, jclass, jint id)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort";
-
-  SOLENOIDJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_SolenoidHandle)id;
   HAL_FreeSolenoidPort((HAL_SolenoidHandle)id);
 }
 
@@ -104,11 +81,6 @@
 Java_edu_wpi_first_hal_SolenoidJNI_setSolenoid
   (JNIEnv* env, jclass, jint solenoid_port, jboolean value)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI SetSolenoid";
-
-  SOLENOIDJNI_LOG(logDEBUG)
-      << "Solenoid Port Handle = " << (HAL_SolenoidHandle)solenoid_port;
-
   int32_t status = 0;
   HAL_SetSolenoid((HAL_SolenoidHandle)solenoid_port, value, &status);
   CheckStatus(env, status);
@@ -209,12 +181,6 @@
 Java_edu_wpi_first_hal_SolenoidJNI_setOneShotDuration
   (JNIEnv* env, jclass, jint solenoid_port, jlong durationMS)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI SetOneShotDuration";
-
-  SOLENOIDJNI_LOG(logDEBUG)
-      << "Solenoid Port Handle = " << (HAL_SolenoidHandle)solenoid_port;
-  SOLENOIDJNI_LOG(logDEBUG) << "Duration (MS) = " << durationMS;
-
   int32_t status = 0;
   HAL_SetOneShotDuration((HAL_SolenoidHandle)solenoid_port, durationMS,
                          &status);
@@ -230,11 +196,6 @@
 Java_edu_wpi_first_hal_SolenoidJNI_fireOneShot
   (JNIEnv* env, jclass, jint solenoid_port)
 {
-  SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI fireOneShot";
-
-  SOLENOIDJNI_LOG(logDEBUG)
-      << "Solenoid Port Handle = " << (HAL_SolenoidHandle)solenoid_port;
-
   int32_t status = 0;
   HAL_FireOneShot((HAL_SolenoidHandle)solenoid_port, &status);
   CheckStatus(env, status);
diff --git a/hal/src/main/native/cpp/jni/ThreadsJNI.cpp b/hal/src/main/native/cpp/jni/ThreadsJNI.cpp
index ea3cac6..d4620e2 100644
--- a/hal/src/main/native/cpp/jni/ThreadsJNI.cpp
+++ b/hal/src/main/native/cpp/jni/ThreadsJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -12,19 +12,9 @@
 #include "HALUtil.h"
 #include "edu_wpi_first_hal_ThreadsJNI.h"
 #include "hal/Threads.h"
-#include "hal/cpp/Log.h"
 
 using namespace frc;
 
-// set the logging level
-TLogLevel threadsJNILogLevel = logWARNING;
-
-#define THREADSJNI_LOG(level)     \
-  if (level > threadsJNILogLevel) \
-    ;                             \
-  else                            \
-    Log().Get(level)
-
 extern "C" {
 /*
  * Class:     edu_wpi_first_hal_ThreadsJNI
@@ -35,7 +25,6 @@
 Java_edu_wpi_first_hal_ThreadsJNI_getCurrentThreadPriority
   (JNIEnv* env, jclass)
 {
-  THREADSJNI_LOG(logDEBUG) << "Callling GetCurrentThreadPriority";
   int32_t status = 0;
   HAL_Bool isRT = false;
   auto ret = HAL_GetCurrentThreadPriority(&isRT, &status);
@@ -52,7 +41,6 @@
 Java_edu_wpi_first_hal_ThreadsJNI_getCurrentThreadIsRealTime
   (JNIEnv* env, jclass)
 {
-  THREADSJNI_LOG(logDEBUG) << "Callling GetCurrentThreadIsRealTime";
   int32_t status = 0;
   HAL_Bool isRT = false;
   HAL_GetCurrentThreadPriority(&isRT, &status);
@@ -69,7 +57,6 @@
 Java_edu_wpi_first_hal_ThreadsJNI_setCurrentThreadPriority
   (JNIEnv* env, jclass, jboolean realTime, jint priority)
 {
-  THREADSJNI_LOG(logDEBUG) << "Callling SetCurrentThreadPriority";
   int32_t status = 0;
   auto ret = HAL_SetCurrentThreadPriority(
       (HAL_Bool)realTime, static_cast<int32_t>(priority), &status);