we map the parts in reverse order because it makes more
sense to parse for the lastname starting from the end

@param array $parts
@return array
354964
protected function mapParts(array $parts): array
    {
        $k = $this->skipIgnoredParts($parts) + 1;
        $remapIgnored = true;

        while (--$k >= 0) {
            $part = $parts[$k];

            if ($part instanceof AbstractPart) {
                break;
            }

            if ($this->isFollowedByLastnamePart($parts, $k)) {
                if ($this->isApplicablePrefix($parts, $k)) {
                    $parts[$k] = new LastnamePrefix($part, $this->prefixes[$this->getKey($part)]);
                    continue;
                }

                if ($this->shouldStopMapping($parts, $k)) {
                    break;
                }
            }

            $parts[$k] = new Lastname($part);
            $remapIgnored = false;
        }

        if ($remapIgnored) {
            $parts = $this->remapIgnored($parts);
        }

        return $parts;
    }
263759
protected function processParts(array $parts)
    {
        return array_values(array_filter($parts, function ($part) {
            if (empty($part) || $part instanceof CommentPart) {
                return false;
            }
            return true;
        }));
    }
1160825
public function getPart($part)
    {
        return isset($this->parts[$part]) ? $this->parts[$part] : null;
    }
1092457
private function getPathLocation($parts)
    {
        $path = '';

        for ($i = 1; $i < count($parts) - 1; ++$i) {
            $part = $parts[$i];
            $path .= $this->keyToName($part).'\\';
        }

        return $path;
    }
1174276
protected function _implodeRecursive(array $pieces)
    {
        $values = array();
        foreach ($pieces as $item) {
            if (is_array($item)) {
                $values[] = $this->_implodeRecursive($item);
            } else {
                $values[] = $item;
            }
        }

        return implode(', ', $values);
    }
1216235
public function merge(array $parts)
    {
        if ( ! count($parts)) return $this->makeNullResponse();

        $response = $parts[0];

        // if there was only one part, just return that
        if (count($parts) == 1) return $response;

        // if there were more parts, combine their data as an array
        $response->setData(
            $this->rebuildArray($parts, function($index, ServiceResponseInterface $part) {
                /** @var ServiceResponse $part */
                return [ $index, $part->getData() ];
            })
        );

        return $response;
    }
455997
protected function processParts(array $parts)
    {
        $strValue = '';
        foreach ($parts as $part) {
            $strValue .= $part->getValue();
        }
        return [$this->partFactory->newDatePart($strValue)];
    }
100248
public static function fromParts(array $parts):UriInterface{
		$uri = new self;

		$uri->parseUriParts($parts);
		$uri->validateState();

		return $uri;
	}
813681
public static function assembleUrl ($parts) {
    $url = '';
    if (isset($parts['scheme'])) {
      $url .= "{$parts['scheme']}:";
    }
    $url .= '//';
    if (isset($parts['user'])) {
      $url .= $parts['user'];
      if (isset($parts['password'])) {
        $url .= ":{$parts['password']}";
      }
      $url .= '@';
    }
    if (isset($parts['host'])) {
      $url .= $parts['host'];
    }
    if (isset($parts['port'])) {
      $url .= ":{$parts['port']}";
    }
    if (isset($parts['path'])) {
      $url .= $parts['path'];
    }
    if (isset($parts['query'])) {
      $url .= "?{$parts['query']}";
    }
    if (isset($parts['fragment'])) {
      $url .= "#{$parts['fragment']}";
    }
    return $url;
  }
497560
protected function normalizeParts(array $parts)
    {
        $blockSize = $this->getPartSize();
        $callback  = function ($value) {
            return Util::safeStrlen($value);
        };
        $maxSize = max(array_map($callback, $parts));
        if ($maxSize % $blockSize != 0) {
            $maxSize += $blockSize - ($maxSize % $blockSize);
        }
        foreach ($parts as &$part) {
            $part = $this->str_pad($part, $maxSize, chr(0));
            $part = str_split($part, $blockSize);
        }

        return $parts;
    }
1142299
public function mix(array $parts)
    {
        if (empty($parts)) {
            return '';
        }
        $len        = Util::safeStrlen($parts[0]);
        $parts      = $this->normalizeParts($parts);
        $stringSize = count($parts[0]);
        $partsSize  = count($parts);
        $result     = '';
        $offset     = 0;
        for ($i = 0; $i < $stringSize; $i++) {
            $stub = $parts[$offset][$i];
            for ($j = 1; $j < $partsSize; $j++) {
                $newKey = $parts[($j + $offset) % $partsSize][$i];
                //Alternately mix the output for each source
                if ($j % 2 == 1) {
                    $stub ^= $this->mixParts1($stub, $newKey);
                } else {
                    $stub ^= $this->mixParts2($stub, $newKey);
                }
            }
            $result .= $stub;
            $offset  = ($offset + 1) % $partsSize;
        }

        return Util::safeSubstr($result, 0, $len);
    }
514800
public function with(array $parts)
    {
        foreach ($parts as $key => $part)
        {
            $this->with[$key] = $part;
        }

        return $this;
    }
134935
public function map(array $parts): array
    {
        if ($this->isMatchingSinglePart($parts)) {
            $parts[0] = new Suffix($parts[0], $this->suffixes[$this->getKey($parts[0])]);
            return $parts;
        }

        $start = count($parts) - 1;

        for ($k = $start; $k > 1; $k--) {
            $part = $parts[$k];

            if (!$this->isSuffix($part)) {
                break;
            }

            $parts[$k] = new Suffix($part, $this->suffixes[$this->getKey($part)]);
        }

        return $parts;
    }
733252
public function map(array $parts): array
    {
        if (count($parts) < 2) {
            return [$this->handleSinglePart($parts[0])];
        }

        $pos = $this->findFirstnamePosition($parts);

        if (null !== $pos) {
            $parts[$pos] = new Firstname($parts[$pos]);
        }

        return $parts;
    }
1368195
public function extract($parts = null) {
        if ($parts === null) {
            return $this->data;
        }

        if (is_array($parts)) {
            $result = array();

            foreach ($this->data as $match) {
                $row = array();
                foreach ($parts as $key) {
                    if (isset($match[$key])) {
                        $row[$key] = isset($match[$key])?$match[$key]:null;
                    }
                }

                $result[] = $row;
            }

            return $result;
        }

        $result = array();
        foreach ($this->data as $match) {
            $result[] = isset($match[$parts])?$match[$parts]:null;
        }

        return $result;
    }
161717
protected function parse($part) {
			$subPos = strpos($part, self::TOKEN_SUBFIELD_OPEN);

			if ($subPos === false)
				return [$part => true];

			$key = substr($part, 0, $subPos++);
			$fields = [];

			$subSelector = substr($part, $subPos, -1);
			$subLength = strlen($subSelector);
			$subPos = 0;

			while ($fragment = $this->getNextFragment($subSelector, $subLength, $subPos))
				if (($index = strpos($fragment, self::TOKEN_SUBFIELD_OPEN)) !== false) {
					$subfields = $this->parse($fragment);

					foreach ($subfields as $k => $v)
						$fields[$k] = $v;
				} else
					$fields[$fragment] = true;

			return [$key => $fields];
		}
835314
public static function getNamespaceFromParts($parts) {
		$resultArray = [ ];
		if (! \is_array ( $parts )) {
			$parts = [ $parts ];
		}
		foreach ( $parts as $part ) {
			$resultArray = \array_merge ( $resultArray, \explode ( "\\", $part ) );
		}
		$resultArray = \array_diff ( $resultArray, [ "" ] );
		return \implode ( "\\", $resultArray );
	}