protected function detectCalculationOrder(array $nodes)
    {
        $operatorNodes = [];

        // Store all symbol nodes that have a symbol of type abstract operator in an array
        foreach ($nodes as $index => $node) {
            if (is_a($node, SymbolNode::class)) {
                if (is_a($node->getSymbol(), AbstractOperator::class)) {
                    $operatorNodes[$index] = $node;
                }
            }
        }

        // Using Quicksort algorithm to sort the operators according to their precedence. Keeps the indices.
        // Returning 1 means $nodeTwo before $nodeOne, returning -1 means $nodeOne before $nodeTwo.
        uasort($operatorNodes, function(SymbolNode $nodeOne, SymbolNode $nodeTwo)
        {
            // First-level precedence of node one
            /** @var AbstractOperator $symbolOne */
            $symbolOne = $nodeOne->getSymbol();
            $precedenceOne = 2;
            if ($nodeOne->isUnaryOperator()) {
                $precedenceOne = 3;
            }

            // First-level precedence of node two
            /** @var AbstractOperator $symbolTwo */
            $symbolTwo = $nodeTwo->getSymbol();
            $precedenceTwo = 2;
            if ($nodeTwo->isUnaryOperator()) {
                $precedenceTwo = 3;
            }

            // If the first-level precedence is the same, compare the second-level precedence
            if ($precedenceOne == $precedenceTwo) {
                $precedenceOne = $symbolOne->getPrecedence();
                $precedenceTwo = $symbolTwo->getPrecedence();
            }

            // If the second-level precedence is the same, we have to ensure that the sorting algorithm does
            // insert the node / token that is left in the term before the node / token that is right.
            // Therefore we cannot return 0 but compare the positions and return 1 / -1.
            if ($precedenceOne == $precedenceTwo) {
                return ($nodeOne->getToken()->getPosition() < $nodeTwo->getToken()->getPosition()) ? -1 : 1;
            }
            return ($precedenceOne < $precedenceTwo) ? 1 : -1;
        });

        return $operatorNodes;
    }