Fetches all properties' annotations
@param string $docType The type of documentation to fetch e.g. param, see, link
@param boolean $forceNew Indicates whether to fetch fresh annotations and not cached ones
@return array
162376
final public function getProperties($docType = '', $forceNew = false) {
        $this->checkExists('properties', $docType, $forceNew);
        return ($this->annotations['properties']) ? $this->annotations['properties'] : array();
    }
274295
public static function init($model, $propertyName, $annotation, $forceInit = false)
    {
        $className = BeanFactory::getObjectClass($model);

        if(!$forceInit)
        {
            $autoSelect = AnnotationManager::getPropertyAnnotations($className, $propertyName, AutoSelect::class)[0] ?? null;
            if($autoSelect && !$autoSelect->status)
            {
                return;
            }
        }

        if(is_array($annotation))
        {
            $firstAnnotation = reset($annotation);
            if($firstAnnotation instanceof \Imi\Model\Annotation\Relation\PolymorphicToOne)
            {
                static::initByPolymorphicToOne($model, $propertyName, $annotation);
            }
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\OneToOne)
        {
            static::initByOneToOne($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\OneToMany)
        {
            static::initByOneToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\ManyToMany)
        {
            static::initByManyToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicOneToOne)
        {
            static::initByPolymorphicOneToOne($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicOneToMany)
        {
            static::initByPolymorphicOneToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicManyToMany)
        {
            static::initByPolymorphicManyToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicToMany)
        {
            static::initByPolymorphicToMany($model, $propertyName, $annotation);
        }
    }
406996
private function annotationRel(array $annotations, LinkType $link, ResourceObject $current) : ResourceObject
    {
        /* @noinspection LoopWhichDoesNotLoopInspection */
        foreach ($annotations as $annotation) {
            if ($annotation->rel !== $link->key) {
                continue;
            }
            $uri = uri_template($annotation->href, $current->body);
            $rel = $this->factory->newInstance($uri);
            /* @noinspection UnnecessaryParenthesesInspection */
            $request = new Request($this->invoker, $rel, Request::GET, (new Uri($uri))->query);

            return $this->invoker->invoke($request);
        }

        throw new LinkRelException("rel:{$link->key} class:" . get_class($current), 500);
    }
393930
public function parse($docblock)
    {
        $docblock = $this->getDocblockTagsSection($docblock);
        $annotations = $this->parseAnnotations($docblock);
        foreach ($annotations as &$value) {
            if (1 == count($value)) {
                $value = $value[0];
            }
        }

        return $annotations;
    }
1199752
final public function getMethods($docType = '', $forceNew = false) {
        $this->checkExists('methods', $docType, $forceNew);
        return ($this->annotations['methods']) ? $this->annotations['methods'] : array();
    }
244971
private static List<Attribute> getResolvableAttrs(EntityType entityType, Fetch fetch) {
    return Streams.stream(entityType.getAtomicAttributes())
        .filter(EntityTypeUtils::isReferenceType)
        .filter(attr -> attr.getExpression() == null)
        .filter(attr -> fetch.hasField(attr.getName()))
        .collect(Collectors.toList());
  }
158393
public function getTypes(DocType $varType): array
    {
        $types = [];
        $nullable = false;

        if ($varType instanceof Nullable) {
            $nullable = true;
            $varType = $varType->getActualType();
        }

        if (!$varType instanceof Compound) {
            if ($varType instanceof Null_) {
                $nullable = true;
            }

            $type = $this->createType($varType, $nullable);
            if (null !== $type) {
                $types[] = $type;
            }

            return $types;
        }

        $varTypes = [];
        for ($typeIndex = 0; $varType->has($typeIndex); ++$typeIndex) {
            $type = $varType->get($typeIndex);

            // If null is present, all types are nullable
            if ($type instanceof Null_) {
                $nullable = true;
                continue;
            }

            $varTypes[] = $type;
        }

        foreach ($varTypes as $varType) {
            $type = $this->createType($varType, $nullable);
            if (null !== $type) {
                $types[] = $type;
            }
        }

        return $types;
    }
1120258
private function mapBindings($bindingType, array $bindings)
    {
        $res = [];
        foreach ($bindings as $key => $binding) {
            if ($binding instanceof Cursor) {
                $value = [
                    'cursor' => $binding->cursor()
                ];
            } else {
                $value = [
                    'value' => $this->entityMapper->valueObject($binding)
                ];
            }

            if ($bindingType === self::BINDING_NAMED) {
                $res[$key] = $value;
            } else {
                $res[] = $value;
            }
        }

        return $res;
    }
291693
public function getAnnotationsByType($type)
    {
        $annotations = [];
        foreach ($this->annotations as $an) {
            if ($an->getName() == $type) {
                $annotations[] = $an;
            }
        }

        return $annotations;
    }
1079270
public static function getDocumentByType($documentType)
    {
        $documentType = strtoupper($documentType);
        if (isset(self::$availableDocumentList[$documentType])) {
            return self::$availableDocumentList[$documentType];
        } else {
            return false;
        }
    }
69930
public function get($doctype)
    {
        if (isset($this->aliases[$doctype])) {
            $doctype = $this->aliases[$doctype];
        }
        if (!isset($this->doctypes[$doctype])) {
            trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR);
            $anon = new HTMLPurifier_Doctype($doctype);
            return $anon;
        }
        return $this->doctypes[$doctype];
    }
1275977
protected function extractParamAnnotations(string $docComment): array
    {
        $pattern = '/@param(?:\s+([^$"]\S+))?(?:\s+\$(\w+))?(?:\s+"([^"]++)")?/';

        if (!(bool)preg_match_all($pattern, $docComment, $matches, PREG_SET_ORDER)) {
            return [];
        }

        $annotations = [];

        foreach ($matches as $index => $match) {
            $annotations[$index] = isset($match[3]) && $match[3] !== '' ? $match[3] : null;
        }

        return $annotations;
    }
994142
public function get($entity, $annotation)
    {
        $properties = $this->getProperties($entity);

        $return = array();
        foreach ($properties as $reflectionProperty) {
            $propertyAnnotation = $this->reader->getPropertyAnnotation($reflectionProperty, $annotation);
            if (!is_null($propertyAnnotation) && get_class($propertyAnnotation) == $annotation) {
                $return[$reflectionProperty->name] = $reflectionProperty;
            }
        }

        return $return;
    }
599328
private function getCurlResource($forceNew = false) {

        if ((true === $forceNew) || (!$this->curlResourceIsValid())) {
            $this->curlResource = curl_init();
        }

        return $this->curlResource;

    }
113587
public function parse($docPath)
    {
        if ( ! is_dir($docPath)) {
            throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $docPath));
        }

        $sorter = function(\SplFileInfo $a, \SplFileInfo $b) {
            $aIsDir = $a->isDir();
            $bIsDir = $b->isDir();

            if ($aIsDir !== $bIsDir) {
                return $aIsDir ? -1 : 1;
            }

            return -1 * strcmp($a->getRealPath(), $b->getRealPath());
        };

        $this->classes = $this->functions = $this->constants = $this->aliasedFunctions = array();
        foreach (Finder::create()->in($docPath)->name('*.xml')->sort($sorter) as $file) {
            assert($file instanceof \SplFileInfo);
            $this->file = $file;

            $content = file_get_contents($file->getRealPath());
            $content = preg_replace('#<refsect1 role="(?:examples|notes|seealso)">.*?</refsect1>#s', '', $content);
            $content = preg_replace(self::$undefinedEntities, '', $content);
            $content = preg_replace(array_keys(self::$entitySubstitutes), array_values(self::$entitySubstitutes), $content);

            if ('' === trim($content)) {
                continue;
            }

            $doc = simplexml_load_string($content);
            $doc->registerXPathNamespace('search', 'http://docbook.org/ns/docbook');
            if (isset($doc->refnamediv)) {
                // Ignore methods, we will parse them as part of the class.
                if (false !== strpos((string) $doc->refnamediv->refname, '::')) {
                    $this->parseMethod($doc);

                    continue;
                }

                $this->parseFunction($doc);

                continue;
            }

            $this->tryParsingClass($doc);
            $this->tryParsingConstant($doc);
        }

        if ( ! empty($this->aliasedFunctions)) {
            foreach ($this->functions as $function) {
                $aliasedNames = array_keys($this->aliasedFunctions, $function->getName(), true);

                if (empty($aliasedNames)) {
                    continue;
                }

                foreach ($aliasedNames as $name) {
                    $newFunction = clone $function;
                    $newFunction->setName($name);
                    $newFunction->setAttribute('alias_of', $function->getName());
                    $this->functions[] = $newFunction;
                }
            }
        }

        foreach ($this->classes as $class) {
            $this->typeRefiner->refineClass($class);
        }

        $rs = array('classes' => $this->classes, 'functions' => $this->functions, 'constants' => $this->constants);
        $this->classes = $this->functions = $this->constants = $this->aliasedFunctions = null;

        return $rs;
    }
1141869
protected static function parseAnnotations($docblock)
    {
        $annotations = array();
        // Strip away the docblock header and footer
        // to ease parsing of one line annotations
        $docblock = substr($docblock, 3, -2);

        $re = '/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m';
        if (preg_match_all($re, $docblock, $matches)) {
            $numMatches = count($matches[0]);

            for ($i = 0; $i < $numMatches; ++$i) {
                $annotations[$matches['name'][$i]][] = $matches['value'][$i];
            }
        }

        return $annotations;
    }
752427
private function parseProperties($docType = '') {
        $parents = $this->parents;
        foreach ($this->reflector->getProperties() as $refProp) {
            if (is_string($parents[$refProp->class]))
                $parents[$refProp->class] = array();
            $parents[$refProp->class][$refProp->name] = $this->parseDocComment($refProp->getDocComment(), $docType);
//            $parsed = $this->parseDocComment($refProp->getDocComment(), $docType);
//            if ($parsed)
//                $this->annotations['properties'][$refProp->name] = $parsed;
        }
        $this->annotations['properties'] = array();
        foreach ($parents as $array) {
            if (is_array($array))
                $this->annotations['properties'] = array_merge($this->annotations['properties'], $array);
        }
    }