protected function createObject(string $typeName, ?bool $nullable = false, ?bool $checkCycles = true, ?bool $treatAsNotFound = true): ?object
    {
        if ($checkCycles) {
            $this->underConstruction[$typeName] = true;
        }
        
        try {
            if (!isset($this->typeCache[$typeName])) {
                if (\class_exists($typeName) || \interface_exists($typeName, false)) {
                    $this->typeCache[$typeName] = new \ReflectionClass($typeName);
                } else {
                    $this->typeCache[$typeName] = false;
                }
            }
            
            if ($this->typeCache[$typeName] === false) {
                if ($nullable) {
                    return null;
                }
                
                if ($treatAsNotFound) {
                    throw new NotFoundException(\sprintf('Cannot load type: %s', $typeName));
                }
                
                throw new ContainerException(\sprintf('Cannot load type: %s', $typeName));
            }
            
            if (!$this->typeCache[$typeName]->isInstantiable()) {
                if ($nullable) {
                    return null;
                }
                
                throw new NotFoundException(\sprintf('Type is not instantiable: %s', $typeName));
            }
            
            if (isset($this->constructorCache[$typeName])) {
                $con = $this->constructorCache[$typeName];
            } else {
                $con = $this->constructorCache[$typeName] = $this->typeCache[$typeName]->getConstructor() ?: false;
            }
            
            return ($con === false) ? new $typeName() : new $typeName(...$this->populateArguments($con, null, $typeName));
        } finally {
            if ($checkCycles) {
                unset($this->underConstruction[$typeName]);
            }
        }
    }