protected DetectedPropertyInfo analyzeForNodeElementType(Node node, String propertyName) {
   if (isPmCommentNestedProperty(propertyName) || isPmCommentMethodCall(propertyName)) {
     return null;
   }
   final DfLanguageGrammar grammar = getLanguageGrammar();
   DetectedPropertyInfo detected = null;
   for (int i = 0; i < node.getChildSize(); i++) {
     final Node childNode = node.getChild(i);
     if (childNode instanceof BindVariableNode) {
       final BindVariableNode bindNode = (BindVariableNode) childNode;
       final String expression = bindNode.getExpression();
       if (!isPmCommentEqualsCurrent(expression)) {
         continue;
       }
       if (isPmCommentNestedProperty(expression) || isPmCommentMethodCall(expression)) {
         continue;
       }
       // /*#current*/ here
       final String testValue = bindNode.getTestValue();
       if (testValue == null) {
         continue;
       }
       final String propertyType = derivePropertyTypeFromTestValue(testValue);
       final String propertyOption = derivePropertyOptionFromTestValue(testValue);
       if (Srl.is_NotNull_and_NotTrimmedEmpty(propertyType)) {
         detected = new DetectedPropertyInfo();
         final String generic = grammar.buildGenericOneClassHint(propertyType);
         detected.setPropertyType("List" + generic);
         detected.setPropertyOption(propertyOption);
       }
     } else if (childNode instanceof ForNode) {
       final ForNode nestedNode = (ForNode) childNode;
       final String expression = nestedNode.getExpression();
       if (!isPmCommentStartsWithCurrent(expression)) {
         continue;
       }
       // /*FOR #current.xxx*/ here
       final String nestedForPropName = substringPmCommentCurrentRear(expression);
       detected = analyzeForNodeElementType(nestedNode, nestedForPropName); // recursive call
       if (detected != null) {
         final String generic = grammar.buildGenericOneClassHint(detected.getPropertyType());
         detected.setPropertyType("List" + generic);
       }
     } else if (childNode instanceof ScopeNode) { // IF, Begin, First, ...
       detected = analyzeForNodeElementType(childNode, propertyName); // recursive call
     }
     if (detected != null) {
       break;
     }
   }
   if (detected == null) {
     return null;
   }
   return detected;
 }
 // -----------------------------------------------------
 //                                         Bind Variable
 //                                         -------------
 protected void processAutoDetectBindNode(
     String sql,
     Map<String, String> propertyNameTypeMap,
     Map<String, String> propertyNameOptionMap,
     Set<String> autoDetectedPropertyNameSet,
     BindVariableNode variableNode) {
   final String expression = variableNode.getExpression();
   final String testValue = variableNode.getTestValue();
   if (testValue == null) {
     return;
   }
   if (!isPmCommentStartsWithPmb(expression)) {
     return;
   }
   if (isPmCommentNestedProperty(expression) || isPmCommentMethodCall(expression)) {
     return;
   }
   final String propertyName = substringPmCommentPmbRear(expression);
   if (isRevervedProperty(propertyName)) {
     return;
   }
   final String typeName = derivePropertyTypeFromTestValue(testValue);
   propertyNameTypeMap.put(propertyName, typeName); // override if same one exists
   autoDetectedPropertyNameSet.add(propertyName);
   final String option = variableNode.getOptionDef();
   // add option if it exists
   // so it is enough to set an option to only one bind variable comment
   // if several bind variable comments for the same property exist
   final String derivedOption = derivePropertyOptionFromTestValue(testValue);
   if (Srl.is_NotNull_and_NotTrimmedEmpty(option)) {
     final String resolvedOption;
     if (Srl.is_NotNull_and_NotTrimmedEmpty(derivedOption)) {
       resolvedOption = option + "|" + derivedOption; // merged
     } else {
       resolvedOption = option;
     }
     propertyNameOptionMap.put(propertyName, resolvedOption);
   } else {
     if (Srl.is_NotNull_and_NotTrimmedEmpty(derivedOption)) {
       propertyNameOptionMap.put(propertyName, derivedOption);
     }
   }
 }