public static function fromReflection(ReflectionClass $reflectionClass)
    {
        if ($reflectionClass->isInterface() === true || $reflectionClass->isTrait() === true) {
            throw new InvalidArgumentException('The reflected class can not be a trait or interface.');
        }

        $cg = new static($reflectionClass->getShortName(), $reflectionClass->getNamespaceName());
        $cg->setFinal($reflectionClass->isFinal());
        $cg->setAbstract($reflectionClass->isAbstract());

        // Extension.
        $parentClass = $reflectionClass->getParentClass();
        if ($parentClass !== false) {
            if ($parentClass->getNamespaceName() === $cg->getNamespace()) {
                $extends = $parentClass->getShortName();
            } else {
                $extends = '\\' . $parentClass->getName();
            }
            $cg->setExtends($extends);
        }

        // Interfaces.
        $interfaces = array();
        foreach ($reflectionClass->getOwnInterfaces() as $interface) {
            if ($interface->getNamespaceName() === $cg->getNamespace()) {
                $interfaces[] = $interface->getShortName();
            } else {
                $interfaces[] = '\\' . $interface->getName();
            }
        }
        $cg->setImplements($interfaces);

        // Documentation.
        if ($reflectionClass->getReflectionDocComment()->isEmpty() !== true) {
            $cg->setDocumentation(DocCommentGenerator::fromReflection($reflectionClass->getReflectionDocComment()));
        }

        // Uses.
        foreach ($reflectionClass->getUses() as $use) {
            $use = UseTraitGenerator::fromReflection($use);
            if ($cg->getNamespace() !== null && strpos($use->getTraitClass(), $cg->getNamespace()) === 0) {
                $use->setTraitClass(substr($use->getTraitClass(), strlen($cg->getNamespace()) + 1));
            }

            $cg->addTraitUse($use);
        }

        // Constants.
        foreach ($reflectionClass->getOwnConstants() as $constant) {
            $cg->addConstant(ClassConstantGenerator::fromReflection($constant));
        }

        // Properties.
        foreach ($reflectionClass->getOwnProperties() as $property) {
            $cg->addProperty(PropertyGenerator::fromReflection($property));
        }

        // Methods.
        foreach ($reflectionClass->getOwnMethods() as $method) {
            $cg->addMethod(MethodGenerator::fromReflection($method));
        }

        return $cg;
    }