@Test
    void testConvertExpressionItemsTree() {
        // AND (op1)
        // --term1field IN term1value1,term1value2,term1value3
        // --OR (op2)
        // ----term2field=term2value
        // ----term3field=term3value
        // ----NOT (op3)
        // ---- term4field=term4value

        // should convert to

        // AND (op1)
        // --OR
        // ----term1field=term1value1
        // ----term1field=term1value2
        // ----term1field=term1value3
        // --OR (op2)
        // ----term2field=term2value
        // ----term3field=term3value
        // ----NOT (op3)
        // ---- term4field=term4value

        final String term1value1 = "term1value1";
        final String term1value2 = "term1value2";
        final String term1value3 = "term1value3";

        final ExpressionOperator.Builder op1 = ExpressionOperator.builder()
                .addTerm("term1field", Condition.IN, term1value1 + "," + term1value2 + "," + term1value3)
                .addOperator(ExpressionOperator.builder().op(Op.OR)
                        .addTerm("term2field", Condition.EQUALS, "term2value")
                        .addTerm("term3field", Condition.EQUALS, "term3value")
                        .addOperator(ExpressionOperator.builder().op(Op.NOT)
                                .addTerm("term4field", Condition.EQUALS, "term4value")
                                .build())
                        .build());

        final FilterTermsTree filterTermsTree = FilterTermsTreeBuilder.convertExpresionItemsTree(op1.build());

        final OperatorNode newOp1 = (OperatorNode) filterTermsTree.getRootNode();

        assertThat(newOp1.getFilterOperationMode().toString()).isEqualTo(Op.AND.toString());

        final OperatorNode newTerm1OpNode = (OperatorNode) newOp1.getChildren().get(0);
        assertThat(newTerm1OpNode.getFilterOperationMode().toString()).isEqualTo(Op.OR.toString());
        assertThat(newTerm1OpNode.getChildren().size()).isEqualTo(3);

        final TermNode newTerm1SubTerm1 = (TermNode) newTerm1OpNode.getChildren().get(0);
        final TermNode newTerm1SubTerm2 = (TermNode) newTerm1OpNode.getChildren().get(1);
        final TermNode newTerm1SubTerm3 = (TermNode) newTerm1OpNode.getChildren().get(2);

        assertThat(newTerm1SubTerm1.getTag()).isEqualTo("term1field");
        assertThat(newTerm1SubTerm1.getValue()).isEqualTo(term1value1);
        assertThat(newTerm1SubTerm2.getTag()).isEqualTo("term1field");
        assertThat(newTerm1SubTerm2.getValue()).isEqualTo(term1value2);
        assertThat(newTerm1SubTerm3.getTag()).isEqualTo("term1field");
        assertThat(newTerm1SubTerm3.getValue()).isEqualTo(term1value3);

        final OperatorNode newOp2 = (OperatorNode) newOp1.getChildren().get(1);

        assertThat(newOp2.getFilterOperationMode().toString()).isEqualTo(Op.OR.toString());

        final TermNode newTerm2 = (TermNode) newOp2.getChildren().get(0);
        final TermNode newTerm3 = (TermNode) newOp2.getChildren().get(1);
        final OperatorNode newOp3 = (OperatorNode) newOp2.getChildren().get(2);

        assertThat(newTerm2.getTag()).isEqualTo("term2field");
        assertThat(newTerm2.getValue()).isEqualTo("term2value");
        assertThat(newTerm3.getTag()).isEqualTo("term3field");
        assertThat(newTerm3.getValue()).isEqualTo("term3value");
        assertThat(newOp3.getFilterOperationMode().toString()).isEqualTo(Op.NOT.toString());

        final TermNode newTerm4 = (TermNode) newOp3.getChildren().get(0);
        assertThat(newTerm4.getTag()).isEqualTo("term4field");
        assertThat(newTerm4.getValue()).isEqualTo("term4value");
    }
Verify that a tree of {@link stroom.query.api.ExpressionItem} objects can be converted
correctly into a {@link FilterTermsTree}
stroom-statistics/stroom-statistics-impl-sql/src/test/java/stroom/statistics/impl/sql/search/TestFilterTermsTreeBuilder.java