public function populate($data)
    {
        if (is_null($data)) {
            return $this;
        }

        $data = $this->normalizeData($data);

        $fromDb = false;
        if ($this->isDbData($data)) {
            $fromDb = true;
        } else {
            unset($data['id']);
            unset($data['_id']);
        }

        $validation = $this->arr();

        /* @var $entityAttribute AbstractAttribute */
        foreach ($this->attributes as $attributeName => $entityAttribute) {
            if (!$entityAttribute->getAfterPopulate()) {
                $this->populateAttribute($attributeName, $entityAttribute, $validation, $data, $fromDb);
            }
        }

        foreach ($this->attributes as $attributeName => $entityAttribute) {
            if ($entityAttribute->getAfterPopulate()) {
                $this->populateAttribute($attributeName, $entityAttribute, $validation, $data, $fromDb);
            }
        }

        if ($validation->count() > 0) {
            $attributes = [];
            foreach ($validation as $attr => $error) {
                foreach ($error as $key => $value) {
                    $attributes[$key] = $value;
                }
            }
            $ex = new EntityException(EntityException::VALIDATION_FAILED, [get_class($this), $validation->count()]);
            $ex->setInvalidAttributes($attributes);
            throw $ex;
        }

        return $this;
    }