public function initialize(array $properties = null)
    {
        $attributes = [];
        $embedOne = [];
        $embedMany = [];

        if (null !== $properties) {
            $attributes = $this->applyDefaultAttrValues($attributes);
            foreach ($properties as $key => $value) {
                if (true === $this->isAttribute($key)) {
                    // Load attribute.
                    $attributes[$key] = $this->convertAttributeValue($key, $value);
                } else if (true === $this->isEmbedHasOne($key) && is_array($value)) {
                    // Load embed one.
                    $embedOne[$key] = $this->getStore()->loadEmbed($this->getMetadata()->getEmbed($key)->embedMeta, $value);
                }
            }
        }

        foreach ($this->getMetadata()->getEmbeds() as $key => $embeddedPropMeta) {
            // Always load embedded collections, regardless if data is set.
            if (true === $embeddedPropMeta->isOne()) {
                continue;
            }
            $embeds = !isset($properties[$key]) ? [] : $properties[$key];
            $embedMany[$key] = $this->getStore()->createEmbedCollection($embeddedPropMeta, $embeds);
        }

        $this->attributes    = (null === $this->attributes) ? new Attributes($attributes) : $this->attributes->replace($attributes);
        $this->hasOneEmbeds  = (null === $this->hasOneEmbeds) ? new Embeds\HasOne($embedOne) : $this->hasOneEmbeds->replace($embedOne);
        $this->hasManyEmbeds = (null === $this->hasManyEmbeds) ? new Embeds\HasMany($embedMany) : $this->hasManyEmbeds->replace($embedMany);

        if (true === $this->getState()->is('new')) {
            // Ensure default values are applied to new models.
            $this->apply([]);
        }

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