protected static function replaceTokensInText(DOMText $node, $regexp, $fn)
	{
		// Grab the node's parent so that we can rebuild the text with added variables right
		// before the node, using DOM's insertBefore(). Technically, it would make more sense
		// to create a document fragment, append nodes then replace the node with the fragment
		// but it leads to namespace redeclarations, which looks ugly
		$parentNode = $node->parentNode;
		$dom        = $node->ownerDocument;

		preg_match_all($regexp, $node->textContent, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
		$lastPos = 0;
		foreach ($matches as $m)
		{
			$pos = $m[0][1];

			// Catch-up to current position
			$text = substr($node->textContent, $lastPos, $pos - $lastPos);
			$parentNode->insertBefore($dom->createTextNode($text), $node);
			$lastPos = $pos + strlen($m[0][0]);

			// Get the replacement for this token
			$replacement = $fn(array_column($m, 0), $node);
			$newNode     = self::createReplacementNode($dom, $replacement);
			$parentNode->insertBefore($newNode, $node);
		}

		// Append the rest of the text
		$text = substr($node->textContent, $lastPos);
		$parentNode->insertBefore($dom->createTextNode($text), $node);

		// Now remove the old text node
		$parentNode->removeChild($node);
	}