/// <summary>
        /// Internal method to set a single color of light.
        /// </summary>
        private bool SetSingleLight(DelcomLightColor color, DelcomLightState newState)
        {
            bool result = false;

            lock (this.lightStates)
            {
                DelcomLightState currentState;
                if (this.lightStates.TryGetValue(color, out currentState) && currentState == newState)
                {
                    // This color is already in appropriate state.
                    result = true;
                }
                else
                {
                    for (int i = 0; i < DelcomLightWrapper.MaxLightRetries; i++)
                    {
                        if (Delcom.DelcomLEDControl(this.deviceHandle, (byte)color, (byte)newState) == 0)
                        {
                            this.lightStates[color] = newState;
                            result = true;
                            break;
                        }
                        else
                        {
                            // Not to log each failure because a) API does not provide any error detail and
                            // b) caller will make an error log if all retries fail.
                            System.Threading.Thread.Sleep(DelcomLightWrapper.LightRetryInterval);
                        }
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// A lLoop in background thread. Change the color of the light and flash.
        /// </summary>
        private void ProcessLightControlRequestsLoop()
        {
            while (true)
            {
                int indexFired = WaitHandle.WaitAny(new WaitHandle[] { this.stopRequested, this.outstandingRequestExist });

                if (indexFired == 0)
                {
                    // this.stopRequested fired. Exit the thread.
                    break;
                }

                LightControlRequest?request = null;
                lock (this.outstandingRequestLock)
                {
                    request = this.outstandingRequest;
                    this.outstandingRequest = null;
                    this.outstandingRequestExist.Reset();
                }

                if (!request.HasValue)
                {
                    // Phantom event. Wait next.
                    continue;
                }
                Trace.TraceInformation("ProcessLightControlRequestsLoop processing: color={0}, flash={1}", request.Value.Color, request.Value.Flash);

                if (request.Value.Color == LightColor.Off)
                {
                    if (!this.wrapper.TurnOffAllLights())
                    {
                        Trace.TraceError("ProcessLightControlRequestsLoop failure: off");
                    }
                    else
                    {
                        TraceVerbose.Trace("ProcessLightControlRequestsLoop success: off");
                    }
                }
                else
                {
                    DelcomLightColor color = ConvertColor(request.Value.Color);
                    DelcomLightState state = request.Value.Flash ? DelcomLightState.Flash : DelcomLightState.On;
                    if (!wrapper.SetLight(color, state))
                    {
                        Trace.TraceError("ProcessLightControlRequestsLoop failure: color={0}, state={1}", color, state);
                    }
                    else
                    {
                        TraceVerbose.Trace("ProcessLightControlRequestsLoop success: color={0}, state={1}", color, state);
                    }
                }
            }
        }
        /// <summary>
        /// Set the state of a specific color of light.
        /// Internally, this turns off the unspecified light.
        /// </summary>
        public bool SetLight(DelcomLightColor color, DelcomLightState newState)
        {
            if (newState == DelcomLightState.Off)
            {
                throw new ArgumentException("SetLight method cannot be used for turning off");
            }

            bool result = true;
            var  colors = new List <DelcomLightColor>(this.lightStates.Keys);

            foreach (DelcomLightColor targetColor in colors)
            {
                bool singleResult = this.SetSingleLight(
                    targetColor,
                    (targetColor == color) ? newState : DelcomLightState.Off);
                if (!singleResult)
                {
                    Trace.TraceError("SetLight: failed to manipulate {0}", targetColor);
                    result = false;
                }
            }

            return(result);
        }
        /// <summary>
        /// Internal method to set a single color of light.
        /// </summary>
        private bool SetSingleLight(DelcomLightColor color, DelcomLightState newState)
        {
            bool result = false;

            lock (this.lightStates)
            {
                DelcomLightState currentState;
                if (this.lightStates.TryGetValue(color, out currentState) && currentState == newState)
                {
                    // This color is already in appropriate state.
                    result = true;
                }
                else
                {
                    for (int i = 0; i < DelcomLightWrapper.MaxLightRetries; i++)
                    {
                        if (Delcom.DelcomLEDControl(this.deviceHandle, (byte)color, (byte)newState) == 0)
                        {
                            this.lightStates[color] = newState;
                            result = true;
                            break;
                        }
                        else
                        {
                            // Not to log each failure because a) API does not provide any error detail and
                            // b) caller will make an error log if all retries fail.
                            System.Threading.Thread.Sleep(DelcomLightWrapper.LightRetryInterval);
                        }
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Set the state of a specific color of light.
        /// Internally, this turns off the unspecified light.
        /// </summary>
        public bool SetLight(DelcomLightColor color, DelcomLightState newState)
        {
            if (newState == DelcomLightState.Off)
            {
                throw new ArgumentException("SetLight method cannot be used for turning off");
            }

            bool result = true;
            var colors = new List<DelcomLightColor>(this.lightStates.Keys);

            foreach (DelcomLightColor targetColor in colors)
            {
                bool singleResult = this.SetSingleLight(
                    targetColor,
                    (targetColor == color) ? newState : DelcomLightState.Off);
                if (!singleResult)
                {
                    Trace.TraceError("SetLight: failed to manipulate {0}", targetColor);
                    result = false;
                }
            }

            return result;
        }