diff --git a/src/edu/caltech/cs2/interfaces/IDeque.java b/src/edu/caltech/cs2/interfaces/IDeque.java
index e0db44669a21b9c6e7744bdd29259207f76c62f2..6bfbcb1e0e963aa3b57943a75e7865840ab12b4b 100644
--- a/src/edu/caltech/cs2/interfaces/IDeque.java
+++ b/src/edu/caltech/cs2/interfaces/IDeque.java
@@ -23,7 +23,7 @@ public interface IDeque<E> extends ICollection<E> {
    * @param e Element to add
    */
   default public void add(E e){
-    this.addFront(e);
+    this.addBack(e);
   }
 
   /**
diff --git a/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java b/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java
index 3ee197f116d237e56a5a164e9c417243cc751988..93534150154c78e18648ebae639f180bdfa0d88f 100644
--- a/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java
+++ b/tests/edu/caltech/cs2/datastructures/ArrayDequeTests.java
@@ -15,11 +15,13 @@ import org.junit.jupiter.params.provider.ValueSource;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Stream;
 
 import static edu.caltech.cs2.project03.Project03TestOrdering.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@@ -86,6 +88,20 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
     Reflection.assertNoPublicFields(ArrayDeque.class);
   }
 
+  @Order(classSpecificTestLevel)
+  @DisplayName("There are no protected fields")
+  @Test
+  public void testNoProtectedFields() {
+    Reflection.assertNoProtectedFields(ArrayDeque.class);
+  }
+
+  @Order(classSpecificTestLevel)
+  @DisplayName("All fields in ArrayDeque have modifiers")
+  @Test
+  public void testFieldModifiers() {
+    Reflection.assertFieldModifiers(ArrayDeque.class);
+  }
+
   @Order(classSpecificTestLevel)
   @DisplayName("The public interface is correct")
   @Test
@@ -145,6 +161,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("addFront() and removeFront() take linear time")
+  @Timeout(value = 20, unit = SECONDS)
   @Test()
   public void testFrontDequeOperationComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -163,6 +180,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("addBack() and removeBack() take linear time")
+  @Timeout(value = 20, unit = SECONDS)
   @Test
   public void testBackDequeOperationComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -181,6 +199,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("enqueue() and dequeue() take linear time")
+  @Timeout(value = 20, unit = SECONDS)
   @Test
   public void testQueueOperationComplexity() {
     Function<Integer, IQueue<Integer>> provide = (Integer numElements) -> {
@@ -199,6 +218,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("push() and pop() take constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testStackOperationComplexity() {
     Function<Integer, IStack<Integer>> provide = (Integer numElements) -> {
@@ -217,6 +237,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("peek() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testPeekComplexity() {
     Function<Integer, IStack<Integer>> provide = (Integer numElements) -> {
@@ -233,6 +254,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("peekFront() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test()
   public void testPeekFrontComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -249,6 +271,7 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("peekBack() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testPeekBackComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -262,4 +285,5 @@ public class ArrayDequeTests implements DequeTests, StackTests, QueueTests {
 
     RuntimeInstrumentation.assertAtMost("peekBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, peekBack, 8);
   }
+
 }
\ No newline at end of file
diff --git a/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java b/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java
index 6123c3fa40341e258839864a79380f1e41c6f460..c1ca90d88c626ead24b918f843850fecec74af22 100644
--- a/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java
+++ b/tests/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueueTests.java
@@ -16,14 +16,16 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 
 import static edu.caltech.cs2.project03.Project03TestOrdering.*;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.jupiter.api.Assertions.*;
 
 @Tag("B")
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
-  private static String FIXED_QUEUE_SOURCE ="src/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueue.java";
+  private static String FIXED_QUEUE_SOURCE = "src/edu/caltech/cs2/datastructures/CircularArrayFixedSizeQueue.java";
 
-  private Constructor circFixedSizeQueueConstructor = Reflection.getConstructor(CircularArrayFixedSizeQueue.class, int.class);
+  private Constructor circFixedSizeQueueConstructor = Reflection.getConstructor(CircularArrayFixedSizeQueue.class,
+      int.class);
   private int DEFAULT_CAPACITY = 10;
 
   public IQueue<Object> newQueue() {
@@ -70,20 +72,26 @@ public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
     Reflection.assertNoPublicFields(CircularArrayFixedSizeQueue.class);
   }
 
+  @Order(classSpecificTestLevel)
+  @DisplayName("There are no protected fields")
+  @Test
+  public void testNoProtectedFields() {
+    Reflection.assertNoProtectedFields(CircularArrayFixedSizeQueue.class);
+  }
+
+  @Order(classSpecificTestLevel)
+  @DisplayName("All fields in CircularArrayFixedSizeQueue have modifiers")
+  @Test
+  public void testFieldModifiers() {
+    Reflection.assertFieldModifiers(CircularArrayFixedSizeQueue.class);
+  }
+
   @Order(classSpecificTestLevel)
   @DisplayName("The public interface is correct")
   @Test
   public void testPublicInterface() {
-    Reflection.assertPublicInterface(CircularArrayFixedSizeQueue.class, List.of(
-            "enqueue",
-            "dequeue",
-            "peek",
-            "iterator",
-            "size",
-            "isFull",
-            "capacity",
-            "toString"
-    ));
+    Reflection.assertPublicInterface(CircularArrayFixedSizeQueue.class,
+        List.of("enqueue", "dequeue", "peek", "iterator", "size", "isFull", "capacity", "toString"));
   }
 
   @Order(classSpecificTestLevel)
@@ -93,7 +101,6 @@ public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
     Inspection.assertConstructorHygiene(FIXED_QUEUE_SOURCE);
   }
 
-
   // TOSTRING TESTS ---------------------------------------------------
 
   @Order(toStringTestLevel)
@@ -106,9 +113,7 @@ public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
   @Order(toStringTestLevel)
   @DisplayName("toString() matches java.util.ArrayDeque")
   @ParameterizedTest(name = "Test toString() on [{arguments}]")
-  @ValueSource(strings = {
-          "0, 1, 2, 3", "5, 4, 3, 2, 1", "8, 3, 5, 7, 4, 3, 12, 12, 1"
-  })
+  @ValueSource(strings = { "0, 1, 2, 3", "5, 4, 3, 2, 1", "8, 3, 5, 7, 4, 3, 12, 12, 1" })
   public void testToString(String inputs) {
     java.util.ArrayDeque<String> reference = new java.util.ArrayDeque<String>();
     Constructor c = Reflection.getConstructor(CircularArrayFixedSizeQueue.class, int.class);
@@ -124,11 +129,12 @@ public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("enqueue() and dequeue() take constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test()
   public void testQueueOperationComplexity() {
     Function<Integer, IFixedSizeQueue<Integer>> provide = (Integer numElements) -> {
       Constructor c = Reflection.getConstructor(CircularArrayFixedSizeQueue.class, int.class);
-      IFixedSizeQueue<Integer> q = Reflection.newInstance(c, numElements*2);
+      IFixedSizeQueue<Integer> q = Reflection.newInstance(c, numElements * 2);
       for (int i = 0; i < numElements; i++) {
         q.enqueue(i);
       }
@@ -141,14 +147,14 @@ public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
     RuntimeInstrumentation.assertAtMost("dequeue", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, dequeue, 8);
   }
 
-
   @Order(complexityTestLevel)
   @DisplayName("peek() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test()
   public void testPeekComplexity() {
     Function<Integer, IFixedSizeQueue<Integer>> provide = (Integer numElements) -> {
       Constructor c = Reflection.getConstructor(CircularArrayFixedSizeQueue.class, int.class);
-      IFixedSizeQueue<Integer> q = Reflection.newInstance(c, numElements*2);
+      IFixedSizeQueue<Integer> q = Reflection.newInstance(c, numElements * 2);
       for (int i = 0; i < numElements; i++) {
         q.enqueue(i);
       }
@@ -158,4 +164,31 @@ public class CircularArrayFixedSizeQueueTests implements FixedSizeQueueTests {
 
     RuntimeInstrumentation.assertAtMost("peek", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, peek, 8);
   }
-}
\ No newline at end of file
+
+  @Order(fixedSizeQueueLevel)
+  @DisplayName("Test iterator matches reference for wraparound values")
+  @ParameterizedTest(name = "Test iterator and wraparound behavior with {1} random values with seed = {0} and fixed array size = {2}")
+  @CsvSource({ "69, 200, 20", "21, 300, 200" })
+  public void testWrapAround(int seed, int numVals, int queueSize) {
+    Random r = new Random(seed);
+    IFixedSizeQueue<Object> me = newFixedSizeQueue(queueSize);
+    Queue<Object> reference = new java.util.ArrayDeque<>();
+    assertEquals(queueSize, me.capacity(), "capacity does not match expected value");
+    for (int i = 0; i < queueSize; i++) {
+      int num = r.nextInt();
+      assertFalse(me.isFull(), "queue should not be full");
+      assertTrue(me.enqueue(num), "enqueue should be successful");
+      reference.add(num);
+
+    }
+    for (int i = 0; i < numVals; i++) {
+      me.enqueue(me.dequeue());
+      reference.add(reference.remove());
+      assertEquals(reference.peek(), me.peek(), "return values of peek()s are not equal");
+      assertEquals(reference.size(), me.size(), "size()s are not equal");
+      assertEquals(queueSize, me.capacity(), "capacity of a fixed size queue should not change");
+      assertIterableEquals(reference, me, "Reference and implemented queues are not equal");
+    }
+  }
+
+}
diff --git a/tests/edu/caltech/cs2/datastructures/CollectionTests.java b/tests/edu/caltech/cs2/datastructures/CollectionTests.java
index b1b39af9ac161e5a8962b7649003bd2ff7fef6fa..bbc3b056679f4dd4a69699e0676d5bb4eaf206da 100644
--- a/tests/edu/caltech/cs2/datastructures/CollectionTests.java
+++ b/tests/edu/caltech/cs2/datastructures/CollectionTests.java
@@ -74,7 +74,7 @@ public interface CollectionTests {
         ICollection<Object> impl = newCollection();
         for (int i = 0; i < 10; i ++) {
             impl.add("a");
-            assertEquals(impl.size(), 1, "collection should have 1 element");
+            assertEquals(1, impl.size(), "collection should have 1 element");
             impl.clear();
             assertTrue(impl.isEmpty());
         }
diff --git a/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java b/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java
index ad7d4ee4507161c0cd533de63e035c82621c0e1d..40961504a967197edf47cd69a78d77dd7861366a 100644
--- a/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java
+++ b/tests/edu/caltech/cs2/datastructures/LinkedDequeTests.java
@@ -1,6 +1,7 @@
 package edu.caltech.cs2.datastructures;
 
 import edu.caltech.cs2.helpers.Inspection;
+import edu.caltech.cs2.helpers.NodeChecker;
 import edu.caltech.cs2.helpers.Reflection;
 import edu.caltech.cs2.helpers.RuntimeInstrumentation;
 import edu.caltech.cs2.interfaces.ICollection;
@@ -15,16 +16,19 @@ import org.junit.jupiter.params.provider.ValueSource;
 
 import java.lang.reflect.Constructor;
 import java.util.*;
+import java.util.ArrayDeque;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
 import static edu.caltech.cs2.project03.Project03TestOrdering.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 @Tag("C")
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
-  private static String LINKED_DEQUE_SOURCE ="src/edu/caltech/cs2/datastructures/LinkedDeque.java";
+  private static String LINKED_DEQUE_SOURCE = "src/edu/caltech/cs2/datastructures/LinkedDeque.java";
 
   private Constructor linkedDequeConstructor = Reflection.getConstructor(LinkedDeque.class);
 
@@ -80,26 +84,26 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
     Reflection.assertNoPublicFields(LinkedDeque.class);
   }
 
+  @Order(classSpecificTestLevel)
+  @DisplayName("There are no protected fields")
+  @Test
+  public void testNoProtectedFields() {
+    Reflection.assertNoProtectedFields(LinkedDeque.class);
+  }
+
+  @Order(classSpecificTestLevel)
+  @DisplayName("All fields in LinkedDeque have modifiers")
+  @Test
+  public void testFieldModifiers() {
+    Reflection.assertFieldModifiers(LinkedDeque.class);
+  }
+
   @Order(classSpecificTestLevel)
   @DisplayName("The public interface is correct")
   @Test
   public void testPublicInterface() {
-    Reflection.assertPublicInterface(LinkedDeque.class, List.of(
-            "addFront",
-            "addBack",
-            "removeFront",
-            "removeBack",
-            "enqueue",
-            "dequeue",
-            "push",
-            "pop",
-            "peek",
-            "peekFront",
-            "peekBack",
-            "iterator",
-            "size",
-            "toString"
-    ));
+    Reflection.assertPublicInterface(LinkedDeque.class, List.of("addFront", "addBack", "removeFront", "removeBack",
+        "enqueue", "dequeue", "push", "pop", "peek", "peekFront", "peekBack", "iterator", "size", "toString"));
   }
 
   @Order(classSpecificTestLevel)
@@ -109,6 +113,18 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
     Inspection.assertConstructorHygiene(LINKED_DEQUE_SOURCE);
   }
 
+  @Order(classSpecificTestLevel)
+  @DisplayName("Check for linked node class")
+  @Test
+  public void testLinkedNode() {
+    Class[] classes = LinkedDeque.class.getDeclaredClasses();
+    for (Class clazz : classes) {
+      if (Iterator.class.isAssignableFrom(clazz)) {
+        continue;
+      }
+      NodeChecker.isNode(clazz, true);
+    }
+  }
 
   // TOSTRING TESTS ---------------------------------------------------
 
@@ -122,9 +138,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
   @Order(toStringTestLevel)
   @DisplayName("toString() matches java.util.ArrayDeque")
   @ParameterizedTest(name = "Test toString() on [{arguments}]")
-  @ValueSource(strings = {
-          "0, 1, 2, 3", "5, 4, 3, 2, 1", "8, 3, 5, 7, 4, 3, 12, 12, 1"
-  })
+  @ValueSource(strings = { "0, 1, 2, 3", "5, 4, 3, 2, 1", "8, 3, 5, 7, 4, 3, 12, 12, 1" })
   public void testToString(String inputs) {
     java.util.ArrayDeque<String> reference = new java.util.ArrayDeque<String>();
     LinkedDeque<String> me = new LinkedDeque<>();
@@ -139,6 +153,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("addFront() and removeFront() take constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testFrontDequeOperationComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -151,12 +166,15 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
     Consumer<IDeque<Integer>> addFront = (IDeque<Integer> q) -> q.addFront(0);
     Consumer<IDeque<Integer>> removeFront = (IDeque<Integer> q) -> q.removeFront();
 
-    RuntimeInstrumentation.assertAtMost("addFront", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, addFront, 8);
-    RuntimeInstrumentation.assertAtMost("removeFront", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, removeFront, 8);
+    RuntimeInstrumentation.assertAtMost("addFront", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, addFront,
+        8);
+    RuntimeInstrumentation.assertAtMost("removeFront", RuntimeInstrumentation.ComplexityType.CONSTANT, provide,
+        removeFront, 8);
   }
 
   @Order(complexityTestLevel)
   @DisplayName("addBack() and removeBack() take constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testBackDequeOperationComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -170,11 +188,13 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
     Consumer<IDeque<Integer>> removeBack = (IDeque<Integer> q) -> q.removeBack();
 
     RuntimeInstrumentation.assertAtMost("addBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, addBack, 8);
-    RuntimeInstrumentation.assertAtMost("removeBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, removeBack, 8);
+    RuntimeInstrumentation.assertAtMost("removeBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide,
+        removeBack, 8);
   }
 
   @Order(complexityTestLevel)
   @DisplayName("enqueue() and dequeue() take constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testQueueOperationComplexity() {
     Function<Integer, IQueue<Integer>> provide = (Integer numElements) -> {
@@ -193,6 +213,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("push() and pop() take constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testStackOperationComplexity() {
     Function<Integer, IStack<Integer>> provide = (Integer numElements) -> {
@@ -211,6 +232,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("peek() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testPeekComplexity() {
     Function<Integer, IStack<Integer>> provide = (Integer numElements) -> {
@@ -227,6 +249,7 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
 
   @Order(complexityTestLevel)
   @DisplayName("peekFront() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testPeekFrontComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -238,11 +261,13 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
     };
     Consumer<IDeque<Integer>> peekFront = (IDeque<Integer> q) -> q.peekFront();
 
-    RuntimeInstrumentation.assertAtMost("peekFront", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, peekFront, 8);
+    RuntimeInstrumentation.assertAtMost("peekFront", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, peekFront,
+        8);
   }
 
   @Order(complexityTestLevel)
   @DisplayName("peekBack() takes constant time")
+  @Timeout(value = 10, unit = SECONDS)
   @Test
   public void testPeekBackComplexity() {
     Function<Integer, IDeque<Integer>> provide = (Integer numElements) -> {
@@ -254,7 +279,78 @@ public class LinkedDequeTests implements DequeTests, StackTests, QueueTests {
     };
     Consumer<IDeque<Integer>> peekBack = (IDeque<Integer> q) -> q.peekBack();
 
-    RuntimeInstrumentation.assertAtMost("peekBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, peekBack, 8);
+    RuntimeInstrumentation.assertAtMost("peekBack", RuntimeInstrumentation.ComplexityType.CONSTANT, provide, peekBack,
+        8);
+  }
+
+  @Order(dequeTestLevel)
+  @DisplayName("Cycle detection for addFront(...), addBack(...), removeFront(...), and removeBack(...)")
+  @ParameterizedTest(name = "Test cycles - {1} random numbers with seed = {0}")
+  @CsvSource({ "69, 2000", "20, 3000" })
+  public void checkForCycles(int seed, int size) {
+    Random r = new Random(seed);
+    Deque<Object> reference = new ArrayDeque<>();
+    IDeque<Object> impl = new LinkedDeque<>();
+    // Test that first peek is null
+    assertNull(impl.peekFront(), "empty peek should return null");
+    // Test adding values updates size and displays contained correctly
+    for (int i = 0; i < size; i++) {
+      int num = r.nextInt();
+      if (num % 2 == 0) {
+        reference.addLast(num);
+        impl.addBack(num);
+      } else {
+        reference.addFirst(num);
+        impl.addFront(num);
+      }
+      if (reference.size() > 1 && impl.size() > 1) {
+        if (num % 5 == 0) {
+          reference.removeFirst();
+          impl.removeFront();
+        } else if (num % 7 == 0) {
+          reference.removeLast();
+          impl.removeBack();
+        }
+      }
+      NodeChecker.cycleDetection(impl, true);
+      assertEquals(reference.size(), impl.size(), "size()s are not equal");
+      assertEquals(reference.toString(), impl.toString(), "toStrings()s are not equal");
+    }
+  }
+
+  @Order(dequeTestLevel)
+  @DisplayName("Check reverses for addFront(...), addBack(...), removeFront(...), and removeBack(...)")
+  @ParameterizedTest(name = "Test reverse - {1} random numbers with seed = {0}")
+  @CsvSource({ "31, 2000", "64, 3000" })
+  public void checkReverses(int seed, int size) {
+    Random r = new Random(seed);
+    Deque<Object> reference = new ArrayDeque<>();
+    IDeque<Object> impl = new LinkedDeque<>();
+    // Test that first peek is null
+    assertNull(impl.peekFront(), "empty peek should return null");
+    // Test adding values updates size and displays contained correctly
+    for (int i = 0; i < size; i++) {
+      int num = r.nextInt();
+      if (num % 2 == 0) {
+        reference.addLast(num);
+        impl.addBack(num);
+      } else {
+        reference.addFirst(num);
+        impl.addFront(num);
+      }
+      if (reference.size() > 1 && impl.size() > 1) {
+        if (num % 5 == 0) {
+          reference.removeFirst();
+          impl.removeFront();
+        } else if (num % 7 == 0) {
+          reference.removeLast();
+          impl.removeBack();
+        }
+      }
+      NodeChecker.checkReverse(impl);
+      assertEquals(reference.size(), impl.size(), "size()s are not equal");
+      assertEquals(reference.toString(), impl.toString(), "toStrings()s are not equal");
+    }
   }
 
 }
\ No newline at end of file
diff --git a/tests/edu/caltech/cs2/helpers/NodeChecker.java b/tests/edu/caltech/cs2/helpers/NodeChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..75e3ef4cd3abbe9acc557215d41700eaddae73f8
--- /dev/null
+++ b/tests/edu/caltech/cs2/helpers/NodeChecker.java
@@ -0,0 +1,318 @@
+package edu.caltech.cs2.helpers;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.hamcrest.collection.IsIterableContainingInOrder;
+
+import edu.caltech.cs2.interfaces.IDeque;
+
+/**
+ * @author Archie Shahidullah <archie@caltech.edu>
+ */
+public class NodeChecker {
+
+    /**
+     * This method checks whether a given class is a linked node or not.
+     *
+     * @param clazz        the class you want to check
+     * @param doublyLinked whether or not the list <em>can</em> be doubly linked
+     */
+    public static void isNode(Class clazz, boolean doublyLinked) {
+        // Check if class is private
+        if (!Modifier.isPrivate(clazz.getModifiers())) {
+            fail("Class " + clazz.getTypeName() + " is not private");
+        }
+
+        // Check if class is static
+        if (!Modifier.isStatic(clazz.getModifiers())) {
+            fail("Class " + clazz.getTypeName() + " is not static");
+        }
+
+        // Get fields
+        SortedSet<String> fields = new TreeSet<>(
+                Stream.of(clazz.getDeclaredFields()).map(x -> x.getName()).collect(Collectors.toList()));
+
+        boolean hasData = false;
+        boolean hasNode = false;
+
+        // Check fields
+        for (String field : fields) {
+            Field f = null;
+            try {
+                f = clazz.getDeclaredField(field);
+                f.setAccessible(true);
+            } catch (NoSuchFieldException ex) {
+                ex.printStackTrace();
+                fail();
+            }
+
+            if (f.getType().toString().equals("class " + clazz.getTypeName())) {
+                if (hasNode && !doublyLinked) {
+                    // Returns false is the list is doubly linked
+                    fail("Class " + clazz.getName() + " is a doubly linked node");
+                    return;
+                }
+                // Linked to another node
+                hasNode = true;
+            } else if (f.getType().toString().equals("class java.lang.Object")) {
+                if (!Modifier.isFinal(f.getModifiers())) {
+                    fail("Field \"" + field + "\" in class " + clazz.getName() + " is not final");
+                }
+                // Has a generic type to store data
+                if (hasData) {
+                    // Checks for multiple data fields
+                    fail("Class " + clazz.getName() + " has multiple generic fields: \"" + field + "\"");
+                    return;
+                }
+                hasData = true;
+            } else {
+                fail("Field \"" + field + "\" is not a generic type in " + clazz.getTypeName());
+            }
+        }
+
+        // Get constructors
+        Constructor[] constructors = clazz.getConstructors();
+
+        // Checks arguments to the constructors
+        for (Constructor c : constructors) {
+            boolean hasConstructor = false;
+            for (Class type : c.getParameterTypes()) {
+                if (type.toString().equals("class java.lang.Object")) {
+                    if (hasConstructor) {
+                        // Checks for multiple arguments
+                        fail("Constructor \"" + c.getName() + "\" has multiple generic arguments");
+                        return;
+                    }
+                    hasConstructor = true;
+                } else if (!type.toString().equals("class " + clazz.getTypeName())) {
+                    // Check for invalid argument types
+                    fail("Constructor \"" + c.getName() + "\" has an argument that is not a " + "generic type in class "
+                            + clazz.getTypeName());
+                }
+            }
+        }
+    }
+
+    /**
+     * This method performs a node check on every internal class.
+     *
+     * @param clazz        the class you want to check
+     * @param doublyLinked whether or not the list <em>can</em> be doubly linked
+     */
+    public static void checkInternalClasses(Class clazz, boolean doublyLinked) {
+        Class[] classes = clazz.getDeclaredClasses();
+        boolean node = false;
+        for (Class c : classes) {
+            String className = c.toString().replaceFirst("class ", "");
+            try {
+                isNode(Class.forName(className), doublyLinked);
+            } catch (ClassNotFoundException ex) {
+                ex.printStackTrace();
+                fail();
+            } catch (AssertionError e) {
+                continue;
+            }
+            node = true;
+        }
+        if (!node) {
+            fail("There are no valid node classes in " + clazz.getName());
+        }
+    }
+
+    /**
+     * This method gets a valid, internal node class from a given class.
+     *
+     * @param clazz        the class you want to check
+     * @param doublyLinked whether or not the list <em>can</em> be doubly linked
+     * @return the node class
+     */
+    public static Class getNodeClass(Class clazz, boolean doublyLinked) {
+        Class[] classes = clazz.getDeclaredClasses();
+        for (Class c : classes) {
+            try {
+                isNode(c, doublyLinked);
+            } catch (AssertionError e) {
+                // Is not a node class so continue searching
+                continue;
+            }
+            return c;
+        }
+        fail("There are no valid node classes in " + clazz.getName());
+        // Should never reach here
+        return null;
+    }
+
+    /**
+     * This method gets fields of specified type from a given class.
+     *
+     * @param clazz the class you want to check
+     * @param type  the type of field you want
+     * @return a list of fields matching the given type
+     */
+    public static List<Field> getFields(Class clazz, Class type) {
+        Field[] fields = clazz.getDeclaredFields();
+        List<Field> namedFields = new ArrayList<>();
+        for (Field f : fields) {
+            f.setAccessible(true);
+            if (f.getType().toString().equals("class " + type.getTypeName())) {
+                namedFields.add(f);
+            }
+        }
+        return namedFields;
+    }
+
+    /**
+     * This method checks whether a given pointer permutation in a deque contains a
+     * cycle.
+     *
+     * @param deque      the deque you want to check
+     * @param nextField  the field corresponding to the next pointer in a linked
+     *                   node
+     * @param dequeField the field corresponding to the head pointer in a linked
+     *                   deque
+     * @param <E>        the generic type of the data field in a linked node
+     * @return an array containing the indices of the cyclic nodes
+     */
+    public static <E> int[] checkCycle(IDeque<E> deque, Field nextField, Field dequeField) {
+        // Grab head of list
+        Object head = null;
+        try {
+            head = dequeField.get(deque);
+        } catch (IllegalAccessException ex) {
+            ex.printStackTrace();
+            fail();
+        }
+        // Create array to store all nodes
+        Object[] nodes = new Object[deque.size() + 1];
+        // Iterate through list
+        Object temp = head;
+        int i = 0;
+        while (temp != null) {
+            nodes[i] = temp;
+            for (int j = 0; j < i; j++) {
+                // Check if memory locations are equal
+                if (nodes[j] == nodes[i]) {
+                    // Return indices of nodes that create a cycle
+                    return new int[] { i, j };
+                }
+            }
+            try {
+                // Next node
+                temp = nextField.get(temp);
+            } catch (IllegalAccessException ex) {
+                ex.printStackTrace();
+                fail();
+            }
+            i++;
+        }
+        // No cycle
+        return new int[] { -1, -1 };
+    }
+
+    /**
+     * This method checks whether a given deque contains a cycle.
+     *
+     * @param deque        the deque you want to check
+     * @param doublyLinked whether or not the list <em>can</em> be doubly linked
+     * @param <E>          the generic type of the data field in a linked node
+     */
+    public static <E> void cycleDetection(IDeque<E> deque, boolean doublyLinked) {
+        Class nodeClass = getNodeClass(deque.getClass(), doublyLinked);
+        // Can be either next or previous pointer
+        List<Field> nextFields = getFields(nodeClass, nodeClass);
+        // Can be either head or tail pointer
+        List<Field> dequeFields = getFields(deque.getClass(), nodeClass);
+        // Check all permutations of pointers
+        int[] nodes;
+        for (Field nextField : nextFields) {
+            for (Field dequeField : dequeFields) {
+                // Check for a cycle
+                nodes = checkCycle(deque, nextField, dequeField);
+                if (nodes[0] == -1 && nodes[1] == -1) {
+                    // No cycle
+                    continue;
+                }
+                if (nodes[0] == deque.size() && nodes[1] == 0) {
+                    fail("The last node is connected to the first node in " + nodeClass.getName() + " object");
+                } else {
+                    fail("Node " + nodes[0] + " is connected to Node " + nodes[1] + " in " + nodeClass.getName()
+                            + " object");
+                }
+            }
+        }
+    }
+
+    /**
+     * This method checks whether iterating through a list forwards and backwards
+     * returns the same values.
+     *
+     * @param deque the deque you want to check
+     * @param <E>   the generic type of the data field in a linked node
+     */
+    public static <E> void checkReverse(IDeque<E> deque) {
+        // Grab the linked node class and possible pointers to the head and tail
+        Class nodeClass = getNodeClass(deque.getClass(), true);
+        List<Field> dequePointers = getFields(deque.getClass(), nodeClass);
+        assertEquals(2, dequePointers.size(), "List does not have one head and tail pointer");
+        // Try all permutations of pointers
+        try {
+            for (int i = 0; i < 2; i++) {
+                // Get trial head and tail pointers
+                Field headField = dequePointers.get(i);
+                Field tailField = dequePointers.get((i + 1) % 2);
+                Object head = headField.get(deque);
+                Object tail = tailField.get(deque);
+                // If deque size is one, tests will fail so check alternative
+                if (deque.size() == 1) {
+                    assertEquals(head, tail, "Deque of size 1 does not have same head and tail");
+                    return;
+                }
+                // Grab possible next and previous pointers
+                List<Field> pointers = getFields(head.getClass(), nodeClass);
+                assertEquals(2, pointers.size(), "List is not doubly linked");
+                for (int j = 0; j < 2; j++) {
+                    // Get trial next and previous pointers
+                    Field next = pointers.get(j);
+                    Field prev = pointers.get((j + 1) % 2);
+                    // Get data field
+                    List<Field> dataFields = getFields(nodeClass, Object.class);
+                    assertEquals(1, dataFields.size(), "Incorrect number of generic types in node class");
+                    Field data = dataFields.get(0);
+                    // Iterate through linked list and construct value lists
+                    List<E> forwardValues = new ArrayList<>();
+                    List<E> backwardValues = new ArrayList<>();
+                    Object temp = head;
+                    while (temp != null) {
+                        forwardValues.add((E) data.get(temp));
+                        temp = next.get(temp);
+                    }
+                    temp = tail;
+                    while (temp != null) {
+                        backwardValues.add((E) data.get(temp));
+                        temp = prev.get(temp);
+                    }
+                    Collections.reverse(backwardValues);
+                    // Test the reverse of the backwards equals the forwards
+                    if (IsIterableContainingInOrder.contains(forwardValues.toArray()).matches(backwardValues)) {
+                        return;
+                    }
+                }
+            }
+        } catch (IllegalAccessException ex) {
+            ex.printStackTrace();
+            fail();
+        }
+        // Exiting the loop indicates failure
+        fail("Forwards and backwards lists of values do not agree");
+    }
+
+}
diff --git a/tests/edu/caltech/cs2/helpers/Reflection.java b/tests/edu/caltech/cs2/helpers/Reflection.java
index 8f776cefde5b336c6e99d5727f2ea01fa4394f6b..1f4b95089489a98defaad8131d895ee83095d7c8 100644
--- a/tests/edu/caltech/cs2/helpers/Reflection.java
+++ b/tests/edu/caltech/cs2/helpers/Reflection.java
@@ -5,6 +5,7 @@ import java.util.*;
 import java.util.function.*;
 import java.util.stream.*;
 
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
 public class Reflection {
@@ -40,7 +41,9 @@ public class Reflection {
       c.setAccessible(true);
     } catch (NoSuchMethodException e) {
       e.printStackTrace();
-      fail("Could not find constructor " + clazz.getName() + "(" + String.join(", ", (String[])Stream.of(params).map(x -> x.getName()).collect(Collectors.toList()).toArray()) + ")" + " in class " + clazz.getName());
+      fail("Could not find constructor " + clazz.getName() + "("
+          + String.join(", ", (String[]) Stream.of(params).map(x -> x.getName()).collect(Collectors.toList()).toArray())
+          + ")" + " in class " + clazz.getName());
       return null;
     }
     return c;
@@ -56,7 +59,6 @@ public class Reflection {
     return result;
   }
 
-
   public static <T> T invokeStatic(Method m, Object... args) {
     T result = null;
     try {
@@ -83,12 +85,18 @@ public class Reflection {
 
   private static int stringToIntModifier(String modifier) {
     switch (modifier.toLowerCase()) {
-      case "private": return Modifier.PRIVATE;
-      case "public": return Modifier.PUBLIC;
-      case "protected": return Modifier.PROTECTED;
-      case "static": return Modifier.STATIC;
-      case "final": return Modifier.FINAL;
-      default: fail("Unknown modifier test.");
+      case "private":
+        return Modifier.PRIVATE;
+      case "public":
+        return Modifier.PUBLIC;
+      case "protected":
+        return Modifier.PROTECTED;
+      case "static":
+        return Modifier.STATIC;
+      case "final":
+        return Modifier.FINAL;
+      default:
+        fail("Unknown modifier test.");
     }
     /* Should never reach here... */
     return -1;
@@ -111,17 +119,21 @@ public class Reflection {
   }
 
   public static void assertFieldsLessThan(Class clazz, Class FieldType, int x) {
-    assertFieldsLessThan(clazz, null, FieldType, x );
+    assertFieldsLessThan(clazz, null, FieldType, x);
   }
+
   public static void assertFieldsLessThan(Class clazz, String modifier, int x) {
     assertFieldsLessThan(clazz, modifier, null, x);
   }
+
   public static void assertFieldsLessThan(Class clazz, Stream<Field> fields, int x) {
-    assertFieldsLessThan(clazz, fields, null, null, x );
+    assertFieldsLessThan(clazz, fields, null, null, x);
   }
+
   public static void assertFieldsLessThan(Class clazz, String modifier, Class FieldType, int x) {
     assertFieldsLessThan(clazz, getFields(clazz), modifier, FieldType, x);
   }
+
   public static void assertFieldsLessThan(Class clazz, Stream<Field> fields, String modifier, Class FieldType, int x) {
     if (modifier != null) {
       fields = fields.filter(hasModifier(modifier)).filter(doesNotHaveModifier("static"));
@@ -131,27 +143,29 @@ public class Reflection {
     }
 
     if (fields.count() >= x) {
-      fail(clazz.getName() + " has too many fields" +
-              (modifier != null ? " with modifier " + modifier : "") + "" +
-              (FieldType != null ? " of type " + FieldType.getName() : "")
-      );
+      fail(clazz.getName() + " has too many fields" + (modifier != null ? " with modifier " + modifier : "") + ""
+          + (FieldType != null ? " of type " + FieldType.getName() : ""));
     }
   }
 
-
   public static void assertFieldsGreaterThan(Class clazz, Class FieldType, int x) {
-    assertFieldsGreaterThan(clazz, null, FieldType, x );
+    assertFieldsGreaterThan(clazz, null, FieldType, x);
   }
+
   public static void assertFieldsGreaterThan(Class clazz, String modifier, int x) {
     assertFieldsGreaterThan(clazz, modifier, null, x);
   }
+
   public static void assertFieldsGreaterThan(Class clazz, Stream<Field> fields, int x) {
-    assertFieldsGreaterThan(clazz, fields, null, null, x );
+    assertFieldsGreaterThan(clazz, fields, null, null, x);
   }
+
   public static void assertFieldsGreaterThan(Class clazz, String modifier, Class FieldType, int x) {
     assertFieldsGreaterThan(clazz, getFields(clazz), modifier, FieldType, x);
   }
-  public static void assertFieldsGreaterThan(Class clazz, Stream<Field> fields, String modifier, Class FieldType, int x) {
+
+  public static void assertFieldsGreaterThan(Class clazz, Stream<Field> fields, String modifier, Class FieldType,
+      int x) {
     if (modifier != null) {
       fields = fields.filter(hasModifier(modifier));
     }
@@ -160,26 +174,27 @@ public class Reflection {
     }
 
     if (fields.count() <= x) {
-      fail(clazz.getName() + " has too few fields" +
-              (modifier != null ? " with modifier " + modifier : "") + " " +
-              (FieldType != null ? " of type " + FieldType.getName() : "")
-      );
+      fail(clazz.getName() + " has too few fields" + (modifier != null ? " with modifier " + modifier : "") + " "
+          + (FieldType != null ? " of type " + FieldType.getName() : ""));
     }
   }
 
-
   public static void assertFieldsEqualTo(Class clazz, Class FieldType, int x) {
-    assertFieldsEqualTo(clazz, null, FieldType, x );
+    assertFieldsEqualTo(clazz, null, FieldType, x);
   }
+
   public static void assertFieldsEqualTo(Class clazz, String modifier, int x) {
-    assertFieldsEqualTo(clazz, modifier, null, x );
+    assertFieldsEqualTo(clazz, modifier, null, x);
   }
+
   public static void assertFieldsEqualTo(Class clazz, Stream<Field> fields, int x) {
-    assertFieldsEqualTo(clazz, fields, null, null, x );
+    assertFieldsEqualTo(clazz, fields, null, null, x);
   }
+
   public static void assertFieldsEqualTo(Class clazz, String modifier, Class FieldType, int x) {
     assertFieldsEqualTo(clazz, getFields(clazz), modifier, FieldType, x);
   }
+
   public static void assertFieldsEqualTo(Class clazz, Stream<Field> fields, String modifier, Class FieldType, int x) {
     if (modifier != null) {
       fields = fields.filter(hasModifier(modifier));
@@ -189,16 +204,26 @@ public class Reflection {
     }
 
     if (fields.count() != x) {
-      fail(clazz.getName() + " has the wrong number of fields" +
-              (modifier != null ? " with modifier " + modifier : "") + " " +
-              (FieldType != null ? " of type " + FieldType.getName() : "")
-      );
+      fail(clazz.getName() + " has the wrong number of fields" + (modifier != null ? " with modifier " + modifier : "")
+          + " " + (FieldType != null ? " of type " + FieldType.getName() : ""));
     }
   }
 
   public static void assertNoPublicFields(Class clazz) {
-    assertFieldsEqualTo(clazz, getFields(clazz).filter(doesNotHaveModifier("static")),
-            "public", null, 0);
+    assertFieldsEqualTo(clazz, getFields(clazz).filter(doesNotHaveModifier("static")), "public", null, 0);
+  }
+
+  public static void assertNoProtectedFields(Class clazz) {
+    assertFieldsEqualTo(clazz, getFields(clazz).filter(doesNotHaveModifier("static")), "protected", null, 0);
+  }
+
+  public static void assertFieldModifiers(Class clazz) {
+    List<Field> fields = getFields(clazz).collect(Collectors.toList());
+    for (Field f : fields) {
+      int m = f.getModifiers();
+      assertTrue(Modifier.isPrivate(m) || Modifier.isProtected(m) || Modifier.isPublic(m),
+          "Field \"" + f.getName() + "\" does not have one of {public, private, protected}");
+    }
   }
 
   public static Field getFieldByName(Class clazz, String name) {
@@ -215,20 +240,13 @@ public class Reflection {
     Stream<Field> fields = getFields(clazz).filter(hasType(FieldType)).filter(doesNotHaveModifier("static"));
     List<Field> fieldsList = fields.collect(Collectors.toList());
     if (fieldsList.isEmpty()) {
-      fail(clazz.getName() +
-              " should have a field with the type '" + FieldType.getName() +
-              "', but does not."
-      );
+      fail(clazz.getName() + " should have a field with the type '" + FieldType.getName() + "', but does not.");
       // Should not reach here!
       return null;
     }
 
     if (fieldsList.size() > 1) {
-      fail(clazz.getName() +
-              " should only have one field with the type '" +
-              FieldType.getName() +
-              "', but has more."
-      );
+      fail(clazz.getName() + " should only have one field with the type '" + FieldType.getName() + "', but has more.");
       // Should not reach here
       return null;
     }
@@ -240,20 +258,13 @@ public class Reflection {
     Stream<Field> fields = getFields(clazz).filter(hasType(FieldType));
     List<Field> fieldsList = fields.collect(Collectors.toList());
     if (fieldsList.isEmpty()) {
-      fail(clazz.getName() +
-              " should have a field with the type '" + FieldType.getName() +
-              "', but does not."
-      );
+      fail(clazz.getName() + " should have a field with the type '" + FieldType.getName() + "', but does not.");
       // Should not reach here!
       return null;
     }
 
     if (fieldsList.size() > 1) {
-      fail(clazz.getName() +
-              " should only have one field with the type '" +
-              FieldType.getName() +
-              "', but has more."
-      );
+      fail(clazz.getName() + " should only have one field with the type '" + FieldType.getName() + "', but has more.");
       // Should not reach here
       return null;
     }
@@ -272,21 +283,15 @@ public class Reflection {
     }
     List<Field> fieldsList = fields.collect(Collectors.toList());
     if (fieldsList.isEmpty()) {
-      fail(clazz.getName() +
-              " should have a field with the modifiers '" +
-              String.join(", ", modifiers) +
-              "', but does not."
-      );
+      fail(clazz.getName() + " should have a field with the modifiers '" + String.join(", ", modifiers)
+          + "', but does not.");
       // Should not reach here!
       return null;
     }
 
     if (fieldsList.size() > 1) {
-      fail(clazz.getName() +
-              " should only have one field with the modifiers '" +
-              String.join(", ", modifiers) +
-              "', but has more."
-      );
+      fail(clazz.getName() + " should only have one field with the modifiers '" + String.join(", ", modifiers)
+          + "', but has more.");
       // Should not reach here
       return null;
     }
@@ -297,6 +302,7 @@ public class Reflection {
   public static void checkFieldModifiers(Field f, String modifier) {
     checkFieldModifiers(f, List.of(modifier));
   }
+
   public static void checkFieldModifiers(Field f, List<String> modifiers) {
     if (!modifiers.stream().allMatch(m -> hasModifier(m).test(f))) {
       fail(f.getName() + " is missing at least one of the modifiers: " + String.join(", ", modifiers));
@@ -305,10 +311,8 @@ public class Reflection {
 
   public static void assertPublicInterface(Class clazz, List<String> methods) {
     SortedSet<String> expected = new TreeSet<>(methods);
-    SortedSet<String> actual = new TreeSet<>(Stream.of(clazz.getDeclaredMethods())
-            .filter(hasModifier("public"))
-            .map(x -> x.getName())
-            .collect(Collectors.toList()));
+    SortedSet<String> actual = new TreeSet<>(Stream.of(clazz.getDeclaredMethods()).filter(hasModifier("public"))
+        .map(x -> x.getName()).collect(Collectors.toList()));
     if (!expected.equals(actual)) {
       String diff = "expected: " + expected + "\nactual:  " + actual;
       fail("The public interface of " + clazz.getName() + " has incorrect functionality.\n" + diff);
@@ -322,4 +326,5 @@ public class Reflection {
       fail("You should be overriding the " + method + "method, but your signature wasn't correct.");
     }
   }
+  
 }
diff --git a/tests/edu/caltech/cs2/project03/GuitarStringTests.java b/tests/edu/caltech/cs2/project03/GuitarStringTests.java
index 0586d8e051e6be53961893c6fce6a6ff1bbb127c..81fabe06152bac315ec51b37b2778c18d5464f64 100644
--- a/tests/edu/caltech/cs2/project03/GuitarStringTests.java
+++ b/tests/edu/caltech/cs2/project03/GuitarStringTests.java
@@ -35,7 +35,8 @@ public class GuitarStringTests {
   }
 
   public static IFixedSizeQueue<Double> getQueueFromString(CircularArrayFixedSizeQueueGuitarString string) {
-    String queueName = Reflection.getFieldByType(CircularArrayFixedSizeQueueGuitarString.class, IFixedSizeQueue.class).getName();
+    String queueName = Reflection.getFieldByType(CircularArrayFixedSizeQueueGuitarString.class, IFixedSizeQueue.class)
+        .getName();
     return Reflection.getFieldValue(CircularArrayFixedSizeQueueGuitarString.class, queueName, string);
   }
 
@@ -63,7 +64,8 @@ public class GuitarStringTests {
     Stream<Field> fields = Reflection.getFields(CircularArrayFixedSizeQueueGuitarString.class);
     fields.filter(Reflection.hasModifier("static")).forEach((field) -> {
       Reflection.checkFieldModifiers(field, List.of("private", "static"));
-      assertTrue(Reflection.hasModifier("final").test(field) || field.getType().equals(Random.class), "non-final static class must be a random value generator");
+      assertTrue(Reflection.hasModifier("final").test(field) || field.getType().equals(Random.class),
+          "non-final static class must be a random value generator");
     });
   }
 
@@ -81,28 +83,32 @@ public class GuitarStringTests {
     Reflection.assertNoPublicFields(CircularArrayFixedSizeQueueGuitarString.class);
   }
 
+  @Order(classSpecificTestLevel)
+  @DisplayName("There are no protected fields")
+  @Test
+  public void testNoProtectedFields() {
+    Reflection.assertNoProtectedFields(CircularArrayFixedSizeQueueGuitarString.class);
+  }
+
+  @Order(classSpecificTestLevel)
+  @DisplayName("All fields in CircularArrayFixedSizeQueueGuitarString have modifiers")
+  @Test
+  public void testFieldModifiers() {
+    Reflection.assertFieldModifiers(CircularArrayFixedSizeQueueGuitarString.class);
+  }
+
   @Order(classSpecificTestLevel)
   @DisplayName("The public interface is correct")
   @Test
   public void testPublicInterface() {
-    Reflection.assertPublicInterface(CircularArrayFixedSizeQueueGuitarString.class, List.of(
-            "length",
-            "pluck",
-            "tic",
-            "sample"
-    ));
+    Reflection.assertPublicInterface(CircularArrayFixedSizeQueueGuitarString.class,
+        List.of("length", "pluck", "tic", "sample"));
   }
 
   @Order(classSpecificTestLevel)
   @DisplayName("The constructor correctly sets up the queue")
   @ParameterizedTest(name = "Test constructor with CircularArrayFixedSizeQueue and a frequency of {0} Hz; expected queue size is {1}")
-  @CsvSource({
-          "110, 401",
-          "340, 130",
-          "512, 87",
-          "600.5, 74",
-          "880, 51"
-  })
+  @CsvSource({ "110, 401", "340, 130", "512, 87", "600.5, 74", "880, 51" })
   public void testConstructor(double frequency, int expectedSize) {
     CircularArrayFixedSizeQueueGuitarString string = constructGuitarString(frequency);
     IFixedSizeQueue<Double> queue = getQueueFromString(string);
@@ -116,41 +122,32 @@ public class GuitarStringTests {
   @Order(guitarStringTestLevel)
   @DisplayName("The pluck() method randomizes the values in the queue")
   @ParameterizedTest(name = "Test pluck() with CircularArrayFixedSizeQueue and a frequency of {0} Hz")
-  @CsvSource({
-          "100",
-          "50",
-          "10",
-          "8",
-          "5"
-  })
+  @CsvSource({ "100", "50", "10", "8", "5" })
   public void testPluck(double frequency) {
     final double DELTA = 0.05;
     // Set up class and retrieve queue
     CircularArrayFixedSizeQueueGuitarString string = constructGuitarString(frequency);
     IFixedSizeQueue<Double> queue = getQueueFromString(string);
     // Checks all values are initially 0
-    for(double val : queue){
+    for (double val : queue) {
       assertEquals(0, val, "initial values must be 0");
     }
     string.pluck();
+    queue = getQueueFromString(string);
     double sum = 0;
     double absSum = 0;
-    for(double val : queue){
+    for (double val : queue) {
       sum += val;
       absSum += abs(val);
     }
-    assertEquals(0, sum/queue.size(), DELTA, "average value of uniform distribution should be near 0");
-    assertEquals(0.25, absSum/queue.size(), DELTA, "average magnitude of uniform distribution should be near 0.25");
+    assertEquals(0, sum / queue.size(), DELTA, "average value of uniform distribution should be near 0");
+    assertEquals(0.25, absSum / queue.size(), DELTA, "average magnitude of uniform distribution should be near 0.25");
   }
 
   @Order(guitarStringTestLevel)
   @DisplayName("The tic() method correctly applies the Karplus-Strong algorithm")
   @ParameterizedTest(name = "Test tic() with CircularArrayFixedSizeQueue and a frequency of {0} Hz; data file {1}.txt")
-  @CsvSource({
-          "10000, ticStates1",
-          "8000, ticStates2",
-          "5000, ticStates3"
-  })
+  @CsvSource({ "10000, ticStates1", "8000, ticStates2", "5000, ticStates3" })
   public void testTic(double frequency, String filename) {
     // Set up scanner
     String filepath = "tests/data/" + filename + ".txt";
@@ -164,19 +161,21 @@ public class GuitarStringTests {
     CircularArrayFixedSizeQueueGuitarString string = constructGuitarString(frequency);
     IFixedSizeQueue<Double> queue = getQueueFromString(string);
     // Reinitialize queue with new data
-    for(int i = 0; i < queue.size(); i++){
+    for (int i = 0; i < queue.size(); i++) {
       queue.dequeue();
       queue.enqueue(in.nextDouble());
     }
     int initSize = queue.size();
     // Pass through the same number of tics as elements in the array
-    for(int i = 0; i < initSize; i++){
+    for (int i = 0; i < initSize; i++) {
       string.tic();
+      queue = getQueueFromString(string);
       assertEquals(initSize, queue.size(), "queue size must remain the same");
     }
     // Compare peek() values with the expected values in the files
     while (in.hasNext()) {
       string.tic();
+      queue = getQueueFromString(string);
       assertEquals(initSize, queue.size(), "queue size must remain the same");
       assertEquals(in.nextDouble(), queue.peek(), "next expected value not at front of queue");
     }
@@ -185,13 +184,7 @@ public class GuitarStringTests {
   @Order(guitarStringTestLevel)
   @DisplayName("The length() method correctly gives the length of the queue")
   @ParameterizedTest(name = "Test length() with CircularArrayFixedSizeQueue and a frequency of {0} Hz; expected length = {1}; iterations = {2}")
-  @CsvSource({
-          "110, 401, 1000",
-          "340, 130, 500",
-          "512, 87, 200",
-          "600.5, 74, 150",
-          "880, 51, 100"
-  })
+  @CsvSource({ "110, 401, 1000", "340, 130, 500", "512, 87, 200", "600.5, 74, 150", "880, 51, 100" })
   public void testLength(double frequency, int expectedLength, int iterations) {
     // Set up class and retrieve queue
     CircularArrayFixedSizeQueueGuitarString string = constructGuitarString(frequency);
@@ -202,12 +195,15 @@ public class GuitarStringTests {
     assertEquals(expectedLength, string.length(), "Length should be same as expected");
     assertEquals(queue.size(), string.length(), "Length should be same as queue size");
     string.pluck();
+    queue = getQueueFromString(string);
     assertEquals(initSize, string.length(), "Length should not have changed from beginning");
     assertEquals(queue.size(), string.length(), "Length should be same as queue size");
 
-    // Run through many iterations, making sure both the queue size and length are constant
+    // Run through many iterations, making sure both the queue size and length are
+    // constant
     for (int i = 0; i < iterations; i++) {
       string.tic();
+      queue = getQueueFromString(string);
       assertEquals(initSize, string.length(), "Length should not have changed from beginning");
       assertEquals(queue.size(), string.length(), "Length should be same as queue size");
     }
@@ -217,13 +213,7 @@ public class GuitarStringTests {
   @Order(guitarStringTestLevel)
   @DisplayName("The sample() method gives the same values as peek()ing the queue")
   @ParameterizedTest(name = "Test sample() with CircularArrayFixedSizeQueue and a frequency of {0} Hz")
-  @CsvSource({
-          "110, 1000",
-          "340, 500",
-          "512, 200",
-          "600.5, 150",
-          "880, 100"
-  })
+  @CsvSource({ "110, 1000", "340, 500", "512, 200", "600.5, 150", "880, 100" })
   public void testSample(double frequency, int iterations) {
     // Set up class and retrieve queue
     CircularArrayFixedSizeQueueGuitarString string = constructGuitarString(frequency);
@@ -233,11 +223,13 @@ public class GuitarStringTests {
     assertEquals(0, string.sample(), "Sample should return 0 before plucking");
     assertEquals(queue.peek(), string.sample(), "Sample should same as peek()ing queue");
     string.pluck();
+    queue = getQueueFromString(string);
     assertEquals(queue.peek(), string.sample(), "Sample should same as peek()ing queue");
 
     // Run through many iterations, making sure sample() matches peek()
     for (int i = 0; i < iterations; i++) {
       string.tic();
+      queue = getQueueFromString(string);
       assertEquals(queue.peek(), string.sample(), "Sample should same as peek()ing queue");
     }