Returns the protocol if needed.

@param string $matched The matched host.
@param array  $parsed  The results of parse_url.

@return string
968894
protected function addProtocolPortIfNeeded(string $matched, array $parsed) : string
    {
        if ('' === $matched || '*' === $matched) {
            $return = $matched;

            return $return;
        }
        $protocol = 'https://';
        $port     = 0;
        if (true === isset($parsed['scheme'])) {
            $this->addLog('Parsed a protocol from origin: '.$parsed['scheme']);
            $protocol = $parsed['scheme'].'://';
        } else {
            $this->addLog('Unable to parse protocol/scheme from origin');
        }
        if (true === isset($parsed['port'])) {
            $this->addLog('Parsed a port from origin: '.$parsed['port']);
            $port = (int) $parsed['port'];
        } else {
            $this->addLog('Unable to parse port from origin');
        }

        if (0 === $port) {
            if ('https://' === $protocol) {
                $port = 443;
            } else {
                $port = 80;
            }
        }

        if (('http://' === $protocol && 80 === $port) || ('https://' === $protocol && 443 === $port)) {
            $return = $protocol.$matched;
        } else {
            $return = $protocol.$matched.':'.$port;
        }
        return $return;
    }
1113138
protected function get_header($header = null, $formatted = true)
	{
		if ($header === null)
		{
			return $this->headers;
		}

		if (array_key_exists($header, $this->headers))
		{
			$prefix = ($formatted) ? $header.': ' : '';
			$suffix = ($formatted) ? $this->config['newline'] : '';
			return $prefix.$this->headers[$header].$suffix;
		}

		return '';
	}
1372527
public function call(callable $callback, array $matched)
    {
        $parameters = $this->bindParameters($callback, $matched);

        return call_user_func_array($callback, $parameters);
    }
946687
private function expandMatch(array $matches)
    {
        static $rfc1738to3986 = array(
            '+'   => '%20',
            '%7e' => '~'
        );

        $parsed = self::parseExpression($matches[1]);
        $replacements = array();

        $prefix = $parsed['operator'];
        $joiner = $parsed['operator'];
        $useQueryString = false;
        if ($parsed['operator'] == '?') {
            $joiner = '&';
            $useQueryString = true;
        } elseif ($parsed['operator'] == '&') {
            $useQueryString = true;
        } elseif ($parsed['operator'] == '#') {
            $joiner = ',';
        } elseif ($parsed['operator'] == ';') {
            $useQueryString = true;
        } elseif ($parsed['operator'] == '' || $parsed['operator'] == '+') {
            $joiner = ',';
            $prefix = '';
        }

        foreach ($parsed['values'] as $value) {

            if (!array_key_exists($value['value'], $this->variables) || $this->variables[$value['value']] === null) {
                continue;
            }

            $variable = $this->variables[$value['value']];
            $actuallyUseQueryString = $useQueryString;
            $expanded = '';

            if (is_array($variable)) {

                $isAssoc = $this->isAssoc($variable);
                $kvp = array();
                foreach ($variable as $key => $var) {

                    if ($isAssoc) {
                        $key = rawurlencode($key);
                        $isNestedArray = is_array($var);
                    } else {
                        $isNestedArray = false;
                    }

                    if (!$isNestedArray) {
                        $var = rawurlencode($var);
                        if ($parsed['operator'] == '+' || $parsed['operator'] == '#') {
                            $var = $this->decodeReserved($var);
                        }
                    }

                    if ($value['modifier'] == '*') {
                        if ($isAssoc) {
                            if ($isNestedArray) {
                                // Nested arrays must allow for deeply nested structures
                                $var = strtr(http_build_query(array($key => $var)), $rfc1738to3986);
                            } else {
                                $var = $key . '=' . $var;
                            }
                        } elseif ($key > 0 && $actuallyUseQueryString) {
                            $var = $value['value'] . '=' . $var;
                        }
                    }

                    $kvp[$key] = $var;
                }

                if (empty($variable)) {
                    $actuallyUseQueryString = false;
                } elseif ($value['modifier'] == '*') {
                    $expanded = implode($joiner, $kvp);
                    if ($isAssoc) {
                        // Don't prepend the value name when using the explode modifier with an associative array
                        $actuallyUseQueryString = false;
                    }
                } else {
                    if ($isAssoc) {
                        // When an associative array is encountered and the explode modifier is not set, then the
                        // result must be a comma separated list of keys followed by their respective values.
                        foreach ($kvp as $k => &$v) {
                            $v = $k . ',' . $v;
                        }
                    }
                    $expanded = implode(',', $kvp);
                }

            } else {
                if ($value['modifier'] == ':') {
                    $variable = substr($variable, 0, $value['position']);
                }
                $expanded = rawurlencode($variable);
                if ($parsed['operator'] == '+' || $parsed['operator'] == '#') {
                    $expanded = $this->decodeReserved($expanded);
                }
            }

            if ($actuallyUseQueryString) {
                if (!$expanded && $joiner != '&') {
                    $expanded = $value['value'];
                } else {
                    $expanded = $value['value'] . '=' . $expanded;
                }
            }

            $replacements[] = $expanded;
        }

        $ret = implode($joiner, $replacements);
        if ($ret && $prefix) {
            return $prefix . $ret;
        }

        return $ret;
    }
625409
function () {
        var matchPattern = this.pattern,
            // Check the match pattern of sanity and split it into protocol, host and path
            match = matchPattern.match(regexes.patternSplit);

        if (!match) {
            // This ensures it is a invalid match pattern
            return;
        }

        return {
            protocols: _.uniq(match[1].split(PROTOCOL_DELIMITER)),
            host: match[5],
            port: match[6] && match[6].substr(1), // remove leading `:`
            path: this.globPatternToRegexp(match[7])
        };
    }
914980
public function matchPath($pattern, &$matches = null, $flags = 0, $offset = 0)
	{
		return preg_match($pattern, $this->_path ?: '', $matches, $flags, $offset);
	}
30065
private function decodeMatchedEntity($matches)
    {
        $body = $matches[4];
        if (strtoupper($matches[3]) === 'Q') {
            $body = quoted_printable_decode(str_replace('_', '=20', $body));
        } else {
            $body = base64_decode($body);
        }
        $language = $matches[2];
        $decoded = $this->convertEncoding($body, $matches[1], true);
        $this->addToLanguage($decoded, $language);
        return $decoded;
    }
539899
protected function & matchesParseRewriteParams (& $matchedValues, & $defaults) {
		$matchedParams = [];
		array_shift($matchedValues); // first item is always matched whole `$request->GetPath()` string.
		foreach ($matchedValues as $key => $matchedValueArr) {
			if (is_numeric($key)) continue;
			$matchedValue = (string) current($matchedValueArr);
			if (!isset($defaults[$key])) 
				$defaults[$key] = NULL;
			$matchedEmptyString = mb_strlen($matchedValue) === 0;
			if ($matchedEmptyString)
				$matchedValue = $defaults[$key];
			// continue if there is already valid ctrl and action from route ctrl or action configuration
			if (isset($matchedParams[$key]) && $matchedEmptyString) continue;
			$matchedParams[$key] = $matchedValue;
		}
		return $matchedParams;
	}
469760
public static function getProtocol(array $server): string
    {
        if (!isset($server['SERVER_PROTOCOL'])) {
            return '1.1';
        }

        if (!\preg_match('#^(HTTP/)?(?P<version>[1-9]\d*(?:\.\d)?)$#', $server['SERVER_PROTOCOL'], $matches)) {
            throw new \UnexpectedValueException("Unrecognized protocol version ({$server['SERVER_PROTOCOL']})");
        }

        return $matches['version'];
    }
433516
public function parse($mixed)
    {
        if (\Staq\Util::isStack($mixed)) {
            return $this->parseFromStack($mixed);
        }
        return $this->parseFromString($mixed);
    }
131470
final public function getAttributes($parsed = false) {
        if (!is_array($this->attributes)) {
            $this->attributes = array();
        }
        return ($parsed) ? $this->parseAttributes() : $this->attributes;
    }
1116325
public function getMatch(string $pattern, int $flags = 0, int $offset = 0)
	{
		return preg_match($pattern, $this->str, $matches, $flags, $offset) === false ? null : $matches;
	}
300809
protected function parseDocLicense( $matches )
	{
		$name	= NULL;
		$url	= NULL;
		if( isset( $matches[2] ) )
		{
			$url	= trim( $matches[1] );
			$name	= trim( $matches[2] );
			if( preg_match( "@^http://@", $matches[2] ) )
			{
				$url	= trim( $matches[2] );
				$name	= trim( $matches[1] );
			}
		}
		else
		{
			$name	= trim( $matches[1] );
			if( preg_match( "@^http://@", $matches[1] ) )
				$url	= trim( $matches[1] );
		}
		$license	= new ADT_PHP_License( $name, $url );
		return $license;
	}
202273
protected function _doAnchors_inline_callback($matches) {
		$whole_match	=  $matches[1];
		$link_text		=  $this->runSpanGamut($matches[2]);
		$url			=  $matches[3] == '' ? $matches[4] : $matches[3];
		$title			=& $matches[7];
		$attr  = $this->doExtraAttributes("a", $dummy =& $matches[8]);

		// if the URL was of the form <s p a c e s> it got caught by the HTML
		// tag parser and hashed. Need to reverse the process before using the URL.
		$unhashed = $this->unhash($url);
		if ($unhashed != $url)
			$url = preg_replace('/^<(.*)>$/', '\1', $unhashed);

		$url = $this->encodeURLAttribute($url);

		$result = "<a href=\"$url\"";
		if (isset($title)) {
			$title = $this->encodeAttribute($title);
			$result .=  " title=\"$title\"";
		}
		$result .= $attr;
		
		$link_text = $this->runSpanGamut($link_text);
		$result .= ">$link_text</a>";

		return $this->hashPart($result);
	}
1316918
protected function _emailCallback($matches) {
        // is like http://user:pass@domain.com ? Then we do not touch it.
        if ($matches[1]) {
            return $matches[0];
        }

        return $this->getParser()->getFilter('Email')->parse(array(
            'tag' => 'email',
            'attributes' => array()
        ), trim($matches[2]));
    }
1277563
final public function getSuccessMessage($parsed = true) {
        return ($parsed) ? $this->parseMessages($this->successMessages) :
                $this->successMessages;
    }
554485
public static function Match ($pattern, $subject, array &$matches = array(), $flags = 0, $offset = 0, $from_encoding = Encoding::DEFAULT_ENCODING) {
		return Regex::match($pattern, $subject, $matches, $flags, $offset, $from_encoding);
	}