protected function copy(Array $filter = array())
    {
        $filter = array_flip(array_merge($filter, $this->_readonlyAttr));

        $copy = new $this();
        $attributes = $this->selfToArray();
        foreach ($attributes as $key => &$value) {
            if (array_key_exists($key, $filter)) {
                unset($attributes[$key]);
            } elseif ($value instanceof ArrayObject) {
                try {
                    $newElements = $value->copy($filter);
                    $value = new $value;
                    foreach ($newElements as $elmCopy) {
                        $value->append($elmCopy);
                    }
                } catch (ArrayObject\UndefinedMethodException $e) {
                    // pass
                }
            } elseif ($value instanceof AbstractModel) {
                $value = $value->copy($filter);
            }
        }
        $copy->setData($attributes);
        return $copy;
    }