/// <summary>
        /// Main Detection function.  The main cause of an error here is the inability to connect to the remote
        /// systems registry.  This will most often be down to either the remote registry service not running
        /// or the user having insufficient privilege to access the remote registry
        /// </summary>
        /// <param name="remoteCredentials"></param>
        /// <param name="onlyMicrosoft"></param>
        /// <returns></returns>
        public int Detect(RemoteCredentials remoteCredentials, ref String errorText)
        {
            Layton.Common.Controls.Impersonator impersonator = null;
            String remoteHost            = remoteCredentials.RemoteHost;
            int    status                = 0;
            bool   existingServiceStatus = false;

            try
            {
                // We may want to impersonate a different user so that we can audit remote computers - if so
                // start the impersonation here
                if (remoteCredentials.Username != null && remoteCredentials.Username != "")
                {
                    impersonator = new Impersonator(remoteCredentials.Username, remoteCredentials.Domain, remoteCredentials.Password);
                }

                // Ensure that the remote registry service is running on the remote Asset and that we can
                // connect.  If the service is not active we may start it
                status = ValidateRemoteRegistryService(remoteCredentials, out existingServiceStatus);
                if (status != 0)
                {
                    errorText = "The Remote Registry Service was not active and could not be started";
                    return(status);
                }

                // Now begin the audit
                this.ReadPublisherMappings();
                this._applicationSerials.Detect(remoteHost);
                RegistryKey    rootCUKey;
                RegistryAccess registryAccess = new RegistryAccess();
                RegistryKey    rootLMKey      = null;

                // Attempt to connect to the remote registry and open the HKEY_LOCAL_MACHINE key
                status = registryAccess.OpenRegistry(Registry.LocalMachine, remoteHost, out rootLMKey);
                if (status != 0)
                {
                    errorText = registryAccess.LastErrorText;
                    return(status);
                }

                // Attempt to connect to the remote registry and open the HKEY_CURRENT_USER key
                status = registryAccess.OpenRegistry(Registry.CurrentUser, remoteHost, out rootCUKey);
                if (status != 0)
                {
                    errorText = registryAccess.LastErrorText;
                    return(status);
                }

                // Open the Softare uninstall key under HKLM and scan it
                RegistryKey uninstallKey = rootLMKey.OpenSubKey(UNINSTALLKEY);
                if (uninstallKey != null)
                {
                    this.ScanUninstallKey(uninstallKey);
                    uninstallKey.Close();
                }

                // Open the software uninstall key under HKCU and scan it
                uninstallKey = rootCUKey.OpenSubKey(UNINSTALLKEY);
                if (uninstallKey != null)
                {
                    this.ScanUninstallKey(uninstallKey);
                    uninstallKey.Close();
                }

                // Scan the Windows installer key
                this.ScanWindowsInstaller(rootLMKey);

                // close all open keys
                rootLMKey.Close();
                rootCUKey.Close();
            }
            catch (Exception ex)
            {
                errorText = "An exception occurred while trying to connect to the system registry on Asset [" + remoteHost + "] - The error was [" + ex.Message + "]";
                return(-1);
            }

            finally
            {
                // Ensure that we restore the initial status of the remote registry service on the target computer
                RestoreRemoteRegistyStatus(remoteCredentials, existingServiceStatus);

                // Displose of any impersonator object if created
                if (impersonator != null)
                {
                    impersonator.Dispose();
                }
            }

            // Iterate through the applications detected by the above and attempt to recover any serial number
            foreach (ApplicationInstance thisApplication in this)
            {
                ApplicationSerial thisSerial = null;
                if (thisApplication.Guid != "")
                {
                    thisSerial = this._applicationSerials.ContainsApplication(thisApplication.Guid);
                }

                if ((thisSerial == null) && (thisApplication.Name != ""))
                {
                    thisSerial = this._applicationSerials.ContainsApplication(thisApplication.Name);
                }

                if (thisSerial != null)
                {
                    thisApplication.Serial = thisSerial;
                    thisSerial.Matched     = true;
                }
            }

            errorText = "";
            return(0);
        }