def convert_mass(mass_from, mass_to, log):
    """
    determines the mass, weight, gravity scale factor

    We apply a gravity_scale_mass for any unit not {kg, slug}.
    Then we convert to N.

    So for SI, if we have kg, we have a base unit, and the length is assumed
    to be m, so we have a consistent system and gravity_scale_mass is 1.0.

    For lbm:
       F = m*a
       1 lbf = 1 lbm * 1 ft/s^2
       32 lbf = 1 slug * 32 ft/s^2
       gscale = 1/g
       F = gscale * m * a
       1 lbf = gscale * 1 lbm * 32 ft/s^2
       --> gscale = 1/32

    For slug:
       F = gscale * m * a
       32 lbf = gscale * 1 slug * 32 ft/s^2
       --> gscale = 1

    For slinch:
       F = gscale * m * a
       386 lbf = gscale * 1 slinch * 12*32 in/s^2
       1 slinch = 12 slug
       12 in = 1 ft
       386 lbf = gscale * 12 slug * 32 ft/s^2
       --> gscale = 1

    TODO: slinch/slug not validated

    """
    mass_scale = 1.0
    weight_scale = 1.0
    gravity_scale_mass = 1.0
    gravity_english_ft = 32.174
    slug_to_kg = 14.5939
    slinch_to_kg = 12.0 * slug_to_kg
    lbf_to_newton = 4.4482216152605
    lbm_to_kg = 0.45359237
    if mass_from == 'kg':
        pass
    elif mass_from == 'Mg':
        mass_scale *= 1000.0
        gravity_scale_mass *= 1000.0
    elif mass_from == 'g':
        mass_scale *= 1.0 / 1000.0
        gravity_scale_mass *= 1 / 1000.0
    elif mass_from == 'lbm':
        mass_scale *= lbm_to_kg
        weight_scale *= lbf_to_newton
        gravity_scale_mass /= gravity_english_ft
    elif mass_from == 'slug':
        mass_scale *= slug_to_kg
        weight_scale *= lbf_to_newton
    elif mass_from == 'slinch':
        mass_scale *= slinch_to_kg
        weight_scale *= lbf_to_newton
    else:
        raise NotImplementedError(
            'mass from unit=%r; expected=[g, kg, Mg, lbm, slug, slinch]' %
            mass_from)
    if mass_to == 'kg':
        pass
    elif mass_to == 'Mg':
        mass_scale /= 1000.0
        gravity_scale_mass /= 1000.0
    elif mass_to == 'g':
        mass_scale *= 1000.0
        gravity_scale_mass *= 1000.0
    elif mass_to == 'lbm':
        mass_scale /= lbm_to_kg
        weight_scale /= lbf_to_newton
        gravity_scale_mass *= gravity_english_ft
    elif mass_to == 'slug':
        mass_scale /= slug_to_kg
        weight_scale /= lbf_to_newton
    elif mass_to == 'slinch':
        mass_scale /= slinch_to_kg
        weight_scale /= lbf_to_newton
    else:
        raise NotImplementedError(
            'mass to unit=%r; expected=[g, kg, Mg, lbm, slug, slinch]' %
            mass_to)
    return mass_scale, weight_scale, gravity_scale_mass
