emit_path();
 }
 
+static void
+reverse_path(point *a)
+{
+       point *tmp;
+       
+       while (a->prev != NULL)
+               a = a->prev;
+       while (a != NULL) {
+               tmp = a->next;
+               a->next = a->prev;
+               a->prev = tmp;
+               a = tmp;
+       }
+}              
+
 /* Join together two points each at the end of a path */
 static void
 join_ends(point *a, point *b)
 {
+       point *tmp;
+
+       if (a->prev == NULL && b->next == NULL) {
+               tmp = a; a = b; b = tmp;
+       }
+       if (a->prev == NULL)
+               reverse_path(a);
+       if (b->next == NULL)
+               reverse_path(b);
        assert(a->next == NULL);
        assert(a->prev != NULL);
        assert(b->prev == NULL);
        a->next = b;
        b->prev = a;
        fix_identical(a); /* Will delete a */
-       fix_collinear(b); /* Will delete b */
+       fix_collinear(b); /* Might delete b */
 }
 
 static bool
        return p->next == NULL || p->prev == NULL;
 }
 
+static bool
+point_deadp(point *p)
+{
+       return p->next == NULL && p->prev == NULL;
+}
+
 static void
 clean_skeleton()
 {
        int i, j;
 
+       /* Pass 1: join collinear connected segments */
        for (i = 0; i < nextpoint; i++) {
-               if (points[i].prev == NULL && points[i].next == NULL)
+               if (point_deadp(&points[i]))
                        continue;
                for (j = 0; j < nextpoint; j++) {
-                       if (points[j].prev == NULL && points[j].next == NULL)
+                       if (point_deadp(&points[j]))
                                continue;
                        if (vec_eqp(points[i].v, points[j].v) &&
                            points[i].next == NULL && points[j].prev == NULL &&
                            vec_inline3(points[i].prev->v, points[i].v,
                                        points[j].next->v))
                                join_ends(&points[i], &points[j]);
-                       if (points[i].prev == NULL && points[i].next == NULL)
+                       if (point_deadp(&points[i]))
+                               break;
+               }
+       }
+       /* Pass 2: join any connected segments */
+       for (i = 0; i < nextpoint; i++) {
+               if (point_deadp(&points[i]))
+                       continue;
+               for (j = i+1; j < nextpoint; j++) {
+                       if (point_deadp(&points[j]))
+                               continue;
+                       if (vec_eqp(points[i].v, points[j].v) &&
+                           point_endp(&points[i]) && point_endp(&points[j]))
+                               join_ends(&points[i], &points[j]);
+                       if (point_deadp(&points[i]))
                                break;
                }
        }