/// <summary>
        /// <see cref="ITypeAutomataBuilder.Build"/>
        /// </summary>
        public override IDeterministicAutomata<MethodInfo> Build(IDeterministicAutomata<MethodInfo> aggregatedAutomata)
        {
            IDictionary<string, ICollection<MethodInfo>> scopesToMandatoryMethods =
                GatherScopesMandatoryMethods();

            ICollection<MethodInfo> alphabet = aggregatedAutomata.Alphabet;

            var scopesToMandatoryValidation =
                scopesToMandatoryMethods.ToDictionary
                    (x => x.Key,
                     x =>
                     (IDeterministicAutomata<MethodInfo>)FundamentalAutomatas.SymbolsAppearFirst
                         (alphabet,
                          x.Value,
                          GetScopeResetTokens(x.Key,
                                              alphabet),
                          new ToStringComparer<MethodInfo>()));

            IDeterministicAutomata<MethodInfo> mandatoryValidation = LinkScopes(scopesToMandatoryValidation);

            IDeterministicAutomata<MethodInfo> result =
                aggregatedAutomata.Intersect(mandatoryValidation);

            result.Alphabet.AddRange(alphabet);

            return result;
        }
        /// <summary>
        /// <see cref="ITypeAutomataBuilder.Build"/>.
        /// Builds a uniquess validation automata.
        /// </summary>
        public override IDeterministicAutomata<MethodInfo> Build(IDeterministicAutomata<MethodInfo> aggregatedAutomata)
        {
            IDictionary<string, ICollection<MethodInfo>> aliasesToMethods =
                GatherAliasesToMethods();

            IDictionary<string, ICollection<string>> scopesToConstraints =
                GatherScopeConstraints();

            ICollection<MethodInfo> alphabet = aggregatedAutomata.Alphabet;

            Dictionary<string, IDeterministicAutomata<MethodInfo>> scopesToUniquenessValidation =
                scopesToConstraints.ToDictionary
                    (x => x.Key,
                     x => BuildScopeValidation(x.Key,
                                               x.Value.Select(y => aliasesToMethods[y]),
                                               alphabet));

            IDeterministicAutomata<MethodInfo> linkedScopes =
                LinkScopes(scopesToUniquenessValidation);

            IExtendableDeterministicAutomata<MethodInfo> result =
                linkedScopes.Intersect(aggregatedAutomata);

            result.Alphabet.AddRange(aggregatedAutomata.Alphabet);

            return result;
        }
        /// <summary>
        /// <see cref="ITypeAutomataBuilder.Build"/>
        /// </summary>
        public IDeterministicAutomata<MethodInfo> Build(IDeterministicAutomata<MethodInfo> aggregatedAutomata)
        {
            IDeterministicAutomata<MethodInfo> result = aggregatedAutomata;

            foreach (ITypeAutomataBuilder builder in mBuilders)
            {
                result = builder.Build(result);
            }

            return result;
        }
        /// <summary>
        /// <see cref="ITypeAutomataBuilder.Build"/>
        /// </summary>
        public IDeterministicAutomata<MethodInfo> Build(IDeterministicAutomata<MethodInfo> aggregatedAutomata)
        {
            IDictionary<Type, ICollection<MethodInfo>> typeToMethods =
                GatherTypeToMethods();

            ICollection<MethodInfo> alphabet =
                typeToMethods.Values.SelectMany(x => x)
                    .Distinct(new ToStringComparer<MethodInfo>())
                    .ToList();

            IDictionary<Type, IExtendableDeterministicAutomata<MethodInfo>> typeToAutomata =
                typeToMethods.ToDictionary
                    (x => x.Key,
                     x => FundamentalAutomatas.OnlySymbolsAreLegal(alphabet, x.Value, new ToStringComparer<MethodInfo>()),
                     new ToStringComparer<Type>());

            IExtendableDeterministicAutomata<MethodInfo> result =
                new DeterministicAutomata<MethodInfo>(new ToStringComparer<MethodInfo>());

            result.Alphabet.AddRange(alphabet);

            foreach (KeyValuePair<Type, ICollection<MethodInfo>> typeToMethod in typeToMethods)
            {
                IExtendableDeterministicAutomata<MethodInfo> currentTypeAutomata =
                    typeToAutomata[typeToMethod.Key];

                foreach (var method in typeToMethod.Value)
                {
                    // Yuck cast...
                    ((IExtendableAutomataState<MethodInfo>)currentTypeAutomata.Root)
                        .Add(method,
                             typeToAutomata[method.ReturnType].Root);
                }

                result.AddRange(currentTypeAutomata);
            }

            return result.Intersect(aggregatedAutomata);
        }
 /// <summary>
 /// Creates a new <see cref="AutomataNamespaceBuilder"/> given 
 /// a <see cref="IDeterministicAutomata{T}"/> of <see cref="MethodInfo"/>.
 /// </summary>
 /// <param name="automata">The given <see cref="IDeterministicAutomata{T}"/>.</param>
 public AutomataNamespaceBuilder(IDeterministicAutomata<MethodInfo> automata)
 {
     mAutomata = automata;
     mAlphabet = automata.Alphabet;
 }
 /// <summary>
 /// <see cref="ITypeAutomataBuilder.Build"/>
 /// </summary>
 public abstract IDeterministicAutomata<MethodInfo> Build(IDeterministicAutomata<MethodInfo> aggregatedAutomata);