void reorderChildren (const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager)
    {
        jassert (newOrder.size() == children.size());

        if (undoManager == nullptr)
        {
            children.clear();
            children.ensureStorageAllocated (newOrder.size());

            for (int i = 0; i < newOrder.size(); ++i)
                children.add (newOrder.getUnchecked(i)->object);

            sendChildOrderChangedMessage();
        }
        else
        {
            for (int i = 0; i < children.size(); ++i)
            {
                SharedObject* const child = newOrder.getUnchecked(i)->object;

                if (children.getObjectPointerUnchecked (i) != child)
                {
                    const int oldIndex = children.indexOf (child);
                    jassert (oldIndex >= 0);
                    moveChild (oldIndex, i, undoManager);
                }
            }
        }
    }
    void moveChild (int currentIndex, int newIndex, UndoManager* undoManager)
    {
        // The source index must be a valid index!
        jassert (isPositiveAndBelow (currentIndex, children.size()));

        if (currentIndex != newIndex
             && isPositiveAndBelow (currentIndex, children.size()))
        {
            if (undoManager == nullptr)
            {
                children.move (currentIndex, newIndex);
                sendChildOrderChangedMessage (currentIndex, newIndex);
            }
            else
            {
                if (! isPositiveAndBelow (newIndex, children.size()))
                    newIndex = children.size() - 1;

                undoManager->perform (new MoveChildAction (this, currentIndex, newIndex));
            }
        }
    }