package uk.org.taverna.scufl2.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.junit.Test;

import uk.org.taverna.scufl2.api.common.Child;
import uk.org.taverna.scufl2.api.common.Visitor;
import uk.org.taverna.scufl2.api.common.WorkflowBean;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.property.PropertyObject;

public class VisitorTest {
	@Test
	public void visitAll() throws Exception {

		final List<WorkflowBean> enters = new ArrayList<WorkflowBean>();
		final List<WorkflowBean> leaves = new ArrayList<WorkflowBean>();
		final List<WorkflowBean> visits = new ArrayList<WorkflowBean>();

		WorkflowBundle example = new ExampleWorkflow().makeWorkflowBundle();

		example.accept(new Visitor() {
			@Override
			public boolean visit(WorkflowBean node) {
				visits.add(node);
				if (node instanceof Child) {
					Child child = (Child) node;
					assertTrue(enters.contains(child.getParent()));
				}
				return true;
			}

			@Override
			public boolean visitEnter(WorkflowBean node) {
				if (enters.contains(node)) {
					fail("Duplicate enter on " + node);
				}
				if (leaves.contains(node)) {
					fail("Leave before enter on " + node);
				}

				enters.add(node);
				return true;
			}

			@Override
			public boolean visitLeave(WorkflowBean node) {
				leaves.add(node);
				assertTrue(enters.contains(node));
				return true;
			}
		});
		assertEquals(enters.size(), leaves.size());
		HashSet entersSet = new HashSet(enters);
		HashSet leavesSet = new HashSet(leaves);
		assertEquals(entersSet, leavesSet);
		assertEquals(enters.size(), entersSet.size());

		for (WorkflowBean b : visits) {
			if (b instanceof Child) {
				@SuppressWarnings("rawtypes")
				Child child = (Child) b;
				WorkflowBean parent = child.getParent();
				assertTrue("", enters.contains(parent));
			} else {
				assertTrue("Bean is not a PropertyObject or Child: " + b,
						b instanceof PropertyObject);
			}
		}

	}
}

@@ -231,16 +231,40 @@
 il.List;
+%0Aimport java.util.Stack;
 %0A%0Aimport
@@ -576,16 +576,64 @@
 rTest %7B%0A
+%09@SuppressWarnings(%7B %22rawtypes%22, %22unchecked%22 %7D)%0A
 %09@Test%0A%09
@@ -875,16 +875,79 @@
 Bean%3E();
+%0A%09%09final Stack%3CWorkflowBean%3E stack = new Stack%3CWorkflowBean%3E();
 %0A%0A%09%09Work
@@ -1045,16 +1045,17 @@
 tor() %7B%0A
+%0A
 %09%09%09@Over
@@ -1130,133 +1130,8 @@
 e);%0A
-%09%09%09%09if (node instanceof Child) %7B%0A%09%09%09%09%09Child child = (Child) node;%0A%09%09%09%09%09assertTrue(enters.contains(child.getParent()));%0A%09%09%09%09%7D%0A
 %09%09%09%09
@@ -1370,24 +1370,45 @@
 node);%0A%09%09%09%09%7D
+%0A%09%09%09%09stack.add(node);
 %0A%0A%09%09%09%09enters
@@ -1523,24 +1523,61 @@
 .add(node);%0A
+%09%09%09%09assertEquals(stack.pop(), node);%0A
 %09%09%09%09assertTr
@@ -1631,16 +1631,47 @@
 %7D%0A%09%09%7D);%0A
+%09%09assertTrue(stack.isEmpty());%0A
 %09%09assert
@@ -1708,16 +1708,17 @@
 ize());%0A
+%0A
 %09%09HashSe
@@ -1950,42 +1950,8 @@
 ) %7B%0A
-%09%09%09%09@SuppressWarnings(%22rawtypes%22)%0A
 %09%09%09%09
@@ -2020,16 +2020,16 @@
 rent();%0A
+
 %09%09%09%09asse
@@ -2039,12 +2039,8 @@
 rue(
-%22%22, 
 ente

remove Child tests - those are tested by uk.org.taverna.scufl2.api.common.TestSetParent