//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package de.ugoe.cs.autoquest.tasktrees.temporalrelation;

import org.junit.Test;

import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
import de.ugoe.cs.autoquest.tasktrees.TaskTreeInstantiator;
import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
import de.ugoe.cs.autoquest.tasktrees.testutils.Utilities;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeBuilder;
import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeNodeFactory;

/**
 * <p>
 * TODO comment
 * </p>
 * 
 * @author Patrick Harms
 */
public class TaskTreeNodeMergerTest {

    /** */
    private ITaskTreeBuilder taskTreeBuilder = new TaskTreeBuilder();

    /** */
    private ITaskTreeNodeFactory taskTreeNodeFactory = new TaskTreeNodeFactory();

    /** */
    private NodeEqualityRuleManager nodeEqualityRuleManager =
        Utilities.getNodeEqualityRuleManagerForTests();

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_1() {
        String spec1 = "EventTask target1 {}";
        String spec2 = "EventTask target1 {}";
        
        String oracleSpec = "EventTask target1 {}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_2() {
        String spec1 = "EventTask target1 {}";
        String spec2 = "EventTask target2 {}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_3() {
        String spec1 =
            "Selection {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 = "EventTask target2 {}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_4() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Selection {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_5() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  EventTask target1 {}" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  EventTask target1 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_6() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_7() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_8() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Sequence {" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "  Sequence {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_EventTaskMerge_9() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  Optional {" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_1() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_2() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target4 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  Selection {" +
            "    EventTask target2 {}" +
            "    EventTask target4 {}" +
            "  }" +
            "  EventTask target3 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_3() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target4 {}" +
            "  EventTask target5 {}" +
            "  EventTask target6 {}" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "  Sequence {" +
            "    EventTask target4 {}" +
            "    EventTask target5 {}" +
            "    EventTask target6 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_4() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target4 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  Selection {" +
            "    EventTask target3 {}" +
            "    EventTask target4 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_5() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target4 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target4 {}" +
            "  }" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_6() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target4 {}" +
            "  EventTask target2 {}" +
            "  EventTask target5 {}" +
            "}";

        String oracleSpec =
            "Sequence {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target4 {}" +
            "  }" +
            "  EventTask target2 {}" +
            "  Selection {" +
            "    EventTask target3 {}" +
            "    EventTask target5 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_7() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  Optional {" +
            "    EventTask target2 {}" +
            "  }" +
            "  EventTask target3 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_8() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  Optional {" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_9() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  Optional {" +
            "    EventTask target1 {}" +
            "  }" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_10() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target2 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  Optional {" +
            "    EventTask target1 {}" +
            "  }" +
            "  EventTask target2 {}" +
            "  Optional {" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SequenceMerge_11() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "  EventTask target4 {}" +
            "  EventTask target5 {}" +
            "  EventTask target6 {}" +
            "  EventTask target7 {}" +
            "}";

        String spec2 =
            "Sequence {" +
            "  EventTask target4 {}" +
            "  EventTask target3 {}" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "  EventTask target4 {}" +
            "  EventTask target4 {}" +
            "  EventTask target2 {}" +
            "  EventTask target6 {}" +
            "  EventTask target7 {}" +
            "}";
        
        String oracleSpec =
            "Sequence {" +
            "  Optional {" +
            "    Sequence {" +
            "      EventTask target4 {}" +
            "      EventTask target3 {}" +
            "    }" +
            "  }" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "  EventTask target4 {}" +
            "  Selection {" +
            "    EventTask target5 {}" +
            "    Sequence {" +
            "      EventTask target4 {}" +
            "      EventTask target2 {}" +
            "    }" +
            "  }" +
            "  EventTask target6 {}" +
            "  EventTask target7 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SelectionMerge_1() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Selection {" +
            "  EventTask target1 {}" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SelectionMerge_2() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Selection {" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "  EventTask target3 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SelectionMerge_3() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  EventTask target1 {}" +
            "  Sequence {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_SelectionMerge_4() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    Optional {" +
            "      EventTask target2 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_SelectionMerge_5() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_SelectionMerge_6() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target3 {}" +
            "    EventTask target4 {}" +
            "  }" +
            "  Sequence {" +
            "    EventTask target5 {}" +
            "    EventTask target6 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Selection {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "  Sequence {" +
            "    EventTask target3 {}" +
            "    EventTask target4 {}" +
            "  }" +
            "  Sequence {" +
            "    EventTask target5 {}" +
            "    EventTask target6 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_IterationMerge_1() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  EventTask target1 {}" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  EventTask target1 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_IterationMerge_2() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_IterationMerge_3() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  Sequence {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    Sequence {" +
            "      EventTask target2 {}" +
            "      EventTask target3 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_IterationMerge_4() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Iteration {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    Optional {" +
            "      EventTask target2 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_IterationMerge_5() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 =
            "Iteration {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_IterationMerge_6() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 =
            "Iteration {" +
            "  Selection {" +
            "    Sequence {" +
            "      EventTask target3 {}" +
            "      EventTask target4 {}" +
            "    }" +
            "    Sequence {" +
            "      EventTask target5 {}" +
            "      EventTask target6 {}" +
            "    }" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Iteration {" +
            "  Selection {" +
            "    Sequence {" +
            "      EventTask target1 {}" +
            "      EventTask target2 {}" +
            "    }" +
            "    Sequence {" +
            "      EventTask target3 {}" +
            "      EventTask target4 {}" +
            "    }" +
            "    Sequence {" +
            "      EventTask target5 {}" +
            "      EventTask target6 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_OptionalMerge_1() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Optional {" +
            "  EventTask target1 {}" +
            "}";
        
        String oracleSpec =
            "Optional {" +
            "  EventTask target1 {}" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_OptionalMerge_2() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Optional {" +
            "  Selection {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Optional {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_OptionalMerge_3() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Optional {" +
            "  Sequence {" +
            "    EventTask target2 {}" +
            "    EventTask target3 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Optional {" +
            "  Selection {" +
            "    EventTask target1 {}" +
            "    Sequence {" +
            "      EventTask target2 {}" +
            "      EventTask target3 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_OptionalMerge_4() {
        String spec1 = "EventTask target1 {}";
        
        String spec2 =
            "Optional {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Optional {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    Optional {" +
            "      EventTask target2 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }

    /**
     * 
     */
    @Test
    public void test_OptionalMerge_5() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 =
            "Optional {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Optional {" +
            "  Sequence {" +
            "    EventTask target1 {}" +
            "    EventTask target2 {}" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    @Test
    public void test_OptionalMerge_6() {
        String spec1 =
            "Sequence {" +
            "  EventTask target1 {}" +
            "  EventTask target2 {}" +
            "}";

        String spec2 =
            "Optional {" +
            "  Selection {" +
            "    Sequence {" +
            "      EventTask target3 {}" +
            "      EventTask target4 {}" +
            "    }" +
            "    Sequence {" +
            "      EventTask target5 {}" +
            "      EventTask target6 {}" +
            "    }" +
            "  }" +
            "}";
        
        String oracleSpec =
            "Optional {" +
            "  Selection {" +
            "    Sequence {" +
            "      EventTask target1 {}" +
            "      EventTask target2 {}" +
            "    }" +
            "    Sequence {" +
            "      EventTask target3 {}" +
            "      EventTask target4 {}" +
            "    }" +
            "    Sequence {" +
            "      EventTask target5 {}" +
            "      EventTask target6 {}" +
            "    }" +
            "  }" +
            "}";
        
        performTest(spec1, spec2, oracleSpec);
    }
    
    /**
     * 
     */
    private void performTest(String spec1, String spec2, String specOracle) {
        TaskTreeInstantiator instantiator =
                new TaskTreeInstantiator(taskTreeNodeFactory, taskTreeBuilder);
            
        ITaskTreeNode node1 = instantiator.instantiateTaskTree(spec1);
        ITaskTreeNode node2 = instantiator.instantiateTaskTree(spec2);
        ITaskTreeNode oracle = instantiator.instantiateTaskTree(specOracle);
        
        TaskTreeNodeComparator comparator =
            new TaskTreeNodeComparator(nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL);
        
        TaskTreeNodeMerger merger = new TaskTreeNodeMerger
            (taskTreeNodeFactory, taskTreeBuilder, comparator);
        
        try {
            ITaskTreeNode result = merger.mergeTaskNodes(node1, node2);
            new TaskTreeChecker().assertTaskNodesEqual(oracle, result);
        }
        catch (AssertionError e) {
            AssertionError toThrow = new AssertionError("first check: " + e.getMessage());
            toThrow.setStackTrace(e.getStackTrace());
            throw toThrow;
        }
        
        node1 = instantiator.instantiateTaskTree(spec1);
        node2 = instantiator.instantiateTaskTree(spec2);
        oracle = instantiator.instantiateTaskTree(specOracle);
        
        comparator =
            new TaskTreeNodeComparator(nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL);
        
        merger = new TaskTreeNodeMerger(taskTreeNodeFactory, taskTreeBuilder, comparator);
            
        try {
            ITaskTreeNode result = merger.mergeTaskNodes(node2, node1);
            new TaskTreeChecker().assertTaskNodesEqual(oracle, result);
        }
        catch (AssertionError e) {
            AssertionError toThrow = new AssertionError("second check: " + e.getMessage());
            toThrow.setStackTrace(e.getStackTrace());
            throw toThrow;
        }
    }
}
