public function isModified()
    {
        if ($this->read_only) {
            return false;
        }

        foreach ($this->getProperties() as $name => $value) {
            $hashed_value = $this->getHashValue($value);
            if (
                isset($this->property_hashes[$name]) &&
                $hashed_value !== $this->property_hashes[$name]
            ) {
                return true;
            }
        }

        foreach ($this->internal_property_autosave as $name => $autosave) {
            if ($autosave && isset($this->sub_data_objects[$name])) {
                $object = $this->sub_data_objects[$name];
                if (
                    $object instanceof SwatDBRecordable &&
                    $object->isModified()
                ) {
                    return true;
                }
            }
        }

        foreach ($this->sub_data_objects as $name => $object) {
            $saver_method =
                'save' . str_replace(' ', '', ucwords(strtr($name, '_', ' ')));

            if (method_exists($this, $saver_method)) {
                $object = $this->sub_data_objects[$name];
                if (
                    $object instanceof SwatDBRecordable &&
                    $object->isModified()
                ) {
                    return true;
                }
            }
        }

        return false;
    }