def flat_correct(ccd, flat, min_value=None, norm_value=None):
    """Correct the image for flat fielding.

    The flat field image is normalized by its mean or a user-supplied value
    before flat correcting.

    Parameters
    ----------
    ccd : `~astropy.nddata.CCDData`
        Data to be transformed.

    flat : `~astropy.nddata.CCDData`
        Flatfield to apply to the data.

    min_value : float or None, optional
        Minimum value for flat field. The value can either be None and no
        minimum value is applied to the flat or specified by a float which
        will replace all values in the flat by the min_value.
        Default is ``None``.

    norm_value : float or None, optional
        If not ``None``, normalize flat field by this argument rather than the
        mean of the image. This allows fixing several different flat fields to
        have the same scale. If this value is negative or 0, a ``ValueError``
        is raised. Default is ``None``.

    {log}

    Returns
    -------
    ccd : `~astropy.nddata.CCDData`
        CCDData object with flat corrected.
    """
    # Use the min_value to replace any values in the flat
    use_flat = flat
    if min_value is not None:
        flat_min = flat.copy()
        flat_min.data[flat_min.data < min_value] = min_value
        use_flat = flat_min

    # If a norm_value was input and is positive, use it to scale the flat
    if norm_value is not None and norm_value > 0:
        flat_mean_val = norm_value
    elif norm_value is not None:
        # norm_value was set to a bad value
        raise ValueError('norm_value must be greater than zero.')
    else:
        # norm_value was not set, use mean of the image.
        flat_mean_val = use_flat.data.mean()

    # Normalize the flat.
    flat_mean = flat_mean_val * use_flat.unit
    flat_normed = use_flat.divide(flat_mean)

    # divide through the flat
    flat_corrected = ccd.divide(flat_normed)

    flat_corrected.meta = ccd.meta.copy()
    return flat_corrected