public static IEnumerable <RegistryObject> WalkHive(RegistryHive Hive, string startingKey = null)
        {
            Stack <RegistryKey> keys = new Stack <RegistryKey>();

            RegistryKey x86_View = null, x64_View = null;

            try
            {
                x86_View = RegistryKey.OpenBaseKey(Hive, RegistryView.Registry32);
            }
            catch (Exception e) when(
                e is IOException ||
                e is ArgumentException ||
                e is UnauthorizedAccessException ||
                e is System.Security.SecurityException)
            {
            }
            try
            {
                x64_View = RegistryKey.OpenBaseKey(Hive, RegistryView.Registry32);
            }
            catch (Exception e) when(
                e is IOException ||
                e is ArgumentException ||
                e is UnauthorizedAccessException ||
                e is System.Security.SecurityException)
            {
            }

            if (x86_View != null)
            {
                if (startingKey != null)
                {
                    x86_View = x86_View.OpenSubKey(startingKey);
                }
                keys.Push(x86_View);
            }

            if (x64_View != null)
            {
                if (startingKey != null)
                {
                    x64_View = x64_View.OpenSubKey(startingKey);
                }
                keys.Push(x64_View);
            }

            while (keys.Count > 0)
            {
                RegistryKey currentKey = keys.Pop();

                if (currentKey == null)
                {
                    continue;
                }
                if (Filter.IsFiltered(AsaHelpers.GetPlatformString(), "Scan", "Registry", "Key", currentKey.Name))
                {
                    continue;
                }

                // First push all the new subkeys onto our stack.
                foreach (string key in currentKey.GetSubKeyNames())
                {
                    try
                    {
                        var next = currentKey.OpenSubKey(name: key, writable: false);
                        keys.Push(next);
                    }
                    // These are expected as we are running as administrator, not System.
                    catch (System.Security.SecurityException e)
                    {
                        Log.Verbose(e, "Permission Denied: {0}", currentKey.Name);
                    }
                    // There seem to be some keys which are listed as existing by the APIs but don't actually exist.
                    // Unclear if these are just super transient keys or what the other cause might be.
                    // Since this isn't user actionable, also just supress these to the verbose stream.
                    catch (System.IO.IOException e)
                    {
                        Log.Verbose(e, "Error Reading: {0}", currentKey.Name);
                    }
                    catch (Exception e)
                    {
                        Log.Information(e, "Unexpected error when parsing {0}:", currentKey.Name);
                        AsaTelemetry.TrackTrace(Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Error, e);
                    }
                }

                var regObj = RegistryKeyToRegistryObject(currentKey);

                if (regObj != null)
                {
                    yield return(regObj);
                }
            }

            x86_View.Dispose();
            x64_View.Dispose();
        }