Index: app/gegl/gimpoperationhuesaturation.c
@@ -96,6 +96,37 @@
 }
 
+static inline gdouble
+map_hue_overlap (GimpHueSaturationConfig *config,
+                 GimpHueRange             primary_range,
+                 GimpHueRange             secondary_range,
+                 gdouble                  value,
+                 gdouble                  primary_intensity,
+                 gdouble                  secondary_intensity)
+{
+  /* When calculating an overlap between two ranges, interpolate the hue
+   * adjustment from config->hue[primary_range] and config->hue[secondary_range]
+   * BEFORE mapping it to the input value.  This is algebraically the same as
+   * previous behavior, but doesn't leave odd edge cases where only one of the ranges
+   * crosses the red/magenta wraparound (bug #527085), or if adjacent channels
+   * intentionally have more than a 180 hue difference from to each other.
+   * (E.g. a hue adjustment of Cyan+91, Blue-91 used to yield a very different
+   * result than the similar adjustment of Cyan+90, Blue-90.  I doubt
+   * anyone would actually encounter it in the wild, but it's still incorrect.)
+   */   
+  gdouble v = config->hue[primary_range]   * primary_intensity + 
+              config->hue[secondary_range] * secondary_intensity;
+
+  value += (config->hue[GIMP_ALL_HUES] + v) / 2.0;
+
+  if (value < 0)
+    return value + 1.0;
+  else if (value > 1.0)
+    return value - 1.0;
+  else
+    return value;
+}
+
 static inline gdouble
 map_saturation (GimpHueSaturationConfig *config,
                 GimpHueRange             range,
                 gdouble                  value)
@@ -212,29 +243,8 @@
 
       if (use_secondary_hue)
         {
-          gdouble mapped_primary_hue;
-          gdouble mapped_secondary_hue;
-          gdouble diff;
+          hsl.h = map_hue_overlap (config, hue, secondary_hue, hsl.h, primary_intensity, secondary_intensity);
 
-          mapped_primary_hue   = map_hue (config, hue,           hsl.h);
-          mapped_secondary_hue = map_hue (config, secondary_hue, hsl.h);
-
-          /* Find nearest hue on the circle between primary and
-           * secondary hue
-           */
-          diff = mapped_primary_hue - mapped_secondary_hue;
-          if (diff < -0.5)
-            {
-              mapped_secondary_hue -= 1.0;
-            }
-          else if (diff >= 0.5)
-            {
-              mapped_secondary_hue += 1.0;
-            }
-
-          hsl.h = (mapped_primary_hue   * primary_intensity +
-                   mapped_secondary_hue * secondary_intensity);
-
           hsl.s = (map_saturation (config, hue,           hsl.s) * primary_intensity +
                    map_saturation (config, secondary_hue, hsl.s) * secondary_intensity);
 
