public function addFormatter($field, $formatter, $options = null)
    {
        // support for field names as array
        if (is_array($field)) {
            foreach ($field as $f) {
                $this->setFormatter($f, $formatter, $options);
            }

            return $this;
        }

        if (!isset($this->columns[$field])) {
            throw new BaseException('Cannot format nonexistant field '.$field);
        }

        if ($formatter instanceof Closure) {
            $m_name = uniqid();
            $this->addMethod('format_'.$m_name, $formatter);
            $formatter = $m_name;
        }

        if ($this->columns[$field]['type']) {
            $this->columns[$field]['type'] .= ','.$formatter;
        } else {
            $this->columns[$field]['type'] = $formatter;
        }

        if ($options) {
            $this->columns[$field] = array_merge($this->columns[$field], $options);
        }
        $descr = $this->columns[$field];

        if (strpos($formatter, '\\') || strpos($formatter, '/')) {
            // add-on functionality:
            // http://agiletoolkit.org/codepad/gui/grid#codepad_gui_grid_view_example_7_ex
            if (!$this->elements[$formatter.'_'.$field]) {
                $addon = $this->app->normalizeClassName($formatter, 'Controller_Grid_Format');
                $this->elements[$formatter.'_'.$field] = $this->add($addon, $formatter);
            }

            $addon = $this->getElement($formatter.'_'.$field);
            if (!$addon instanceof Controller_Grid_Format) {
                throw $this->exception('Grid formatter class should extend Controller_Grid_Format class')
                    ->addMoreInfo('formater', $formatter);
            }
            $addon->initField($field, $descr);

            return $addon;
        } elseif ($this->hasMethod($m = 'init_'.$formatter)) {
            // execute formatter
            $this->$m($field, $descr);
        }

        return $this;
    }