/// <summary>
        /// Try to evaluate the given expression in the context of the variable.
        /// Imagine the variable is a class and the expression is in a method of that class.
        /// Member variables can be accessed and take precedence over global variables of the same name.
        /// Globals can be accessed as well. Returns a variable representing the result of the evaluation
        /// or null if the expression can't be evaluated.
        /// </summary>
        Task <IVariableInformation> EvaluateExpressionInVariableScopeAsync(
            IVariableInformation variable, VsExpression vsExpression, string displayName)
        {
            if (variable.IsPointer || variable.IsReference)
            {
                variable = variable.Dereference();
            }

            return(variable.EvaluateExpressionAsync(displayName, vsExpression));
        }
        /// <summary>
        /// Declare a variable in using the given variable scope to execute the value expression.
        /// Token replacement using scopedNames is done against both the variable name and the
        /// value expression.
        /// </summary>
        /// <exception cref="ExpressionEvaluationFailed">
        /// Expression to declare the variable failed to evaluate.
        /// </exception>
        public async Task DeclareVariableAsync(IVariableInformation variable, string variableName,
                                               string valueExpression, NatvisScope natvisScope)
        {
            string scratchVar =
                ReplaceScopedNames(variableName, natvisScope?.ScopedNames, out bool ignore);
            VsExpression vsExpression = _vsExpressionCreator.Create(valueExpression, "")
                                        .MapValue(e => ReplaceScopedNames(e, natvisScope?.ScopedNames, out ignore));

            // Declare variable and return it. Pure declaration expressions will always return
            // error because these expressions don't return a valid value.
            VsExpression createExpression =
                vsExpression.MapValue(e => $"auto {scratchVar}={e}; {scratchVar}");

            if (variable.IsPointer || variable.IsReference)
            {
                variable = variable.Dereference();
                if (variable == null)
                {
                    string failMsg = $"Failed to dereference pointer: Name: {variableName}";
                    _logger.Error(failMsg);
                    throw new ExpressionEvaluationFailed(failMsg);
                }
            }

            // TODO: Split the logic for LLDB and lldb-eval. Currently, LLDB is always
            // used to create a scratch variable (even if lldb-eval is the selected engine).
            IVariableInformation result =
                await variable.EvaluateExpressionAsync(variableName, createExpression);

            if (result != null && !result.Error && natvisScope != null)
            {
                // Result of 'auto {scratchVar}={e}; {scratchVar}' creates a copy of the scratch
                // variable. Evaluating '{scratchVar}' returns the reference to the original
                // variable. By using the original variable we make sure that the we always use its
                // up-to-date value.
                // TODO: Use RemoteFrame.FindValue to get the scratch variable.
                // EvaluateExpression method already is optimised for the case of fetching scratch
                // variables, but it isn't a convenient one.
                result = await variable.EvaluateExpressionAsync(
                    variableName, _vsExpressionCreator.Create($"{scratchVar}", ""));

                if (result != null && !result.Error)
                {
                    natvisScope.AddContextVariable(scratchVar, result.GetRemoteValue());
                    return;
                }
            }

            string msg = $"Failed to declare variable: Name: {variableName}, " +
                         $"Expression: {valueExpression}";

            string resultMessage = result?.ErrorMessage;

            if (!string.IsNullOrEmpty(resultMessage))
            {
                msg += $", Info: {{{resultMessage}}}";
            }

            _logger.Error(msg);
            throw new ExpressionEvaluationFailed(msg);
        }