void mouseUp (const MouseEvent& e)
    {
        if (e.originalComponent != this)
        {
            if (mouseDragSource != nullptr)
                mouseDragSource->removeMouseListener (this);

            // (note: use a local copy of this in case the callback runs
            // a modal loop and deletes this object before the method completes)
            DragAndDropTarget::SourceDetails details (sourceDetails);
            DragAndDropTarget* finalTarget = nullptr;

            const bool wasVisible = isVisible();
            setVisible (false);
            Component* unused;
            finalTarget = findTarget (e.getScreenPosition(), details.localPosition, unused);

            if (wasVisible) // fade the component and remove it - it'll be deleted later by the timer callback
                dismissWithAnimation (finalTarget == nullptr);

            if (getParentComponent() != nullptr)
                getParentComponent()->removeChildComponent (this);

            if (finalTarget != nullptr)
            {
                currentlyOverComp = nullptr;
                finalTarget->itemDropped (details);
            }

            // careful - this object could now be deleted..
        }
    }
    void mouseUp (const MouseEvent& e)
    {
        if (e.originalComponent != this)
        {
            if (mouseDragSource != nullptr)
                mouseDragSource->removeMouseListener (this);

            bool dropAccepted = false;
            DragAndDropTarget* ddt = nullptr;
            Point<int> relPos;

            if (isVisible())
            {
                setVisible (false);
                ddt = findTarget (e.getScreenPosition(), relPos);

                // fade this component and remove it - it'll be deleted later by the timer callback

                dropAccepted = ddt != nullptr;

                setVisible (true);

                if (dropAccepted || sourceDetails.sourceComponent == nullptr)
                {
                    Desktop::getInstance().getAnimator().fadeOut (this, 120);
                }
                else
                {
                    const Point<int> target (sourceDetails.sourceComponent->localPointToGlobal (sourceDetails.sourceComponent->getLocalBounds().getCentre()));
                    const Point<int> ourCentre (localPointToGlobal (getLocalBounds().getCentre()));

                    Desktop::getInstance().getAnimator().animateComponent (this,
                                                                           getBounds() + (target - ourCentre),
                                                                           0.0f, 120,
                                                                           true, 1.0, 1.0);
                }
            }

            if (getParentComponent() != nullptr)
                getParentComponent()->removeChildComponent (this);

            if (dropAccepted && ddt != nullptr)
            {
                // (note: use a local copy of this in case the callback runs
                // a modal loop and deletes this object before the method completes)
                DragAndDropTarget::SourceDetails details (sourceDetails);
                details.localPosition = relPos;

                currentlyOverComp = nullptr;

                ddt->itemDropped (details);
            }

            // careful - this object could now be deleted..
        }
    }