/*
 * Copyright 2015-2017 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.vintage.engine.discovery;

import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toSet;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Optional;
import java.util.Set;

import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.UniqueId;
import org.junit.runner.Description;
import org.junit.vintage.engine.descriptor.RunnerTestDescriptor;
import org.junit.vintage.engine.descriptor.VintageTestDescriptor;

/**
 * @since 4.12
 */
class UniqueIdFilter extends RunnerTestDescriptorAwareFilter {

	private final UniqueId uniqueId;

	private Deque<Description> path;
	private Set<Description> descendants;

	public UniqueIdFilter(UniqueId uniqueId) {
		this.uniqueId = uniqueId;
	}

	@Override
	void initialize(RunnerTestDescriptor runnerTestDescriptor) {
		Optional<? extends TestDescriptor> identifiedTestDescriptor = runnerTestDescriptor.findByUniqueId(uniqueId);
		descendants = determineDescendants(identifiedTestDescriptor);
		path = determinePath(runnerTestDescriptor, identifiedTestDescriptor);
	}

	private Deque<Description> determinePath(RunnerTestDescriptor runnerTestDescriptor,
			Optional<? extends TestDescriptor> identifiedTestDescriptor) {
		Deque<Description> path = new LinkedList<>();
		Optional<? extends TestDescriptor> current = identifiedTestDescriptor;
		while (current.isPresent() && !current.get().equals(runnerTestDescriptor)) {
			path.addFirst(((VintageTestDescriptor) current.get()).getDescription());
			current = current.get().getParent();
		}
		return path;
	}

	private Set<Description> determineDescendants(Optional<? extends TestDescriptor> identifiedTestDescriptor) {
		if (identifiedTestDescriptor.isPresent()) {
			// @formatter:off
			return identifiedTestDescriptor.get()
					.getDescendants()
					.stream()
					.map(VintageTestDescriptor.class::cast)
					.map(VintageTestDescriptor::getDescription)
					.collect(toSet());
			// @formatter:on
		}
		return emptySet();
	}

	@Override
	public boolean shouldRun(Description description) {
		return path.contains(description) || descendants.contains(description);
	}

	@Override
	public String describe() {
		return "Unique ID " + uniqueId;
	}

}

@@ -380,44 +380,41 @@
 til.
-Collections.empty
+stream.Collectors.to
 Set;%0A
+%0A
 import 
-static 
 java
@@ -423,33 +423,19 @@
 til.
-stream.Collectors.toSet;%0A
+ArrayDeque;
 %0Aimp
@@ -448,21 +448,27 @@
 va.util.
-Deque
+Collections
 ;%0Aimport
@@ -478,26 +478,21 @@
 va.util.
-LinkedList
+Deque
 ;%0Aimport
@@ -993,23 +993,16 @@
 ants;%0A%0A%09
-public 
 UniqueId
@@ -1572,18 +1572,18 @@
 new 
-LinkedList
+ArrayDeque
 %3C%3E()
@@ -1989,55 +1989,8 @@
 ) %7B%0A
-%09%09if (identifiedTestDescriptor.isPresent()) %7B%0A%09
 %09%09//
@@ -2005,17 +2005,16 @@
 ter:off%0A
-%09
 %09%09return
@@ -2043,14 +2043,51 @@
 tor.
-get()%0A
+map(%0A%09%09%09%09testDescriptor -%3E testDescriptor%0A%09
 %09%09%09%09
@@ -2110,16 +2110,17 @@
 ()%0A%09%09%09%09%09
+%09
 .stream(
@@ -2121,16 +2121,17 @@
 tream()%0A
+%09
 %09%09%09%09%09.ma
@@ -2167,16 +2167,17 @@
 ::cast)%0A
+%09
 %09%09%09%09%09.ma
@@ -2222,16 +2222,17 @@
 n)%0A%09%09%09%09%09
+%09
 .collect
@@ -2244,51 +2244,46 @@
 t())
-;
+)
 %0A%09%09%09
-// @formatter:on%0A%09%09%7D%0A%09%09return 
+%09.orElseGet(Collections::
 emptySet
 ();%0A
@@ -2278,20 +2278,38 @@
 emptySet
-(
 );%0A
+%09%09// @formatter:on%0A
 %09%7D%0A%0A%09@Ov

Use `Optional.map` and `ArrayDeque` more consistently