private bool disposedValue = false;         // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                try
                {
                    if (!IsExistingDevice)
                    {
                        // disconnect
                        RunAdbGlobalCommand(string.Format("disconnect {0}", DeviceName));

                        Log.Info("Disconnected {0}", DeviceName);
                    }

                    if (Directory.Exists(LocalCachePath))
                    {
                        Directory.Delete(LocalCachePath, true);
                    }
                }
                catch (Exception Ex)
                {
                    Log.Warning("TargetDeviceAndroid.Dispose() threw: {0}", Ex.Message);
                }
                finally
                {
                    disposedValue = true;
                    AdbCredentialCache.RemoveInstance();
                }
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="InReferenceName"></param>
        /// <param name="InRemoveOnDestruction"></param>
        public TargetDeviceAndroid(string InDeviceName = "", AndroidDeviceData DeviceData = null)
        {
            DeviceName = InDeviceName;

            AdbCredentialCache.AddInstance(DeviceData);

            // If no device name or its 'default' then use the first default device
            if (string.IsNullOrEmpty(DeviceName) || DeviceName.Equals("default", StringComparison.OrdinalIgnoreCase))
            {
                var DefaultDevices = GetAllAvailableDevices();

                if (DefaultDevices.Count() == 0)
                {
                    if (GetAllConnectedDevices().Count > 0)
                    {
                        throw new AutomationException("No default device available. One or more devices are connected but unauthorized. See 'adb devices'");
                    }
                    else
                    {
                        throw new AutomationException("No default device available. See 'adb devices'");
                    }
                }

                DeviceName = DefaultDevices.First();
            }

            if (Log.IsVerbose)
            {
                RunOptions = CommandUtils.ERunOptions.NoWaitForExit;
            }
            else
            {
                RunOptions = CommandUtils.ERunOptions.NoWaitForExit | CommandUtils.ERunOptions.NoLoggingOfRunCommand;
            }

            // if this is not a connected device then remove when done
            var ConnectedDevices = GetAllConnectedDevices();

            IsExistingDevice = ConnectedDevices.Keys.Contains(DeviceName);

            if (!IsExistingDevice)
            {
                // adb uses 5555 by default
                if (DeviceName.Contains(":") == false)
                {
                    DeviceName = DeviceName + ":5555";
                }

                lock (Globals.MainLock)
                {
                    using (var PauseEC = new ScopedSuspendECErrorParsing())
                    {
                        IProcessResult AdbResult = RunAdbGlobalCommand(string.Format("connect {0}", DeviceName));

                        if (AdbResult.ExitCode != 0)
                        {
                            throw new AutomationException("adb failed to connect to {0}. {1}", DeviceName, AdbResult.Output);
                        }
                    }

                    Log.Info("Connected to {0}", DeviceName);

                    // Need to sleep for adb service process to register, otherwise get an unauthorized (especially on parallel device use)
                    Thread.Sleep(5000);
                }
            }

            LocalDirectoryMappings = new Dictionary <EIntendedBaseCopyDirectory, string>();

            // for IP devices need to sanitize this
            Name = DeviceName.Replace(":", "_");

            LocalCachePath = Path.Combine(Path.GetTempPath(), "AndroidDevice_" + Name);

            ConnectedDevices = GetAllConnectedDevices();

            SetUpDirectoryMappings();

            // sanity check that it was now dound
            if (ConnectedDevices.Keys.Contains(DeviceName) == false)
            {
                throw new AutomationException("Failed to find new device {0} in connection list", DeviceName);
            }

            if (ConnectedDevices[DeviceName] == false)
            {
                Dispose();
                throw new AutomationException("Device {0} is connected but this PC is not authorized.", DeviceName);
            }
        }