public function optimize($php)
	{
		$this->tokens = token_get_all('<?php ' . $php);
		$this->cnt    = count($this->tokens);
		$this->i      = 0;

		// Remove line numbers from tokens
		foreach ($this->tokens as &$token)
		{
			if (is_array($token))
			{
				unset($token[2]);
			}
		}
		unset($token);

		// Optimization passes, in order of execution
		$passes = [
			'optimizeOutConcatEqual',
			'optimizeConcatenations',
			'optimizeHtmlspecialchars'
		];

		// Limit the number of loops, in case something would make it loop indefinitely
		$remainingLoops = $this->maxLoops;
		do
		{
			$continue = false;

			foreach ($passes as $pass)
			{
				// Run the pass
				$this->$pass();

				// If the array was modified, reset the keys and keep going
				$cnt = count($this->tokens);
				if ($this->cnt !== $cnt)
				{
					$this->tokens = array_values($this->tokens);
					$this->cnt    = $cnt;
					$continue     = true;
				}
			}
		}
		while ($continue && --$remainingLoops);

		// Optimize common output expressions in if-else-elseif conditionals
		$php = $this->branchOutputOptimizer->optimize($this->tokens);

		// Reclaim some memory
		unset($this->tokens);

		return $php;
	}