protected void keywordParam() throws ParseException {
    if (!fInput.hasNext()) return;

    if (fInput.next().getTyp() == TSExpression.SYMBOL) {
      Symbol symbol = (Symbol) fInput.current();
      if (symbol.getSymbolName().equalsIgnoreCase(TOKEN_KEY)) {

        while (true) {
          if (!fInput.hasNext()) {
            break;
          }

          SExpression next = fInput.next();
          if (isSpecialSymbol(next)) {
            fInput.pushBack();
            break;
          }

          addKey(varInit(next));
        }

        allowOtherKeys();
      } else {
        fInput.pushBack();
      }
    } else {
      error("Unknown symbol in key list: &key expected", fInput.getInputSExpression());
    }
  }
  protected void optionalParam() throws ParseException {
    if (!fInput.hasNext()) return; // leere Lambda Liste

    if (fInput.next().getTyp() == TSExpression.SYMBOL) {
      Symbol symbol = (Symbol) fInput.current();
      if (symbol.getSymbolName().equalsIgnoreCase(TOKEN_OPTIONAL)) {

        // if(!fInput.hasNext()) { //&optional gesehen, aber kein weiteres symbol angegeben
        //	error("At least one &optional parameter must be specified",
        // fInput.getInputSExpression());
        // }
        // addOptional(varInit(fInput.next())); //mindesten ein Symbol ist angegeben

        while (true) {
          if (!fInput.hasNext()) {
            break;
          }

          SExpression next = fInput.next();
          if (isSpecialSymbol(next)) {
            fInput.pushBack();
            break;
          }

          addOptional(varInit(next));
        }

      } else {
        fInput.pushBack();
        return;
      }
    } else {
      error("Unknown symbol in optional parameter list: &optional expected", fInput.current());
    }
  }
  protected void bodyOrRest() throws ParseException {
    if (!fInput.hasNext()) return;

    if (fInput.next().getTyp() == TSExpression.SYMBOL) {
      Symbol symbol = (Symbol) fInput.current();
      if (symbol.getSymbolName().equalsIgnoreCase(TOKEN_BODY)) {
        fBody = readRestOrBodySymbol("body");
      } else if (symbol.getSymbolName().equalsIgnoreCase(TOKEN_REST)) {
        fRest = readRestOrBodySymbol("rest");
      } else {
        fInput.pushBack(); // evtl. &key
        return;
      }
    } else {
      error("Unknown symbol in rest or body list: &body or &rest expected", fInput.current());
    }
  }
  protected boolean isSpecialSymbol(final SExpression sexp) {
    if (sexp.getTyp() != TSExpression.SYMBOL) return false;

    Symbol symbol = (Symbol) sexp;
    String symName = symbol.getSymbolName();
    return symName.equalsIgnoreCase(TOKEN_OPTIONAL)
        || symName.equalsIgnoreCase(TOKEN_BODY)
        || symName.equalsIgnoreCase(TOKEN_KEY)
        || symName.equalsIgnoreCase(TOKEN_REST)
        || symName.equals(TOKEN_AUX)
        || symName.equals(TOKEN_ALLOW_OTHER_KEYS)
        || symName.equals(TOKEN_WHOLE)
        || symName.equals(TOKEN_ENVIRONMENT);
  }