// -----------------------------------------------------
 //                                            If Comment
 //                                            ----------
 protected void doProcessAutoDetectIfNode(
     String sql,
     Map<String, String> propertyNameTypeMap,
     Map<String, String> propertyNameOptionMap,
     IfNode ifNode) {
   final String ifCommentBooleanType = switchPlainTypeName("boolean");
   final String expression = ifNode.getExpression().trim(); // trim it just in case
   final List<String> elementList = Srl.splitList(expression, " ");
   for (int i = 0; i < elementList.size(); i++) {
     // boolean-not mark unused here so remove it at first
     final String element = substringBooleanNotRear(elementList.get(i));
     if (!isPmCommentStartsWithPmb(element)) {
       continue;
     }
     if (isPmCommentNestedProperty(element) || isPmCommentMethodCall(element)) {
       continue;
     }
     final String propertyName = substringPmCommentPmbRear(element);
     if (propertyNameTypeMap.containsKey(propertyName)) {
       // because of priority low (bind variable is given priority over if-comment)
       continue;
     }
     if (isRevervedProperty(propertyName)) {
       continue;
     }
     final int nextIndex = i + 1;
     if (elementList.size() <= nextIndex) { // last now
       propertyNameTypeMap.put(propertyName, ifCommentBooleanType);
       continue;
     }
     // next exists here
     final String nextElement = elementList.get(nextIndex);
     if (isIfCommentStatementConnector(nextElement)) { // e.g. '&&' or '||'
       propertyNameTypeMap.put(propertyName, ifCommentBooleanType);
       continue;
     }
     if (!isIfCommentStatementOperand(nextElement)) { // no way (wrong syntax)
       continue;
     }
     final int nextNextIndex = i + 2;
     if (elementList.size() <= nextNextIndex) { // no way (wrong syntax)
       continue;
     }
     // next next exists
     final String nextNextElement = elementList.get(nextNextIndex);
     if (isPmCommentStartsWithPmb(nextNextElement)) { // e.g. pmb.foo == pmb.bar
       continue;
     }
     // using-value statement here e.g. pmb.foo == 'foo'
     // condition value is treated as testValue to derive
     final String propertyType = derivePropertyTypeFromTestValue(nextNextElement);
     propertyNameTypeMap.put(propertyName, propertyType);
   }
 }
 protected void doProcessAlternateBooleanMethodIfNode(String sql, IfNode ifNode) {
   final String expression = ifNode.getExpression().trim(); // trim it just in case
   if (Srl.containsAny(expression, getIfCommentConnectors())
       || Srl.containsAny(expression, getIfCommentOperands())) {
     return; // unknown (type)
   }
   if (isPmCommentNestedProperty(expression) || !isPmCommentMethodCall(expression)) {
     return; // e.g. pmb.foo.bar
   }
   if (!isPmCommentStartsWithPmb(substringBooleanNotRear(expression))) {
     return; // e.g. #current.isFoo()
   }
   // pmb.foo() or !pmb.foo() here
   String methodName = substringPmCommentPmbRear(expression); // -> foo()
   methodName = Srl.substringLastFront(methodName, "()"); // -> foo
   _alternateBooleanMethodNameSet.add(methodName); // filter later
 }