Fixed Multiple Distance Bug

Change-Id: I7808759316ed6479e874e84acd0afc56f17995cd
diff --git a/Changes b/Changes
index 025236f..3b86823 100644
--- a/Changes
+++ b/Changes
@@ -5,6 +5,8 @@
 	- [bugfix] Escaped characters now supported in MutiTerm (diewald)
 	- [feature] Deserialization of flags (diewald)
 	- [feature] Made responses valid KoralQueries (diewald)
+	- [bugfix] Fixed sequence deserialization bug for simple unordered
+	  constraint (diewald)
 
 0.51 2015-03-17
         - This is a major version (prepared for the GitHub release)
diff --git a/src/main/java/de/ids_mannheim/korap/KrillQuery.java b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
index dd2f819..3fe6f28 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
@@ -844,7 +844,7 @@
             }
 
             // Support korap distances
-            // Support cosmas distances
+            // TODO: Support cosmas distances
             else if (firstDistance.get("@type").asText()
                     .equals("koral:distance")
                     || firstDistance.get("@type").asText()
@@ -869,12 +869,15 @@
                     min = b.min;
                     max = b.max;
                 }
+
+                // <legacy>
                 else {
                     if (constraint.has("min"))
                         min = constraint.get("min").asInt(0);
                     if (constraint.has("max"))
                         max = constraint.get("max").asInt(100);
                 };
+                // </legacy>
 
                 // Add foundry and layer to the unit for new indices
                 if (constraint.has("foundry") && constraint.has("layer")
@@ -908,6 +911,9 @@
 
         // inOrder was set to false without a distance constraint
         if (!sseqqw.isInOrder() && !sseqqw.hasConstraints()) {
+            if (DEBUG)
+                log.trace("Add distance constraint - for the normal inorder case");
+
             sseqqw.withConstraint(1, 1, "w");
         };
 
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java
index 78a80db..08c33b1 100644
--- a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java
@@ -340,8 +340,7 @@
      * say:
      * 
      * <strong>Warning!</strong> Sequence constraints are experimental
-     * and
-     * may (hopefully) change in future versions!
+     * and may (hopefully) change in future versions!
      * 
      * @param min
      *            The minimum number of tokens between the elements
@@ -373,8 +372,7 @@
      * say:
      * 
      * <strong>Warning!</strong> Sequence constraints are experimental
-     * and
-     * may (hopefully) change in future versions!
+     * and may (hopefully) change in future versions!
      * 
      * @param min
      *            The minimum number of tokens between the elements
@@ -393,6 +391,8 @@
             boolean exclusion) {
         if (this.constraints == null)
             this.constraints = new ArrayList<DistanceConstraint>(1);
+        if (DEBUG)
+            log.trace("With contraint {}-{} (excl {})", min, max, exclusion);
         this.constraints.add(new DistanceConstraint(min, max, this.isInOrder,
                 exclusion));
         return this;
@@ -476,12 +476,20 @@
     public SpanSequenceQueryWrapper withConstraint (int min, int max,
             String unit, boolean exclusion) {
 
+        if (DEBUG)
+            log.trace("With contraint {}-{} (unit {}, excl {})",
+                      min, max, unit, exclusion);
+
         // Word unit
         if (unit.equals("w")) {
+
+            // Initialize constraint
             if (this.constraints == null)
                 this.constraints = new ArrayList<DistanceConstraint>(1);
+
             this.constraints.add(new DistanceConstraint(min, max, isInOrder,
                     exclusion));
+
             return this;
         };
 
@@ -527,6 +535,11 @@
      */
     public SpanSequenceQueryWrapper withConstraint (int min, int max,
             SpanElementQueryWrapper unit, boolean exclusion) {
+
+        if (DEBUG)
+            log.trace("With contraint {}-{} (unit {}, excl {})",
+                      min, max, unit.toString(), exclusion);
+
         if (this.constraints == null)
             this.constraints = new ArrayList<DistanceConstraint>(1);
 
@@ -588,8 +601,10 @@
         // that will be optimized away later on
         if (this.constraints.size() == 1) {
             DistanceConstraint dc = this.constraints.get(0);
-            if (dc.getUnit().equals("w") && dc.getMinDistance() == 1
-                    && dc.getMaxDistance() == 1) {
+            if (dc.getUnit().equals("w") &&
+                dc.getMinDistance() == 1 &&
+                dc.getMaxDistance() == 1 &&
+                this.isInOrder) {
                 return false;
             };
         };
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
index b8a21b8..57c29bc 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
@@ -67,18 +67,48 @@
     @Test
     public void testDistanceReferences() throws QueryException {
         String filepath = getClass().getResource(
-        // "/queries/reference/distance-reference.jsonld").getFile();
-                "/queries/reference/bug-multiple-distance.jsonld").getFile();
+            "/queries/reference/bug-multiple-distance-simple.jsonld"
+        ).getFile();
         SpanQueryWrapper sqwi = getJSONQuery(filepath);
         SpanQuery sq = sqwi.toQuery();
 
+        assertEquals("spanDistance(<tokens:c:vb />, <tokens:c:prp />, [(w[1:1], notOrdered, notExcluded)])", sq.toString());
+
+        // "/queries/reference/distance-reference.jsonld").getFile();
+        filepath = getClass().getResource(
+            "/queries/reference/bug-multiple-distance.jsonld"
+        ).getFile();
+        sqwi = getJSONQuery(filepath);
+        sq = sqwi.toQuery();
+
         // 'cat="VP" & cat="NP" & cat="PP" & #1 . #2 & #2 . #3 & #1 .
         // #3 & #2 ->dep #1'
         assertEquals(
-                "spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
-                        + "focus(2: spanDistance(focus(1: spanDistance(<tokens:c:vb />, {1: <tokens:c:prp />}, "
-                        + "[(w[1:1], notOrdered, notExcluded)])), {2: <tokens:c:nn />}, [(w[0:2], ordered, notExcluded)])))), "
-                        + "{1: <tokens:c:prp />})), 1)",
-                sq.toString());
+        "spanReference("+
+          "focus("+
+            "#[1,2]spanSegment("+
+              "focus("+
+                "#2: spanSegment("+
+                  "spanRelation(tokens:>:stanford/d:tag), " +
+                    "focus("+
+                      "2: spanDistance("+
+                        "focus("+
+                          "1: spanDistance("+
+                            "<tokens:c:vb />, "+
+                            "{1: <tokens:c:prp />}, " +
+                            "[(w[1:1], notOrdered, notExcluded)]"+
+                          ")"+
+                        "), "+
+                        "{2: <tokens:c:nn />}, "+
+                        "[(w[0:2], ordered, notExcluded)]"+
+                      ")"+
+                    ")"+
+                  ")"+
+                "), " +
+                "{1: <tokens:c:prp />}"+
+              ")"+
+            "), 1"+
+          ")",
+        sq.toString());
     }
 }
diff --git a/src/test/resources/queries/reference/bug-multiple-distance-simple.jsonld b/src/test/resources/queries/reference/bug-multiple-distance-simple.jsonld
new file mode 100644
index 0000000..72af003
--- /dev/null
+++ b/src/test/resources/queries/reference/bug-multiple-distance-simple.jsonld
@@ -0,0 +1,33 @@
+{
+  "query": {
+    "@type": "koral:group",
+    "operation": "operation:sequence",
+    "operands": [
+      {
+        "@type": "koral:span",
+        "layer": "c",
+        "key": "vb",
+        "match": "match:eq"
+      },
+      {
+        "@type": "koral:span",
+        "layer": "c",
+        "key": "prp",
+        "match": "match:eq"
+      }
+    ],
+    "inOrder": false,
+    "distances": [{
+      "@type": "koral:distance",
+      "key": "w",
+      "boundary": {
+        "@type": "koral:boundary",
+        "min": 1,
+        "max": 1
+      },
+      "min": 1,
+      "max": 1
+    }]                                
+  },
+  "meta": {}
+}
diff --git a/src/test/resources/queries/reference/bug-multiple-distance.jsonld b/src/test/resources/queries/reference/bug-multiple-distance.jsonld
index 4d59d1f..056d8c6 100644
--- a/src/test/resources/queries/reference/bug-multiple-distance.jsonld
+++ b/src/test/resources/queries/reference/bug-multiple-distance.jsonld
@@ -1,97 +1,97 @@
 {
-    "query": {
-        "@type": "koral:group",
-        "operation": "operation:relation",
-        "operands": [
+  "query": {
+    "@type": "koral:group",
+    "operation": "operation:relation",
+    "operands": [
+      {
+        "@type": "koral:reference",
+        "operation": "operation:focus",
+        "classRef": [2],
+        "operands": [{
+          "@type": "koral:group",
+          "operation": "operation:sequence",
+          "operands": [
             {
-                "@type": "koral:reference",
-                "operation": "operation:focus",
-                "classRef": [2],
-                "operands": [{
+              "@type": "koral:reference",
+              "operation": "operation:focus",
+              "classRef": [1],
+              "operands": [{
+                "@type": "koral:group",
+                "operation": "operation:sequence",
+                "operands": [
+                  {
+                    "@type": "koral:span",
+                    "layer": "c",
+                    "key": "vb",
+                    "match": "match:eq"
+                  },
+                  {
                     "@type": "koral:group",
-                    "operation": "operation:sequence",
-                    "operands": [
-                        {
-                            "@type": "koral:reference",
-                            "operation": "operation:focus",
-                            "classRef": [1],
-                            "operands": [{
-                                "@type": "koral:group",
-                                "operation": "operation:sequence",
-                                "operands": [
-                                    {
-                                        "@type": "koral:span",
-                                        "layer": "c",
-                                        "key": "vb",
-                                        "match": "match:eq"
-                                    },
-                                    {
-                                        "@type": "koral:group",
-                                        "operation": "operation:class",
-                                        "classOut": 1,
-                                        "operands": [{
-                                            "@type": "koral:span",
-                                            "layer": "c",
-                                            "key": "prp",
-                                            "match": "match:eq"
-                                        }]
-                                    }
-                                ],
-                                "inOrder": false,
-                                "distances": [{
-                                    "@type": "koral:distance",
-                                    "key": "w",
-                                    "boundary": {
-                                        "@type": "koral:boundary",
-                                        "min": 1,
-                                        "max": 1
-                                    },
-                                    "min": 1,
-                                    "max": 1
-                                }]                                
-                            }]
-                        },
-                        {
-                            "@type": "koral:group",
-                            "operation": "operation:class",
-                            "classOut": 2,
-                            "operands": [{
-                                "@type": "koral:span",
-                                "layer": "c",
-                                "key": "nn",
-                                "match": "match:eq"
-                            }]
-                        }
-                    ],
-                    "distances": [{
-                        "@type": "koral:distance",
-                        "key": "w",
-                        "boundary": {
-                            "@type": "koral:boundary",
-                            "min": 0,
-                            "max": 2
-                        },
-                        "min": 0,
-                        "max": 2
-                    }],
-                    "inOrder": true
-                }]
+                    "operation": "operation:class",
+                    "classOut": 1,
+                    "operands": [{
+                      "@type": "koral:span",
+                      "layer": "c",
+                      "key": "prp",
+                      "match": "match:eq"
+                    }]
+                  }
+                ],
+                "inOrder": false,
+                "distances": [{
+                  "@type": "koral:distance",
+                  "key": "w",
+                  "boundary": {
+                    "@type": "koral:boundary",
+                    "min": 1,
+                    "max": 1
+                  },
+                  "min": 1,
+                  "max": 1
+                }]                                
+              }]
             },
             {
-                "@type": "koral:reference",
-                "operation": "operation:focus",
-                "classRef": [1]
+              "@type": "koral:group",
+              "operation": "operation:class",
+              "classOut": 2,
+              "operands": [{
+                "@type": "koral:span",
+                "layer": "c",
+                "key": "nn",
+                "match": "match:eq"
+              }]
             }
-        ],
-        "relation": {
-            "@type": "koral:relation",
-            "wrap": {
-                "@type": "koral:term",
-                "foundry": "stanford",
-                "layer": "d",
-                "key":"tag"
-            }
-        }
-    },
-    "meta": {}
+          ],
+          "distances": [{
+            "@type": "koral:distance",
+            "key": "w",
+            "boundary": {
+              "@type": "koral:boundary",
+              "min": 0,
+              "max": 2
+            },
+            "min": 0,
+            "max": 2
+          }],
+          "inOrder": true
+        }]
+      },
+      {
+        "@type": "koral:reference",
+        "operation": "operation:focus",
+        "classRef": [1]
+      }
+    ],
+    "relation": {
+      "@type": "koral:relation",
+      "wrap": {
+        "@type": "koral:term",
+        "foundry": "stanford",
+        "layer": "d",
+        "key":"tag"
+      }
+    }
+  },
+  "meta": {}
 }