/// <summary>
        /// Explores given variable initializer using C# lookuper
        /// </summary>
        protected virtual void Explore(AbstractBatchCommand parentCommand, CodeVariable2 codeVariable, CodeNamespace parentNamespace, CodeElement2 codeClassOrStruct, Predicate <CodeElement> exploreable, bool isLocalizableFalse)
        {
            if (codeVariable.InitExpression == null)
            {
                return;                                      // variable must have an initializer
            }
            if (codeClassOrStruct.Kind == vsCMElement.vsCMElementStruct && !codeVariable.IsShared)
            {
                return;                                                                                    // instance variable of structs cannot have initializers
            }
            if (!exploreable(codeVariable as CodeElement))
            {
                return;                                     // predicate must evaluate to true
            }
            string initExpression = codeVariable.GetText(); // get text of initializer

            if (string.IsNullOrEmpty(initExpression))
            {
                return;
            }

            TextPoint startPoint = codeVariable.StartPoint;

            // is variable decorated with Localizable(false)
            bool variableLocalizableFalse = (codeVariable as CodeElement).HasLocalizableFalseAttribute();

            // run lookuper using parent command
            var list = parentCommand.LookupInCSharp(initExpression, startPoint, parentNamespace, codeClassOrStruct, null, codeVariable.Name, isLocalizableFalse || variableLocalizableFalse);

            // add context to result items (surounding few lines of code)
            EditPoint2 editPoint = (EditPoint2)startPoint.CreateEditPoint();

            foreach (AbstractResultItem item in list)
            {
                item.IsConst         = codeVariable.ConstKind == vsCMConstKind.vsCMConstKindConst;
                item.CodeModelSource = codeVariable;
                AddContextToItem(item, editPoint);
            }
        }
        /// <summary>
        /// Used by C# ad-hoc methods (move and inline) to get information about the block of code, where right-click was performed.
        /// This methods makes use of document's FileCodeModel, which is not available for ASP .NET files - these files are thus
        /// handled by their own parser.
        /// </summary>
        /// <param name="text">Text of the block (e.g. code of a method, declaration of a variable...)</param>
        /// <param name="startPoint">Beginning of the text</param>
        /// <param name="codeFunctionName">Name of the function, where right-click was performed, null if right-click was performed on a variable.</param>
        /// <param name="codeVariableName">Name of the variable, where right-click was performed, null otherwise.</param>
        /// <param name="codeClass">Name of the class, where the code block is located.</param>
        /// <param name="selectionSpan">Current selection span.</param>
        /// <returns>True, if all necessary information was succesfully obtained, false otherwise.</returns>
        protected bool GetCodeBlockFromSelection(out string text, out TextPoint startPoint, out string codeFunctionName, out string codeVariableName, out CodeElement2 codeClass, out TextSpan selectionSpan, out bool isConst, out object codeModelSource)
        {
            // get current selection span
            TextSpan[] spans = new TextSpan[1];
            int        hr    = textView.GetSelectionSpan(spans);

            Marshal.ThrowExceptionForHR(hr);

            selectionSpan = spans[0];

            object o;

            hr = textLines.CreateTextPoint(selectionSpan.iStartLine, selectionSpan.iStartIndex, out o);
            Marshal.ThrowExceptionForHR(hr);
            TextPoint selectionPoint = (TextPoint)o;

            startPoint = null;
            text       = null;
            bool ok = false;

            codeFunctionName = null;
            codeVariableName = null;
            codeClass        = null;
            isConst          = false;
            codeModelSource  = null;

            // It is impossible to find out the code block, where right-click was performed. Following code
            // assumes that valid string literals or references can only be found in a method, in a class variable (as initializers)
            // or in a property code. C# syntax permits more locations (attributes, default argument values in .NET 4+) but we can ignore
            // these, because they are all evaluated at compile-time, making resource references impossible.

            // assume we are in a function (method)
            try {
                CodeFunction2 codeFunction = (CodeFunction2)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementFunction);
                codeFunctionName = codeFunction.Name;
                codeClass        = codeFunction.GetClass(); // extension
                codeModelSource  = codeFunction;

                text = codeFunction.GetText();
                if (!string.IsNullOrEmpty(text))
                {
                    startPoint = codeFunction.GetStartPoint(vsCMPart.vsCMPartBody);
                    ok         = true;
                }
            } catch (Exception) {
                // it's not a method - maybe a property?
                try {
                    CodeProperty codeProperty = (CodeProperty)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementProperty);
                    codeFunctionName = codeProperty.Name;
                    codeClass        = codeProperty.GetClass();
                    codeModelSource  = codeProperty;
                    text             = codeProperty.GetText();

                    if (!string.IsNullOrEmpty(text))
                    {
                        startPoint = codeProperty.GetStartPoint(vsCMPart.vsCMPartBody);
                        ok         = true;
                    }
                } catch (Exception) {
                    // not a property, either. It must be a variable - or there's no valid code block
                    try {
                        CodeVariable2 codeVariable = (CodeVariable2)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementVariable);
                        if (codeVariable.InitExpression != null)
                        {
                            codeVariableName = codeVariable.Name;
                            codeClass        = codeVariable.GetClass();
                            isConst          = codeVariable.ConstKind == vsCMConstKind.vsCMConstKindConst;
                            codeModelSource  = codeVariable;

                            startPoint = codeVariable.StartPoint;
                            text       = codeVariable.GetText();
                            if ((codeClass.Kind == vsCMElement.vsCMElementStruct && codeVariable.IsShared) ||
                                (codeClass.Kind == vsCMElement.vsCMElementClass || codeClass.Kind == vsCMElement.vsCMElementModule) &&
                                !string.IsNullOrEmpty(text))
                            {
                                ok = true;
                            }
                        }
                    } catch (Exception) {
                        return(false);
                    }
                }
            }

            return(ok);
        }