public override void Execute(IEnumerable <CodeFile> input, IMetadataRecorder metadataRecorder, IMetadataReader metadataReader, ILogger logger)
        {
            if (input.Any(file => !(file is TCodeFile)))
            {
                throw new InvalidOperationException($"Plugin supports only {typeof(TCodeFile)} as input.");
            }

            var inputConcrete = input.Cast <TCodeFile>();

            List <IFileGroup <TCodeFile, GroupItemDetails> > groups = null;

            if (this.InputAggregator != null)
            {
                groups = new List <IFileGroup <TCodeFile, GroupItemDetails> >(this.InputAggregator.Aggregate(inputConcrete));
            }
            else
            {
                var defaultGroup = new FileGroup <TCodeFile, GroupItemDetails>()
                {
                    Name = DefaultGroupName
                };

                foreach (var i in inputConcrete)
                {
                    defaultGroup.Files.Add(i, new GroupItemDetails());
                }

                groups = new List <IFileGroup <TCodeFile, GroupItemDetails> >()
                {
                    defaultGroup
                };
            }

            foreach (var group in groups)
            {
                var inputGroup = new FileGroup <TCodeFile, GroupItemDetailsParametrized <TInputParameters> >();
                inputGroup.Name = group.Name;

                foreach (var file in group.Files)
                {
                    var metadata = this.Preprocessor.GenerateParameters(file.Key, this.Settings, metadataReader, logger, group);
                    inputGroup.Files.Add(file.Key, new GroupItemDetailsParametrized <TInputParameters>(metadata, file.Value.GroupingTags));
                }

                this.Implementation(inputGroup, metadataRecorder, logger);
            }
        }
        public IEnumerable <IFileGroup <TFile, GroupItemDetails> > Aggregate(IEnumerable <TFile> input)
        {
            var unmatchedGroup = new FileGroup <TFile, GroupItemDetails>()
            {
                Name = this.unmatchedGroupName
            };

            Dictionary <string, FileGroup <TFile, GroupItemDetails> > groups = new Dictionary <string, FileGroup <TFile, GroupItemDetails> >();

            foreach (var file in input)
            {
                var matched = false;
                foreach (var groupSetting in this.groupSettings)
                {
                    var match = Regex.Match(file.Name, groupSetting.Regex);
                    if (match.Success)
                    {
                        this.AddOutputGroup(match.Groups[groupSetting.NameMatchGroupIndex].Value, groupSetting.Tag, file, groups);
                        matched = true;
                        break;
                    }
                }

                if (!matched)
                {
                    unmatchedGroup.Files.Add(file, new GroupItemDetails());
                }
            }

            if (unmatchedGroup.Files.Count > 0)
            {
                groups.Add(unmatchedGroup.Name, unmatchedGroup);
            }

            return(groups.Values);
        }
 protected abstract void Implementation(FileGroup <TCodeFile, GroupItemDetailsParametrized <TInputParameters> > group, IMetadataRecorder metadataRecorder, ILogger logger);