public static 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);
        }
        Deque<DeploymentDescriptor> stack = new ArrayDeque<>();
        descriptorHierarchy.forEach(stack::push);
       
        while (stack.size() > 1) {
            stack.push(merge(stack.pop(), stack.pop(), mode));
        }
        // last element from the stack is the one that contains all merged descriptors
        return stack.pop();
    }
@Test
    public void testDeploymentDesciptorMergeMergeCollections() {
        DeploymentDescriptor primary = new DeploymentDescriptorImpl("org.jbpm.domain");

        primary.getBuilder()
                .addMarshalingStrategy(new ObjectModel("org.jbpm.test.CustomStrategy", new Object[]{"param2"}))
                .setLimitSerializationClasses(true);

        assertThat(primary).isNotNull();
        assertThat(primary.getPersistenceUnit()).isEqualTo("org.jbpm.domain");
        assertThat(primary.getAuditPersistenceUnit()).isEqualTo("org.jbpm.domain");
        assertThat(primary.getAuditMode()).isEqualTo(AuditMode.JPA);
        assertThat(primary.getPersistenceMode()).isEqualTo(PersistenceMode.JPA);
        assertThat(primary.getRuntimeStrategy()).isEqualTo(RuntimeStrategy.SINGLETON);
        assertThat(primary.getMarshallingStrategies().size()).isEqualTo(1);
        assertThat(primary.getConfiguration().size()).isEqualTo(0);
        assertThat(primary.getEnvironmentEntries().size()).isEqualTo(0);
        assertThat(primary.getEventListeners().size()).isEqualTo(0);
        assertThat(primary.getGlobals().size()).isEqualTo(0);
        assertThat(primary.getTaskEventListeners().size()).isEqualTo(0);
        assertThat(primary.getWorkItemHandlers().size()).isEqualTo(0);
        assertThat(primary.getLimitSerializationClasses()).isTrue();

        DeploymentDescriptor secondary = new DeploymentDescriptorImpl("org.jbpm.domain");

        secondary.getBuilder()
                .auditMode(AuditMode.JMS)
                .persistenceMode(PersistenceMode.JPA)
                .persistenceUnit(null)
                .auditPersistenceUnit("")
                .addMarshalingStrategy(new ObjectModel("org.jbpm.test.AnotherCustomStrategy", new Object[]{"param2"}))
                .setLimitSerializationClasses(false);

        assertThat(secondary).isNotNull();
        assertThat(secondary.getPersistenceUnit()).isEqualTo(null);
        assertThat(secondary.getAuditPersistenceUnit()).isEqualTo("");
        assertThat(secondary.getAuditMode()).isEqualTo(AuditMode.JMS);
        assertThat(secondary.getPersistenceMode()).isEqualTo(PersistenceMode.JPA);
        assertThat(secondary.getRuntimeStrategy()).isEqualTo(RuntimeStrategy.SINGLETON);
        assertThat(secondary.getMarshallingStrategies().size()).isEqualTo(1);
        assertThat(secondary.getConfiguration().size()).isEqualTo(0);
        assertThat(secondary.getEnvironmentEntries().size()).isEqualTo(0);
        assertThat(secondary.getEventListeners().size()).isEqualTo(0);
        assertThat(secondary.getGlobals().size()).isEqualTo(0);
        assertThat(secondary.getTaskEventListeners().size()).isEqualTo(0);
        assertThat(secondary.getWorkItemHandlers().size()).isEqualTo(0);
        assertThat(secondary.getLimitSerializationClasses()).isFalse();

        // and now let's merge them
        DeploymentDescriptor outcome = DeploymentDescriptorMerger.merge(primary, secondary,
                MergeMode.MERGE_COLLECTIONS);

        assertThat(outcome).isNotNull();
        assertThat(outcome.getPersistenceUnit()).isEqualTo("org.jbpm.domain");
        assertThat(outcome.getAuditPersistenceUnit()).isEqualTo("org.jbpm.domain");
        assertThat(outcome.getAuditMode()).isEqualTo(AuditMode.JMS);
        assertThat(outcome.getPersistenceMode()).isEqualTo(PersistenceMode.JPA);
        assertThat(outcome.getRuntimeStrategy()).isEqualTo(RuntimeStrategy.SINGLETON);
        assertThat(outcome.getMarshallingStrategies().size()).isEqualTo(2);
        assertThat(outcome.getConfiguration().size()).isEqualTo(0);
        assertThat(outcome.getEnvironmentEntries().size()).isEqualTo(0);
        assertThat(outcome.getEventListeners().size()).isEqualTo(0);
        assertThat(outcome.getGlobals().size()).isEqualTo(0);
        assertThat(outcome.getTaskEventListeners().size()).isEqualTo(0);
        assertThat(outcome.getWorkItemHandlers().size()).isEqualTo(0);
        assertThat(outcome.getLimitSerializationClasses()).isFalse();
    }