/**
  * template method, override to customize
  *
  * @param path path
  * @return field name
  */
 protected String toField(Path<?> path) {
   PathMetadata md = path.getMetadata();
   if (md.getPathType() == PathType.COLLECTION_ANY) {
     return toField(md.getParent());
   } else {
     String rv = md.getName();
     if (md.getParent() != null) {
       Path<?> parent = md.getParent();
       if (parent.getMetadata().getPathType() != PathType.VARIABLE) {
         rv = toField(parent) + "." + rv;
       }
     }
     return rv;
   }
 }
 protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) {
   Path<?> path = getPath(operation.getArg(0));
   String field = toField(path);
   @SuppressWarnings("unchecked") // This is the second argument type
   Constant<Collection<?>> collConstant = (Constant<Collection<?>>) operation.getArg(1);
   Collection<?> values = collConstant.getConstant();
   BooleanQuery bq = new BooleanQuery();
   if (Number.class.isAssignableFrom(path.getType())) {
     for (Object value : values) {
       TermQuery eq = new TermQuery(new Term(field, convertNumber((Number) value)));
       bq.add(eq, Occur.SHOULD);
     }
   } else {
     for (Object value : values) {
       String[] str = convert(path, value);
       bq.add(eq(field, str, ignoreCase), Occur.SHOULD);
     }
   }
   return bq;
 }