Parses the hunk start into appropriate tokens.

@param string $diffLine

@return Token[]
546956
private function getHunkStartTokens(string $diffLine): array
    {
        $tokenList = [];

        if (preg_match(self::HUNK_START_REGEX, $diffLine, $matches)) {
            // File deletion
            if ($this->hasToken($matches, Token::FILE_DELETION_LINE_COUNT)) {
                $tokenList = [
                    new Token(Token::FILE_DELETION_LINE_COUNT, $matches[Token::FILE_DELETION_LINE_COUNT]),
                    new Token(Token::HUNK_NEW_START, $matches[Token::HUNK_NEW_START]),
                    new Token(Token::HUNK_NEW_COUNT, $matches[Token::HUNK_NEW_COUNT])
                ];

            // File creation
            } elseif ($this->hasToken($matches, Token::FILE_CREATION_LINE_COUNT)) {
                $tokenList = [
                    new Token(Token::HUNK_ORIGINAL_START, $matches[Token::HUNK_ORIGINAL_START]),
                    new Token(Token::HUNK_ORIGINAL_COUNT, $matches[Token::HUNK_ORIGINAL_COUNT]),
                    new Token(Token::FILE_CREATION_LINE_COUNT, $matches[Token::FILE_CREATION_LINE_COUNT]),
                ];

            // Standard Case
            } else {
                $tokenList = [
                    new Token(Token::HUNK_ORIGINAL_START, $matches[Token::HUNK_ORIGINAL_START]),
                    new Token(Token::HUNK_ORIGINAL_COUNT, $matches[Token::HUNK_ORIGINAL_COUNT]),
                    new Token(Token::HUNK_NEW_START, $matches[Token::HUNK_NEW_START]),
                    new Token(Token::HUNK_NEW_COUNT, $matches[Token::HUNK_NEW_COUNT])
                ];
            }
        }

        return $tokenList;
    }
592129
protected function highlightDiff($diff)
	{
		$lines = explode("\n", $diff);
		foreach ($lines as $key => $val) {
			if (mb_substr($val,0,1,'utf-8') === '@') {
				$lines[$key] = '<span class="info">'.CHtml::encode($val).'</span>';
			}
			else if (mb_substr($val,0,1,'utf-8') === '+') {
				$lines[$key] = '<ins>'.CHtml::encode($val).'</ins>';
			}
			else if (mb_substr($val,0,1,'utf-8') === '-') {
				$lines[$key] = '<del>'.CHtml::encode($val).'</del>';
			}
			else {
				$lines[$key] = CHtml::encode($val);
			}
		}

		return implode("\n", $lines);
	}
322786
private static function parseHeaderLine(&$headers, $line)
    {
        $parts = explode(':', $line, 2);
        if (count($parts) == 1) {
            return;
        }

        list($name, $value) = $parts;
        $headers[trim($name)] = trim($value);
    }
838342
protected function parseListContent(TokenList $tokenList) {
        $lastToken = $tokenList->last();
        if ($lastToken->getName() === $this->name) {
            $tokenList->removeTokenAt(-1); // Remove last LIST_BLOCK (content)

            $content = $lastToken->get('content', '');

            $containsParagraphs = $tokenList->last()->get('forceParagraph', false);

            if (preg_match('/(?:\n(?:[ \t]*(?=\n))?){2,}/i', $content) === 1) {
                $containsParagraphs = true;

                // Remove starting spaces or tab
                $content = explode("\n", $content);
                $pad = null;
                foreach ($content as $index => &$item) {
                    // Find out lin starting space length up to 4 characters
                    if ($pad === null && $index > 0 && preg_match('/^[ \t]*$/i', $item) !== 1) {
                        if (preg_match('/^[ ]{0,4}/', $item, $matches) === 1) {
                            $pad = strlen($matches[0]);
                        } else {
                            $pad = 4;
                        }
                    }

                    // Remove line starting space or tab characters
                    if ($pad !== null) {
                        $item = preg_replace('/^(?: {' . $pad . '}|\t)/', '', $item);
                    }
                }

                $content = implode("\n", $content);
            }

            $content = "\n" . $content . "\n";

            $contentTokenList = $this->parseContent($content, null, true);

            // Remove beginning and ending new line feed
            if ($contentTokenList->first()->getName() === EolRule::NAME
                && $contentTokenList->last()->getName() === EolRule::NAME
            ) {
                $contentTokenList->removeTokenAt(0);  // Remove first EOL
                $contentTokenList->removeTokenAt(-1); // Remove last EOL
            }

            // Remove paragraphs
            if (!$containsParagraphs
                && $contentTokenList->first()->getName() === PRule::NAME . AbstractBlockRule::OPEN
                && $contentTokenList->last()->getName() === PRule::NAME . AbstractBlockRule::CLOSE
            ) {
                $contentTokenList->removeTokenAt(0);  // Remove first P
                $contentTokenList->removeTokenAt(-1); // Remove last P
            }

            // Add new line indicator for paragraphs
            for ($i = 0; $i < count($contentTokenList); $i++) {
                $token = $contentTokenList->getTokenAt($i);
                if ($token->getName() === EolRule::NAME) {
                    $contentTokenList->removeTokenAt($i);
                    $contentTokenList->insertTokenAt($this->name . '_ITEM_EOL', $token->getPosition(), $i);
                }
            }

            // Change LIST_BLOCK to BASE token
            $startRule = $this->set->getStartRule();

            for ($i = 0; $i < count($contentTokenList); $i++) {
                if ($contentTokenList->getTokenAt($i)->getName() === $this->name) {
                    $token = $contentTokenList->getTokenAt($i);
                    $contentTokenList->removeTokenAt($i);
                    $contentTokenList->insertTokenAt($startRule->getName(), $token->getPosition(), $i)
                        ->set('content', $token->get('content', ''));
                }
            }

            $tokenList->merge($contentTokenList);
        }
    }
1120010
public function parseLine($line) {
        $line = trim($line, "\r\n");

        if (preg_match('/^([\w-]+):\s+(.+)/', $line, $matches)) {
            $name = strtolower($matches[1]);
            $value = $matches[2];
            $this->currentHeader = $name;

            if (isset($this->headers[$name])) {
                if (!is_array($this->headers[$name])) {
                    $this->headers[$name] = [$this->headers[$name]];
                }
                $this->headers[$name][] = $value;
            }
            else {
                $this->headers[$name] = $value;
            }
        }
        elseif (preg_match('/^\s+(.+)$/', $line, $matches) && $this->currentHeader !== null) {
            if (is_array($this->headers[$this->currentHeader])) {
                $lastKey = sizeof($this->headers[$this->currentHeader]) - 1;
                $this->headers[$this->currentHeader][$lastKey] .= $matches[1];
            }
            else {
                $this->headers[$this->currentHeader] .= $matches[1];
            }
        }

        return $this;
    }
763355
protected function parseColumnAlignments($line)
	{
		// Use a bitfield to represent the colons' presence and map it to the CSS value
		$align = [
			0b00 => '',
			0b01 => 'right',
			0b10 => 'left',
			0b11 => 'center'
		];

		$cols = [];
		preg_match_all('/(:?)-+(:?)/', $line, $matches, PREG_SET_ORDER);
		foreach ($matches as $m)
		{
			$key = (!empty($m[1]) ? 2 : 0) + (!empty($m[2]) ? 1 : 0);
			$cols[] = $align[$key];
		}

		return $cols;
	}
664597
private function parseNormal(array $lines, $inline = false, $start)
    {
        foreach ($lines as $key => &$line) {
            $line = $this->parseInline($line);
            if (!preg_match("/^\s*$/", $line)) {
                $line = $this->markLine($start + $key) . $line;
            }
        }
        $str = trim(implode("\n", $lines));
        $str = preg_replace("/(\n\s*){2,}/", "</p><p>", $str);
        $str = preg_replace("/\n/", "<br>", $str);
        return preg_match("/^\s*$/", $str) ? '' : ($inline ? $str : "<p>{$str}</p>");
    }
1008296
public static function parseMultiLineComment($line)
    {
        $parsed = preg_replace('-^\s*/\*+-', '', $line);
        $parsed = preg_replace('-\*/-', '', $parsed);
        return rtrim($parsed);
    }
822779
protected function decodeSize($lines)
    {
        $sizes = [];
        foreach (array_map([$this, 'decodeLine'], $lines) as $tokens) {
            if (!isset($tokens[1]) || $tokens[1] !== 'FETCH') {
                continue;
            }
            if (!isset($tokens[2][0]) || $tokens[2][0] !== 'UID') {
                continue;
            }
            if (!isset($tokens[2][2]) || $tokens[2][2] !== 'RFC822.SIZE') {
                continue;
            }
            if (!isset($tokens[2][1]) || !isset($tokens[2][3])) {
                continue;
            }
            $sizes[$tokens[2][1]] = $tokens[2][3];
        }
        return $sizes;
    }
192263
private function findSimilarityIndex(string $line)
    {
        $matches = [];
        if (preg_match('/^similarity index (.*)\%$/', $line, $matches)) {
            $this->similarityIndex = $matches[1];
        }
    }
379055
protected function extractElements($line)
    {
        $elements = [];
        $buffer   = '';
        $quote    = false;

        foreach (\str_split($line) as $character)
        {
            if (\in_array($character, ['\'', '"']))
            {
                $quote = ! $quote;

                continue;
            }

            if ((':' == $character) and ! $quote)
            {
                $elements[] = $buffer;

                $buffer = '';

                continue;
            }

            $buffer .= $character;
        }

        if ($buffer)
        {
            $elements[] = $buffer;
        }

        return $elements;
    }
1257188
private function parseLines(array $lines)
    {
        $originUnchanged = $this->originStartLine;
        $destUnchanged = $this->destStartLine;

        $deleted = $this->originStartLine;
        $new = $this->destStartLine;
        foreach ($lines as $line) {
            if (preg_match('/^\+(.*)/', $line)) {
                $this->lines[] = new DiffChunkLineAdded($new++, preg_replace('/\+(.*)/', ' $1', $line));
                $destUnchanged++;
            } else if (preg_match('/^-(.*)/', $line)) {
                $this->lines[] = new DiffChunkLineDeleted($deleted++, preg_replace('/-(.*)/', ' $1', $line));
                $originUnchanged++;
            } else if (preg_match('/^ (.*)/', $line) || $line == '') {
                $this->lines[] = new DiffChunkLineUnchanged($originUnchanged++, $destUnchanged++, $line);
                $deleted++;
                $new++;
            } else if (!preg_match('/\\ No newline at end of file/', $line)) {
                throw new \Exception(sprintf('GitElephant was unable to parse the line %s', $line));
            }
        }
    }
71544
private function getFromConst($line)
    {
        $eq_pos = strpos($line, '=');
        $semicolon_pos = strrpos($line, ';');

        $constant_name = trim(substr($line, 6, $eq_pos - 6));
        $value = trim(substr($line, $eq_pos + 1, $semicolon_pos - $eq_pos - 1));

        return [$constant_name, $this->getNativeValueFromDefinition($value)];
    }
415226
private function parse_ftp_rawlist($line) {
		$output = array();

		ereg('([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|) +(.+)', $Current, $split);
		if (is_array($split)) {
			if ($split[3] < 70) {
				$split[3] += 2000;
			} else {
				$split[3] += 1900;
			}
			$output['isdir'] = ($split[7] == '');
			$output['size'] = $split[7];
			$output['month'] = $split[1];
			$output['day'] = $split[2];
			$output['time/year'] = $split[3];
			$output['name'] = $split[8];
		}
		return !empty($output) ? $output : false;
	}
663648
private function parseLine($line)
    {
        if ($line == '') {
            return;
        }

        $slices = NodeObject::getLineSlices($line);
        if ($this->isBlob()) {
            $this->pathChildren[] = $this->blob->getName();
        } else {
            if ($this->isRoot()) {
                // if is root check for first children
                $pattern = '/(\w+)\/(.*)/';
                $replacement = '$1';
            } else {
                // filter by the children of the path
                $actualPath = $this->subject->getFullPath();
                if (!preg_match(sprintf('/^%s\/(\w*)/', preg_quote($actualPath, '/')), $slices['fullPath'])) {
                    return;
                }
                $pattern = sprintf('/^%s\/(\w*)/', preg_quote($actualPath, '/'));
                $replacement = '$1';
            }

            $name = preg_replace($pattern, $replacement, $slices['fullPath']);
            if (strpos($name, '/') !== false) {
                return;
            }

            if (!in_array($name, $this->pathChildren)) {
                $path = rtrim(rtrim($slices['fullPath'], $name), '/');
                $treeObject = new TreeObject(
                    $this->repository,
                    $slices['permissions'],
                    $slices['type'],
                    $slices['sha'],
                    $slices['size'],
                    $name,
                    $path
                );
                $this->children[] = $treeObject;
                $this->pathChildren[] = $name;
            }
        }
    }
84318
public static function csvFields(string $line, string $delimiter = ','): array
    {
        if (trim($line) === '') {
            return [];
        }
        $fields = [];
        $parts = str_getcsv($line, $delimiter);
        if ($parts !== null && count($parts) > 0) {
            foreach ($parts as $part) {
                $part = trim($part);
                if (substr($part, 0, 1) === '"' || substr($part, 0, 1) === '\'') {
                    $part = substr($part, 1);
                }
                if (substr($part, -1) === '"' || substr($part, -1) === '\'') {
                    $part = substr($part, 0, -1);
                }
                if ($part !== '') {
                    $fields[] = $part;
                }
            }
        }
        return $fields;
    }
1279
protected function parseTag($line) {
		$matches = [];
		if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)?/us', $line, $matches)) {
			throw new \InvalidArgumentException('Invalid tag line detected: ' . $line);
		}
		
		$tagName = $matches[1];
		$content = isset($matches[2]) ? $matches[2] : '';
		
		return TagFactory::create($tagName, $content);
	}