public function fetch()
    {
        $ret = array();
        $pos = 0;
        $len = count($this->_arguments);

        foreach ($this->_descriptors as $name => $descriptor) {
            $value = $descriptor->getDefault();

            for ($i = $pos; ; $i++) {
                if ($i < $len && $descriptor->match($this->_arguments[$i])) {
                    $value = $this->_arguments[$i];
                    $pos = $i + 1;
                    break;
                } else {
                    if ($descriptor->isRequired()) {
                        throw new InvalidArgumentException(
                            "Argument is required: `$name`"
                        );
                    }
                    if ($i > $len - 1) {
                        break;
                    }
                }
            }

            $ret[$name] = $value;
        }

        return $ret;
    }