Build message part object

@param array  $part
@param int    $count
@param string $parent
555577
protected function structure_part($part, $count = 0, $parent = '', $mime_headers = null)
    {
        $struct = new rcube_message_part;
        $struct->mime_id = empty($parent) ? (string)$count : "$parent.$count";

        // multipart
        if (is_array($part[0])) {
            $struct->ctype_primary = 'multipart';

        /* RFC3501: BODYSTRUCTURE fields of multipart part
            part1 array
            part2 array
            part3 array
            ....
            1. subtype
            2. parameters (optional)
            3. description (optional)
            4. language (optional)
            5. location (optional)
        */

            // find first non-array entry
            for ($i=1; $i<count($part); $i++) {
                if (!is_array($part[$i])) {
                    $struct->ctype_secondary = strtolower($part[$i]);

                    // read content type parameters
                    if (is_array($part[$i+1])) {
                        $struct->ctype_parameters = array();
                        for ($j=0; $j<count($part[$i+1]); $j+=2) {
                            $param = strtolower($part[$i+1][$j]);
                            $struct->ctype_parameters[$param] = $part[$i+1][$j+1];
                        }
                    }

                    break;
                }
            }

            $struct->mimetype = 'multipart/'.$struct->ctype_secondary;

            // build parts list for headers pre-fetching
            for ($i=0; $i<count($part); $i++) {
                if (!is_array($part[$i])) {
                    break;
                }
                // fetch message headers if message/rfc822
                // or named part (could contain Content-Location header)
                if (!is_array($part[$i][0])) {
                    $tmp_part_id = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1;
                    if (strtolower($part[$i][0]) == 'message' && strtolower($part[$i][1]) == 'rfc822') {
                        $mime_part_headers[] = $tmp_part_id;
                    }
                    else if (in_array('name', (array)$part[$i][2]) && empty($part[$i][3])) {
                        $mime_part_headers[] = $tmp_part_id;
                    }
                }
            }

            // pre-fetch headers of all parts (in one command for better performance)
            // @TODO: we could do this before _structure_part() call, to fetch
            // headers for parts on all levels
            if ($mime_part_headers) {
                $mime_part_headers = $this->conn->fetchMIMEHeaders($this->folder,
                    $this->msg_uid, $mime_part_headers);
            }

            $struct->parts = array();
            for ($i=0, $count=0; $i<count($part); $i++) {
                if (!is_array($part[$i])) {
                    break;
                }
                $tmp_part_id = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1;
                $struct->parts[] = $this->structure_part($part[$i], ++$count, $struct->mime_id,
                    $mime_part_headers[$tmp_part_id]);
            }

            return $struct;
        }

        /* RFC3501: BODYSTRUCTURE fields of non-multipart part
            0. type
            1. subtype
            2. parameters
            3. id
            4. description
            5. encoding
            6. size
          -- text
            7. lines
          -- message/rfc822
            7. envelope structure
            8. body structure
            9. lines
          --
            x. md5 (optional)
            x. disposition (optional)
            x. language (optional)
            x. location (optional)
        */

        // regular part
        $struct->ctype_primary = strtolower($part[0]);
        $struct->ctype_secondary = strtolower($part[1]);
        $struct->mimetype = $struct->ctype_primary.'/'.$struct->ctype_secondary;

        // read content type parameters
        if (is_array($part[2])) {
            $struct->ctype_parameters = array();
            for ($i=0; $i<count($part[2]); $i+=2) {
                $struct->ctype_parameters[strtolower($part[2][$i])] = $part[2][$i+1];
            }

            if (isset($struct->ctype_parameters['charset'])) {
                $struct->charset = $struct->ctype_parameters['charset'];
            }
        }

        // #1487700: workaround for lack of charset in malformed structure
        if (empty($struct->charset) && !empty($mime_headers) && $mime_headers->charset) {
            $struct->charset = $mime_headers->charset;
        }

        // read content encoding
        if (!empty($part[5])) {
            $struct->encoding = strtolower($part[5]);
            $struct->headers['content-transfer-encoding'] = $struct->encoding;
        }

        // get part size
        if (!empty($part[6])) {
            $struct->size = intval($part[6]);
        }

        // read part disposition
        $di = 8;
        if ($struct->ctype_primary == 'text') {
            $di += 1;
        }
        else if ($struct->mimetype == 'message/rfc822') {
            $di += 3;
        }

        if (is_array($part[$di]) && count($part[$di]) == 2) {
            $struct->disposition = strtolower($part[$di][0]);
            if ($struct->disposition && $struct->disposition !== 'inline' && $struct->disposition !== 'attachment') {
                // RFC2183, Section 2.8 - unrecognized type should be treated as "attachment"
                $struct->disposition = 'attachment';
            }
            if (is_array($part[$di][1])) {
                for ($n=0; $n<count($part[$di][1]); $n+=2) {
                    $struct->d_parameters[strtolower($part[$di][1][$n])] = $part[$di][1][$n+1];
                }
            }
        }

        // get message/rfc822's child-parts
        if (is_array($part[8]) && $di != 8) {
            $struct->parts = array();
            for ($i=0, $count=0; $i<count($part[8]); $i++) {
                if (!is_array($part[8][$i])) {
                    break;
                }
                $struct->parts[] = $this->structure_part($part[8][$i], ++$count, $struct->mime_id);
            }
        }

        // get part ID
        if (!empty($part[3])) {
            $struct->content_id = $part[3];
            $struct->headers['content-id'] = $part[3];

            if (empty($struct->disposition)) {
                $struct->disposition = 'inline';
            }
        }

        // fetch message headers if message/rfc822 or named part (could contain Content-Location header)
        if ($struct->ctype_primary == 'message' || ($struct->ctype_parameters['name'] && !$struct->content_id)) {
            if (empty($mime_headers)) {
                $mime_headers = $this->conn->fetchPartHeader(
                    $this->folder, $this->msg_uid, true, $struct->mime_id);
            }

            if (is_string($mime_headers)) {
                $struct->headers = rcube_mime::parse_headers($mime_headers) + $struct->headers;
            }
            else if (is_object($mime_headers)) {
                $struct->headers = get_object_vars($mime_headers) + $struct->headers;
            }

            // get real content-type of message/rfc822
            if ($struct->mimetype == 'message/rfc822') {
                // single-part
                if (!is_array($part[8][0])) {
                    $struct->real_mimetype = strtolower($part[8][0] . '/' . $part[8][1]);
                }
                // multi-part
                else {
                    for ($n=0; $n<count($part[8]); $n++) {
                        if (!is_array($part[8][$n])) {
                            break;
                        }
                    }
                    $struct->real_mimetype = 'multipart/' . strtolower($part[8][$n]);
                }
            }

            if ($struct->ctype_primary == 'message' && empty($struct->parts)) {
                if (is_array($part[8]) && $di != 8) {
                    $struct->parts[] = $this->structure_part($part[8], ++$count, $struct->mime_id);
                }
            }
        }

        // normalize filename property
        $this->set_part_filename($struct, $mime_headers);

        return $struct;
    }
303836
private static function getStringElement(\DOMElement $parent, string $name) : ?string
    {
        $e = self::getStringElements($parent, $name);
        if (empty($e)) {
            return null;
        }
        if (count($e) > 1) {
            throw new \Exception('More than one '.$name.' in '.$parent->tagName);
        }

        return $e[0];
    }
1001548
private function extractHeaderAddressPart($header, $part) {
        if (property_exists($header, $part)) {
            $this->$part = $this->parseAddresses($header->$part);
        }
    }
612738
private function joinWithRelation($parent, $child)
    {
        if (!empty($child->join)) {
            foreach ($child->join as $join) {
                $this->join[] = $join;
            }
        }
    }
673719
private function finalizeRouterArguments(
        array $parts,
        array $camelizedParts,
        $actionNamespace,
        $bundleName,
        $method
    ) {
        array_splice($camelizedParts, 1, 1, 'Responder');
        $responderNamespace = implode('\\', $camelizedParts) . 'Responder';

        $delta = ($this->routingPhase == self::ROUTING_PHASE_METHOD) ? 2 : 1;

        $this->action = ($this->routingPhase == self::ROUTING_PHASE_METHOD)
            ? $method
            : $parts[count($camelizedParts) - 2];
        $this->bundle = strtolower($bundleName);
        $this->actionNamespace = $actionNamespace;
        $this->responderNamespace = $responderNamespace;
        $this->params = array_slice($parts, count($camelizedParts) - $delta, -1);

        $this->isMatched = true;
    }
1262142
public function append(DOMElement &$parent, &$child)
    {
        // Check element
        if (empty($child)) {
            throw new InvalidArgumentException('You are trying to append an empty element.');
        }

        // Append element
        $parent->appendChild($child);

        // Return the DOMElement
        return $parent;
    }
251741
protected function buildRegex(array $parts, array $constraints, &$groupIndex = 1) {
        $regex = '';
        foreach ($parts as $part) {
            switch ($part[0]) {
                case 'literal':
                    $regex .= preg_quote($part[1]);
                    break;
                case 'parameter':
                    $groupName = '?P<param' . $groupIndex . '>';
                    if (isset($constraints[$part[1]])) {
                        $regex .= '(' . $groupName . $constraints[$part[1]] . ')';
                    } elseif ($part[2] === null) {
                        $regex .= '(' . $groupName . '[^/]+)';
                    } else {
                        $regex .= '(' . $groupName . '[^' . $part[2] . ']+)';
                    }
                    $this->paramMap['param' . $groupIndex++] = $part[1];
                    break;
                case 'optional':
                    $regex .= '(?:' . $this->buildRegex($part[1], $constraints, $groupIndex) . ')?';
                    break;
            }
        }
        return $regex;
    }
387153
private function failsSignedPartFilter(MessagePart $part)
    {
        if ($this->signedpart === static::FILTER_OFF) {
            return false;
        } elseif (!$part->isMime() || $part->getParent() === null) {
            return ($this->signedpart === static::FILTER_INCLUDE);
        }
        $partMimeType = $part->getContentType();
        $parentMimeType = $part->getParent()->getContentType();
        $parentProtocol = $part->getParent()->getHeaderParameter('Content-Type', 'protocol');
        if (strcasecmp($parentMimeType, 'multipart/signed') === 0 && strcasecmp($partMimeType, $parentProtocol) === 0) {
            return ($this->signedpart === static::FILTER_EXCLUDE);
        }
        return ($this->signedpart === static::FILTER_INCLUDE);
    }
1147100
public function addPart(PartInterface $part, $name = null)
    {
        if ($name == null) {
            $name = $part->getName();
        }
        $this->parts[$name] = $part;
    }
67425
protected function joinSegment(Model $parent, $segment, $type)
    {
        $relation = $parent->{$segment}();
        $related  = $relation->getRelated();
        $table    = $related->getTable();

        if ($relation instanceof BelongsToMany || $relation instanceof HasManyThrough) {
            $this->joinIntermediate($parent, $relation, $type);
        }

        if (!$this->alreadyJoined($join = $this->getJoinClause($parent, $relation, $table, $type))) {
            $this->query->joins[] = $join;
        }

        return $related;
    }
1035082
public function upToSegment($count) {
		$segments = new ArrayObject();
		for ($i = 0; $i < $count; $i++) {
			$segments->push($this->segments[$i]);
		}

		return new Path($segments->join('/'));
	}
907540
public function part($channelarray, $reason = null,
        $priority = SMARTIRC_MEDIUM
    ) {
        if (!is_array($channelarray)) {
            $channelarray = array($channelarray);
        }

        $channellist = implode(',', $channelarray);

        if ($reason !== null) {
            $this->send('PART '.$channellist.' :'.$reason, $priority);
        } else {
            $this->send('PART '.$channellist, $priority);
        }
        return $this;
    }
910588
private function get_mime_numbers(&$part)
    {
        if (strlen($part->mime_id))
            $this->mime_parts[$part->mime_id] = &$part;

        if (is_array($part->parts))
            for ($i=0; $i<count($part->parts); $i++)
                $this->get_mime_numbers($part->parts[$i]);
    }
855265
public function add(Expr\Part $part)
    {
        if(!$part instanceof ConditionalExpression) {
            throw new \RuntimeException(sprintf('ConditionalClause only accept ConditionalExpression, but "%s" is given', is_object($part) ? get_class($part) : gettype($part)));
        }

        if(!$this->expression) {
            $this->expression = $part;
        } else if(($this->expression instanceof LogicalExpression) && $this->expression->isType(LogicalExpression::TYPE_AND)) {
            // if root expression is AND logicalExpression, then append
            $this->expression->add($part);
        } else {
            // create new AND logicalExpression and append both current expression and new expresion
            $and = new Expr\LogicalExpression(array(
                    $this->expression,
                    $part
                ), Expr\LogicalExpression::TYPE_AND);

            $this->expression = $and;
        }
        return $this;
    }
944965
public function countParts(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null)
    {
        $partial = $this->collPartsPartial && !$this->isNew();
        if (null === $this->collParts || null !== $criteria || $partial) {
            if ($this->isNew() && null === $this->collParts) {
                return 0;
            }

            if ($partial && !$criteria) {
                return count($this->getParts());
            }

            $query = ChildSkillPartQuery::create(null, $criteria);
            if ($distinct) {
                $query->distinct();
            }

            return $query
                ->filterBySkillRelatedByPartId($this)
                ->count($con);
        }

        return count($this->collParts);
    }
571397
@SuppressWarnings("unchecked")
  public void setParent(PvmExecutionImpl parent) {
    PvmExecutionImpl currentParent = getParent();

    setParentExecution(parent);

    if (currentParent != null) {
      currentParent.getExecutions().remove(this);
    }

    if (parent != null) {
      ((List<PvmExecutionImpl>) parent.getExecutions()).add(this);
    }
  }
1188656
private function _rebuild(NodeInfo $parentNodeInfo, bool $onlyValidate = false, int $left = 1, int $level = 0): int
    {
        $adapter = $this->getManipulator();

        $right = $left + 1;

        $children = $adapter->getChildrenNodeInfo($parentNodeInfo->getId());

        foreach ($children as $childNode) {
            $right = $this->_rebuild($childNode, $onlyValidate, $right, $level + 1);
        }

        if ($parentNodeInfo->getLeft() != $left
            || $parentNodeInfo->getRight() != $right
            || $parentNodeInfo->getLevel() != $level) {
            $parentNodeInfo->setLeft($left);
            $parentNodeInfo->setRight($right);
            $parentNodeInfo->setLevel($level);

            if ($onlyValidate) {
                throw new TreeIsBrokenException();
            } else {
                $adapter->updateNodeMetadata($parentNodeInfo);
            }
        }

        return $right + 1;
    }