class DroolsGroupingBiConstraintStream<Solution_, NewA, NewB>
        extends DroolsAbstractBiConstraintStream<Solution_, NewA, NewB> {

    private final Supplier<BiLeftHandSide<NewA, NewB>> leftHandSide;

    public <A> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractUniConstraintStream<Solution_, A> parent, Function<A, NewA> groupKeyAMapping,
            Function<A, NewB> groupKeyBMapping) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyAMapping, groupKeyBMapping);
    }

    public <A, B> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractBiConstraintStream<Solution_, A, B> parent, BiFunction<A, B, NewA> groupKeyAMapping,
            BiFunction<A, B, NewB> groupKeyBMapping) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyAMapping, groupKeyBMapping);
    }

    public <A, B, C> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractTriConstraintStream<Solution_, A, B, C> parent, TriFunction<A, B, C, NewA> groupKeyAMapping,
            TriFunction<A, B, C, NewB> groupKeyBMapping) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyAMapping, groupKeyBMapping);
    }

    public <A, B, C, D> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractQuadConstraintStream<Solution_, A, B, C, D> parent,
            QuadFunction<A, B, C, D, NewA> groupKeyAMapping, QuadFunction<A, B, C, D, NewB> groupKeyBMapping) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyAMapping, groupKeyBMapping);
    }

    public <A> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractUniConstraintStream<Solution_, A> parent, Function<A, NewA> groupKeyMapping,
            UniConstraintCollector<A, ?, NewB> collector) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyMapping, collector);
    }

    public <A, B> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractBiConstraintStream<Solution_, A, B> parent, BiFunction<A, B, NewA> groupKeyMapping,
            BiConstraintCollector<A, B, ?, NewB> collector) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyMapping, collector);
    }

    public <A, B, C> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractTriConstraintStream<Solution_, A, B, C> parent, TriFunction<A, B, C, NewA> groupKeyMapping,
            TriConstraintCollector<A, B, C, ?, NewB> collector) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyMapping, collector);
    }

    public <A, B, C, D> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractQuadConstraintStream<Solution_, A, B, C, D> parent,
            QuadFunction<A, B, C, D, NewA> groupKeyMapping, QuadConstraintCollector<A, B, C, D, ?, NewB> collector) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(groupKeyMapping, collector);
    }

    public <A> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractUniConstraintStream<Solution_, A> parent, UniConstraintCollector<A, ?, NewA> collectorA,
            UniConstraintCollector<A, ?, NewB> collectorB) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(collectorA, collectorB);
    }

    public <A, B> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractBiConstraintStream<Solution_, A, B> parent, BiConstraintCollector<A, B, ?, NewA> collectorA,
            BiConstraintCollector<A, B, ?, NewB> collectorB) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(collectorA, collectorB);
    }

    public <A, B, C> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractTriConstraintStream<Solution_, A, B, C> parent,
            TriConstraintCollector<A, B, C, ?, NewA> collectorA, TriConstraintCollector<A, B, C, ?, NewB> collectorB) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(collectorA, collectorB);
    }

    public <A, B, C, D> DroolsGroupingBiConstraintStream(DroolsConstraintFactory<Solution_> constraintFactory,
            DroolsAbstractQuadConstraintStream<Solution_, A, B, C, D> parent,
            QuadConstraintCollector<A, B, C, D, ?, NewA> collectorA,
            QuadConstraintCollector<A, B, C, D, ?, NewB> collectorB) {
        super(constraintFactory, parent.getRetrievalSemantics());
        this.leftHandSide = () -> parent.createLeftHandSide().andGroupBy(collectorA, collectorB);
    }

    @Override
    public boolean guaranteesDistinct() {
        return true;
    }

    @Override
    public BiLeftHandSide<NewA, NewB> createLeftHandSide() {
        return leftHandSide.get();
    }

    @Override
    public String toString() {<FILL_FUNCTION_BODY>}
}

        return "BiGroup() with " + getChildStreams().size() + " children";
    
<methods>public void <init>(DroolsConstraintFactory<Solution_>, org.optaplanner.constraint.streams.common.RetrievalSemantics) ,public BiConstraintStream<NewA,NewB> filter(BiPredicate<NewA,NewB>) ,public BiConstraintStream<NewA,ResultB_> flattenLast(Function<NewB,Iterable<ResultB_>>) ,public UniConstraintStream<Result_> groupBy(BiConstraintCollector<NewA,NewB,ResultContainer_,Result_>) ,public BiConstraintStream<ResultA_,ResultB_> groupBy(BiConstraintCollector<NewA,NewB,ResultContainerA_,ResultA_>, BiConstraintCollector<NewA,NewB,ResultContainerB_,ResultB_>) ,public TriConstraintStream<ResultA_,ResultB_,ResultC_> groupBy(BiConstraintCollector<NewA,NewB,ResultContainerA_,ResultA_>, BiConstraintCollector<NewA,NewB,ResultContainerB_,ResultB_>, BiConstraintCollector<NewA,NewB,ResultContainerC_,ResultC_>) ,public QuadConstraintStream<ResultA_,ResultB_,ResultC_,ResultD_> groupBy(BiConstraintCollector<NewA,NewB,ResultContainerA_,ResultA_>, BiConstraintCollector<NewA,NewB,ResultContainerB_,ResultB_>, BiConstraintCollector<NewA,NewB,ResultContainerC_,ResultC_>, BiConstraintCollector<NewA,NewB,ResultContainerD_,ResultD_>) ,public UniConstraintStream<GroupKey_> groupBy(BiFunction<NewA,NewB,GroupKey_>) ,public BiConstraintStream<GroupKey_,Result_> groupBy(BiFunction<NewA,NewB,GroupKey_>, BiConstraintCollector<NewA,NewB,__,Result_>) ,public TriConstraintStream<GroupKey_,ResultB_,ResultC_> groupBy(BiFunction<NewA,NewB,GroupKey_>, BiConstraintCollector<NewA,NewB,ResultContainerB_,ResultB_>, BiConstraintCollector<NewA,NewB,ResultContainerC_,ResultC_>) ,public QuadConstraintStream<GroupKey_,ResultB_,ResultC_,ResultD_> groupBy(BiFunction<NewA,NewB,GroupKey_>, BiConstraintCollector<NewA,NewB,ResultContainerB_,ResultB_>, BiConstraintCollector<NewA,NewB,ResultContainerC_,ResultC_>, BiConstraintCollector<NewA,NewB,ResultContainerD_,ResultD_>) ,public BiConstraintStream<GroupKeyA_,GroupKeyB_> groupBy(BiFunction<NewA,NewB,GroupKeyA_>, BiFunction<NewA,NewB,GroupKeyB_>) ,public TriConstraintStream<GroupKeyA_,GroupKeyB_,Result_> groupBy(BiFunction<NewA,NewB,GroupKeyA_>, BiFunction<NewA,NewB,GroupKeyB_>, BiConstraintCollector<NewA,NewB,ResultContainer_,Result_>) ,public QuadConstraintStream<GroupKeyA_,GroupKeyB_,ResultC_,ResultD_> groupBy(BiFunction<NewA,NewB,GroupKeyA_>, BiFunction<NewA,NewB,GroupKeyB_>, BiConstraintCollector<NewA,NewB,ResultContainerC_,ResultC_>, BiConstraintCollector<NewA,NewB,ResultContainerD_,ResultD_>) ,public TriConstraintStream<GroupKeyA_,GroupKeyB_,GroupKeyC_> groupBy(BiFunction<NewA,NewB,GroupKeyA_>, BiFunction<NewA,NewB,GroupKeyB_>, BiFunction<NewA,NewB,GroupKeyC_>) ,public QuadConstraintStream<GroupKeyA_,GroupKeyB_,GroupKeyC_,ResultD_> groupBy(BiFunction<NewA,NewB,GroupKeyA_>, BiFunction<NewA,NewB,GroupKeyB_>, BiFunction<NewA,NewB,GroupKeyC_>, BiConstraintCollector<NewA,NewB,ResultContainerD_,ResultD_>) ,public QuadConstraintStream<GroupKeyA_,GroupKeyB_,GroupKeyC_,GroupKeyD_> groupBy(BiFunction<NewA,NewB,GroupKeyA_>, BiFunction<NewA,NewB,GroupKeyB_>, BiFunction<NewA,NewB,GroupKeyC_>, BiFunction<NewA,NewB,GroupKeyD_>) ,public final transient BiConstraintStream<NewA,NewB> ifExists(Class<C>, TriJoiner<NewA,NewB,C>[]) ,public final transient BiConstraintStream<NewA,NewB> ifExistsIncludingNullVars(Class<C>, TriJoiner<NewA,NewB,C>[]) ,public final transient BiConstraintStream<NewA,NewB> ifNotExists(Class<C>, TriJoiner<NewA,NewB,C>[]) ,public final transient BiConstraintStream<NewA,NewB> ifNotExistsIncludingNullVars(Class<C>, TriJoiner<NewA,NewB,C>[]) ,public BiConstraintBuilder<NewA,NewB,Score_> innerImpact(Score_, ToIntBiFunction<NewA,NewB>, org.optaplanner.constraint.streams.common.ScoreImpactType) ,public BiConstraintBuilder<NewA,NewB,Score_> innerImpact(Score_, ToLongBiFunction<NewA,NewB>, org.optaplanner.constraint.streams.common.ScoreImpactType) ,public BiConstraintBuilder<NewA,NewB,Score_> innerImpact(Score_, BiFunction<NewA,NewB,java.math.BigDecimal>, org.optaplanner.constraint.streams.common.ScoreImpactType) ,public final transient TriConstraintStream<NewA,NewB,C> join(UniConstraintStream<C>, TriJoiner<NewA,NewB,C>[]) ,public UniConstraintStream<ResultA_> map(BiFunction<NewA,NewB,ResultA_>) <variables>