diff --git a/querydsl-core/src/test/java/com/mysema/query/support/GroupBy2.java b/querydsl-core/src/test/java/com/mysema/query/support/GroupBy2.java
new file mode 100644
index 000000000..0861f5891
--- /dev/null
+++ b/querydsl-core/src/test/java/com/mysema/query/support/GroupBy2.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2010 Mysema Ltd.
+ * All rights reserved.
+ *
+ */
+package com.mysema.query.support;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+
+import com.mysema.commons.lang.CloseableIterator;
+import com.mysema.query.Projectable;
+import com.mysema.query.ResultTransformer;
+import com.mysema.query.Tuple;
+import com.mysema.query.types.Expression;
+import com.mysema.query.types.Visitor;
+
+/**
+ * Groups results by the first expression.
+ *
+ * - Order of groups by position of the first row of a group
+ *
- Rows belonging to a group may appear in any order
+ *
- Group of null is handled correctly
+ *
+ *
+ * @author sasa
+ */
+//@SuppressWarnings("unchecked")
+public class GroupBy2 implements ResultTransformer> {
+
+ private final Expression>[] expressions;
+
+ private static interface GroupFactory {
+
+ public void add(Object o);
+
+ public R get();
+
+ }
+
+ /**
+ * NOTE: This expression only applies to GroupBy.transform
+ *
+ * @param
+ * @param
+ */
+ public static abstract class GroupAsExpression implements Expression {
+
+ private static final long serialVersionUID = -8164758792405567077L;
+
+ private final Expression expr;
+
+ public GroupAsExpression(Expression expr) {
+ this.expr = expr;
+ }
+
+ @Override
+ public S accept(Visitor v, C context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Class extends R> getType() {
+ throw new UnsupportedOperationException();
+ }
+
+ public int hashCode() {
+ return expr.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ } else if (o instanceof GroupAsExpression) {
+ GroupAsExpression, ?> other = (GroupAsExpression, ?>) o;
+ return this.expr.equals(other.expr);
+ } else {
+ return false;
+ }
+ }
+
+ public abstract GroupFactory createGroupFactory();
+
+ }
+
+ public static GroupAsExpression> set(Expression expr) {
+ return new GroupAsExpression>(expr) {
+
+ private static final long serialVersionUID = -2507144565843468159L;
+
+ @Override
+ public GroupFactory> createGroupFactory() {
+ return new GroupFactory>() {
+
+ private final Set set = new HashSet();
+
+ @Override
+ public void add(Object o) {
+ set.add((T) o);
+ }
+
+ @Override
+ public Set get() {
+ return set;
+ }
+
+ };
+ }
+
+ };
+ }
+
+ public static GroupAsExpression> list(Expression expr) {
+ return new GroupAsExpression>(expr) {
+
+ private static final long serialVersionUID = -6941324182786049824L;
+
+ @Override
+ public GroupFactory> createGroupFactory() {
+ return new GroupFactory>() {
+
+ private final List list = new ArrayList();
+
+ @Override
+ public void add(Object o) {
+ list.add((T) o);
+ }
+
+ @Override
+ public List get() {
+ return list;
+ }
+
+ };
+ }
+
+ };
+ }
+
+ private static class ValueGroupFactory implements GroupFactory {
+ private T val;
+
+ private boolean first = true;
+
+ @Override
+ public void add(Object o) {
+ if (first) {
+ val = (T) o;
+ first = false;
+ }
+ }
+
+ @Override
+ public T get() {
+ return val;
+ }
+
+ }
+
+ public GroupBy2(Expression> groupBy, Expression>... args) {
+ expressions = new Expression>[args.length + 1];
+ expressions[0] = groupBy;
+ System.arraycopy(args, 0, expressions, 1, args.length);
+ }
+
+ @Override
+ public Collection transform(Projectable projectable) {
+ final LinkedHashMap