internal SampleStackFrame(SampleDebugAdapter adapter, SampleModule module, string functionName, IEnumerable <SampleFunctionArgument> args, string fileName, int line, int column)
            : base(adapter)
        {
            this.childScopes = new List <SampleScope>();

            this.localsScope = new SampleScope(this.Adapter, "Locals", false);

            this.Module       = module;
            this.FunctionName = functionName;
            this.FileName     = fileName;
            this.Line         = line;
            this.Column       = column;

            if (args != null && args.Any())
            {
                this.Args      = args.ToList();
                this.argsScope = new SampleScope(this.Adapter, "Arguments", false);

                foreach (SampleFunctionArgument arg in args)
                {
                    SimpleVariable variable = new SimpleVariable(
                        adapter: this.Adapter,
                        name: arg.Name,
                        type: arg.Type,
                        value: arg.Value);

                    this.argsScope.AddVariable(variable);
                }
            }
            else
            {
                this.Args = Enumerable.Empty <SampleFunctionArgument>().ToList();;
            }
        }
        private bool DoPushStackFrame(PushStackFrameArgs args, StringBuilder output)
        {
            List <SampleFunctionArgument> stackArgs = null;

            if (args.ArgName != null && args.ArgName.Length > 0)
            {
                if (args.ArgType == null || args.ArgType.Length != args.ArgName.Length ||
                    args.ArgValue == null || args.ArgValue.Length != args.ArgName.Length)
                {
                    output.AppendLine("Error: Must have same number of -argName, -argType, and -argValue arguments!");
                    return(false);
                }

                stackArgs = new List <SampleFunctionArgument>();
                for (int i = 0; i < args.ArgName.Length; i++)
                {
                    stackArgs.Add(new SampleFunctionArgument(args.ArgType[i], args.ArgName[i], args.ArgValue[i]));
                }
            }

            SampleModule module = null;

            if (!String.IsNullOrEmpty(args.ModuleId))
            {
                module = this.adapter.ModuleManager.GetModuleById(args.ModuleId);
                if (module == null)
                {
                    output.AppendLine(Invariant($"Error: Unknown module id '{args.ModuleId}'!"));
                    return(false);
                }
            }

            SampleThread targetThread = this.GetThread(args.ThreadId);

            if (targetThread == null)
            {
                output.AppendLine(Invariant($"Error: Unknown thread id '{args.ThreadId}'!"));
                return(false);
            }

            targetThread.PushStackFrame(new SampleStackFrame(this.adapter, module, args.Name, stackArgs, this.adapter.Source.Path, 0, 0));

            return(true);
        }
        private bool DoUnloadModule(UnloadModuleArgs args, StringBuilder output)
        {
            SampleModule module = this.loadedModules.FirstOrDefault(m => String.Equals(m.Name, args.ModuleName, StringComparison.OrdinalIgnoreCase));

            if (module == null)
            {
                output.AppendLine(Invariant($"Error: Unknown module '{args.ModuleName}'!"));
                return(false);
            }

            output.AppendLine(Invariant($"Unloading module '{args.ModuleName}'"));
            this.adapter.Protocol.SendEvent(
                new ModuleEvent(
                    reason: ModuleEvent.ReasonValue.Removed,
                    module: new Module(
                        id: module.Id,
                        name: null)));

            return(true);
        }
        private bool DoLoadModule(LoadModuleArgs args, StringBuilder output)
        {
            SampleModule module;

            if (String.IsNullOrEmpty(args.Id))
            {
                module = new SampleModule(args.ModuleName);
            }
            else
            {
                module = new SampleModule(args.Id, args.ModuleName);
            }

            bool shouldPopulateRandom = true;

            if (!String.IsNullOrEmpty(args.Version))
            {
                module.Version       = args.Version;
                shouldPopulateRandom = false;
            }

            if (!String.IsNullOrEmpty(args.SymbolStatus))
            {
                module.SymbolStatus  = args.SymbolStatus;
                shouldPopulateRandom = false;
            }

            if (!String.IsNullOrEmpty(args.LoadAddress))
            {
                NumberStyles styles = NumberStyles.Number;
                if (args.LoadAddress.StartsWith("0x", StringComparison.Ordinal))
                {
                    args.LoadAddress = args.LoadAddress.Substring(2);
                    styles           = NumberStyles.HexNumber;
                }

                ulong addr;
                if (UInt64.TryParse(args.LoadAddress, styles, CultureInfo.InvariantCulture, out addr))
                {
                    module.LoadAddress   = addr;
                    shouldPopulateRandom = false;
                }
                else
                {
                    output.AppendLine(Invariant($"Could not parse '{args.LoadAddress}' as an address!"));
                    return(false);
                }
            }

            if (!String.IsNullOrEmpty(args.PreferredLoadAddress))
            {
                NumberStyles styles = NumberStyles.Number;
                if (args.PreferredLoadAddress.StartsWith("0x", StringComparison.Ordinal))
                {
                    args.PreferredLoadAddress = args.PreferredLoadAddress.Substring(2);
                    styles = NumberStyles.HexNumber;
                }

                ulong addr;
                if (UInt64.TryParse(args.PreferredLoadAddress, styles, CultureInfo.InvariantCulture, out addr))
                {
                    module.PreferredLoadAddress = addr;
                    shouldPopulateRandom        = false;
                }
                else
                {
                    output.AppendLine(Invariant($"Could not parse '{args.PreferredLoadAddress}' as an address!"));
                    return(false);
                }
            }

            if (!String.IsNullOrEmpty(args.Size))
            {
                NumberStyles styles = NumberStyles.Number;
                if (args.Size.StartsWith("0x", StringComparison.Ordinal))
                {
                    args.Size = args.Size.Substring(2);
                    styles    = NumberStyles.HexNumber;
                }

                int size;
                if (Int32.TryParse(args.Size, styles, CultureInfo.InvariantCulture, out size))
                {
                    module.Size          = size;
                    shouldPopulateRandom = false;
                }
                else
                {
                    output.AppendLine(Invariant($"Could not parse '{args.Size}' as an integer!"));
                    return(false);
                }
            }

            if (!String.IsNullOrEmpty(args.Timestamp))
            {
                DateTime timestamp;
                if (DateTime.TryParse(args.Timestamp, out timestamp))
                {
                    // We assume the provided date is in the local timezone, so convert to UTC
                    module.TimestampUTC  = timestamp.ToUniversalTime();
                    shouldPopulateRandom = false;
                }
                else
                {
                    output.AppendLine(Invariant($"Could not parse '{args.Timestamp}' as a date / time!"));
                    return(false);
                }
            }

            if (!String.IsNullOrEmpty(args.SymbolFile))
            {
                module.SymbolFile    = args.SymbolFile;
                shouldPopulateRandom = false;
            }

            if (args.Is64Bit.HasValue)
            {
                module.Is64Bit       = args.Is64Bit.Value;
                shouldPopulateRandom = false;
            }

            if (args.IsOptimized.HasValue)
            {
                module.IsOptimized   = args.IsOptimized.Value;
                shouldPopulateRandom = false;
            }

            if (args.IsUserCode.HasValue)
            {
                module.IsUserCode    = args.IsUserCode.Value;
                shouldPopulateRandom = false;
            }

            if (!String.IsNullOrEmpty(args.AppDomain))
            {
                module.AppDomain     = args.AppDomain;
                shouldPopulateRandom = false;
            }

            if (shouldPopulateRandom)
            {
                module.PopulateRandom();
            }

            output.AppendLine(Invariant($"Loading module '{args.ModuleName}'"));

            this.loadedModules.Add(module);

            this.adapter.Protocol.SendEvent(
                new ModuleEvent(
                    reason: ModuleEvent.ReasonValue.New,
                    module: module.GetProtocolModule()));

            return(true);
        }