docs: private BaseDescr lhsAnd(final CEDescrBuilder<?, ?> ce,
              boolean allowOr) throws RecognitionException {
          BaseDescr result = null;
          if (input.LA(1) == DRL6Lexer.LEFT_PAREN && helper.validateLT(2,
                  DroolsSoftKeywords.AND)) {
              // prefixed AND
              CEDescrBuilder<?, AndDescr> and = null;
              if (state.backtracking == 0) {
                  and = ce.and();
                  result = ce.getDescr();
                  helper.start(and,
                          CEDescrBuilder.class,
                          null);
              }
              try {
                  match(input,
                          DRL6Lexer.LEFT_PAREN,
                          null,
                          null,
                          DroolsEditorType.SYMBOL);
                  if (state.failed)
                      return null;
  
                  match(input,
                          DRL6Lexer.ID,
                          DroolsSoftKeywords.AND,
                          null,
                          DroolsEditorType.KEYWORD);
                  if (state.failed)
                      return null;
  
                  while (input.LA(1) == DRL6Lexer.AT) {
                      // annotation*
                      annotation(and);
                      if (state.failed)
                          return null;
                  }
  
                  if (state.backtracking == 0) {
                      helper.emit(Location.LOCATION_LHS_BEGIN_OF_CONDITION_AND_OR);
                  }
                  while (input.LA(1) != DRL6Lexer.RIGHT_PAREN) {
                      lhsUnary(and,
                              allowOr);
                      if (state.failed)
                          return null;
                  }
  
                  match(input,
                          DRL6Lexer.RIGHT_PAREN,
                          null,
                          null,
                          DroolsEditorType.SYMBOL);
                  if (state.failed)
                      return null;
              } finally {
                  if (state.backtracking == 0) {
                      helper.end(CEDescrBuilder.class,
                              and);
                  }
              }
          } else {
              // infix AND
  
              // create an AND anyway, since if it is not an AND we remove it later
              CEDescrBuilder<?, AndDescr> and = null;
              if (state.backtracking == 0) {
                  and = ce.and();
                  result = and.getDescr();
                  helper.start(and,
                          CEDescrBuilder.class,
                          null);
              }
              try {
                  lhsUnary(and,
                          allowOr);
                  if (state.failed)
                      return null;
  
                  if (helper.validateIdentifierKey(DroolsSoftKeywords.AND) ||
                          input.LA(1) == DRL6Lexer.DOUBLE_AMPER) {
                      while (helper.validateIdentifierKey(DroolsSoftKeywords.AND) ||
                              input.LA(1) == DRL6Lexer.DOUBLE_AMPER) {
                          if (input.LA(1) == DRL6Lexer.DOUBLE_AMPER) {
                              match(input,
                                      DRL6Lexer.DOUBLE_AMPER,
                                      null,
                                      null,
                                      DroolsEditorType.SYMBOL);
                          } else {
                              match(input,
                                      DRL6Lexer.ID,
                                      DroolsSoftKeywords.AND,
                                      null,
                                      DroolsEditorType.KEYWORD);
                          }
                          if (state.failed)
                              return null;
  
                          while (input.LA(1) == DRL6Lexer.AT) {
                              // annotation*
                              annotation(and);
                              if (state.failed)
                                  return null;
                          }
  
                          if (state.backtracking == 0) {
                              helper.emit(Location.LOCATION_LHS_BEGIN_OF_CONDITION_AND_OR);
                          }
                          lhsUnary(and,
                                  allowOr);
                          if (state.failed)
                              return null;
                      }
                  } else {
                      if (state.backtracking == 0 && and.getDescr().getDescrs().size() < 2) {
                          // if no AND present, then remove it and add children to parent
                          ((ConditionalElementDescr) ce.getDescr()).getDescrs().remove(and.getDescr());
                          for (BaseDescr base : and.getDescr().getDescrs()) {
                              ((ConditionalElementDescr) ce.getDescr()).addDescr(base);
                          }
                          result = ce.getDescr();
                      }
                  }
              } finally {
                  if (state.backtracking == 0) {
                      helper.end(CEDescrBuilder.class,
                              and);
                  }
              }
          }
          return result;
      }