diff --git a/utils/misc/pom.xml b/utils/misc/pom.xml
index d1d3a50..fcb0eb8 100644
--- a/utils/misc/pom.xml
+++ b/utils/misc/pom.xml
@@ -24,6 +24,7 @@
         <dependency>
             <groupId>org.onlab.onos</groupId>
             <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
diff --git a/utils/misc/src/main/java/org/onlab/util/TestUtils.java b/utils/misc/src/main/java/org/onlab/util/TestUtils.java
deleted file mode 100644
index 7e59564..0000000
--- a/utils/misc/src/main/java/org/onlab/util/TestUtils.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.onlab.util;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-
-/**
- * Utilities for testing.
- */
-public final class TestUtils {
-
-    /**
-     * Sets the field, bypassing scope restriction.
-     *
-     * @param subject Object where the field belongs
-     * @param fieldName name of the field to set
-     * @param value value to set to the field.
-     * @param <T> subject type
-     * @param <U> value type
-     * @throws TestUtilsException if there are reflection errors while setting
-     * the field
-     */
-    public static <T, U> void setField(T subject, String fieldName, U value)
-            throws TestUtilsException {
-        @SuppressWarnings("unchecked")
-        Class<T> clazz = (Class<T>) subject.getClass();
-        try {
-            Field field = clazz.getDeclaredField(fieldName);
-            field.setAccessible(true);
-            field.set(subject, value);
-        } catch (NoSuchFieldException | SecurityException |
-                 IllegalArgumentException | IllegalAccessException e) {
-            throw new TestUtilsException("setField failed", e);
-        }
-    }
-
-    /**
-     * Gets the field, bypassing scope restriction.
-     *
-     * @param subject Object where the field belongs
-     * @param fieldName name of the field to get
-     * @return value of the field.
-     * @param <T> subject type
-     * @param <U> field value type
-     * @throws TestUtilsException if there are reflection errors while getting
-     * the field
-     */
-    public static <T, U> U getField(T subject, String fieldName)
-            throws TestUtilsException {
-        try {
-            @SuppressWarnings("unchecked")
-            Class<T> clazz = (Class<T>) subject.getClass();
-            Field field = clazz.getDeclaredField(fieldName);
-            field.setAccessible(true);
-
-            @SuppressWarnings("unchecked")
-            U result = (U) field.get(subject);
-            return result;
-        } catch (NoSuchFieldException | SecurityException |
-                 IllegalArgumentException | IllegalAccessException e) {
-            throw new TestUtilsException("getField failed", e);
-        }
-    }
-
-    /**
-     * Calls the method, bypassing scope restriction.
-     *
-     * @param subject Object where the method belongs
-     * @param methodName name of the method to call
-     * @param paramTypes formal parameter type array
-     * @param args arguments
-     * @return return value or null if void
-     * @param <T> subject type
-     * @param <U> return value type
-     * @throws TestUtilsException if there are reflection errors while calling
-     * the method
-     */
-    public static <T, U> U callMethod(T subject, String methodName,
-            Class<?>[] paramTypes, Object...args) throws TestUtilsException {
-
-        try {
-            @SuppressWarnings("unchecked")
-            Class<T> clazz = (Class<T>) subject.getClass();
-            final Method method;
-            if (paramTypes == null || paramTypes.length == 0) {
-                method = clazz.getDeclaredMethod(methodName);
-            } else {
-                method = clazz.getDeclaredMethod(methodName, paramTypes);
-            }
-            method.setAccessible(true);
-
-            @SuppressWarnings("unchecked")
-            U result = (U) method.invoke(subject, args);
-            return result;
-        } catch (NoSuchMethodException | SecurityException |
-                IllegalAccessException | IllegalArgumentException |
-                InvocationTargetException e) {
-            throw new TestUtilsException("callMethod failed", e);
-        }
-    }
-
-    /**
-     * Calls the method, bypassing scope restriction.
-     *
-     * @param subject Object where the method belongs
-     * @param methodName name of the method to call
-     * @param paramType formal parameter type
-     * @param arg argument
-     * @return return value or null if void
-     * @param <T> subject type
-     * @param <U> return value type
-     * @throws TestUtilsException if there are reflection errors while calling
-     * the method
-     */
-    public static <T, U> U callMethod(T subject, String methodName,
-            Class<?> paramType, Object arg) throws TestUtilsException {
-        return callMethod(subject, methodName, new Class<?>[]{paramType}, arg);
-    }
-
-    /**
-     * Triggers an allocation of an object of type <T> and forces a call to
-     * the private constructor.
-     *
-     * @param constructor Constructor to call
-     * @param <T> type of the object to create
-     * @return created object of type <T>
-     * @throws TestUtilsException if there are reflection errors while calling
-     * the constructor
-     */
-    public static <T> T callConstructor(Constructor<T> constructor)
-            throws TestUtilsException {
-        try {
-            constructor.setAccessible(true);
-            return constructor.newInstance();
-        } catch (InstantiationException | IllegalAccessException |
-                InvocationTargetException error) {
-            throw new TestUtilsException("callConstructor failed", error);
-        }
-    }
-
-    /**
-     * Avoid instantiation.
-     */
-    private TestUtils() {}
-
-    /**
-     * Exception that can be thrown if problems are encountered while executing
-     * the utility method. These are usually problems accessing fields/methods
-     * through reflection. The original exception can be found by examining the
-     * cause.
-     */
-    public static class TestUtilsException extends Exception {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Constructs a new exception with the specified detail message and
-         * cause.
-         *
-         * @param message the detail message
-         * @param cause the original cause of this exception
-         */
-        public TestUtilsException(String message, Throwable cause) {
-            super(message, cause);
-        }
-    }
-}
diff --git a/utils/misc/src/test/java/org/onlab/util/TestUtilsTest.java b/utils/misc/src/test/java/org/onlab/util/TestUtilsTest.java
deleted file mode 100644
index 58e60c1..0000000
--- a/utils/misc/src/test/java/org/onlab/util/TestUtilsTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package org.onlab.util;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.util.TestUtils.TestUtilsException;
-
-/**
- * Test and usage examples for TestUtils.
- */
-public class TestUtilsTest {
-
-    /**
-     * Test data.
-     */
-    private static final class TestClass {
-
-        @SuppressWarnings("unused")
-        private int privateField = 42;
-
-        @SuppressWarnings("unused")
-        protected int protectedField = 2501; // CHECKSTYLE IGNORE THIS LINE
-
-        /**
-         * Protected method with multiple argument.
-         *
-         * @param x simply returns
-         * @param y not used
-         * @return x
-         */
-        @SuppressWarnings("unused")
-        private int privateMethod(Number x, Long y) {
-            return x.intValue();
-        }
-
-        /**
-         * Protected method with no argument.
-         *
-         * @return int
-         */
-        @SuppressWarnings("unused")
-        protected int protectedMethod() {
-            return 42;
-        }
-
-        /**
-         * Method returning array.
-         *
-         * @param ary random array
-         * @return ary
-         */
-        @SuppressWarnings("unused")
-        private int[] arrayReturnMethod(int[] ary) {
-            return ary;
-        }
-
-        /**
-         * Method without return value.
-         *
-         * @param s ignored
-         */
-        @SuppressWarnings("unused")
-        private void voidMethod(String s) {
-            System.out.println(s);
-        }
-    }
-
-    private TestClass test;
-
-    /**
-     * Sets up the test fixture.
-     */
-    @Before
-    public void setUp() {
-        test = new TestClass();
-    }
-
-    /**
-     * Example to access private field.
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testSetGetPrivateField() throws TestUtilsException {
-
-        assertEquals(42, TestUtils.getField(test, "privateField"));
-        TestUtils.setField(test, "privateField", 0xDEAD);
-        assertEquals(0xDEAD, TestUtils.getField(test, "privateField"));
-    }
-
-    /**
-     * Example to access protected field.
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testSetGetProtectedField() throws TestUtilsException {
-
-        assertEquals(2501, TestUtils.getField(test, "protectedField"));
-        TestUtils.setField(test, "protectedField", 0xBEEF);
-        assertEquals(0xBEEF, TestUtils.getField(test, "protectedField"));
-    }
-
-    /**
-     * Example to call private method and multiple parameters.
-     * <p/>
-     * It also illustrates that paramTypes must match declared type,
-     * not the runtime types of arguments.
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testCallPrivateMethod() throws TestUtilsException {
-
-        int result = TestUtils.callMethod(test, "privateMethod",
-                        new Class<?>[] {Number.class, Long.class},
-                        Long.valueOf(42), Long.valueOf(32));
-        assertEquals(42, result);
-    }
-
-    /**
-     * Example to call protected method and no parameters.
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testCallProtectedMethod() throws TestUtilsException {
-
-        int result = TestUtils.callMethod(test, "protectedMethod",
-                        new Class<?>[] {});
-        assertEquals(42, result);
-    }
-
-    /**
-     * Example to call method returning array.
-     * <p/>
-     * Note: It is not required to receive as Object.
-     * Following is just verifying it is not Boxed arrays.
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testCallArrayReturnMethod() throws TestUtilsException {
-
-        int[] array = {1, 2, 3};
-        Object aryResult = TestUtils.callMethod(test, "arrayReturnMethod",
-                new Class<?>[] {int[].class}, array);
-        assertEquals(int[].class, aryResult.getClass());
-        assertArrayEquals(array, (int[]) aryResult);
-    }
-
-
-    /**
-     * Example to call void returning method.
-     * <p/>
-     * Note: Return value will be null for void methods.
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testCallVoidReturnMethod() throws TestUtilsException {
-
-        Object voidResult = TestUtils.callMethod(test, "voidMethod",
-                String.class, "foobar");
-        assertNull(voidResult);
-    }
-}
