/// <summary>
        /// Gets the pattern implementations.
        /// </summary>
        /// <param name="pattern">The pattern.</param>
        /// <param name="componentMatches">The component matches.</param>
        /// <returns>A list of pattern implementations that need to be checked on completeness</returns>
        private List <Dictionary <Component, List <ComponentMatch> > > GetPatternImplementations(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > componentMatches)
        {
            this.possibleImplementations = new List <Dictionary <Component, List <ComponentMatch> > >();
            var singularComponentNames = graph.GetSingularComponentNames();

            if (singularComponentNames.Count == 0)
            {
                // Todo. Not supported for v1. - Removed exception, just return null.
                return(null);
            }

            var startGraphComponent   = graph.GetGraphComponent(singularComponentNames[0]);
            var startComponentMatches = componentMatches[startGraphComponent.Component];

            foreach (var startComponentMatch in startComponentMatches)
            {
                this.possibleImplementations.Add(new Dictionary <Component, List <ComponentMatch> >()
                {
                    { startGraphComponent.Component, new List <ComponentMatch>()
                      {
                          startComponentMatch
                      } }
                });
            }

            var foundComponents = new List <GraphComponent>()
            {
                startGraphComponent
            };

            return(this.MapImplementations(graph, foundComponents, componentMatches));
        }
        /// <summary>
        /// Matches the component match types, with the implementations.
        /// </summary>
        /// <param name="graph">The graph.</param>
        /// <param name="possibleImplementation">The possible implementation.</param>
        private Dictionary <Component, List <ComponentMatch> > MatchImplementationComponentTypes(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > possibleImplementation)
        {
            var componentsToRemove = new List <Component>();

            foreach (var componentToCheck in possibleImplementation)
            {
                var componentToCheckMatch = componentToCheck.Value[0];
                var currentComponent      = componentToCheck.Key;
                var currentGraphComponent = graph.GetGraphComponent(currentComponent.Name);

                var otherComponents      = possibleImplementation.Where(i => i.Key != currentComponent);
                var otherGraphComponents = graph.GetGraphComponents(otherComponents.Select(c => c.Key.Name));

                var currentComponentReferences   = currentGraphComponent.References;
                var currentComponentReferencedBy = otherGraphComponents.Where(c => c.References.Any(r => r.ReferencedComponent == currentGraphComponent));

                var typeMatch = true;

                foreach (var currentComponentReference in currentComponentReferences)
                {
                    var knownParentTypes = this.GetSymbolInformation(possibleImplementation, currentComponentReference.ReferencedComponent.Component);
                    typeMatch &= this.MatchUnknownChildWithKnownParent(componentToCheckMatch, knownParentTypes, currentComponentReference);
                }

                foreach (var referencedBy in currentComponentReferencedBy)
                {
                    var knownChildTypes = this.GetSymbolInformation(possibleImplementation, referencedBy.Component);
                    var reference       = referencedBy.References.Single(r => r.ReferencedComponent == currentGraphComponent);
                    typeMatch &= this.MatchKnownChildWithUnknownParent(knownChildTypes, componentToCheckMatch, reference);
                }

                // if there is no match, remove the first hit from the pattern. The pattern is incomplete.
                if (!typeMatch)
                {
                    componentsToRemove.Add(currentGraphComponent.Component);
                }
            }

            foreach (var componentToRemove in componentsToRemove)
            {
                possibleImplementation.Remove(componentToRemove);
            }

            return(possibleImplementation);
        }
        /// <summary>
        /// Matches the remaining component.
        /// </summary>
        /// <param name="graph">The graph.</param>
        /// <param name="remainingMatch">The remaining match.</param>
        /// <param name="foundComponents">The found components.</param>
        /// <returns>The component if it has been matched, null otherwise.</returns>
        private GraphComponent MatchRemainingComponent(PatternGraph graph, KeyValuePair <Component, List <ComponentMatch> > remainingMatch, List <GraphComponent> foundComponents)
        {
            var componentMatchFound = false;

            // check if the component inherits any found components
            var remainingMatchGraphComponent = graph.GetGraphComponent(remainingMatch.Key.Name);
            var foundComponentReferences     = remainingMatchGraphComponent.References.Where(r => foundComponents.Contains(r.ReferencedComponent));

            if (foundComponentReferences.Any())
            {
                var componentRef = foundComponentReferences.First();

                this.MatchComponentTypes(remainingMatchGraphComponent, componentRef.ReferencedComponent, componentRef, remainingMatch.Value, true);
                componentMatchFound = true;
            }
            else
            {
                // otherwise check if the component is inherited by any found components
                var referencedByFoundComponents = foundComponents.Where(c => c.References.Any(r => r.ReferencedComponent == remainingMatchGraphComponent));

                if (referencedByFoundComponents.Any())
                {
                    var refByComponent          = referencedByFoundComponents.First();
                    var refByComponentReference = refByComponent.References.Single(r => r.ReferencedComponent == remainingMatchGraphComponent);

                    this.MatchComponentTypes(refByComponent, remainingMatchGraphComponent, refByComponentReference, remainingMatch.Value, false);
                    componentMatchFound = true;
                }
            }

            if (componentMatchFound)
            {
                return(remainingMatchGraphComponent);
            }

            return(null);
        }