private function matchChild(FormInterface $form, PropertyPathIteratorInterface $it)
    {
        $target = null;
        $chunk = '';
        $foundAtIndex = null;

        // Construct mapping rules for the given form
        $rules = [];

        foreach ($form->getConfig()->getOption('error_mapping') as $propertyPath => $targetPath) {
            // Dot rules are considered at the very end
            if ('.' !== $propertyPath) {
                $rules[] = new MappingRule($form, $propertyPath, $targetPath);
            }
        }

        $children = iterator_to_array(new \RecursiveIteratorIterator(new InheritDataAwareIterator($form)), false);

        while ($it->valid()) {
            if ($it->isIndex()) {
                $chunk .= '['.$it->current().']';
            } else {
                $chunk .= ('' === $chunk ? '' : '.').$it->current();
            }

            // Test mapping rules as long as we have any
            foreach ($rules as $key => $rule) {
                /* @var MappingRule $rule */

                // Mapping rule matches completely, terminate.
                if (null !== ($form = $rule->match($chunk))) {
                    return $form;
                }

                // Keep only rules that have $chunk as prefix
                if (!$rule->isPrefix($chunk)) {
                    unset($rules[$key]);
                }
            }

            /** @var FormInterface $child */
            foreach ($children as $i => $child) {
                $childPath = (string) $child->getPropertyPath();
                if ($childPath === $chunk) {
                    $target = $child;
                    $foundAtIndex = $it->key();
                } elseif (0 === strpos($childPath, $chunk)) {
                    continue;
                }

                unset($children[$i]);
            }

            $it->next();
        }

        if (null !== $foundAtIndex) {
            $it->seek($foundAtIndex);
        }

        return $target;
    }