public function addArgument(Argument $argument)
    {
        $name = $argument->getName();

        if ($this->hasArgument($name)) {
            throw CannotAddArgumentException::existsAlready($name);
        }

        if ($this->hasMultiValuedArgument()) {
            throw CannotAddArgumentException::cannotAddAfterMultiValued();
        }

        if ($argument->isRequired() && $this->hasOptionalArgument()) {
            throw CannotAddArgumentException::cannotAddRequiredAfterOptional();
        }

        if ($argument->isMultiValued()) {
            $this->hasMultiValuedArg = true;
        }

        if ($argument->isOptional()) {
            $this->hasOptionalArg = true;
        }

        $this->arguments[$name] = $argument;

        return $this;
    }