public static DataMap parseDataMapKeys(Map<String, List<String>> queryParameters) throws PathSegmentSyntaxException
  {
    // The parameters are parsed into an intermediary structure comprised of
    // HashMap<String,Object> and HashMap<Integer,Object>, defined respectively
    // as MapMap and ListMap for convenience. This is done for two reasons:
    // - first, indexed keys representing lists are parsed into ListMaps keyed on
    //   index values, since the indices may come in any order in the query parameter,
    //   while we want to preserve the order.
    // - second, DataMap only accepts Data objects as values, so ListMaps cannot
    //   be stored there, so using an intermediary structure even for maps.

    MapMap dataMap = new MapMap();

    for (Map.Entry<String, List<String>> entry : queryParameters.entrySet())
    {
      // As per the notation above, we no longer support multiple occurrences of
      // a parameter (considering its full multi-part and indexed name), i.e
      // there should be only a single entry in each list. For backward compatibility
      // as well as ease of use, repeated parameters are still allowed if they
      // are "simple", i.e. they are not multi-part or indexed.
      List<String> valueList = entry.getValue();
      if (valueList.size() == 1)
      {
        String[] key = SEGMENT_DELIMITER_PATTERN.split(entry.getKey());
        parseParameter(key, valueList.get(0), dataMap);
      }
      else
      {
        String parameterName = entry.getKey();
        // In case of multiple parameters ensure they are not delimited or
        // indexed and then simulate the index for each one.
        if(parameterName.indexOf('.') != -1)
          throw new PathSegmentSyntaxException("Multiple values of complex query parameter are not supported");

        if(parameterName.charAt(parameterName.length()-1) == ']')
          throw new PathSegmentSyntaxException("Multiple values of indexed query parameter are not supported");

        if(dataMap.containsKey(parameterName))
          throw new PathSegmentSyntaxException("Conflicting references to key " + parameterName + "[0]");

        else
        {
          dataMap.put(parameterName, new DataList(valueList));
        }
      }
    }

    return (DataMap)convertToDataCollection(dataMap);
  }
@Test
  public void testParseDataMapKeys() throws Exception {
    String testQS = "ids[0].params.versionTag=tag1&ids[0].params.authToken=tok1&ids[0].memberID=1&ids[0].groupID=2&" +
                    "ids[1].params.versionTag=tag2&ids[1].params.authToken=tok2&ids[1].memberID=2&ids[1].groupID=2&" +
                    "q=someFinder";
    /*
     * Resulting DataMap:
     *
     * {    q=someFinder,
     *      ids=[
     *          {groupID=2,
     *           params={
     *                  versionTag=tag2,
     *                  authToken=tok2
     *           },
     *           memberID=2
     *           },
     *
     *           {groupID=2,
     *           params={
     *                  versionTag=tag1,
     *                  authToken=tok1
     *                  },
     *           memberID=1
     *           }
     *       ]
     * }
     */
    DataMap queryParamDataMap = queryParamsDataMap(testQS);

    Assert.assertNotNull(queryParamDataMap);
    Assert.assertEquals("someFinder", queryParamDataMap.get("q"));

    DataList ids = queryParamDataMap.getDataList("ids");

    DataMap ids0 = ids.getDataMap(0);
    Assert.assertEquals(ids0.get("memberID"), "1");
    Assert.assertEquals(ids0.get("groupID"), "2");
    DataMap params = ids0.getDataMap("params");
    Assert.assertEquals(params.get("versionTag"), "tag1");
    Assert.assertEquals(params.get("authToken"), "tok1");

    ids0 = ids.getDataMap(1);
    Assert.assertEquals(ids0.get("memberID"), "2");
    Assert.assertEquals(ids0.get("groupID"), "2");
    params = ids0.getDataMap("params");
    Assert.assertEquals(params.get("versionTag"), "tag2");
    Assert.assertEquals(params.get("authToken"), "tok2");
  }