class DeploymentDescriptorMerger {

	public DeploymentDescriptor merge(List<DeploymentDescriptor> descriptorHierarchy, MergeMode mode) {
		if (descriptorHierarchy == null || descriptorHierarchy.isEmpty()) {
			throw new IllegalArgumentException("Descriptor hierarchy list cannot be empty");
		}

		if (descriptorHierarchy.size() == 1) {
			return descriptorHierarchy.get(0);
		}
		Stack<DeploymentDescriptor> stack = new Stack<DeploymentDescriptor>();
		stack.addAll(descriptorHierarchy);
		if (mode == null) {
			mode = MergeMode.MERGE_COLLECTIONS;
		}

		while (stack.size() > 1) {
			DeploymentDescriptor master = stack.pop();
			DeploymentDescriptor slave = stack.pop();
			DeploymentDescriptor desc = merge(master, slave, mode);
			// add merged one to be next iteration slave
			stack.push(desc);
		}
		// last element from the stack is the one that contains all merged descriptors
		return stack.pop();
	}

}