/// <overloads>
        ///   Simulates releasing the <see cref="MouseButtons"/> or modifier <see cref="Keys"/>.
        /// </overloads>
        /// <summary>
        ///   Simulate releasing the mouse modifier key(s) (Alt, Shift and Control).
        /// </summary>
        /// <param name="keys">
        ///   A bitwise combination of the <see cref="Keys"/> enumeration values. Only <b>Alt</b>, <b>Shift</b>
        ///   and <b>Control</b> are allowed.
        /// </param>
        /// <remarks>
        ///   <b>Release</b> simulates releasing the specified <paramref name="keys"/>.
        /// </remarks>
        /// <exception cref="ArgumentOutOfRangeException">
        ///   When <paramref name="keys"/> contains a value that is not
        ///   <b>Alt</b>, <b>Shift</b> or <b>Control</b>.
        /// </exception>
        /// <example>
        ///   The following example performs a "shift drag" and verifies that
        ///   two objects are selected.
        /// <code>
        /// public class ATest : XunitFormTest
        ///{
        ///  // Gets the Form used for testing.
        ///  public override Type FormType
        ///  {
        ///    get {return typeof(MyTestForm);}
        ///  }
        ///
        ///  [Fact] public void Selecting()
        ///  {
        ///    ControlTester myControl = new ControlTester("myControl", CurrentForm);
        ///    using (MouseController mouse = myControl.MouseController())
        ///    {
        ///      mouse.Drag (10,10, 20,20);
        ///      AssertEquals (1, myControl.Properties.SelectedObjects.Count);
        ///
        ///      mouse.PressAndRelease(Keys.Shift);
        ///      mouse.Drag(100,100, 200,200);
        ///      mouse.Release(Keys.Shift);
        ///      AssertEquals (2, myControl.Properties.SelectedObjects.Count);
        ///    }
        ///  }
        /// </code>
        /// </example>
        public void Release(Keys keys)
        {
            if ((keys & ~(Keys.Alt | Keys.Shift | Keys.Control)) != 0)
            {
                throw new ArgumentOutOfRangeException("keys", "Only Alt, Shift and Control is allowed.");
            }

            Win32.KEYBDINPUT ki = new Win32.KEYBDINPUT();
            ki.type        = Win32.INPUT_KEYBOARD;
            ki.dwExtraInfo = Win32.GetMessageExtraInfo();
            ki.dwFlags     = Win32.KEYEVENTF_KEYUP;
            ki.time        = 0;
            ki.wScan       = 0;

            if ((keys & Keys.Alt) == Keys.Alt)
            {
                ki.wVk = Win32.VK_MENU;
                if (0 == Win32.SendKeyboardInput(1, ref ki, Marshal.SizeOf(ki)))
                {
                    throw new Win32Exception();
                }
            }
            if ((keys & Keys.Control) == Keys.Control)
            {
                ki.wVk = Win32.VK_CONTROL;
                if (0 == Win32.SendKeyboardInput(1, ref ki, Marshal.SizeOf(ki)))
                {
                    throw new Win32Exception();
                }
            }
            if ((keys & Keys.Shift) == Keys.Shift)
            {
                ki.wVk = Win32.VK_SHIFT;
                if (0 == Win32.SendKeyboardInput(1, ref ki, Marshal.SizeOf(ki)))
                {
                    throw new Win32Exception();
                }
            }

            Application.DoEvents();
        }
        /// <overloads>
        ///   Simulates releasing the <see cref="MouseButtons"/> or modifier <see cref="Keys"/>.
        /// </overloads>
        /// <summary>
        ///   Simulate releasing the mouse modifier key(s) (Alt, Shift and Control).
        /// </summary>
        /// <param name="keys">
        ///   A bitwise combination of the <see cref="Keys"/> enumeration values. Only <b>Alt</b>, <b>Shift</b>
        ///   and <b>Control</b> are allowed.
        /// </param>
        /// <remarks>
        ///   <b>Release</b> simulates releasing the specified <paramref name="keys"/>.
        /// </remarks>
        /// <exception cref="ArgumentOutOfRangeException">
        ///   When <paramref name="keys"/> contains a value that is not 
        ///   <b>Alt</b>, <b>Shift</b> or <b>Control</b>.
        /// </exception>
        /// <example>
        ///   The following example performs a "shift drag" and verifies that
        ///   two objects are selected.
        /// <code>
        /// public class ATest : XunitFormTest
        ///{
        ///  // Gets the Form used for testing.
        ///  public override Type FormType
        ///  {
        ///    get {return typeof(MyTestForm);}
        ///  }
        ///  
        ///  [Fact] public void Selecting()
        ///  {
        ///    ControlTester myControl = new ControlTester("myControl", CurrentForm);
        ///    using (MouseController mouse = myControl.MouseController())
        ///    {
        ///      mouse.Drag (10,10, 20,20);
        ///      AssertEquals (1, myControl.Properties.SelectedObjects.Count);
        ///      
        ///      mouse.PressAndRelease(Keys.Shift);
        ///      mouse.Drag(100,100, 200,200);
        ///      mouse.Release(Keys.Shift);
        ///      AssertEquals (2, myControl.Properties.SelectedObjects.Count);
        ///    }
        ///  }
        /// </code>
        /// </example>
        public void Release(Keys keys)
        {
            if ((keys & ~(Keys.Alt | Keys.Shift | Keys.Control)) != 0)
            {
                throw new ArgumentOutOfRangeException("keys", "Only Alt, Shift and Control is allowed.");
            }

            Win32.KEYBDINPUT ki = new Win32.KEYBDINPUT();
            ki.type = Win32.INPUT_KEYBOARD;
            ki.dwExtraInfo = Win32.GetMessageExtraInfo();
            ki.dwFlags = Win32.KEYEVENTF_KEYUP;
            ki.time = 0;
            ki.wScan = 0;

            if ((keys & Keys.Alt) == Keys.Alt)
            {
                ki.wVk = Win32.VK_MENU;
                if (0 == Win32.SendKeyboardInput(1, ref ki, Marshal.SizeOf(ki)))
                {
                    throw new Win32Exception();
                }
            }
            if ((keys & Keys.Control) == Keys.Control)
            {
                ki.wVk = Win32.VK_CONTROL;
                if (0 == Win32.SendKeyboardInput(1, ref ki, Marshal.SizeOf(ki)))
                {
                    throw new Win32Exception();
                }
            }
            if ((keys & Keys.Shift) == Keys.Shift)
            {
                ki.wVk = Win32.VK_SHIFT;
                if (0 == Win32.SendKeyboardInput(1, ref ki, Marshal.SizeOf(ki)))
                {
                    throw new Win32Exception();
                }
            }

            Application.DoEvents();
        }