final public function setData($data) {
        if ((is_object($data) && !is_a($data, 'Object')) || (!is_object($data) && !is_array($data)))
            throw new \Exception('Data must be either an array or an object that extends Object: ' . gettype($data));
        $data = is_array($data) ? $data : $data->toArray();
        foreach ($data as $attr => $value) {
            if ($this->elements[$attr]) {
                $this->elements[$attr]->setData($value);
            } else
                $this->data[$attr] = $value;
        }
        $this->valid = null;
        return $this;
    }