@Test
  public void testEvaluate_Null() {
    Expression gtNull = new ASTGreaterOrEqual(new ASTObjPath("estimatedPrice"), null);
    Expression gtNotNull =
        new ASTGreaterOrEqual(new ASTObjPath("estimatedPrice"), new BigDecimal(10000d));

    Painting noMatch = new Painting();
    assertFalse(gtNull.match(noMatch));
    assertFalse(gtNotNull.match(noMatch));
  }
  @Test
  public void testEvaluate() {
    Expression e = new ASTGreaterOrEqual(new ASTObjPath("estimatedPrice"), new BigDecimal(10000d));

    Painting noMatch = new Painting();
    noMatch.setEstimatedPrice(new BigDecimal(9999));
    assertFalse(e.match(noMatch));

    Painting match1 = new Painting();
    match1.setEstimatedPrice(new BigDecimal(10000));
    assertTrue(e.match(match1));

    Painting match = new Painting();
    match.setEstimatedPrice(new BigDecimal(10001));
    assertTrue("Failed: " + e, e.match(match));
  }
  /**
   * Returns the deepest possible entity in the inheritance hierarchy that can be used to create
   * objects from a given DataRow.
   */
  public ObjEntity entityMatchingRow(DataRow row) {
    // match depth first
    if (subentities != null) {
      for (EntityInheritanceTree child : subentities) {
        ObjEntity matched = child.entityMatchingRow(row);

        if (matched != null) {
          return matched;
        }
      }
    }

    Expression qualifier = getDbQualifier();
    if (qualifier != null) {
      return qualifier.match(row) ? entity : null;
    }

    // no qualifier ... matches all rows
    return entity;
  }