protected function initFromSpecString($specString)
    {
        $pattern = '/
        (
                (?:[a-zA-Z0-9-]+)
                (?:
                    \|
                    (?:[a-zA-Z0-9-]+)
                )?
        )

        # option attribute operators
        ([:+?])?

        # value types
        (?:=(boolean|string|number|date|file|dir|url|email|ip|ipv6|ipv4))?
        /x';
        $ret = preg_match($pattern, $specString, $regs);
        if ($ret === false || $ret === 0) {
            throw new Exception('Incorrect spec string');
        }

        $orig = $regs[0];
        $name = $regs[1];
        $attributes = isset($regs[2]) ? $regs[2] : null;
        $type = isset($regs[3]) ? $regs[3] : null;

        $short = null;
        $long = null;

        // check long,short option name.
        if (strpos($name, '|') !== false) {
            list($short, $long) = explode('|', $name);
        } else if (strlen($name) === 1) {
            $short = $name;
        } else if (strlen($name) > 1) {
            $long = $name;
        }

        $this->short = $short;
        $this->long = $long;

        // option is required.
        if (strpos($attributes, ':') !== false) {
            $this->required();
        } else if (strpos($attributes, '+') !== false) {
            // option with multiple value
            $this->multiple();
        } else if (strpos($attributes, '?') !== false) {
            // option is optional.(zero or one value)
            $this->optional();
        } else {
            $this->flag();
        }
        if ($type) {
            $this->isa($type);
        }
    }