Bug 576333 - StrongIterableTest support for next() without hasNext()

just in case someone would use that in future.

Change-Id: I32f92b160af0808e2918dbf9b8dee41c6fa2d3eb
Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.runtime/+/186074
Tested-by: Platform Bot <platform-bot@eclipse.org>
Reviewed-by: Sebastian Zarnekow <sebastian.zarnekow@gmail.com>
Reviewed-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/StrongIterable.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/StrongIterable.java
index fe30589..ac402d4 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/StrongIterable.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/StrongIterable.java
@@ -65,10 +65,11 @@
 
 			@Override
 			public T next() {
+				if (!hasNext()) {
+					throw new NoSuchElementException();
+				}
 				T result = next;
 				next = null;
-				if (result == null)
-					throw new NoSuchElementException();
 				return result;
 			}
 
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/StrongIterableTest.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/StrongIterableTest.java
index 09ec8f2..3665fb1 100644
--- a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/StrongIterableTest.java
+++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/StrongIterableTest.java
@@ -49,6 +49,52 @@
 		testRemoveWhileIterate(constructor.get());
 		testRemoveAll(constructor.get());
 		testRemoveByClear(constructor.get());
+		testNextWithoutHasNext(constructor.get());
+	}
+
+	private void testNextWithoutHasNext(Collection<Reference<Integer>> iterable) {
+		WeakReference<Integer> EMPTY1 = new WeakReference<>(null);
+		WeakReference<Integer> EMPTY2 = new WeakReference<>(null);
+		WeakReference<Integer> ONE = new WeakReference<>(1);
+		WeakReference<Integer> TWO = new WeakReference<>(2);
+		WeakReference<Integer> THREE = new WeakReference<>(3);
+		iterable.add(EMPTY1); // ignored
+		iterable.add(ONE);
+		iterable.add(TWO);
+		iterable.add(EMPTY2); // ignored
+		iterable.add(THREE);
+		StrongIterable<Integer> strongIterable = new StrongIterable<>(iterable);
+		{
+			Iterator<Integer> i = strongIterable.iterator();
+			assertEquals(1, i.next().intValue());
+			assertEquals(2, i.next().intValue());
+			assertEquals(3, i.next().intValue());
+			try {
+				i.next();
+			} catch (NoSuchElementException e) {
+				assertNotNull(e);
+			}
+		}
+		{
+			Iterator<Integer> i = strongIterable.iterator();
+			assertEquals(1, i.next().intValue());
+			assertEquals(3L, count(strongIterable));
+			assertEquals(3L, poorMansCount(strongIterable));
+			i.remove();
+			assertEquals(2L, count(strongIterable));
+			assertEquals(2L, poorMansCount(strongIterable));
+			assertEquals(2, i.next().intValue());
+			i.remove();
+			assertEquals(3, i.next().intValue());
+			i.remove();
+			try {
+				i.next();
+			} catch (NoSuchElementException e) {
+				assertNotNull(e);
+			}
+		}
+		assertEquals(0L, count(strongIterable));
+		assertEquals(0L, poorMansCount(strongIterable));
 	}
 
 	void testRemoveWhileIterate(Collection<Reference<Integer>> iterable) {
@@ -59,20 +105,25 @@
 		iterable.add(TWO);
 		iterable.add(THREE);
 
+		assertEquals(3L, poorMansCount(iterable));
 		StrongIterable<Integer> strongIterable = new StrongIterable<>(iterable);
 		{
 			Iterator<Integer> i = strongIterable.iterator();
 			assertEquals(3L, count(strongIterable));
+			assertEquals(3L, poorMansCount(strongIterable));
+
 			assertTrue(i.hasNext());
 			assertEquals(1, i.next().intValue());
 			assertTrue(i.hasNext());
 			assertEquals(2, i.next().intValue());
 			i.remove(); // remove TWO
 			assertEquals(2L, count(strongIterable));
+			assertEquals(2L, poorMansCount(strongIterable));
 			assertTrue(i.hasNext());
 			assertEquals(3, i.next().intValue());
 			i.remove(); // remove THREE
 			assertEquals(1L, count(strongIterable));
+			assertEquals(1L, poorMansCount(strongIterable));
 			assertFalse(i.hasNext());
 			try {
 				i.next();
@@ -97,6 +148,7 @@
 			i.remove();
 		}
 		assertEquals(0L, count(strongIterable));
+		assertEquals(0L, poorMansCount(strongIterable));
 	}
 
 	void testRemoveByClear(Collection<Reference<Integer>> iterable) {
@@ -203,8 +255,18 @@
 		}
 	}
 
-	private long count(StrongIterable<?> i) {
+	private long count(Iterable<?> i) {
 		return StreamSupport.stream(i.spliterator(), false).count();
 	}
 
+	private long poorMansCount(Iterable<?> i) {
+		long count = -1;
+		try {
+			for (Iterator<?> it = i.iterator();; it.next()) {
+				count++;
+			}
+		} catch (NoSuchElementException expected) {
+		}
+		return count;
+	}
 }