/// <summary>
        /// Compares two SubStep and annotates the differences on the first one
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="other"></param>
        public static void compareSubStep(Generated.SubStep obj, Generated.SubStep other, VersionDiff diff)
        {
            if ( other == null )
            {
                diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "", "", obj.Name ) );
                return;
            }

            compareNamable (obj, other, diff);

            if ( obj.allActions() != null )
            {
                if ( other.allActions() != null )
                {
                    int i = 0;
                    while ( i < obj.countActions() && i < other.countActions() )
                    {
                        Generated.Action element = obj.getActions( i );
                        Generated.Action otherElement = other.getActions( i );
                        compareAction ( element, otherElement, diff );
                        i += 1;
                    }
                    while ( i < obj.countActions() )
                    {
                        diff.appendChanges ( new Diff(obj.getActions(i), HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "Actions", "", obj.getActions( i ).Name ) );
                        i += 1;
                    }
                    while ( i < other.countActions() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove, "Actions", other.getActions( i ).Name) );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.Action subElement in obj.allActions() )
                    {
                        diff.appendChanges ( new Diff(subElement, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "Actions", "", subElement.Name ) );
                    }
                }
            }
            else
            {
                if ( other.allActions() != null )
                {
                    foreach ( Generated.Action otherElement in other.allActions() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove , "Actions", otherElement.Name) );
                    }
                }
            }
            if ( obj.allExpectations() != null )
            {
                if ( other.allExpectations() != null )
                {
                    int i = 0;
                    while ( i < obj.countExpectations() && i < other.countExpectations() )
                    {
                        Generated.Expectation element = obj.getExpectations( i );
                        Generated.Expectation otherElement = other.getExpectations( i );
                        compareExpectation ( element, otherElement, diff );
                        i += 1;
                    }
                    while ( i < obj.countExpectations() )
                    {
                        diff.appendChanges ( new Diff(obj.getExpectations(i), HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "Expectations", "", obj.getExpectations( i ).Name ) );
                        i += 1;
                    }
                    while ( i < other.countExpectations() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove, "Expectations", other.getExpectations( i ).Name) );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.Expectation subElement in obj.allExpectations() )
                    {
                        diff.appendChanges ( new Diff(subElement, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "Expectations", "", subElement.Name ) );
                    }
                }
            }
            else
            {
                if ( other.allExpectations() != null )
                {
                    foreach ( Generated.Expectation otherElement in other.allExpectations() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove , "Expectations", otherElement.Name) );
                    }
                }
            }
            if ( obj.getSkipEngine() != other.getSkipEngine() )
            {
                diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aChange, "SkipEngine", other.getSkipEngine().ToString(), obj.getSkipEngine().ToString()) );
            }
            if ( obj.getTimeDelay() != other.getTimeDelay() )
            {
                diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aChange, "TimeDelay", other.getTimeDelay().ToString(), obj.getTimeDelay().ToString()) );
            }
            if ( obj.getTimer() != other.getTimer() )
            {
                diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aChange, "Timer", other.getTimer().ToString(), obj.getTimer().ToString()) );
            }
            if ( !CompareUtil.canonicalStringEquality(obj.getComment(), other.getComment()) )
            {
                diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aChange, "Comment", other.getComment(), obj.getComment()) );
            }
        }
        /// <summary>
        /// Compares two RuleCondition and annotates the differences on the first one
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="other"></param>
        public static void compareRuleCondition(Generated.RuleCondition obj, Generated.RuleCondition other, VersionDiff diff)
        {
            if ( other == null )
            {
                diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "", "", obj.Name ) );
                return;
            }

            compareReqRelated (obj, other, diff);

            if ( obj.allPreConditions() != null )
            {
                if ( other.allPreConditions() != null )
                {
                    int i = 0;
                    while ( i < obj.countPreConditions() && i < other.countPreConditions() )
                    {
                        Generated.PreCondition element = obj.getPreConditions( i );
                        Generated.PreCondition otherElement = other.getPreConditions( i );
                        comparePreCondition ( element, otherElement, diff );
                        i += 1;
                    }
                    while ( i < obj.countPreConditions() )
                    {
                        diff.appendChanges ( new Diff(obj.getPreConditions(i), HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "PreConditions", "", obj.getPreConditions( i ).Name ) );
                        i += 1;
                    }
                    while ( i < other.countPreConditions() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove, "PreConditions", other.getPreConditions( i ).Name) );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.PreCondition subElement in obj.allPreConditions() )
                    {
                        diff.appendChanges ( new Diff(subElement, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "PreConditions", "", subElement.Name ) );
                    }
                }
            }
            else
            {
                if ( other.allPreConditions() != null )
                {
                    foreach ( Generated.PreCondition otherElement in other.allPreConditions() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove , "PreConditions", otherElement.Name) );
                    }
                }
            }
            if ( obj.allActions() != null )
            {
                if ( other.allActions() != null )
                {
                    int i = 0;
                    while ( i < obj.countActions() && i < other.countActions() )
                    {
                        Generated.Action element = obj.getActions( i );
                        Generated.Action otherElement = other.getActions( i );
                        compareAction ( element, otherElement, diff );
                        i += 1;
                    }
                    while ( i < obj.countActions() )
                    {
                        diff.appendChanges ( new Diff(obj.getActions(i), HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "Actions", "", obj.getActions( i ).Name ) );
                        i += 1;
                    }
                    while ( i < other.countActions() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove, "Actions", other.getActions( i ).Name) );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.Action subElement in obj.allActions() )
                    {
                        diff.appendChanges ( new Diff(subElement, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "Actions", "", subElement.Name ) );
                    }
                }
            }
            else
            {
                if ( other.allActions() != null )
                {
                    foreach ( Generated.Action otherElement in other.allActions() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove , "Actions", otherElement.Name) );
                    }
                }
            }
            if ( obj.allSubRules() != null )
            {
                if ( other.allSubRules() != null )
                {
                    foreach ( Generated.Rule subElement in obj.allSubRules() )
                    {
                        bool compared = false;
                        foreach ( Generated.Rule otherElement in other.allSubRules() )
                        {
                            if ( subElement.Guid == otherElement.Guid )
                            {
                                compareRule ( subElement, otherElement, diff );
                                compared = true;
                            break;
                            }
                        }

                        if ( !compared )
                        {
                            diff.appendChanges ( new Diff(subElement, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "SubRules", "", subElement.Name ) );
                        }
                    }

                    foreach ( Generated.Rule otherElement in other.allSubRules() )
                    {
                        bool found = false;
                        foreach ( Generated.Rule subElement in obj.allSubRules() )
                        {
                            if ( subElement.Guid == otherElement.Guid )
                            {
                                found = true;
                                break;
                            }
                        }

                        if ( !found )
                        {
                            diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove , "SubRules", otherElement.Name) );
                        }
                    }
                }
                else
                {
                    foreach ( Generated.Rule subElement in obj.allSubRules() )
                    {
                        diff.appendChanges ( new Diff(subElement, HistoricalData.Generated.acceptor.ChangeOperationEnum.aAdd, "SubRules", "", subElement.Name ) );
                    }
                }
            }
            else
            {
                if ( other.allSubRules() != null )
                {
                    foreach ( Generated.Rule otherElement in other.allSubRules() )
                    {
                        diff.appendChanges ( new Diff(obj, HistoricalData.Generated.acceptor.ChangeOperationEnum.aRemove , "SubRules", otherElement.Name) );
                    }
                }
            }
        }
        /// <summary>
        /// Searches a specific string in SubStep and updates the list 
        /// of model element with all the elements in which that string is found
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="obj">The string to search for</param>
        /// <param name="occurences">The list of model elements which hold the searched string</param>
        public static void searchSubStep(Generated.SubStep obj, string searchString, List<ModelElement> occurences)
        {
            searchNamable (obj, searchString, occurences);

            if ( obj.allActions() != null )
            {
                foreach ( Generated.Action subElement in obj.allActions() )
                {
                    searchAction ( subElement, searchString, occurences );
                }
            }
            if ( obj.allExpectations() != null )
            {
                foreach ( Generated.Expectation subElement in obj.allExpectations() )
                {
                    searchExpectation ( subElement, searchString, occurences );
                }
            }
            if ( obj.getComment() != null && obj.getComment().Contains (searchString) )
            {
                occurences.Add ( obj );
            }
        }
        /// <summary>
        /// Searches a specific string in RuleCondition and updates the list 
        /// of model element with all the elements in which that string is found
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="obj">The string to search for</param>
        /// <param name="occurences">The list of model elements which hold the searched string</param>
        public static void searchRuleCondition(Generated.RuleCondition obj, string searchString, List<ModelElement> occurences)
        {
            searchReqRelated (obj, searchString, occurences);

            if ( obj.allPreConditions() != null )
            {
                foreach ( Generated.PreCondition subElement in obj.allPreConditions() )
                {
                    searchPreCondition ( subElement, searchString, occurences );
                }
            }
            if ( obj.allActions() != null )
            {
                foreach ( Generated.Action subElement in obj.allActions() )
                {
                    searchAction ( subElement, searchString, occurences );
                }
            }
            if ( obj.allSubRules() != null )
            {
                foreach ( Generated.Rule subElement in obj.allSubRules() )
                {
                    searchRule ( subElement, searchString, occurences );
                }
            }
        }
        /// <summary>
        /// Ensures that two SubStep have matching GUID, and recursively.
        /// obj is the leader for Guid. If other doesn't match obj guid, 
        ///   1. other does not have a guid, in that case, other should have the same guid as obj
        ///   2. other already has a guid. In that case, there is a mismatch between objects, and the process stops here
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="other"></param>
        public static void ensureGuidSubStep(Generated.SubStep obj, Generated.SubStep other)
        {
            if ( obj == null )
            {
                if ( other != null )
                {
                    // Side effect, setup a GUID if needed for the other part (other)
                    string guid = other.Guid;
                }
                return;
            }

            if ( other == null )
            {
                if ( obj != null )
                {
                    // Side effect, setup a GUID if needed for the other part (obj)
                    string guid = obj.Guid;
                }
                return;
            }

            if ( obj.Guid != other.getGuid() )
            {
                if ( string.IsNullOrEmpty(other.getGuid()) || GuidByName && (obj.Name == other.Name) )
                {
                    // These are matching elements, copy the guid from  obj
                    other.setGuid ( obj.Guid );
                }
                else
                {
                    // Elements do not match. Stop the recursive process
                    return;
                }
            }

            ensureGuidNamable (obj, other);

            if ( obj.allActions() != null )
            {
                if ( other.allActions() != null )
                {
                    int i = 0;
                    while ( i < obj.countActions() && i < other.countActions() )
                    {
                        Generated.Action element = obj.getActions( i );
                        Generated.Action otherElement = other.getActions( i );
                        ensureGuidAction ( element, otherElement );
                        i += 1;
                    }
                    while ( i < obj.countActions() )
                    {
                        Generated.Action element = obj.getActions( i );
                        ensureGuidAction ( element, null );
                        i += 1;
                    }
                    while ( i < other.countActions() )
                    {
                        Generated.Action otherElement = other.getActions( i );
                        ensureGuidAction ( null, otherElement );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.Action subElement in obj.allActions() )
                    {
                        ensureGuidAction ( subElement, null );
                    }
                }
            }
            else
            {
                if ( other.allActions() != null )
                {
                    foreach ( Generated.Action otherElement in other.allActions() )
                    {
                        ensureGuidAction ( null, otherElement );
                    }
                }
            }
            if ( obj.allExpectations() != null )
            {
                if ( other.allExpectations() != null )
                {
                    int i = 0;
                    while ( i < obj.countExpectations() && i < other.countExpectations() )
                    {
                        Generated.Expectation element = obj.getExpectations( i );
                        Generated.Expectation otherElement = other.getExpectations( i );
                        ensureGuidExpectation ( element, otherElement );
                        i += 1;
                    }
                    while ( i < obj.countExpectations() )
                    {
                        Generated.Expectation element = obj.getExpectations( i );
                        ensureGuidExpectation ( element, null );
                        i += 1;
                    }
                    while ( i < other.countExpectations() )
                    {
                        Generated.Expectation otherElement = other.getExpectations( i );
                        ensureGuidExpectation ( null, otherElement );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.Expectation subElement in obj.allExpectations() )
                    {
                        ensureGuidExpectation ( subElement, null );
                    }
                }
            }
            else
            {
                if ( other.allExpectations() != null )
                {
                    foreach ( Generated.Expectation otherElement in other.allExpectations() )
                    {
                        ensureGuidExpectation ( null, otherElement );
                    }
                }
            }
        }
        /// <summary>
        /// Ensures that two RuleCondition have matching GUID, and recursively.
        /// obj is the leader for Guid. If other doesn't match obj guid, 
        ///   1. other does not have a guid, in that case, other should have the same guid as obj
        ///   2. other already has a guid. In that case, there is a mismatch between objects, and the process stops here
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="other"></param>
        public static void ensureGuidRuleCondition(Generated.RuleCondition obj, Generated.RuleCondition other)
        {
            if ( obj == null )
            {
                if ( other != null )
                {
                    // Side effect, setup a GUID if needed for the other part (other)
                    string guid = other.Guid;
                }
                return;
            }

            if ( other == null )
            {
                if ( obj != null )
                {
                    // Side effect, setup a GUID if needed for the other part (obj)
                    string guid = obj.Guid;
                }
                return;
            }

            if ( obj.Guid != other.getGuid() )
            {
                if ( string.IsNullOrEmpty(other.getGuid()) || GuidByName && (obj.Name == other.Name) )
                {
                    // These are matching elements, copy the guid from  obj
                    other.setGuid ( obj.Guid );
                }
                else
                {
                    // Elements do not match. Stop the recursive process
                    return;
                }
            }

            ensureGuidReqRelated (obj, other);

            if ( obj.allPreConditions() != null )
            {
                if ( other.allPreConditions() != null )
                {
                    int i = 0;
                    while ( i < obj.countPreConditions() && i < other.countPreConditions() )
                    {
                        Generated.PreCondition element = obj.getPreConditions( i );
                        Generated.PreCondition otherElement = other.getPreConditions( i );
                        ensureGuidPreCondition ( element, otherElement );
                        i += 1;
                    }
                    while ( i < obj.countPreConditions() )
                    {
                        Generated.PreCondition element = obj.getPreConditions( i );
                        ensureGuidPreCondition ( element, null );
                        i += 1;
                    }
                    while ( i < other.countPreConditions() )
                    {
                        Generated.PreCondition otherElement = other.getPreConditions( i );
                        ensureGuidPreCondition ( null, otherElement );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.PreCondition subElement in obj.allPreConditions() )
                    {
                        ensureGuidPreCondition ( subElement, null );
                    }
                }
            }
            else
            {
                if ( other.allPreConditions() != null )
                {
                    foreach ( Generated.PreCondition otherElement in other.allPreConditions() )
                    {
                        ensureGuidPreCondition ( null, otherElement );
                    }
                }
            }
            if ( obj.allActions() != null )
            {
                if ( other.allActions() != null )
                {
                    int i = 0;
                    while ( i < obj.countActions() && i < other.countActions() )
                    {
                        Generated.Action element = obj.getActions( i );
                        Generated.Action otherElement = other.getActions( i );
                        ensureGuidAction ( element, otherElement );
                        i += 1;
                    }
                    while ( i < obj.countActions() )
                    {
                        Generated.Action element = obj.getActions( i );
                        ensureGuidAction ( element, null );
                        i += 1;
                    }
                    while ( i < other.countActions() )
                    {
                        Generated.Action otherElement = other.getActions( i );
                        ensureGuidAction ( null, otherElement );
                        i += 1;
                    }
                }
                else
                {
                    foreach ( Generated.Action subElement in obj.allActions() )
                    {
                        ensureGuidAction ( subElement, null );
                    }
                }
            }
            else
            {
                if ( other.allActions() != null )
                {
                    foreach ( Generated.Action otherElement in other.allActions() )
                    {
                        ensureGuidAction ( null, otherElement );
                    }
                }
            }
            if ( obj.allSubRules() != null )
            {
                if ( other.allSubRules() != null )
                {
                    foreach ( Generated.Rule subElement in obj.allSubRules() )
                    {
                        bool found = false;

                        // Try first to assign Guid to elements which do not have a guid
                        // This helps handling duplicated in lists
                        foreach ( Generated.Rule otherElement in other.allSubRules() )
                        {
                            if ( CompareUtil.canonicalStringEquality(subElement.Name, otherElement.Name) && otherElement.getGuid() == null )
                            {
                                ensureGuidRule ( subElement, otherElement );
                                found = true;
                                break;
                            }
                        }

                        if ( !found )
                        {
                            foreach ( Generated.Rule otherElement in other.allSubRules() )
                            {
                                if ( CompareUtil.canonicalStringEquality(subElement.Name, otherElement.Name) )
                                {
                                    ensureGuidRule ( subElement, otherElement );
                                    found = true;
                                    break;
                                }
                            }
                        }

                        if ( !found )
                        {
                            ensureGuidRule ( subElement, null );
                        }
                    }

                    foreach ( Generated.Rule otherElement in other.allSubRules() )
                    {
                        bool found = false;
                        foreach ( Generated.Rule subElement in obj.allSubRules() )
                        {
                            if ( CompareUtil.canonicalStringEquality(subElement.Name, otherElement.Name) )
                            {
                                found = true;
                                break;
                            }
                        }

                        if ( !found )
                        {
                            ensureGuidRule ( null, otherElement );
                        }
                    }
                }
                else
                {
                    foreach ( Generated.Rule subElement in obj.allSubRules() )
                    {
                        ensureGuidRule ( subElement, null );
                    }
                }
            }
            else
            {
                if ( other.allSubRules() != null )
                {
                    foreach ( Generated.Rule otherElement in other.allSubRules() )
                    {
                        ensureGuidRule ( null, otherElement );
                    }
                }
            }
        }