/** @throws Exception */
  @Test
  public void testGroup() throws Exception {
    QueryDefinition queryDefn = newReportQuery();

    // column mapping
    String[] name = new String[] {"testColumn1", "testColumn2", "AMOUNT1"};
    ScriptExpression[] se = new ScriptExpression[name.length];
    se[0] = new ScriptExpression("dataSetRow.COUNTRY");
    se[1] = new ScriptExpression("dataSetRow.CITY");
    se[2] = new ScriptExpression("dataSetRow.AMOUNT");
    for (int i = 0; i < name.length; i++) queryDefn.addBinding(new Binding(name[i], se[i]));

    GroupDefinition groupDefn = new GroupDefinition("group1");
    groupDefn.setKeyColumn("testColumn1");
    String name2 = "testColumn3";
    ScriptExpression se2 = new ScriptExpression("Total.sum(dataSetRow.AMOUNT)");
    se2.setGroupName("group1");
    // groupDefn.addResultSetExpression( name2, new ColumnBindingExpression(se2) );
    queryDefn.addBinding(new Binding(name2, se2));
    queryDefn.addGroup(groupDefn);
    String name3 = "testColumn4";
    ScriptExpression se3 = new ScriptExpression("row[\"testColumn1\"]");
    GroupDefinition groupDefn1 = new GroupDefinition("group2");
    groupDefn1.setKeyColumn("testColumn4");
    se3.setGroupName("group2");
    // groupDefn1.addResultSetExpression( name3, new ColumnBindingExpression(se3) );
    queryDefn.addBinding(new Binding(name3, se3));
    queryDefn.addGroup(groupDefn1);

    IResultIterator ri = executeQuery(queryDefn);
    while (ri.next()) {
      String str = "";
      for (int i = 0; i < name.length; i++) {
        str += ri.getValue(name[i]);
        str += ", ";
      }
      str += ri.getValue(name2);

      testPrintln(str);
    }

    checkOutputFile();
  }
  /**
   * Adapts a model oda data set handle
   *
   * @param modelDataSet model handle
   * @param propBindingScope Javascript scope in which to evaluate property binding expressions. If
   *     null, property binding is not resolved
   * @throws BirtException
   */
  public OdaDataSetAdapter(
      OdaDataSetHandle modelDataSet,
      Scriptable propBindingScope,
      ModelAdapter adapter,
      DataEngineContext dtContext)
      throws BirtException {
    super(modelDataSet.getQualifiedName());

    // TODO: event handler

    // Adapt base class properties
    DataAdapterUtil.adaptBaseDataSet(modelDataSet, this, adapter);

    // Adapt extended data set elements

    // Set query text; if binding exists, use its result; otherwise
    // use static design
    Expression expression = modelDataSet.getPropertyBindingExpression(OdaDataSet.QUERY_TEXT_PROP);
    org.eclipse.birt.data.engine.api.querydefn.ScriptExpression script =
        adapter.adaptExpression(expression);

    if (propBindingScope != null
        && script != null
        && DataSessionContext.MODE_UPDATE != dtContext.getMode()) {
      String queryText =
          JavascriptEvalUtil.evaluateScript(
                  null, propBindingScope, script.getText(), ScriptExpression.defaultID, 0)
              .toString();
      setQueryText(queryText);
    } else {
      setQueryText(modelDataSet.getQueryText());
    }

    // type of extended data set
    setExtensionID(modelDataSet.getExtensionID());

    // result set name
    setPrimaryResultSetName(modelDataSet.getResultSetName());

    if (modelDataSet.getPropertyHandle(IOdaDataSetModel.RESULT_SET_NUMBER_PROP).isSet())
      setPrimaryResultSetNumber(modelDataSet.getResultSetNumber());
    // static ROM properties defined by the ODA driver extension
    Map staticProps =
        DataAdapterUtil.getExtensionProperties(
            modelDataSet, modelDataSet.getExtensionPropertyDefinitionList());
    if (staticProps != null && !staticProps.isEmpty()) {
      Iterator propNamesItr = staticProps.keySet().iterator();
      while (propNamesItr.hasNext()) {
        String propName = (String) propNamesItr.next();
        assert (propName != null);
        String propValue;
        String bindingExpr = modelDataSet.getPropertyBinding(propName);
        if (propBindingScope != null && bindingExpr != null && bindingExpr.length() > 0) {
          propValue =
              JavascriptEvalUtil.evaluateScript(
                      null, propBindingScope, bindingExpr, ScriptExpression.defaultID, 0)
                  .toString();
        } else {
          propValue = (String) staticProps.get(propName);
        }
        addPublicProperty((String) propName, propValue);
      }
    }

    // private driver properties / private runtime data
    Iterator elmtIter = modelDataSet.privateDriverPropertiesIterator();
    if (elmtIter != null) {
      while (elmtIter.hasNext()) {
        ExtendedPropertyHandle modelProp = (ExtendedPropertyHandle) elmtIter.next();
        addPrivateProperty(modelProp.getName(), modelProp.getValue());
      }
    }
  }