protected function processOrder($order)
    {
        if (!is_string($order) && is_callable($order)) {
            $expr  = $this->createOrder();
            /**
             * @param  OrderInterface           $expr The new order expression object.
             * @param  OrderCollectionInterface $this The context of the collection.
             * @return string|array|OrderInterface The prepared order expression
             *     string, structure, object.
             */
            $order = $order($expr, $this);
        }

        if (is_string($order)) {
            $expr  = $this->createOrder()->setCondition($order);
            $order = $expr;
        } elseif (is_array($order)) {
            $expr  = $this->createOrder()->setData($order);
            $order = $expr;
        }

        /** Append the order to the expression's stack. */
        if ($order instanceof OrderInterface) {
            return $order;
        }

        throw new InvalidArgumentException(sprintf(
            'Order must be a string, structure, or Expression object; received %s',
            is_object($order) ? get_class($order) : gettype($order)
        ));
    }