public function add(core\interfaces\Named $argument) : core\collections\interfaces\NamedObjectSet
    {
        // The Collection is locked once populated with an Argument accepting multiple values and since we don't allow
        // overwriting by setting, might as well check for this here already.
        if ($this->hasMultiparam) {
            throw new \LogicException("Cannot define additional arguments after an Argument [name: ".end($this->items)->getName()."] which accepts multiple values.");
        }

        // Make sure we got the proper type.
        if (!$argument instanceof input\Argument) {
            throw new \InvalidArgumentException('Expected an instance of ['.input\Argument::class.'], got ['.diagnostics\Debug::getTypeName($argument).'] instead.');
        }

        // We'll need those a few times.
        $name  = $argument->getName();
        $value = $argument->getValue();

        // Arguments are stored by name so no duplicates allowed here.
        if (isset($this->items[$name])) {
            throw new \LogicException("An Argument with this name [$name] has already been defined.");
        }

        // Keep track of how many Arguments we will require to be present in the Input later on.
        if ($value->is(input\Value::REQUIRED)) {
            if ($this->hasOptional) {
                throw new \LogicException("Cannot add a required Argument after an optional one.");
            }

            ++$this->required;
        } else {
            $this->hasOptional = true;
        }

        // If the Argument accepts multiple values, this effectively requires it to be the last Argument in
        // the definition, which locks this Bag.
        if ($value instanceof input\values\Multiple) {
            $this->hasMultiparam = true;
        }

        // Finally, store the Argument.
        $this->items[$name] = $argument;

        return $this;
    }