public static void Resizable(this Control control,
                                     ResizingDirection resizableVertical   = (ResizingDirection.ResizingForward | ResizingDirection.ResizingReverse),
                                     ResizingDirection resizableHorizontal = (ResizingDirection.ResizingForward | ResizingDirection.ResizingReverse))
        {
            if (resizables.ContainsKey(control))
            {
                return;
            }

            ResizingData data = new ResizingData()
            {
                verticalAllowed   = resizableVertical,
                horizontalAllowed = resizableHorizontal,
                verticalCurrent   = ResizingDirection.NoResizing,
                horizontalCurrent = ResizingDirection.NoResizing,
                minWidth          = null,
                maxWidth          = null,
                minHeight         = null,
                maxHeight         = null,
                originalLocation  = control.Location,
                originalSize      = control.Size,
                originalCursor    = control.Cursor,
                resizingCursor    = false
            };

            resizables.Add(control, data);

            control.MouseDown += new MouseEventHandler(control_MouseDown);
            control.MouseUp   += new MouseEventHandler(control_MouseUp);
            control.MouseMove += new MouseEventHandler(control_MouseMove);
        }
        static void control_MouseUp(object sender, MouseEventArgs e)
        {
            Control      typedSender  = (Control)sender;
            ResizingData resizingData = resizables[typedSender];

            resizingData.originalLocation  = typedSender.Location;
            resizingData.originalSize      = typedSender.Size;
            resizingData.verticalCurrent   = ResizingDirection.NoResizing;
            resizingData.horizontalCurrent = ResizingDirection.NoResizing;
        }
        static void control_MouseMove(object sender, MouseEventArgs e)
        {
            Control      typedSender  = (Control)sender;
            ResizingData resizingData = resizables[typedSender];

            if ((resizingData.verticalCurrent == ResizingDirection.NoResizing) && (resizingData.horizontalCurrent == ResizingDirection.NoResizing))
            { // Cursor and start
                Cursor newCursor = null;
                PossibleResizingDirection prd = getPossibleResizingDirection(typedSender, e);
                if ((prd.vertical == prd.horizontal) && (prd.vertical != ResizingDirection.NoResizing))
                {
                    newCursor = Cursors.SizeNWSE;
                }
                else if ((prd.vertical != prd.horizontal) && (prd.vertical != ResizingDirection.NoResizing) && (prd.horizontal != ResizingDirection.NoResizing))
                {
                    newCursor = Cursors.SizeNESW;
                }
                else if (prd.vertical != ResizingDirection.NoResizing)
                {
                    newCursor = Cursors.SizeNS;
                }
                else if (prd.horizontal != ResizingDirection.NoResizing)
                {
                    newCursor = Cursors.SizeWE;
                }

                if (newCursor != null)
                {
                    if (!resizingData.resizingCursor)
                    {
                        resizingData.originalCursor = typedSender.Cursor;
                    }
                    resizingData.resizingCursor = true;
                    typedSender.Cursor          = newCursor;
                }
                else
                {
                    resizingData.resizingCursor = false;
                    typedSender.Cursor          = resizingData.originalCursor;
                }
            }
            else
            { // Resizing
                Point      newMouseOffset = (e.Location - mouseOffset) + new Size(typedSender.Location - new Size(resizingData.originalLocation));
                SizeChange scH            = getNewSize(resizingData.horizontalCurrent, resizingData.originalSize.Width, newMouseOffset.X, resizingData.minWidth, resizingData.maxWidth);
                SizeChange scV            = getNewSize(resizingData.verticalCurrent, resizingData.originalSize.Height, newMouseOffset.Y, resizingData.minHeight, resizingData.maxHeight);
                typedSender.Width    = scH.newSize;
                typedSender.Height   = scV.newSize;
                typedSender.Location = resizingData.originalLocation + new Size(scH.locationDelta, scV.locationDelta);
            }
        }
        static void control_MouseDown(object sender, MouseEventArgs e)
        {
            Control typedSender           = (Control)sender;
            PossibleResizingDirection prd = getPossibleResizingDirection(typedSender, e);

            if ((prd.vertical != ResizingDirection.NoResizing) || (prd.horizontal != ResizingDirection.NoResizing))
            {
                mouseOffset = new Size(e.Location);
                ResizingData resizingData = resizables[typedSender];
                resizingData.originalLocation  = typedSender.Location;
                resizingData.originalSize      = typedSender.Size;
                resizingData.verticalCurrent   = prd.vertical;
                resizingData.horizontalCurrent = prd.horizontal;
            }
        }