/// <summary>
        /// Adds new result item to the list of results
        /// </summary>
        private AspNetStringResultItem AddResult(AttributeInfo info, string elementPrefix, string elementName, bool comesFromClientComment,
                                                 bool propertyLocalizableFalse, bool comesFromElement, bool stripApos)
        {
            if (!(parentCommand is BatchMoveCommand))
            {
                return(null);
            }

            BatchMoveCommand bCmd = (BatchMoveCommand)parentCommand;

            if (stripApos)
            {
                info.BlockSpan.Move(1, 0);
            }

            TextSpan span = new TextSpan();

            span.iStartLine  = info.BlockSpan.StartLine;
            span.iStartIndex = info.BlockSpan.StartIndex + (stripApos ? 1 : 0);
            span.iEndLine    = info.BlockSpan.EndLine;
            span.iEndIndex   = info.BlockSpan.EndIndex - (stripApos ? 1 : 0);

            AspNetStringResultItem resultItem = new AspNetStringResultItem();

            resultItem.Value                            = info.Value.ConvertAspNetEscapeSequences().Trim();
            resultItem.ReplaceSpan                      = span;
            resultItem.AbsoluteCharOffset               = info.BlockSpan.AbsoluteCharOffset + (stripApos ? 2 : 0);
            resultItem.AbsoluteCharLength               = info.Value.Length;
            resultItem.WasVerbatim                      = false;
            resultItem.IsWithinLocalizableFalse         = propertyLocalizableFalse;
            resultItem.IsMarkedWithUnlocalizableComment = false;
            resultItem.ClassOrStructElementName         = ClassFileName;
            resultItem.DeclaredNamespaces               = declaredNamespaces;
            resultItem.ComesFromElement                 = comesFromElement;
            resultItem.ComesFromClientComment           = comesFromClientComment;
            resultItem.ElementPrefix                    = elementPrefix;
            resultItem.ElementName                      = elementName;
            resultItem.Language                         = fileLanguage == FILETYPE.CSHARP ? LANGUAGE.CSHARP : LANGUAGE.VB;
            resultItem.AttributeName                    = info.Name;

            AddContextToItem(resultItem);

            bCmd.AddToResults(resultItem);

            return(resultItem);
        }
        /// <summary>
        /// Called after code block &lt;% %&gt;
        /// </summary>
        public void OnCodeBlock(CodeBlockContext context)
        {
            context.InnerBlockSpan.Move(1, 1); // fix numbering

            // run parent command methods, adding found result items to results
            IList list = null;

            try {
                if (fileLanguage == FILETYPE.CSHARP)
                {
                    list = parentCommand.LookupInCSharpAspNet(context.BlockText, context.InnerBlockSpan, declaredNamespaces, ClassFileName);
                }
                else if (fileLanguage == FILETYPE.VB)
                {
                    list = parentCommand.LookupInVBAspNet(context.BlockText, context.InnerBlockSpan, declaredNamespaces, ClassFileName);
                }
            } catch (Exception ex) {
                if (!(parentCommand is ReferenceLister))
                {
                    VLOutputWindow.VisualLocalizerPane.WriteLine("\tException occured while processing " + projectItem.Name);
                    VLOutputWindow.VisualLocalizerPane.WriteException(ex);
                }
            }

            if (list != null)
            {
                foreach (AbstractResultItem item in list)
                {
                    AspNetStringResultItem aitem = item as AspNetStringResultItem;
                    if (aitem != null)
                    {
                        aitem.ComesFromClientComment   = context.WithinClientSideComment;
                        aitem.ComesFromCodeBlock       = true;
                        aitem.ClassOrStructElementName = ClassFileName;
                    }
                }

                AddContextToItems((IEnumerable)list);
            }
        }
        /// <summary>
        /// Called after beginnnig tag is read
        /// </summary>
        public void OnElementBegin(ElementContext context)
        {
            if (!context.IsEnd)
            {
                openedElements.Push(context);
            }

            if (parentCommand is BatchMoveCommand)   // no resource references can be directly in the attributes, safe to look only for string literals
            {
                foreach (var info in context.Attributes)
                {
                    if (info.ContainsAspTags)
                    {
                        continue;                       // attribute's value contains &lt;%= - like tags - localization is not desirable
                    }
                    if (ShouldIgnoreThisAttribute(context.ElementName, info.Name))
                    {
                        continue;                                              // attribute is not localizable
                    }
                    if (Settings.SettingsObject.Instance.UseReflectionInAsp)   // attempt to resolve type
                    {
                        bool isLocalizableFalse;
                        bool?isString = webConfig.IsTypeof(context.Prefix, context.ElementName, info.Name, typeof(string), out isLocalizableFalse);

                        AspNetStringResultItem newItem = null;
                        if (isString == null || isString.Value)   // add to results if resolution returned true or was not conclusive
                        {
                            newItem = AddResult(info, context, false);
                            newItem.IsWithinLocalizableFalse = isLocalizableFalse;
                            newItem.LocalizabilityProved     = isString.HasValue && isString.Value;
                        }
                    }
                    else     // type resolution not enabled
                    {
                        AddResult(info, context, false);
                    }
                }
            }
        }
        /// <summary>
        /// Called after page directive &lt;%@ %&gt;
        /// </summary>
        public void OnPageDirective(DirectiveContext context)
        {
            // add new imported namespace
            if (context.DirectiveName == "Import" && context.Attributes.Exists((info) => { return(info.Name == "Namespace"); }))
            {
                declaredNamespaces.Add(new UsedNamespaceItem(context.Attributes.Find((info) => { return(info.Name == "Namespace"); }).Value, null, true));
            }
            if (context.DirectiveName == "Page" || context.DirectiveName == "Control")
            {
                string lang = null; // value of Language attribute
                string ext  = null; // extension of the code-behind file
                foreach (var info in context.Attributes)
                {
                    if (info.Name == "Language")
                    {
                        lang = info.Value;         // get file language
                    }
                    if (info.Name == "CodeFile")   // get code-behind file
                    {
                        int index = info.Value.LastIndexOf('.');
                        if (index != -1 && index + 1 < info.Value.Length)
                        {
                            ext = info.Value.Substring(index + 1);
                        }
                    }
                }
                if (string.IsNullOrEmpty(lang))
                {
                    if (!string.IsNullOrEmpty(ext))   // infer file language from the extension
                    {
                        fileLanguage = StringConstants.CsExtensions.Contains(ext.ToLower()) ? FILETYPE.CSHARP : FILETYPE.VB;
                    }
                }
                else
                {
                    fileLanguage = lang == "C#" ? FILETYPE.CSHARP : FILETYPE.VB;
                }
            }
            if (context.DirectiveName == "Register")
            {
                string assembly = null, nmspc = null, src = null, tagName = null, tagPrefix = null;
                foreach (AttributeInfo info in context.Attributes)
                {
                    if (info.Name == "Assembly")
                    {
                        assembly = info.Value;
                    }
                    if (info.Name == "Namespace")
                    {
                        nmspc = info.Value;
                    }
                    if (info.Name == "Src")
                    {
                        src = info.Value;
                    }
                    if (info.Name == "TagName")
                    {
                        tagName = info.Value;
                    }
                    if (info.Name == "TagPrefix")
                    {
                        tagPrefix = info.Value;
                    }
                }
                // add definitions of elements for future type resolution
                if (!string.IsNullOrEmpty(tagPrefix))
                {
                    if (!string.IsNullOrEmpty(assembly) && !string.IsNullOrEmpty(nmspc))
                    {
                        if (webConfig != null)
                        {
                            webConfig.AddTagPrefixDefinition(new TagPrefixAssemblyDefinition(assembly, nmspc, tagPrefix));
                        }
                    }
                    else if (!string.IsNullOrEmpty(tagName) && !string.IsNullOrEmpty(src))
                    {
                        if (webConfig != null)
                        {
                            webConfig.AddTagPrefixDefinition(new TagPrefixSourceDefinition(projectItem,
                                                                                           VisualLocalizerPackage.Instance.DTE.Solution, tagName, src, tagPrefix));
                        }
                    }
                }
            }

            if (parentCommand is BatchMoveCommand)   // no resource references can be directly in the attributes, safe to look only for string literals
            {
                foreach (AttributeInfo info in context.Attributes)
                {
                    if (info.ContainsAspTags)
                    {
                        continue;                       // attribute's value contains &lt;%= - like tags - localization is not desirable
                    }
                    if (info.Name.ToLower() == "language")
                    {
                        continue;
                    }

                    AspNetStringResultItem item = AddResult(info, null, context.DirectiveName, context.WithinClientSideComment, false, false, true);
                    if (item != null)
                    {
                        item.ComesFromDirective = true;
                        item.AttributeName      = info.Name;
                    }
                }
            }
        }