protected CommandEvaluator<Criterion, Object> compileIdentifierToValueCMP(
     IdentifierToValueCMP node) {
   Identifier id = node.getIdentifier();
   if (id instanceof Field) {
     String name = id.getName();
     Value value = node.getValue();
     if (INSTANCE_ID_FIELD.equals(name)) {
       value.setValue(Long.valueOf((String) value.getValue()));
     } else if (INSTANCE_STARTED_FIELD.equals(name) || INSTANCE_LAST_ACTIVE_FIELD.equals(name)) {
       try {
         value.setValue(ISO8601DateParser.parse((String) value.getValue()));
       } catch (ParseException ex) {
         throw new RuntimeException(ex);
       }
     }
   }
   if (node instanceof Equality) {
     return compileEqual((Equality) node);
   } else if (node instanceof Less) {
     return compileLess((Less) node);
   } else if (node instanceof Greater) {
     return compileGreater((Greater) node);
   } else if (node instanceof GE) {
     return compileGE((GE) node);
   } else if (node instanceof LE) {
     return compileLE((LE) node);
   } else if (node instanceof Like) {
     return compileLike((Like) node);
   } else {
     throw new IllegalArgumentException("Unsupported node " + node.getClass());
   }
 }
  protected INEvaluator<String, Criterion, Object> compileIn(final In in) {
    if (in.getIdentifier() instanceof Property) {
      propertyInQuery = true;
      final Property property = (Property) in.getIdentifier();
      return new INEvaluator<String, Criterion, Object>() {
        public Criterion evaluate(Object paramValue) {
          Disjunction disj = Restrictions.disjunction();

          String propertyNS = property.getNamespace();
          String propertyName = property.getName();

          for (Value value : in.getValues()) {
            Conjunction conj = Restrictions.conjunction();
            if (!StringUtils.isEmpty(property.getNamespace())) {
              conj.add(Restrictions.gt(PROPERTY_NS_DB_FIELD, propertyNS));
            }
            conj.add(Restrictions.gt(PROPERTY_NAME_DB_FIELD, propertyName));
            conj.add(Restrictions.gt(PROPERTY_VALUE_DB_FIELD, value.getValue()));

            disj.add(conj);
          }
          return disj;
        };

        public String getIdentifier() {
          return property.toString();
        };
      };
    } else {
      final String fieldName = in.getIdentifier().getName();

      if (INSTANCE_STATUS_FIELD.equals(fieldName)) {
        short noState = 200; // TODO move to constants
        final Disjunction disj = Restrictions.disjunction();

        final Collection values = ValuesHelper.extract((Collection<Value>) in.getValues());

        if (values.contains(STATUS_ACTIVE)) {
          disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_NEW));
          disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_ACTIVE));
          disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_READY));
        }
        if (values.contains(STATUS_SUSPENDED)) {
          disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_SUSPENDED));
        }
        if (values.contains(STATUS_ERROR)) {
          disj.add(
              Restrictions.eq(
                  INSTANCE_STATUS_DB_FIELD, noState)); // Error instance state doesn't exist yet
        }
        if (values.contains(STATUS_COMPLETED)) {
          disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_COMPLETED_OK));
        }
        if (values.contains(STATUS_TERMINATED)) {
          disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_TERMINATED));
        }
        if (values.contains(STATUS_FAULTED)) {
          disj.add(
              Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_COMPLETED_WITH_FAULT));
        }
        return new INEvaluator<String, Criterion, Object>() {
          public Criterion evaluate(Object paramValue) {
            return disj;
          };

          public String getIdentifier() {
            return INSTANCE_STATUS_DB_FIELD;
          };
        };
      } else {
        final Collection objValues;
        final Collection<Value> values = in.getValues();
        if (INSTANCE_ID_FIELD.equals(fieldName)) {
          objValues = new ArrayList<Long>(values.size());
          for (Value value : values) {
            objValues.add(Long.valueOf((String) value.getValue()));
          }
        } else if (INSTANCE_STARTED_FIELD.equals(fieldName)
            || INSTANCE_LAST_ACTIVE_FIELD.equals(fieldName)) {
          objValues = new ArrayList<Date>(values.size());
          try {
            for (Value value : values) {
              objValues.add(ISO8601DateParser.parse((String) value.getValue()));
            }
          } catch (ParseException ex) {
            throw new RuntimeException(ex);
          }
        } else {
          objValues = ValuesHelper.extract((Collection<Value>) values);
        }
        final String dbField = getDBField(fieldName);
        return new INEvaluator<String, Criterion, Object>() {
          /** @see org.apache.ode.ql.eval.skel.CommandEvaluator#evaluate(java.lang.Object) */
          public Criterion evaluate(Object paramValue) {
            return Restrictions.in(dbField, objValues);
          }

          /** @see org.apache.ode.ql.eval.skel.Identified#getIdentifier() */
          public String getIdentifier() {
            return dbField;
          }
        };
      }
    }
  }