/// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data.</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            if (BufferedPaintSupported)
            {
                bool stateChanged = !Object.Equals(currentState, newState);

                using (var hdc = new SafeGDIHandle(e.Graphics))
                {
                    if (!hdc.IsInvalid)
                    {
                        // see if this paint was generated by a soft-fade animation
                        if (!NativeMethods.BufferedPaintRenderAnimation(this.Handle, hdc))
                        {
                            NativeMethods.BufferedPaintAnimationParams animParams = new NativeMethods.BufferedPaintAnimationParams(NativeMethods.BufferedPaintAnimationStyle.Linear);

                            // get appropriate animation time depending on state transition (or 0 if unchanged)
                            if (stateChanged)
                            {
                                foreach (var item in transitions)
                                {
                                    if (item.currentState == currentState && item.newState == newState)
                                    {
                                        animParams.Duration = item.duration;
                                        break;
                                    }
                                }
                            }

                            Rectangle rc = this.ClientRectangle;
                            IntPtr    hdcFrom, hdcTo;
                            IntPtr    hbpAnimation = NativeMethods.BeginBufferedAnimation(this.Handle, hdc, ref rc, NativeMethods.BufferedPaintBufferFormat.CompatibleBitmap, IntPtr.Zero, ref animParams, out hdcFrom, out hdcTo);
                            if (hbpAnimation != IntPtr.Zero)
                            {
                                if (hdcFrom != IntPtr.Zero)
                                {
                                    using (Graphics gfxFrom = Graphics.FromHdc(hdcFrom))
                                        PaintControl(new PaintEventArgs(gfxFrom, e.ClipRectangle));
                                }
                                currentState = newState;
                                if (hdcTo != IntPtr.Zero)
                                {
                                    using (Graphics gfxTo = Graphics.FromHdc(hdcTo))
                                        PaintControl(new PaintEventArgs(gfxTo, e.ClipRectangle));
                                }
                                NativeMethods.EndBufferedAnimation(hbpAnimation, true);
                            }
                            else
                            {
                                hdc.Dispose();
                                currentState = newState;
                                PaintControl(e);
                            }
                        }
                    }
                }
            }
            else
            {
                // buffered painting not supported, just paint using the current state
                currentState = newState;
                PaintControl(e);
            }
        }