public function save($force=false)
    {
        if (!self::$_loaded) {
            self::_loadColumns();
        }

        // check for callbacks before validation below
        $calling = get_called_class();
        if (!self::_checkCallback($calling, "before_save", $this)) {
            return false;
        }

        // with all the before callbacks checked, check if its valid
        if (!$this->isValid()) {
            return false;
        }

        $pk         = $calling::isIgnoringCase() ? strtolower($calling::getPK()) : $calling::getPK();
        $pk_value   = array_key_exists($pk, $this->_data) ? $this->_data[$pk] : null;
        $attrs      = $this->_data;

        if (!$pk_value) {
            // if there is a method to get the new primary key value on the class, 
            // call it
            if (method_exists($calling, "getNewPKValue")) {
                $pk_value = $calling::getNewPKValue();
                if (!$this->_data[$pk]) {
                    $this->_data[$pk] = $pk_value;
                }
                $attrs = $this->_data;
            }
        }

        // if found a primary key value, check if exists
        if ($pk_value) {
            $this->_new_rec = !self::find($pk_value);
        }

        $rst    = false;
        $newr   = false;

        if ($this->_new_rec) {
            $newr = true;
            self::_checkCallback($calling, "before_create", $this);
            $rst = $this->_insert($attrs, $calling, $pk, $pk_value);
        } else {
            self::_checkCallback($calling, "before_update", $this);

            // no need to update if there weren't changes
            if (sizeof($this->changed()) < 1 && !$force) {
                Log::log("No changes, not updating");
                $rst = true;
            } else {
                $rst = $this->_update($attrs, $calling, $pk, $pk_value);
            }
        }

        if ($rst) {
            self::_checkCallback($calling, "after_save", $this);
            if ($newr) {
                self::_checkCallback($calling, "after_create", $this);
            } else {
                self::_checkCallback($calling, "after_update", $this);
            }
        }
        $this->_prev_data = $this->_data;
        return $rst;
    }