protected function parse(array $args)
    {
        $params     = array(
            'serverURL'     => null,
            'procedure'     => null,
            'additional'    => array(),
        );
        $options    = array(
            'd' => false,
            'h' => false,
            'n' => false,
            't' => new \DateTimeZone(@date_default_timezone_get()),
            'v' => 0,
            'V' => false,
            'x' => false,
        );

        while (count($args)) {
            $v = array_shift($args);

            if ($params['serverURL'] === null) {
                if (substr($v, 0, 1) == '-') {
                    $p = array();
                    $v = (string) substr($v, 1);
                    foreach (str_split($v) as $o) {
                        if (!array_key_exists($o, $options)) {
                            throw new \Exception(
                                'Unknown option "'.$o.'". '.
                                'Use -h to get help.'
                            );
                        }

                        if (is_bool($options[$o])) {
                            $options[$o] = true;
                        } elseif (is_int($options[$o])) {
                            $options[$o]++;
                        } else {
                            $p[] = $o;
                        }
                    }

                    foreach ($p as $o) {
                        if (!count($args)) {
                            throw new \Exception(
                                'Not enough arguments for option "'.$o.'".'
                            );
                        }
                        $v = array_shift($args);
                        if (!($options[$o] instanceof \DateTimeZone)) {
                            $options[$o] = new \DateTimeZone($v);
                        }
                    }
                } else {
                    $params['serverURL'] = $v;
                }
                continue;
            }

            if ($params['procedure'] === null) {
                $params['procedure'] = $v;
                break;
            }
        }

        while (count($args)) {
            $params['additional'][] = $this->parseParam($args, $options['t']);
        }

        return array($options, $params);
    }