public function form($form, $submissionToDtoMapping = null)
    {
        $stagedForm = null;

        if ($form instanceof FormBuilder) {
            $form = $form->build();
        } elseif ($form instanceof StagedFormBuilder) {
            $form = $form->build();
        }

        if ($form instanceof IForm) {
            $stagedForm = $form->asStagedForm();
        } elseif ($form instanceof IStagedForm) {
            $stagedForm = $form;
        } else {
            throw InvalidArgumentException::format(
                'Invalid form supplied to %s: expecting %s, %s given',
                __METHOD__, implode('|', [IForm::class, IStagedForm::class, FormBuilder::class, StagedFormBuilder::class]),
                Debug::getType($form)
            );
        }

        $this->formDtoMappingCallback = function ($handlerParameterType) use ($form, $stagedForm, $submissionToDtoMapping) {

            if ($form instanceof FormObject) {
                $mapping = new FormObjectMapping($form);
            } elseif ($form instanceof StagedFormObject) {
                $mapping = new StagedFormObjectMapping($form);
            } elseif ($submissionToDtoMapping instanceof IStagedFormDtoMapping) {
                $mapping = $submissionToDtoMapping;
            } elseif (is_callable($submissionToDtoMapping)) {
                $mapping = new CustomStagedFormDtoMapping($stagedForm, $handlerParameterType, $submissionToDtoMapping);
            } else {
                $mapping = new ArrayDataObjectFormMapping($stagedForm);
            }

            return $mapping;
        };


        return $this;
    }