Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 15182)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 15183)
@@ -81,4 +81,6 @@
     /** set when used to build a multipolygon relation */
     private Relation createdRelation;
+    /** might be set when creating a relation and touching rings were found. */
+    private boolean repeatCheck;
 
     /**
@@ -250,5 +252,5 @@
             // we found no intersection or crossing between the polygons and they are closed
             // now we can calculate the nesting level to verify the roles with some simple node checks
-            checkRoles(r, allPolygons, wayMap, sharedNodes);
+            checkOrSetRoles(r, allPolygons, wayMap, sharedNodes);
         }
     }
@@ -461,5 +463,5 @@
      * @param sharedNodes all nodes shared by multiple ways of this multipolygon
      */
-    private void checkRoles(Relation r, List<PolyData> allPolygons, Map<Long, RelationMember> wayMap, Set<Node> sharedNodes) {
+    private void checkOrSetRoles(Relation r, List<PolyData> allPolygons, Map<Long, RelationMember> wayMap, Set<Node> sharedNodes) {
         PolygonLevelFinder levelFinder = new PolygonLevelFinder(sharedNodes);
         List<PolygonLevel> list = levelFinder.findOuterWays(allPolygons);
@@ -577,5 +579,7 @@
                         }
                     }
-                    if (loop == 0 || samePoly || (loop == 1 && !allInner)) {
+                    if (r == createdRelation && loop == 1 && !allInner) {
+                        repeatCheck = true;
+                    } else if (loop == 0 || samePoly || (loop == 1 && !allInner)) {
                         String msg = loop == 0 ? tr("Intersection between multipolygon ways")
                                 : samePoly ? tr("Multipolygon ring contains segments twice")
@@ -922,13 +926,16 @@
             r.addMember(new RelationMember("", w));
         }
-        errors.clear();
-        Multipolygon polygon = null;
-        boolean hasRepeatedMembers = checkRepeatedWayMembers(r);
-        if (!hasRepeatedMembers) {
-            polygon = new Multipolygon(r);
-            // don't check style consistency here
-            checkGeometryAndRoles(r, polygon);
-        }
-        createdRelation = null;
+        do {
+            repeatCheck = false;
+            errors.clear();
+            Multipolygon polygon = null;
+            boolean hasRepeatedMembers = checkRepeatedWayMembers(r);
+            if (!hasRepeatedMembers) {
+                polygon = new Multipolygon(r);
+                // don't check style consistency here
+                checkGeometryAndRoles(r, polygon);
+            }
+            createdRelation = null; // makes sure that repeatCheck is only set once
+        } while (repeatCheck);
         errors.removeIf(e->e.getSeverity() == Severity.OTHER);
         return r;
Index: /trunk/test/data/regress/17768/touching-inner-outer.osm
===================================================================
--- /trunk/test/data/regress/17768/touching-inner-outer.osm	(revision 15183)
+++ /trunk/test/data/regress/17768/touching-inner-outer.osm	(revision 15183)
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version='0.6' generator='JOSM'>
+  <node id='-107285' action='modify' visible='true' lat='44.64336908343' lon='-82.22912811082' />
+  <node id='-107286' action='modify' visible='true' lat='44.64203585847' lon='-82.21278067994' />
+  <node id='-107288' action='modify' visible='true' lat='44.63592102046' lon='-82.21200530773' />
+  <node id='-107290' action='modify' visible='true' lat='44.63454164462' lon='-82.23675260427' />
+  <node id='-107294' action='modify' visible='true' lat='44.64028882765' lon='-82.2257035502' />
+  <node id='-107295' action='modify' visible='true' lat='44.64042675305' lon='-82.21911288637' />
+  <node id='-107297' action='modify' visible='true' lat='44.63702449753' lon='-82.21698061278' />
+  <node id='-107299' action='modify' visible='true' lat='44.63702449753' lon='-82.22783582379' />
+  <node id='-107302' action='modify' visible='true' lat='44.6404152248' lon='-82.21588212035' />
+  <node id='-107303' action='modify' visible='true' lat='44.64076416419' lon='-82.21261942014' />
+  <node id='-107306' action='modify' visible='true' lat='44.63772647559' lon='-82.21223423412' />
+  <node id='-107309' action='modify' visible='true' lat='44.63772561986' lon='-82.21509059454' />
+  <way id='-107287' action='modify' visible='true'>
+    <nd ref='-107285' />
+    <nd ref='-107286' />
+    <nd ref='-107303' />
+    <nd ref='-107306' />
+    <nd ref='-107288' />
+    <nd ref='-107290' />
+    <nd ref='-107285' />
+  </way>
+  <way id='-107296' action='modify' visible='true'>
+    <nd ref='-107294' />
+    <nd ref='-107295' />
+    <nd ref='-107297' />
+    <nd ref='-107299' />
+    <nd ref='-107294' />
+  </way>
+  <way id='-107304' action='modify' visible='true'>
+    <nd ref='-107302' />
+    <nd ref='-107303' />
+    <nd ref='-107306' />
+    <nd ref='-107309' />
+    <nd ref='-107302' />
+  </way>
+</osm>
Index: /trunk/test/data/regress/17768/touching-inner.osm
===================================================================
--- /trunk/test/data/regress/17768/touching-inner.osm	(revision 15183)
+++ /trunk/test/data/regress/17768/touching-inner.osm	(revision 15183)
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version='0.6' generator='JOSM'>
+  <node id='-102238' action='modify' visible='true' lat='44.65669085736' lon='-82.21609411432' />
+  <node id='-102242' action='modify' visible='true' lat='44.65234549815' lon='-82.21492630445' />
+  <node id='-102244' action='modify' visible='true' lat='44.65196206847' lon='-82.22256198437' />
+  <node id='-102246' action='modify' visible='true' lat='44.65745765165' lon='-82.22651457162' />
+  <node id='-102250' action='modify' visible='true' lat='44.65828552582' lon='-82.21282670072' />
+  <node id='-102252' action='modify' visible='true' lat='44.65157582772' lon='-82.21008683911' />
+  <node id='-102259' action='modify' visible='true' lat='44.66371661758' lon='-82.22347173684' />
+  <node id='-102260' action='modify' visible='true' lat='44.65991490677' lon='-82.23088283793' />
+  <node id='-102262' action='modify' visible='true' lat='44.6510645808' lon='-82.22899637584' />
+  <node id='-102264' action='modify' visible='true' lat='44.64678271091' lon='-82.21242245884' />
+  <node id='-102266' action='modify' visible='true' lat='44.65036160892' lon='-82.20577492574' />
+  <node id='-102268' action='modify' visible='true' lat='44.66164008375' lon='-82.20775121937' />
+  <way id='-102239' action='modify' visible='true'>
+    <nd ref='-102246' />
+    <nd ref='-102238' />
+    <nd ref='-102242' />
+    <nd ref='-102244' />
+    <nd ref='-102246' />
+  </way>
+  <way id='-102251' action='modify' visible='true'>
+    <nd ref='-102238' />
+    <nd ref='-102250' />
+    <nd ref='-102252' />
+    <nd ref='-102242' />
+    <nd ref='-102238' />
+  </way>
+  <way id='-102261' action='modify' visible='true'>
+    <nd ref='-102259' />
+    <nd ref='-102260' />
+    <nd ref='-102262' />
+    <nd ref='-102264' />
+    <nd ref='-102266' />
+    <nd ref='-102268' />
+    <nd ref='-102259' />
+  </way>
+</osm>
Index: /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MultipolygonTestTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MultipolygonTestTest.java	(revision 15182)
+++ /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MultipolygonTestTest.java	(revision 15183)
@@ -2,9 +2,15 @@
 package org.openstreetmap.josm.data.validation.tests;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
 import java.util.stream.Collectors;
 
 import org.junit.Rule;
 import org.junit.Test;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.io.OsmReader;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 
@@ -16,6 +22,4 @@
 public class MultipolygonTestTest {
 
-    private static final MultipolygonTest MULTIPOLYGON_TEST = new MultipolygonTest();
-    private static final RelationChecker RELATION_TEST = new RelationChecker();
 
     /**
@@ -24,5 +28,5 @@
     @Rule
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules().projection().mapStyles().presets().main();
+    public JOSMTestRules test = new JOSMTestRules().projection().mapStyles().presets().main().preferences();
 
     /**
@@ -32,7 +36,37 @@
     @Test
     public void testMultipolygonFile() throws Exception {
+        final MultipolygonTest MULTIPOLYGON_TEST = new MultipolygonTest();
+        final RelationChecker RELATION_TEST = new RelationChecker();
         ValidatorTestUtils.testSampleFile("data_nodist/multipolygon.osm",
                 ds -> ds.getRelations().stream().filter(Relation::isMultipolygon).collect(Collectors.toList()),
                 name -> name.startsWith("06") || name.startsWith("07") || name.startsWith("08"), MULTIPOLYGON_TEST, RELATION_TEST);
     }
+
+    /**
+     * Non-regression test for ticket #17768.
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testTicket17768TouchingInner() throws Exception {
+        try (InputStream is = TestUtils.getRegressionDataStream(17768, "touching-inner.osm")) {
+            MultipolygonTest mpTest = new MultipolygonTest();
+            mpTest.makeFromWays(OsmReader.parseDataSet(is, null).getWays());
+            // inner touches inner, is considered OK in OSM
+            assertTrue(mpTest.getErrors().isEmpty());
+        }
+    }
+
+    /**
+     * Non-regression test for ticket #17768.
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testTicket17768TouchingInnerOuter() throws Exception {
+        try (InputStream is = TestUtils.getRegressionDataStream(17768, "touching-inner-outer.osm")) {
+            MultipolygonTest mpTest = new MultipolygonTest();
+            mpTest.makeFromWays(OsmReader.parseDataSet(is, null).getWays());
+            // inner touches outer, should return error
+            assertEquals(1, mpTest.getErrors().size());
+        }
+    }
 }
