public function apply(array $properties)
    {
        $properties = $this->applyDefaultAttrValues($properties);
        foreach ($properties as $key => $value) {
            if (true === $this->isAttribute($key)) {
                $this->set($key, $value);
                continue;
            }

            if (true === $this->isEmbedHasOne($key)) {
                if (empty($value)) {
                    $this->clear($key);
                    continue;
                }
                $embed = $this->get($key) ?: $this->createEmbedFor($key, $value);
                if (!is_array($value)) {
                    continue;
                }
                $embed->apply($value);
                $this->set($key, $embed);
                continue;
            }
        }

        foreach ($this->getMetadata()->getEmbeds() as $key => $embeddedPropMeta) {
            if (true === $embeddedPropMeta->isOne() || !isset($properties[$key])) {
                continue;
            }

            $collection = $this->getStore()->createEmbedCollection($embeddedPropMeta, $properties[$key]);
            if ($collection->getHash() === $this->get($key)->getHash()) {
                // The current collection is the same as the incoming collection.
                continue;
            }

            // The incoming collection is different. Clear the current collection and push the new values.
            $this->clear($key);
            foreach ($collection as $value) {
                $this->pushEmbed($key, $value);
            }
        }

        $this->doDirtyCheck();
        return $this;
    }