protected function doHydrate(array $data, $object)
    {
        $previousHydrationContext = $this->currentHydrationContext;
        $this->currentHydrationContext = new CurrentHydrationContext($data, $object);

        foreach ($this->metadata->getMappedFieldNames() as $mappedFieldName) {
            $defaultValue = $this->metadata->getFieldDefaultValue($mappedFieldName);

            if (null !== $defaultValue) {
                $this->resolveValue($defaultValue, $object);
                $this->memberAccessStrategy->setValue($defaultValue, $object, $mappedFieldName);   
            }
        }

        if (! $this->metadata->hasCustomHydrator()) {

            $this->executeMethods($object, $this->metadata->getPreHydrateListeners());

            foreach ($data as $originalFieldName => $value) {
                $mappedFieldName = $this->metadata->getMappedFieldName($originalFieldName);
                if (null === $mappedFieldName) {

                    //It's possible that a raw field name has no corresponding field name
                    //because a raw field can be a value object part.
                    continue;
                }

                if (! $this->metadata->hasSource($mappedFieldName)) {
                    //Classical hydration.
                    $this->walkHydration($mappedFieldName, $object, $value, $data);
                }
            }
        } else {
            list($customHydratorClass, $customHydrateMethod) = $this->metadata->getCustomHydratorInfo();
            $this->executeMethod($object, new ClassMetadata\Model\Method($customHydratorClass, $customHydrateMethod, [$data, $object]));
        }

        //DataSources hydration.
        foreach ($this->metadata->getFieldsWithDataSources() as $mappedFieldName) {

            if ($this->metadata->hasDataSource($mappedFieldName)) {//<= Is this test usefull ?
                $this->walkHydrationByDataSource($mappedFieldName, $object, false);
            }
        }

        //Providers hydration.
        foreach ($this->metadata->getFieldsWithProviders() as $mappedFieldName) {

            if ($this->metadata->hasProvider($mappedFieldName)) {//<= Is this test usefull ?
                $this->walkHydrationByProvider($mappedFieldName, $object, false);
            }
        }

        //Value objects hydration.
        foreach ($this->metadata->getFieldsWithValueObjects() as $mappedFieldName) {
            $this->walkValueObjectHydration($mappedFieldName, $object, $data);
        }

        $this->executeMethods($object, $this->metadata->getPostHydrateListeners());

        $this->currentHydrationContext = $previousHydrationContext;

        return $object;
    }