public void ResolvedSinglePartToRuleTemplate(ISoftTemplateReferenceProductionRuleItem item, IOilexerGrammarProductionRuleTemplateEntry primary)
 {
     if (item.PrimaryToken != null)
     {
         this.handler.ReclassifyToken(item.PrimaryToken, primary);
     }
 }
        public static IProductionRuleItem ResolveTemplateSoftReference<T>(this ISoftTemplateReferenceProductionRuleItem item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors)
            where T :
                IOilexerGrammarProductionRuleEntry
        {
            IOilexerGrammarProductionRuleTemplateEntry iprte = null;
            var closeMatches = GetList(new { Entry = (IOilexerGrammarProductionRuleTemplateEntry)null, ArgumentInformation = default(TemplateArgumentInformation) });
            foreach (IOilexerGrammarProductionRuleTemplateEntry template in ruleTemplEntries)
            {
                if (template.Name == item.PrimaryName)
                {
                    TemplateArgumentInformation tai = template.GetArgumentInformation();
                    if (item.Parts.Count >= tai.FixedArguments)
                    {
                        closeMatches.Add(new { Entry = template, ArgumentInformation = tai });
                        if (tai.DynamicArguments > 0)
                        {
                            if ((item.Parts.Count - tai.FixedArguments) % tai.DynamicArguments == 0)
                            {
                                if (tai.InvalidArguments == 0)
                                {
                                    iprte = template;
                                    break;
                                }
                            }
                        }
                        else if (tai.InvalidArguments == 0)
                        {
                            if (item.Parts.Count == tai.FixedArguments)
                            {
                                iprte = template;
                                break;
                            }
                        }
                    }
                    else
                    {
                        closeMatches.Add(new { Entry = template, ArgumentInformation = tai });
                        continue;
                    }
                }
            }

            if (iprte != null)
            {
                foreach (IProductionRuleSeries iprs in item.Parts)
                    iprs.ResolveProductionRuleSeries(entry, file, errors);
                TemplateReferenceProductionRuleItem rResult = new TemplateReferenceProductionRuleItem(iprte, new List<IProductionRuleSeries>(item.Parts.ToArray()), item.Column, item.Line, item.Position);
                if (resolutionAid != null)
                    resolutionAid.ResolvedSinglePartToRuleTemplate(item, iprte);
                if (item.RepeatOptions != ScannableEntryItemRepeatInfo.None)
                    rResult.RepeatOptions = item.RepeatOptions;
                if (item.Name != null && item.Name != string.Empty)
                    rResult.Name = item.Name;
                return rResult;
            }
            else if (closeMatches.Count > 0)
            {
                var fixedMatch = (from templateArguments in closeMatches
                                  let arguments = templateArguments.ArgumentInformation
                                  where arguments.FixedArguments > 0
                                  orderby arguments.FixedArguments descending
                                  select templateArguments.Entry);
                IOilexerGrammarProductionRuleTemplateEntry closestMismatch = null;
                foreach (var mismatch in fixedMatch)
                {
                    if (item.Parts.Count > mismatch.Parts.Count)
                    {
                        closestMismatch = mismatch;
                        break;
                    }
                }
                /**/
                if (closestMismatch == null)
                    closestMismatch = fixedMatch.Last();
                if (fixedMatch != null)
                    errors.SourceModelError<ISoftTemplateReferenceProductionRuleItem, IOilexerGrammarProductionRuleTemplateEntry>(OilexerGrammarCore.CompilerErrors.FixedArgumentMismatch, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, closestMismatch, new string[] { closestMismatch.Name, closestMismatch.Parts.Count.ToString(), item.Parts.Count.ToString() });
                else
                {
                    var dynamicMatch = (from templateArguments in closeMatches
                                        let arguments = templateArguments.ArgumentInformation
                                        where arguments.DynamicArguments > 0
                                        select templateArguments.Entry).FirstOrDefault();
                    if (dynamicMatch != null)
                        errors.SourceModelError<IOilexerGrammarProductionRuleTemplateEntry>(OilexerGrammarCore.CompilerErrors.DynamicArgumentCountError, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), dynamicMatch);
                    else
                    {
                        var invalidMatch = (from templateArguments in closeMatches
                                            let arguments = templateArguments.ArgumentInformation
                                            where arguments.InvalidArguments > 0
                                            select templateArguments.Entry).FirstOrDefault();
                        if (invalidMatch != null)
                            errors.SourceModelError<IOilexerGrammarProductionRuleTemplateEntry>(OilexerGrammarCore.CompilerErrors.InvalidRepeatOptions, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), invalidMatch);
                        else if (ruleEntries.OilexerGrammarFindScannableEntry(item.PrimaryName) != null)
                            errors.SourceModelError<ISoftTemplateReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.RuleNotTemplate, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, item.PrimaryName);
                    }
                }
                //errors.Add(OilexerGrammarCore.GetParserError(entry.FileName, item.Line, item.Column, OilexerGrammarParserErrors.DynamicArgumentCountError));
            }
            else if (ruleEntries.OilexerGrammarFindScannableEntry(item.PrimaryName) != null)
                errors.SourceModelError<ISoftTemplateReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.RuleNotTemplate, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, item.PrimaryName);
            else
            {
                var matches = (from template in ruleTemplEntries
                               where template.Name == item.PrimaryName
                               select template).Count();
                if (matches > 0)
                    errors.SourceError(OilexerGrammarCore.CompilerErrors.FixedArgumentMismatch, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item.PrimaryName);
                else
                    errors.SourceError(OilexerGrammarCore.CompilerErrors.UndefinedRuleReference, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item.PrimaryName);
            }
            return item;
        }

        public static IProductionRuleItem ResolveSoftReference<T>(this ISoftReferenceProductionRuleItem item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors)
            where T :
                IOilexerGrammarProductionRuleEntry
        {
            if (entry is IOilexerGrammarProductionRuleTemplateEntry)
            {
                var templateEntry = entry as IOilexerGrammarProductionRuleTemplateEntry;
                if (string.IsNullOrEmpty(item.SecondaryName))
                    foreach (IProductionRuleTemplatePart iprtp in templateEntry.Parts)
                        if (iprtp.Name == item.PrimaryName)
                        {
                            TemplateParamReferenceProductionRuleItem result = new TemplateParamReferenceProductionRuleItem(templateEntry, iprtp, item.Column, item.Line, item.Position);
                            if (resolutionAid != null)
                                resolutionAid.ResolvedSinglePartToTemplateParameter(templateEntry, iprtp, item);
                            if (item.RepeatOptions != ScannableEntryItemRepeatInfo.None)
                                result.RepeatOptions = item.RepeatOptions;
                            if (item.Name != null && result.Name == null)
                                result.Name = item.Name;
                            return result;
                        }
            }
            IOilexerGrammarProductionRuleEntry ipre = ruleEntries.OilexerGrammarFindScannableEntry(item.PrimaryName);
            if (ipre != null)
            {
                RuleReferenceProductionRuleItem rrpri = new RuleReferenceProductionRuleItem(ipre, item.Column, item.Line, item.Position);
                if (resolutionAid != null)
                    resolutionAid.ResolvedSinglePartToRule(item, ipre);
                ((ProductionRuleItem)(item)).CloneData(rrpri);
                return rrpri;
            }
            else if (ruleTemplEntries.OilexerGrammarFindScannableEntry(item.PrimaryName) != null)
                errors.SourceModelError<ISoftReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.RuleIsTemplate, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, item.PrimaryName);
            else
            {
                IOilexerGrammarTokenEntry tokenE = tokenEntries.OilexerGrammarFindScannableEntry(item.PrimaryName);
                if (tokenE != null)
                    if (item.SecondaryName != null)
                    {
                        ITokenItem iti = tokenE.FindTokenItem(item.SecondaryName);
                        if (iti != null)
                        {
                            IProductionRuleItem result = null;
                            if (iti is ILiteralCharTokenItem)
                            {
                                if (resolutionAid != null)
                                    resolutionAid.ResolvedDualPartToTokenItem(item, tokenE, iti);
                                result = new LiteralCharReferenceProductionRuleItem(((ILiteralCharTokenItem)(iti)), tokenE, item.Column, item.Line, item.Position, item.IsFlag, item.Counter);
                            }
                            else if (iti is ILiteralStringTokenItem)
                            {
                                if (resolutionAid != null)
                                    resolutionAid.ResolvedDualPartToTokenItem(item, tokenE, iti);
                                result = new LiteralStringReferenceProductionRuleItem(((ILiteralStringTokenItem)(iti)), tokenE, item.Column, item.Line, item.Position, item.IsFlag, item.Counter);
                            }
                            else
                            {
                                /* *
                                 * ToDo: Throw an error here for referencing the wrong type of token
                                 * */
                            }
                            if (result != null)
                            {
                                result.Name = item.Name;
                                result.RepeatOptions = item.RepeatOptions;
                                return result;
                            }
                        }