docs: private Expression readCaseWhen(final Expression l) {
  
          readThis(Tokens.WHEN);
  
          Expression condition = null;
  
          if (l == null) {
              condition = XreadBooleanValueExpression();
          } else {
              while (true) {
                  Expression newCondition = XreadPredicateRightPart(l);
  
                  if (l == newCondition) {
                      newCondition =
                          new ExpressionLogical(l, XreadRowValuePredicand());
                  }
  
                  if (condition == null) {
                      condition = newCondition;
                  } else {
                      condition = new ExpressionLogical(OpTypes.OR, condition,
                                                        newCondition);
                  }
  
                  if (token.tokenType == Tokens.COMMA) {
                      read();
                  } else {
                      break;
                  }
              }
          }
  
          readThis(Tokens.THEN);
  
          Expression current  = XreadValueExpression();
          Expression elseExpr = null;
  
          if (token.tokenType == Tokens.WHEN) {
              elseExpr = readCaseWhen(l);
          } else if (token.tokenType == Tokens.ELSE) {
              read();
  
              elseExpr = XreadValueExpression();
  
              readThis(Tokens.END);
              readIfThis(Tokens.CASE);
          } else {
              elseExpr = new ExpressionValue((Object) null, Type.SQL_ALL_TYPES);
  
              readThis(Tokens.END);
              readIfThis(Tokens.CASE);
          }
  
          Expression alternatives = new ExpressionOp(OpTypes.ALTERNATIVE,
              current, elseExpr);
          Expression casewhen = new ExpressionOp(OpTypes.CASEWHEN, condition,
                                                 alternatives);
  
          return casewhen;
      }