protected function updateInternal($attributes = null)
{
    if (!$this->beforeSave(false)) {
        return false;
    }
    $values = $this->getDirtyAttributes($attributes);
    if (empty($values)) {
        $this->afterSave(false, $values);
        return 0;
    }
    $collection = static::getCollection();
    if (isset($values['newFileContent'])) {
        $newFileContent = $values['newFileContent'];
        unset($values['newFileContent']);
    }
    if (isset($values['file'])) {
        $newFile = $values['file'];
        unset($values['file']);
    }
    if (isset($newFileContent) || isset($newFile)) {
        $fileAssociatedAttributeNames = [
            'filename',
            'uploadDate',
            'length',
            'chunkSize',
            'md5',
            'file',
            'newFileContent'
        ];
        $values = array_merge($this->getAttributes(null, $fileAssociatedAttributeNames), $values);
        $rows = $this->deleteInternal();
        $insertValues = $values;
        $insertValues['_id'] = $this->getAttribute('_id');
        if (isset($newFileContent)) {
            $collection->insertFileContent($newFileContent, $insertValues);
        } else {
            $fileName = $this->extractFileName($newFile);
            $collection->insertFile($fileName, $insertValues);
        }
        $this->setAttribute('newFileContent', null);
        $this->setAttribute('file', null);
    } else {
        $condition = $this->getOldPrimaryKey(true);
        $lock = $this->optimisticLock();
        if ($lock !== null) {
            if (!isset($values[$lock])) {
                $values[$lock] = $this->$lock + 1;
            }
            $condition[$lock] = $this->$lock;
        }
        
        
        $rows = $collection->update($condition, $values);
        if ($lock !== null && !$rows) {
            throw new StaleObjectException('The object being updated is outdated.');
        }
    }
    $changedAttributes = [];
    foreach ($values as $name => $value) {
        $changedAttributes[$name] = $this->getOldAttribute($name);
        $this->setOldAttribute($name, $value);
    }
    $this->afterSave(false, $changedAttributes);
    return $rows;
}