DefaultTraversalStrategies implements TraversalStrategies { @Override public DefaultTraversalStrategies clone() { try { final DefaultTraversalStrategies clone = (DefaultTraversalStrategies) super.clone(); clone.traversalStrategies = new LinkedHashSet<>(this.traversalStrategies.size()); clone.traversalStrategies.addAll(this.traversalStrategies); return clone; } catch (final CloneNotSupportedException e) { throw new IllegalStateException(e.getMessage(), e); } }  @Override @SuppressWarnings({"unchecked", "varargs"}) TraversalStrategies addStrategies(final TraversalStrategy<?>... strategies); @Override @SuppressWarnings({"unchecked", "varargs"}) TraversalStrategies removeStrategies(final Class<? extends TraversalStrategy>... strategyClasses); @Override List<TraversalStrategy<?>> toList(); @Override Iterator<TraversalStrategy<?>> iterator(); @Override Optional<T> getStrategy(final Class<T> traversalStrategyClass); @Override DefaultTraversalStrategies clone(); @Override String toString();  }
@Test public void testCloningAndStatefulStrategies() { final DefaultTraversal firstTraversal = new DefaultTraversal(); final DefaultTraversalStrategies first = new DefaultTraversalStrategies(); assertEquals(0, first.traversalStrategies.size()); SideEffectStrategy.addSideEffect(first, "a", 2, Operator.sum); assertEquals(1, first.traversalStrategies.size()); firstTraversal.setStrategies(first); firstTraversal.applyStrategies(); assertEquals(1, firstTraversal.getSideEffects().keys().size()); assertEquals(2, firstTraversal.getSideEffects().<Integer>get("a").intValue()); final DefaultTraversalStrategies second = first.clone(); SideEffectStrategy.addSideEffect(second, "b", "marko", Operator.assign); final DefaultTraversal secondTraversal = new DefaultTraversal(); secondTraversal.setStrategies(first); secondTraversal.applyStrategies(); assertEquals(1, secondTraversal.getSideEffects().keys().size()); assertEquals(2, secondTraversal.getSideEffects().<Integer>get("a").intValue()); final DefaultTraversal thirdTraversal = new DefaultTraversal(); thirdTraversal.setStrategies(second); thirdTraversal.applyStrategies(); assertEquals(2, thirdTraversal.getSideEffects().keys().size()); assertEquals(2, thirdTraversal.getSideEffects().<Integer>get("a").intValue()); assertEquals("marko", thirdTraversal.getSideEffects().get("b")); SideEffectStrategy.addSideEffect(second, "c", "hello", Operator.assign); final DefaultTraversal forthTraversal = new DefaultTraversal(); forthTraversal.setStrategies(second); forthTraversal.applyStrategies(); assertEquals(3, forthTraversal.getSideEffects().keys().size()); assertEquals(2, forthTraversal.getSideEffects().<Integer>get("a").intValue()); assertEquals("marko", forthTraversal.getSideEffects().get("b")); assertEquals("hello", forthTraversal.getSideEffects().get("c")); final DefaultTraversal fifthTraversal = new DefaultTraversal(); fifthTraversal.setStrategies(first); fifthTraversal.applyStrategies(); assertEquals(1, fifthTraversal.getSideEffects().keys().size()); assertEquals(2, fifthTraversal.getSideEffects().<Integer>get("a").intValue()); assertTrue(firstTraversal.getStrategies() == secondTraversal.getStrategies()); assertTrue(firstTraversal.getStrategies() != thirdTraversal.getStrategies()); assertTrue(forthTraversal.getStrategies() == thirdTraversal.getStrategies()); assertTrue(fifthTraversal.getStrategies() == firstTraversal.getStrategies()); }