package pete.metrics.adaptability.elements;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

class GatewayElements {

	private final Collection<AdaptableElement> elements;

	public GatewayElements() {
		elements = new HashSet<>();
		buildExclusiveGateway();
		buildInclusiveGateway();
		buildParallelGateway();
		buildComplexGateway();
		buildEventBasedGateway();
	}

	private void buildEventBasedGateway() {
		AdaptableElement eventBasedGateway = new AdaptableElement("eventBasedGateway");
		eventBasedGateway.setDocumentation("An eventBasedGateway can be adapted to a solution where the events are processed through tasks before the gateway and set conditions to be evaluated by the gateway");
		eventBasedGateway.setLocatorExpression("//*[local-name() = 'eventBasedGateway']");
		eventBasedGateway.addAdaption("parallelEventBasedGateway");
		eventBasedGateway.addAdaption("inclusiveGateway");
		eventBasedGateway.addAdaption("complexGateway");
		eventBasedGateway.addAdaption("exclusiveGateway");
		addToSet(eventBasedGateway);
	}

	private void buildComplexGateway() {
		AdaptableElement complexGateway = new AdaptableElement("complexGateway");
		complexGateway.setLocatorExpression("//*[local-name() = 'complexGateway']");
		complexGateway.addAdaption("parallelEventBasedGateway");
		addToSet(complexGateway);
	}

	private void buildParallelGateway() {
		AdaptableElement parallelGateway = new AdaptableElement("parallelGateway");
		parallelGateway.setLocatorExpression("//*[local-name() = 'parallelGateway']");
		parallelGateway.addAdaption("parallelEventBasedGateway");
		parallelGateway.addAdaption("inclusiveGateway");
		parallelGateway.addAdaption("complexGateway");
		addToSet(parallelGateway);
	}

	private void buildInclusiveGateway() {
		AdaptableElement inclusiveGateway = new AdaptableElement("inclusiveGateway");
		inclusiveGateway.setLocatorExpression("//*[local-name() = 'inclusiveGateway']");
		inclusiveGateway.addAdaption("parallelEventBasedGateway");
		inclusiveGateway.addAdaption("complexGateway");
		addToSet(inclusiveGateway);
	}

	private void buildExclusiveGateway() {
		AdaptableElement exclusiveGateway = new AdaptableElement("exclusiveGateway");
		exclusiveGateway.setLocatorExpression("//*[local-name() = 'exclusiveGateway']");
		exclusiveGateway.addAdaption("eventBasedGateway");
		exclusiveGateway.addAdaption("complexGateway");
		exclusiveGateway.addAdaption("inclusiveGateway");
		addToSet(exclusiveGateway);
	}

	private void addToSet(AdaptableElement element) {
		boolean success = elements.add(element);
		if (!success) {
			throw new IllegalStateException(element.getName()
					+ " was tried to be added twice");
		}
	}

	public List<String> getElementNames() {
		List<String> result = new ArrayList<>(elements.size());
		elements.forEach(element -> result.add(element.getName()));
		return result;
	}

	public List<AdaptableElement> getElements() {
		List<AdaptableElement> result = new ArrayList<>(elements.size());
		elements.forEach(element -> result.add(element));
		return result;
	}

	public Map<String, AdaptableElement> getElementsByName() {
		HashMap<String, AdaptableElement> result = new HashMap<>();
		elements.forEach(element -> result.put(element.getName(), element));
		return result;
	}



}

@@ -464,16 +464,665 @@
 eway();%0A
+%09%09buildParallelEventBasedGateway();%0A%09%7D%0A%0A%09private void buildParallelEventBasedGateway() %7B%0A%09%09AdaptableElement eventBasedGateway = new AdaptableElement(%22parallelEventBasedGateway%22);%0A%09%09eventBasedGateway.setDocumentation(%22A parallel eventBasedGateway can be adapted to a solution where the events are processed through tasks before the gateway and set conditions to be evaluated by the gateway%22);%0A%09%09eventBasedGateway.setLocatorExpression(%22//*%5Blocal-name() = 'eventBasedGateway' and (@eventGatewayType = 'parallel')%5D%22);%0A%09%09eventBasedGateway.addAdaption(%22inclusiveGateway%22);%0A%09%09eventBasedGateway.addAdaption(%22complexGateway%22);%0A%09%09addToSet(eventBasedGateway);%0A
 %09%7D%0A%0A%09pri
@@ -1517,32 +1517,73 @@
 entBasedGateway'
+ and not (@eventGatewayType = 'parallel')
 %5D%22);%0A%09%09eventBase

Add tests for parallel eventBasedGateway