def prepare(self):
        """Method to check if the impact function can be run.

        :return: A tuple with the status of the IF and an error message if
            needed.
            The status is PREPARE_SUCCESS if everything was fine.
            The status is PREPARE_FAILED_BAD_INPUT if the client should fix
                something.
            The status is PREPARE_FAILED_INSUFFICIENT_OVERLAP if the client
                should fix the analysis extent.
            The status is PREPARE_FAILED_BAD_CODE if something went wrong
                from the code.
        :rtype: (int, m.Message)
        """
        self._provenance_ready = False
        if len(self._exposures) < 2:  # 2 layers minimum.
            message = generate_input_error_message(
                tr('Not enough exposure layer'),
                m.Paragraph(tr('You need to provide at least two exposures.')))
            self._is_ready = False
            return PREPARE_FAILED_BAD_INPUT, message

        existing_exposure = []
        for exposure in self._exposures:
            status, message = check_input_layer(exposure, 'exposure')
            if status != PREPARE_SUCCESS:
                return status, message

            if exposure.keywords['exposure'] in existing_exposure:
                message = generate_input_error_message(
                    tr('Same exposure'),
                    m.Paragraph(tr('Not the same exposure')))
                self._is_ready = False
                return PREPARE_FAILED_BAD_INPUT, message
            else:
                existing_exposure.append(exposure.keywords['exposure'])

        status, message = check_input_layer(self.hazard, 'hazard')
        if status != PREPARE_SUCCESS:
            return status, message

        if self.aggregation:
            status, message = check_input_layer(
                self.aggregation, 'aggregation')
            if status != PREPARE_SUCCESS:
                return status, message

            if self._crs:
                message = generate_input_error_message(
                    tr('Error with the requested CRS'),
                    m.Paragraph(tr(
                        'Requested CRS must be null when an '
                        'aggregation is provided in the multiexposure '
                        'analysis.'))
                )
                return PREPARE_FAILED_BAD_INPUT, message
        else:
            if not self._crs:
                message = generate_input_error_message(
                    tr('Error with the requested CRS'),
                    m.Paragraph(tr(
                        'CRS must be set when you don\'t use an '
                        'aggregation layer. It will be used for the '
                        'analysis CRS in the multiexposue analysis..'))
                )
                return PREPARE_FAILED_BAD_INPUT, message

        # We let other checks like extent,... to the first single exposure IF.
        # The prepare step will fail if needed and the stop the multiexposure.

        self._impact_functions = []
        self._hazard_keywords = copy_layer_keywords(self.hazard.keywords)

        # We delegate the prepare to the main IF for each exposure
        for exposure in self._exposures:
            impact_function = ImpactFunction()
            impact_function.debug_mode = self.debug_mode
            impact_function.hazard = clone_layer(self._hazard)
            impact_function.exposure = exposure
            impact_function.debug_mode = self.debug
            impact_function.use_rounding = self.use_rounding
            if self.callback:
                impact_function.callback = self.callback
            if self._aggregation:
                impact_function.aggregation = clone_layer(self._aggregation)
                impact_function.use_selected_features_only = (
                    self.use_selected_features_only)
            else:
                impact_function.crs = self._crs

            code, message = impact_function.prepare()
            if code != PREPARE_SUCCESS:
                return code, message

            self._impact_functions.append(impact_function)

        hazard_name = get_name(self.hazard.keywords.get('hazard'))
        hazard_geometry_name = get_name(geometry_type(self.hazard))
        self._name = (
            'Multi exposure {hazard_type} {hazard_geometry} On '.format(
                hazard_type=hazard_name, hazard_geometry=hazard_geometry_name))
        exposures_strings = []
        for exposure in self.exposures:
            exposure_name = get_name(exposure.keywords.get('exposure'))
            exposure_geometry_name = get_name(geometry_type(exposure))
            exposures_strings.append(
                '{exposure_type} {exposure_geometry}'.format(
                    exposure_type=exposure_name,
                    exposure_geometry=exposure_geometry_name))
        self._name += ', '.join(exposures_strings)

        self._output_layer_expected = self._compute_output_layer_expected()

        # Set provenance
        set_provenance(
            self._provenance,
            provenance_multi_exposure_layers,
            [l.source() for l in self._exposures])
        # reference to original layer being used
        set_provenance(
            self._provenance,
            provenance_multi_exposure_layers_id,
            [l.id() for l in self._exposures])
        set_provenance(
            self._provenance,
            provenance_multi_exposure_keywords,
            {l.keywords['exposure']: copy_layer_keywords(l.keywords)
                for l in self.exposures})
        set_provenance(
            self._provenance,
            provenance_hazard_layer,
            self.hazard.publicSource())
        # reference to original layer being used
        set_provenance(
            self._provenance,
            provenance_hazard_layer_id,
            self.hazard.id())
        set_provenance(
            self._provenance,
            provenance_hazard_keywords,
            copy_layer_keywords(self.hazard.keywords))
        # reference to original layer being used
        if self.aggregation:
            set_provenance(
                self._provenance,
                provenance_aggregation_layer_id,
                self.aggregation.id())
            set_provenance(
                self._provenance,
                provenance_aggregation_layer,
                self.aggregation.source())
            set_provenance(
                self._provenance,
                provenance_aggregation_keywords,
                copy_layer_keywords(self.aggregation.keywords))
        else:
            set_provenance(
                self._provenance,
                provenance_aggregation_layer_id,
                None)
            set_provenance(
                self._provenance,
                provenance_aggregation_layer,
                None)
            set_provenance(
                self._provenance,
                provenance_aggregation_keywords,
                None)

        self._is_ready = True
        return PREPARE_SUCCESS, None