Index: /trunk/resources/data/validator/combinations.mapcss
===================================================================
--- /trunk/resources/data/validator/combinations.mapcss	(revision 16859)
+++ /trunk/resources/data/validator/combinations.mapcss	(revision 16860)
@@ -73,5 +73,4 @@
 *[source:addr:housenumber      ][!addr:housenumber] {
   throwWarning: tr("{0} without {1}", "{0.key}", "{1.key}");
-  set MissingKeyWarning;
   group: tr("missing tag");
   assertMatch: "way lanes=42";
@@ -606,11 +605,14 @@
 
 /* see #8519, #11529, limited to motorways and trunks to avoid false positives for streets with lanes for non motorized traffic */
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][turn:lanes              ][tag(lanes)!=eval(count(split("|", tag("turn:lanes"))))],
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][change:lanes            ][tag(lanes)!=eval(count(split("|", tag("change:lanes"))))],
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][maxspeed:lanes          ][tag(lanes)!=eval(count(split("|", tag("maxspeed:lanes"))))],
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][minspeed:lanes          ][tag(lanes)!=eval(count(split("|", tag("minspeed:lanes"))))],
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][destination:lanes       ][tag(lanes)!=eval(count(split("|", tag("destination:lanes"))))],
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][destination:ref:lanes   ][tag(lanes)!=eval(count(split("|", tag("destination:ref:lanes"))))],
-way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/][lanes][destination:symbol:lanes][tag(lanes)!=eval(count(split("|", tag("destination:symbol:lanes"))))] {
+way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/] {
+  set MotorwayTrunk;
+}
+way.MotorwayTrunk[lanes][turn:lanes              ][tag(lanes)!=eval(count(split("|", tag("turn:lanes"))))],
+way.MotorwayTrunk[lanes][change:lanes            ][tag(lanes)!=eval(count(split("|", tag("change:lanes"))))],
+way.MotorwayTrunk[lanes][maxspeed:lanes          ][tag(lanes)!=eval(count(split("|", tag("maxspeed:lanes"))))],
+way.MotorwayTrunk[lanes][minspeed:lanes          ][tag(lanes)!=eval(count(split("|", tag("minspeed:lanes"))))],
+way.MotorwayTrunk[lanes][destination:lanes       ][tag(lanes)!=eval(count(split("|", tag("destination:lanes"))))],
+way.MotorwayTrunk[lanes][destination:ref:lanes   ][tag(lanes)!=eval(count(split("|", tag("destination:ref:lanes"))))],
+way.MotorwayTrunk[lanes][destination:symbol:lanes][tag(lanes)!=eval(count(split("|", tag("destination:symbol:lanes"))))] {
     throwWarning: tr("Different number of lanes in the keys {0} and {1}", "{1.key}", "{2.key}");
     group: tr("suspicious tag combination");
@@ -618,5 +620,5 @@
 
 /* #14125, #14323, #18185 */
-way[highway][lanes][!lanes:forward][!lanes:backward][oneway!=yes][oneway!=-1][oneway!=reversible][junction!=roundabout][lanes>2][get(split(".", tag(lanes)/2), 1)=5] {
+way[highway][lanes][!lanes:forward][!lanes:backward][oneway!=yes][oneway!=-1][oneway!=reversible][highway!=motorway][junction!=roundabout][lanes>2][get(split(".", tag(lanes)/2), 1)=5] {
   throwWarning: tr("street with odd number of {0}, but without {1} and {2} or {3}", "{1.key}", "{2.key}", "{3.key}", "{4.key}");
   group: tr("missing tag");
@@ -628,15 +630,21 @@
 }
 
-/* #10932 */
-way[highway][!lanes][/^.*:lanes$/]!.MissingKeyWarning, 
-way[highway][!lanes:forward][/^.*:lanes:forward$/], 
-way[highway][!lanes:backward][/^.*:lanes:backward$/],
+/* #10932, #19609 */
+way[highway][!lanes][/^.*:lanes$/][!source:lanes],
+way[highway][!lanes][/^.*:lanes:(forward|backward|both_ways)$/],
 way[highway][!lanes:both_ways][/^.*:lanes:both_ways$/] {
   throwWarning: tr("{0} without {1}", "{2.key}", "{1.key}");
   group: tr("missing tag");
   assertMatch: "way highway=primary turn:lanes=left|right";
+  assertMatch: "way highway=primary turn:lanes:forward=left|right";
   assertNoMatch: "way highway=primary turn:lanes=left|right lanes=2";
-  assertMatch: "way highway=primary turn:lanes:forward=left|right";
+}
+way[highway][!lanes:forward][/^.*:lanes:forward$/][!lanes:backward][!get(split(".", tag(lanes)/2), 1)=5],
+way[highway][!lanes:backward][/^.*:lanes:backward$/][!lanes:forward][!get(split(".", tag(lanes)/2), 1)=5] {
+  throwOther: tr("{0} without {1}", "{2.key}", "{1.key}");
+  group: tr("missing tag");
+  assertMatch: "way highway=primary turn:lanes:forward=left|right lanes=2";
   assertNoMatch: "way highway=primary turn:lanes:forward=left|right lanes:forward=2";
+  assertNoMatch: "way highway=primary turn:lanes:forward=left|right lanes=3";
 }
 
Index: /trunk/resources/data/validator/unnecessary.mapcss
===================================================================
--- /trunk/resources/data/validator/unnecessary.mapcss	(revision 16859)
+++ /trunk/resources/data/validator/unnecessary.mapcss	(revision 16860)
@@ -153,5 +153,5 @@
   assertNoMatch: "way name=kiosk amenity=grave_yard";
 }
-  /* the following without fixRemove to avoid informatin loss, should be checked manually */
+  /* the following without fixRemove to avoid information loss, should be checked manually */
 *[name][name=~/^(?i)(chapel|chapelle|kapelle)$/], /* check if amenity=place_of_worship and/or building=chapel applies */
 *[name][name=~/^(?i)(silo)$/][man_made!=silo], /* check if man_made=silo and/or building=silo applies */
