/// <summary>
        /// Creates a proxy Fluent Method Group.
        /// </summary>
        /// <param name="subjectFluentMethodGroup">the first group that become either subject or gets generalized depending on the generalizeSubject parameter</param>
        /// <param name="secondaryFluentMethodGroup">the second group which is always gets generalized</param>
        /// <param name="generalizeSubject">decides whether the subject fluent method group also needs to be generalized</param>
        /// <returns>proxy fluent method group</returns>
        public static ProxyFluentMethodGroup Create(IFluentMethodGroup subjectFluentMethodGroup, IFluentMethodGroup secondaryFluentMethodGroup, bool generalizeSubject)
        {
            ProxyFluentMethodGroup proxy = Init(subjectFluentMethodGroup);

            //
            if (generalizeSubject)
            {
                proxy.subjectFluentMethodGroup = null;  // No subject, means use nullObjects
                // -- Generalize the subject Fluent Method Group --
                GeneralizedOutput subjectGeneralized = GeneralizedOutput.Generalize(subjectFluentMethodGroup);
                //
                if (!subjectGeneralized.IsEmpty)
                {
                    proxy.generalizedOutputs.Add(subjectGeneralized);
                }
                foreach (var output in subjectGeneralized.GeneralizedOutputs.Where(gop => !gop.IsEmpty))
                {
                    proxy.generalizedOutputs.Add(output);
                }
                //
                proxy.innerMethods.AddRange(subjectFluentMethodGroup.InnerMethods);
                proxy.childFluentMethodGroups.AddRange(subjectFluentMethodGroup.ChildFluentMethodGroups);
            }
            else
            {
                proxy.subjectFluentMethodGroup = subjectFluentMethodGroup;
                //
                foreach (var output in subjectFluentMethodGroup.GeneralizedOutputs.Where(gop => !gop.IsEmpty))
                {
                    proxy.generalizedOutputs.Add(output);
                }
                proxy.innerMethods.AddRange(subjectFluentMethodGroup.InnerMethods);
                proxy.childFluentMethodGroups.AddRange(subjectFluentMethodGroup.ChildFluentMethodGroups);
            }
            //
            // -- Generalize the secondary  Fluent Method Group  --
            GeneralizedOutput secondaryGeneralized = GeneralizedOutput.Generalize(secondaryFluentMethodGroup);

            //
            if (!secondaryGeneralized.IsEmpty)
            {
                proxy.generalizedOutputs.Add(secondaryGeneralized);
            }
            foreach (var output in secondaryGeneralized.GeneralizedOutputs.Where(gop => !gop.IsEmpty))
            {
                proxy.generalizedOutputs.Add(output);
            }
            //
            proxy.innerMethods.AddRange(secondaryFluentMethodGroup.InnerMethods);
            //
            proxy.childFluentMethodGroups.AddRange(secondaryFluentMethodGroup.ChildFluentMethodGroups);
            //
            return(proxy);
        }
        public static GeneralizedOutput Generalize(IFluentMethodGroup fluentMethodGroup)
        {
            GeneralizedOutput generalizedOutput = new GeneralizedOutput(fluentMethodGroup);

            return(generalizedOutput);
        }