function create($spec) { if (!is_string($spec)) { throw new \lang\IllegalArgumentException('Create expects its first argument to be a string'); } // Parse type specification: "new " TYPE "()"? // TYPE:= B "<" ARGS ">" // ARGS:= TYPE [ "," TYPE [ "," ... ]] $b = strpos($spec, '<'); $base = substr($spec, 4, $b - 4); $typeargs = \lang\Type::forNames(substr($spec, $b + 1, strrpos($spec, '>') - $b - 1)); // Instantiate, passing the rest of any arguments passed to create() // BC: Wrap IllegalStateExceptions into IllegalArgumentExceptions $class = \lang\XPClass::forName(strstr($base, '.') ? $base : \lang\XPClass::nameOf($base)); try { $reflect = $class->newGenericType($typeargs)->reflect(); if ($reflect->hasMethod('__construct')) { $a = func_get_args(); return $reflect->newInstanceArgs(array_slice($a, 1)); } else { return $reflect->newInstance(); } } catch (\lang\IllegalStateException $e) { throw new \lang\IllegalArgumentException($e->getMessage()); } catch (ReflectionException $e) { throw new \lang\IllegalAccessException($e->getMessage()); } }