#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hashtable.h"

// 20051222: schrijft [STAM] in het info-veld tbv Vertaler.log
// 20050829: afgeleid van wwverbuig.cpp; andere inhoud van wwoordenlijst
// 20050910: F_POE in werking gesteld

FILE* pfLog;
char sLog[256];
void log(char* sLog){
  if (!pfLog){
    pfLog= fopen("wwverbuig.log", "w+t");
  }
  fprintf(pfLog, sLog);
  fflush(pfLog);
}
void log(char* sLog1, char* sLog2){
  strcpy(sLog, sLog1);
  strcat(sLog, sLog2);
  log(sLog);
}

bool endsWith(char* sSrc, char* s2){
  return (!strncmp(sSrc + strlen(sSrc) - strlen(s2), s2, strlen(s2)));
}

bool startsWith(char* sSrc, char* s2){
  return (!strncmp(sSrc, s2, strlen(s2)));
}

bool isCons(char c){
  if (c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){
    return false;
  } else{
    return true;
  }
}

/**
 *  maak meervoud van enkelvoud, rekening houdend met verzachting van medeklinkers
 */
char sRet[80];
char* meervoud(char* sOrig){
  strcpy(sRet, sOrig);
  /* eerst de onregelmatige meervoudsvormen */
  if (!strcmp(sOrig, "was")){
    return "waren";
  } else if (endsWith(sOrig, "e")){
    strcat(sRet, "n");
    return sRet;
  } else if (endsWith(sOrig, "f")){
    sRet[strlen(sRet) - 1]= 'v';
  } else if (endsWith(sOrig, "s")){
    sRet[strlen(sRet) - 1]= 'z';
  } else{
  }
  strcat(sRet, "en");
  return sRet;
}

int lastIndexOf(const char* sSrc, const char c){
  for (int i= strlen(sSrc) - 1; i>= 0; i--){
    if (sSrc[i] == c){
      return i;
    }
  }
  return -1;
}

int indexOf(char* sSrc, char c){
  for (int i= 0; i < strlen(sSrc); i++){
    if (sSrc[i] == c){
      return i;
    }
  }
  return -1;
}

int indexOf(const char* sSrc, const char* s2){
  if (strlen(s2) > strlen(sSrc)){
    return -1;
  }
  for (int i= 0; i <= strlen(sSrc) - strlen(s2); i++){
    if (!strncmp(sSrc + i, s2, strlen(s2))){
      return i;
    }
  }
  return -1;
}

int lastIndexOf(const char* sSrc, const char* s2){
  if (strlen(s2) > strlen(sSrc)){
    return -1;
  }
  for (int i= strlen(sSrc) - strlen(s2); i >= 0 ; i--){
    if (!strncmp(sSrc + i, s2, strlen(s2))){
      return i;
    }
  }
  return -1;
}

bool endsWith(char* sSrc, char c){
  return (sSrc[strlen(sSrc) - 1] == c);
}

/**
 *  Haalt rechts en links overtollige spaties weg
 */
void trim(char* s){
  while (s[0]==' '){
    strcpy(s, s+1);
  }
  while (s[strlen(s) - 1]==' '){
    s[strlen(s) - 1]= '\0';
  }
}

// einde functiedefinities
//------------------------------------------------------------------------------

class Exception{
  char* sValue;
  public: 
  Exception(char* s){
    sValue= s;
  };
  char* toString(){
    return sValue;
  };
};

Hashtable htPersTitle;
Hashtable htHebben;
Hashtable htZijn;
Hashtable htZich;
Hashtable htZullen;
Hashtable htBijzStammen;

void init(){
  htPersTitle.put("1s", "ik");
  htPersTitle.put("2s", "jij");
  htPersTitle.put("3s", "hij");
  htPersTitle.put("3sf", "zij");
  htPersTitle.put("1p", "wij");
  htPersTitle.put("2p", "jullie");
  htPersTitle.put("3p", "zij");
  htPersTitle.put("s", "");
  htPersTitle.put("p", "");

  htHebben.put("1s", "heb");
  htHebben.put("2s", "hebt");
  htHebben.put("3s", "heeft");
  htHebben.put("3sf", "heeft");
  htHebben.put("1p", "hebben");
  htHebben.put("2p", "hebben");
  htHebben.put("3p", "hebben");

  htZijn.put("1s", "ben");
  htZijn.put("2s", "bent");
  htZijn.put("3s", "is");
  htZijn.put("3sf", "is");
  htZijn.put("1p", "zijn");
  htZijn.put("2p", "zijn");
  htZijn.put("3p", "zijn");

  htZich.put("1s", "me");
  htZich.put("2s", "je");
  htZich.put("3s", "zich");
  htZich.put("3sf", "zich"); // haar is ouderwets
  htZich.put("1p", "ons");
  htZich.put("2p", "je");
  htZich.put("3p", "zich");
  htZich.put("s", "zich");
  htZich.put("p", "zich");

  htZullen.put("1s", "zal");
  htZullen.put("2s", "zult");
  htZullen.put("3s", "zal");
  htZullen.put("3sf", "zal");
  htZullen.put("1p", "zullen");
  htZullen.put("2p", "zullen");
  htZullen.put("3p", "zullen");

  htBijzStammen.put("ga", "ga(a)");
  htBijzStammen.put("do", "doe");
  htBijzStammen.put("sta", "sta(a)");
  htBijzStammen.put("sla", "sla(a)");
  htBijzStammen.put("ben", "ben");
  htBijzStammen.put("kom", "kom");
  //htBijzStammen.put("", "");
};

class Woord{
  char sDeel1[80];
  char sNaAccent[80];
  char sDeel2[80];
  char sDeel3[80];
  char sVtStam[80];
  char sVtRest[80];
  char sVtRestSjabloon[80];
  char sTtStamEn[80]; // het deel van Deel1 dat de stam bevat (stam+en)
  char sTtStam[80]; // het deel van Deel1 dat de stam bevat (stam in enkelvoud)
  char sDeel3Sjabloon[80]; // voorbeeld: "%s gedaan"
  char sDeel1Sjabloon[80]; // voorbeeld: "%s wassen" (voor "z. wassen")
  char sRet[80]; // voor returns
  bool bOk; // of de constructor volledig is uitgevoerd
  bool bZijn; // in plaats van hebben
  bool bWederkerig;
  //----------------------------------------------------------------------------

  /**
   *  Of dit een enkel-lettergrepige stam is
   */
  bool isSingleSyl(char* sStam){
    char* sVows= "aeiou";
    int nVows= 0;
    for (int i= 0; i < strlen(sStam); i++){
      nVows+= indexOf(sVows, sStam[i]) >= 0 ? 1 : 0;
    }
    return nVows==1;
  }
  //----------------------------------------------------------------------------

  public: 
  /**
   *  Perfectum: voorbeeld: "(ik) heb gedaan"
   *  @param sMod cijfer voor persoon, s of p voor enkel- of meervoud en f voor vrouwelijk.
   */
  char* perf(char* sMod){
    char sDeel3Filled[80];
    sprintf(sDeel3Filled, sDeel3Sjabloon, 
        bZijn ? htZijn.get(sMod) : htHebben.get(sMod),
        bWederkerig ? htZich.get(sMod) : NULL);
    sprintf(sRet, "(%s) %s", 
        htPersTitle.get(sMod),
        sDeel3Filled);
    return sRet;
  }
  //----------------------------------------------------------------------------

  /**
   *  Voor toekomende tijd en perfectum consecutivum: voorbeeld: "[en] (ik) zal doen"
   *  @param sMod cijfer voor persoon, s of p voor enkel- of meervoud en f voor vrouwelijk.
   */
  char* toek(char* sMod){
    char sDeel1Filled[80];
    sprintf(sDeel1Filled, sDeel1Sjabloon,
        bWederkerig ? htZich.get(sMod) : NULL);
    sprintf(sRet, "(%s) %s %s",
        htPersTitle.get(sMod),
        htZullen.get(sMod),
        sDeel1Filled);
    return sRet;
  }
  //----------------------------------------------------------------------------

  /**
   *  Voor narrativus: voorbeeld: "toen ging (ik) me te buiten"
   *  @param sMod cijfer voor persoon, s of p voor enkel- of meervoud en f voor vrouwelijk.
   */
   /*
  char* narr(char* sMod){
    int iSpc= indexOf(sDeel2, ' ');
    char sVtStam[80];
    strcpy(sVtStam, sDeel2);
    if (iSpc > 0){
      sVtStam[iSpc]= '\0';
    }
    char sVtExt[80]= "";
    strcpy(sVtExt, iSpc > 0 ? sVtStam + iSpc + 1 : "");
    if (indexOf(sVtExt, "z.") >= 0){
      char sTmp[80];
      strcpy(sTmp, sVtExt);
      strncpy(sTmp + indexOf(sVtExt, "z."), "%s", 2);
      sprintf(sVtExt, sTmp, htZich.get(sMod));
    }
    if (indexOf(sMod, "p") >= 0){ // meervoud nodig
      if (endsWith(sVtStam, "e")){
        strcat(sVtStam, "n");
      } else if (!strcmp(sVtStam, "werd")){
        strcpy(sVtStam, "werden");
      } else if (endsWith(sVtStam, "d")){
        strcat(sVtStam, "den");
      } else if (!strcmp(sVtStam, "was")){
        strcpy(sVtStam, "waren");
      } else if (!strncmp(sVtStam + strlen(sVtStam) - 3, "oo", 2)
               ||!strncmp(sVtStam + strlen(sVtStam) - 3, "ee", 2)
               ||!strncmp(sVtStam + strlen(sVtStam) - 3, "uu", 2)){
        strcpy(sVtStam + strlen(sVtStam) - 3, sVtStam + strlen(sVtStam) - 2);
        strcat(sVtStam, "en");
      } else if (endsWith(sVtStam, "f")){
        strcpy(sVtStam + strlen(sVtStam) - 1, "ven");
      } else{
        strcat(sVtStam, "en");  // TODO: meer regels, want soms fout
      }
      if (endsWith(sVtStam, "fen")){
        sVtStam[strlen(sVtStam) - 3]= 'v';
      } else if (endsWith(sVtStam, "sen")){
        sVtStam[strlen(sVtStam) - 3]= 'z';
      }
    }
    sprintf(sRet, "toen %s (%s) %s",
        sVtStam,
        htPersTitle.get(sMod),
        sVtExt);
    return sRet;
  }
  */
  //----------------------------------------------------------------------------

  /**
   *  Voor narrativus: voorbeeld: "(ik) ging me te buiten"
   *  @param sMod cijfer voor persoon, s of p voor enkel- of meervoud en f voor vrouwelijk.
   */
  char* ovt(char* sMod){
    int iSpc= indexOf(sDeel2, ' ');
    char sVtStam[80];
    strcpy(sVtStam, sDeel2);
    if (iSpc > 0){
      sVtStam[iSpc]= '\0';
    }
    char sVtExt[80]= "";
    strcpy(sVtExt, iSpc > 0 ? sVtStam + iSpc + 1 : "");
    if (indexOf(sVtExt, "z.") >= 0){
      char sTmp[80];
      strcpy(sTmp, sVtExt);
      strncpy(sTmp + indexOf(sVtExt, "z."), "%s", 2);
      sprintf(sVtExt, sTmp, htZich.get(sMod));
    }
    if (indexOf(sMod, "p") >= 0){ // meervoud nodig
      if (endsWith(sVtStam, "e")){
        strcat(sVtStam, "n");
      } else if (!strcmp(sVtStam, "werd")){
        strcpy(sVtStam, "werden");
      } else if (endsWith(sVtStam, "d")){
        strcat(sVtStam, "den");
      } else if (!strcmp(sVtStam, "was")){
        strcpy(sVtStam, "waren");
      } else if (!strncmp(sVtStam + strlen(sVtStam) - 3, "oo", 2)
               ||!strncmp(sVtStam + strlen(sVtStam) - 3, "ee", 2)
               ||!strncmp(sVtStam + strlen(sVtStam) - 3, "uu", 2)){
        strcpy(sVtStam + strlen(sVtStam) - 3, sVtStam + strlen(sVtStam) - 2);
        strcat(sVtStam, "en");
      } else if (endsWith(sVtStam, "f")){
        strcpy(sVtStam + strlen(sVtStam) - 1, "ven");
      } else{
        strcat(sVtStam, "en");  // TODO: meer regels, want soms fout
      }
      if (endsWith(sVtStam, "fen")){
        sVtStam[strlen(sVtStam) - 3]= 'v';
      } else if (endsWith(sVtStam, "sen")){
        sVtStam[strlen(sVtStam) - 3]= 'z';
      }
    }
    sprintf(sRet, "(%s) %s %s",
        htPersTitle.get(sMod),
        sVtStam,
        sVtExt);
    return sRet;
  }
  //----------------------------------------------------------------------------

  char* tegenw(char* sMod){
     char sVtRestFilled[80];
     sprintf(sVtRestFilled, sVtRestSjabloon,
         bWederkerig ? htZich.get(sMod) : NULL);
     char sTt[80];
     if (/*indexOf(sMod,'p') >= 0*/ sMod[0]=='p'){
       strcpy(sTt, sTtStamEn);
     } else{
       strcpy(sTt, sTtStam);
       if (!endsWith(sTt, "t")){
         strcat(sTt, "(t)");
       }
     }
     sprintf(sRet, "%s %s",
         /*htPersTitle.get(sMod),*/
         sTt,
         sVtRestFilled);
     // TODO: andere stamverbuigingen voor 1,2,3e persoon
     trim(sRet);
     return sRet;
  }
  //----------------------------------------------------------------------------

  /**
   *  Onbepaalde wijs: "zich te bescheuren"
   */
  char* onbep(){
     char sVtRestFilled[80];
     sprintf(sVtRestFilled, sVtRestSjabloon,
         bWederkerig ? htZich.get("3s") : NULL);
     char sTt[80];
     strcpy(sTt, sTtStamEn);
     sprintf(sRet, "%s te %s", sVtRestFilled, sTt);
     trim(sRet);
     return sRet;
  }
  //----------------------------------------------------------------------------

  /**
   *  Gebiedende wijs: leunt zwaar op tegenw. tijd
   */
  char* geb(char* sMod){
    tegenw("2s"); // vult sRet
    if (indexOf(sRet, "(") >= 0){
      if (indexOf(sMod, "p") >= 0){
        // vervang "(t)" door "t" of "(a)(t)" door "at"
        int i0= indexOf(sRet, "(t");
        int i2= lastIndexOf(sRet, ")");
        strcpy(sRet + i0, "t");
        strcpy(sRet + i0 + 1, sRet + i2 + 1);
      } else{
        // vervang "(t)" door "" of "(a)(t)" door ""
        int i0= indexOf(sRet, "(");
        int i2= lastIndexOf(sRet, ")");
        strcpy(sRet + i0, sRet + i2 + 1);
      }
    }
    strcat(sRet, "!");
    return sRet;
  }
  //----------------------------------------------------------------------------


  /**
   *  Input: bijvoorbeeld: "doen (deed, h. gedaan)"
   */
  Woord(char* sN){
    bOk= false;
    int iHaakOpen= indexOf(sN, '(');
    if (iHaakOpen < 0){
      fprintf(stderr, "Fout: haak open ontbreekt: %s\n", sN);
      exit(1);
    }
    strncpy(sDeel1, sN, iHaakOpen - 1);
    sDeel1[iHaakOpen - 1]= '\0';
    int iKomma= indexOf(sN, ',');
    if (iKomma < 0){
      fprintf(stderr, "Fout: komma ontbreekt: %s\n", sN);
      exit(1);
    }
    int iHaakSluiten= indexOf(sN, ')');
    if (iHaakSluiten < 0){
      fprintf(stderr, "Fout: haak sluiten ontbreekt: %s\n", sN);
      exit(1);
    }
    strncpy(sDeel2, sN + iHaakOpen + 1, iKomma - iHaakOpen - 1);
    sDeel2[iKomma - iHaakOpen - 1]= '\0';
    strncpy(sDeel3, sN + iKomma + 2, iHaakSluiten - iKomma - 2);
    sDeel3[iHaakSluiten - iKomma - 2]= '\0';
    //printf("%s\t%s\t%s\n", sDeel1, sDeel2, sDeel3);

    /* In het eerste deel (de onbepaalde wijs) vinden we een accentteken achter
       de lettergreep met klemtoon. Die gebruiken we voor het vormen van de stam.
    */
    int iAAccent= indexOf(sDeel1, '\'');
    if (iAAccent >= 0){
      strcpy(sDeel1 + iAAccent, sDeel1 + iAAccent + 1);
    } else{
      iAAccent= strlen(sDeel1);
      if (indexOf(sDeel1, " zijn") < 0 && strcmp(sDeel1, "zijn")
        && indexOf(sDeel1, " slaan") < 0 && strcmp(sDeel1, "slaan")
        && indexOf(sDeel1, " staan") < 0 && strcmp(sDeel1, "staan")
        && indexOf(sDeel1, " gaan") < 0 && strcmp(sDeel1, "gaan")
        && indexOf(sDeel1, " zien") < 0 && strcmp(sDeel1, "zien")
        && indexOf(sDeel1, " doen") < 0 && strcmp(sDeel1, "doen")){
        fprintf(stderr, "Klemtoon-indicatie ontbreekt in %s\n", sDeel1);
      }
    }
    strcpy(sNaAccent, sDeel1 + iAAccent);
    if (indexOf(sNaAccent,' ') > 0){
      sNaAccent[indexOf(sNaAccent,' ')]= '\0';
    }

    /* Van de verleden tijd (deel 2) kunnen we nu leren welk deel van het werkwoord
       vervoegd wordt en wel deel constant is: alleen het eerste deel wordt vervoegd.
       Het constante deel kunnen we opzoeken in Deel1, waar de stam+en dan overblijft.
    */
    int iRest= indexOf(sDeel2, ' ');
    if (iRest > 0){
      strncpy(sVtStam, sDeel2, iRest);
      sVtStam[iRest]= '\0';
      strncpy(sVtRest, sDeel2 + iRest + 1, strlen(sDeel2) - iRest - 1);
      sVtRest[strlen(sDeel2) - iRest - 1]= '\0';
      //printf("[%s]\t[%s]\n", sVtStam, sVtRest);
      int iIn= indexOf(sDeel1, sVtRest);
      if (iIn < 0){
        /* de OVT-rest zou in twee delen gesplitst kunnen worden */
        int iSplit= lastIndexOf(sVtRest, ' ');
        // gevallen als 'in rook laten opgaan' en 'z. laten zweven'
        if (iSplit < 0){
          fprintf(stderr, "Fout: rest in OVT (%s) komt niet voor in onb. wijs: %s\n",
              sVtRest, sDeel1);
          goto WoordConstructorEnd;
        }
        char sVtRest1[80];
        char sVtRest2[80];
        strncpy(sVtRest1, sVtRest, iSplit);
        sVtRest1[iSplit]= '\0';
        strcpy(sVtRest2, sVtRest + iSplit + 1);
        int iIn1= indexOf(sDeel1, sVtRest1);
        int iIn2= indexOf(sDeel1, sVtRest2);
        if (iIn1 != 0 || iIn2 <= 0){
          fprintf(stderr, "Rest in OVT (%s) (%s + %s) komt niet voor in onb. wijs: %s\n",
              sVtRest, sVtRest1, sVtRest2, sDeel1);
          goto WoordConstructorEnd;
        }
        strncpy(sTtStamEn, sDeel1 + strlen(sVtRest1) + 1, iIn2 - strlen(sVtRest1) - 2);
        sTtStamEn[iIn2 - strlen(sVtRest1) - 2]= '\0';
      } else if (iIn==0){
        strcpy(sTtStamEn, sDeel1 + strlen(sVtRest));
        trim(sTtStamEn);
      } else{ // bijv. Dee1 = [la'ten zondigen]
        strncpy(sTtStamEn, sDeel1, iIn - 1);
        sTtStamEn[iIn - 1]= '\0';
      }
    } else{
      strcpy(sVtStam, sDeel2);
      strcpy(sVtRest, "");
      strcpy(sTtStamEn, sDeel1);
    }
    /* construeer uit sTtStamEn het enkelvoud */
    { // vanwege goto een blok
      strcpy(sTtStam, sTtStamEn);
      char *sEnd= sTtStamEn + strlen(sTtStamEn) - 2;
      if (!strncmp(sEnd-1, "ie", 2)){ // zien
        sTtStam[strlen(sTtStamEn) - 1]= '\0';
      } else{
        sTtStam[strlen(sTtStamEn) - 2]= '\0'; // TODO: cru, meestal niet goed
      }
      /* bijzondere gevallen: */
      if (!strcmp(sTtStamEn,"zijn")){
        strcpy(sTtStam, "ben");
      }
      if (!strncmp(sEnd-1, "ie", 2)
        &&!strncmp(sEnd-1, "ei", 2)){
        strcat(sTtStam, "e");
      }
      
      if (htBijzStammen.get(sTtStam)){
        strcpy(sTtStam, htBijzStammen.get(sTtStam));
      } else if (sTtStam[strlen(sTtStam) - 1]==sTtStam[strlen(sTtStam) - 2]){
        // medeklinkers verenkelen:
        sTtStam[strlen(sTtStam) - 1]= '\0';
      } else if (strlen(sNaAccent)==3 || strlen(sNaAccent)==0 || isSingleSyl(sTtStam)){ 
        // klinkers verdubbelen:
        if (sTtStam[strlen(sTtStam) - 2]=='a' // laten werd lat, wordt nu laat
            || (sTtStam[strlen(sTtStam) - 2]=='u'
              &&sTtStam[strlen(sTtStam) - 3]!='o')
            || sTtStam[strlen(sTtStam) - 2]=='o'
            || (sTtStam[strlen(sTtStam) - 2]=='e'
              &&sTtStam[strlen(sTtStam) - 3]!='i'
              &&sTtStam[strlen(sTtStam) - 3]!='o')){ 
          char sEnd[2];
          strcpy(sEnd, sTtStam + strlen(sTtStam) - 1);
          sTtStam[strlen(sTtStam) - 1]= sTtStam[strlen(sTtStam) - 2];
          strcat(sTtStam, sEnd);
        }
      }
      if (endsWith(sTtStam, 'z')){
        sTtStam[strlen(sTtStam) - 1]= 's';
      } else if (endsWith(sTtStam, 'v')){
        sTtStam[strlen(sTtStam) - 1]= 'f';
      }


    } // einde vorming stam

    strcpy(sDeel1Sjabloon, sDeel1);
    strcpy(sDeel3Sjabloon, sDeel3);
    strcpy(sVtRestSjabloon, sVtRest);
    if (indexOf(sDeel3, "h.") >= 0){
      bZijn= false;
      int iHe= indexOf(sDeel3, "h. ");
      strncpy(sDeel3Sjabloon + iHe, "%s", 2);
    } else if (indexOf(sDeel3, "is ") >= 0){
      bZijn= true;
      int iIs= indexOf(sDeel3, "is ");
      strncpy(sDeel3Sjabloon + iIs, "%s", 2);
    } else{
      fprintf(stderr, "Bij voltooid deelwoord (%s) ontbreekt 'is ' of 'h. '\n", sDeel3);
      goto WoordConstructorEnd;
    }

    if (indexOf(sDeel3, "z. ") >= 0
        && indexOf(sDeel1, "z. ") >= 0){
      bWederkerig= true;
      int iZi1= indexOf(sDeel1, "z. ");
      strncpy(sDeel1Sjabloon + iZi1, "%s", 2);
      int iZi3= indexOf(sDeel3, "z. ");
      strncpy(sDeel3Sjabloon + iZi3, "%s", 2);
      int iZiV= indexOf(sVtRest, "z.");
      strncpy(sVtRestSjabloon + iZiV, "%s", 2);
    } else if (indexOf(sDeel3, "z. ") >= 0
        || indexOf(sDeel1, "z. ") >= 0){
      fprintf(stderr, "Gedeeltelijk wederkerig (%s vs. %s)\n", sDeel1, sDeel3);
      goto WoordConstructorEnd;
    } else{
      bWederkerig= false;
    }

    bOk= true;
    WoordConstructorEnd:;
  }; // Woord(char*)
  //----------------------------------------------------------------------------

  bool isOk(){
    return bOk;
  }
  //----------------------------------------------------------------------------
}; // class Woord
//------------------------------------------------------------------------------

int main(void){
#define MAXLINELEN 512
  init();
  char sLine[MAXLINELEN];
  while(fgets(sLine, MAXLINELEN, stdin)){
    if (strlen(sLine) < 3){
      continue;
    }
    /* tab-gecheiden, 1e deel hebreeuwse werkwoordstam, 2e deel NL */
    /* Hebreeuwse werkwoorden worden vooraf gegaan door een cijfer
     * voor de stamformatie (1. voor qal etc.); Nederlandse vertalingen
     * worden voorafgegaan door '=' als de voltooide tijd met het werk-
     * woord 'zijn' gevormd wordt. */
    char* sH;
    char* sN= NULL;
    int nCharsInLine= strlen(sLine);
    for (int i= 0; i < nCharsInLine; i++){
      if (sLine[i] == '\t'){
	sLine[i]= '\0';
        if (sN){
	  // rest commentaar
	  break; // klaar
	} else{
          sN= sLine + i + 1;
          sH= sLine;
	}
      } else if (sLine[i] == '\n' || sLine[i] == '\r'){
        // einde-regel
        sLine[i]= '\0';
	break; // klaar
      }
    }
    // we hebben een sH(ebreeuwse) en een sN(ederlands) werkwoord (onbep. wijs)
    char cForm= sH[0];
    char* sSrc= new char[20];
    sprintf(sSrc, "[%s]", sH);
    sH += 2; // voorbeeld: 1.$DQ wordt '1' en "$DQ"

    /***************** Nederlandse verbuigingen *****************/

    //printf("%s\n", sN);
    Woord wN= Woord(sN);
    if (!wN.isOk()){
      fprintf(stderr, "Waarschuwing: dit werkwoord werd niet verder verwerkt.\n");
      continue;
    }
    /* debug: */
    //printf("%s / %s\n", wN.tegenw("s"), wN.tegenw("p")); // niet zo, vanwege hergebruik sRet
    char pszLog[80];
    sprintf(pszLog, "%s / ", wN.tegenw("s"));
    log (pszLog);
    sprintf(pszLog, "%s\n", wN.tegenw("p"));
    log (pszLog);
    sprintf(pszLog, "\t%s\n", wN.perf("1p"));
    log (pszLog);
    sprintf(pszLog, "\t\t%s\n", wN.toek("1p"));
    log (pszLog);
    sprintf(pszLog, "\t\t\t%s\n", wN.ovt("1p"));
    log (pszLog);
    sprintf(pszLog, "\t\t\t\t%s\n", wN.geb("p"));
    log (pszLog);

    /***************** Hebreeuwse verbuigingen *****************/

    /* Stamformaties */
    const int F_QAL= 1; // qal,        normaal
    const int F_NIF= 2; // nief'iel,   lijdend van normaal 1
    const int F_PIE= 3; // pie'eel,    intensief
    const int F_POE= 4; // poe'al,     lijdend van intensief 3 (vrij zeldzaam)
    const int F_HIF= 5; // hief'iel    causatief
    const int F_HOE= 6; // hoef'al,    lijdend van causatief 5 (vrij zeldzaam)
    const int F_HIT= 7; // hietpa'eel, wederkerend
    int iForm= cForm - '0';

    /* stammen (voorl. alleen gedefinieerd tbv Hif') */
    const int S__23= 1; // XBB
    const int S___A= 2; // MLA en M$A
    const int S_A__= 3; // AKL en AM$
    const int S_N__= 4; // NPL en N$L
    const int S_I__= 5; // ISB en IDO
    const int S__W_= 6; // QWM en DWN
    const int S___E= 7; // CLE
    const int S____= 0; // PQD
    int iStam= S____; // tenzij anders vastgesteld
    char sCore[8]= ""; // onaantastbare kern van het werkwoord (bij hit')

    /* bepaling van de stamletters */
    char c1;
    char c2;
    char s1[14]= ""; // c1 en c2 samen, een deel van sH in elk geval
    char c3;
    if (iForm == F_PIE || iForm == F_POE){ // bijv. PiQD, PuQD
      c1= sH[0];
      c2= sH[strlen(sH) -2];
      c3= sH[strlen(sH) -1];
    } else if (iForm == F_QAL){ // bijv. PQD
      c1= sH[0];
      c2= sH[1];
      c3= sH[strlen(sH) - 1]; // dat moet, voor werkwoorden zoals IKWL
    } else if (iForm == F_NIF){ // bijv. nPQD
      c1= sH[1];
      c2= sH[2];
      c3= sH[strlen(sH) - 1];
      strcpy(s1, sH);
      s1[strlen(sH) - 1]= '\0';
    } else if (iForm == F_HIF){ // bijv. ePQiD, eBIA
      // de eerste stamletter is altijd een E
      c1= sH[1];
      c2= sH[2];
      s1[1]= '\0'; // bij samenvallen 1e twee stamletters
      s1[2]= '\0'; // bij 3 verschillende stamletters
      s1[3]= '\0'; // bij 4 verschillende stamletters
      if (strlen(sH)==3){ // bijv. EXB, EKE, EKN
        if (sH[2]=='E'){ // stam eindigt op E
          iStam= S___E;
          strncpy(s1, sH + 1, 1); // EKE: stam KE, waarbij de E vaak nog wegvalt ook.
          c3= 'E';
        } else{
          iStam= S__23; // c1 en c2 zeggen al alles
          s1[0]= sH[1];
          c3= sH[2];
        }
      } else if (sH[strlen(sH)-1]=='A'){
        iStam= S___A;
        strncpy(s1, sH + 1, strlen(sH)-3); // bijv. eMSiA, eBiA
        c3= 'A';
      } else if (sH[1]=='A'){
        iStam= S_A__;
        strncpy(s1, sH + 1, strlen(sH)-3);
        c3= sH[strlen(sH)-1];
      } else if (strlen(sH)==4 && sH[2]=='I'){ // '1e N' of '2e F', bijv. EPIL, EQIM
        iStam= S_N__; // S__W_ ziet er hetzelfde uit!
        strncpy(s1, sH + 1, strlen(sH)-3);
        c3= sH[3];
      } else if (strlen(sH)==5 && sH[1]=='W'){ // '1e I', bijv. EWSIB
        iStam= S_I__;
        strncpy(s1, sH + 1, strlen(sH)-3);
        c3= sH[4];
      } else if (sH[3]=='E'){ // 'laatste E'
        iStam= S___E;
        strncpy(s1, sH + 1, strlen(sH)-2);
        c3= sH[3];
      } else{ // regelmatig
        iStam= S____;
        strncpy(s1, sH + 1, strlen(sH)-3);
        c3= sH[4];
      }
    } else if (iForm == F_HIT){ // bijv. etPQD
      /* sH[1] kan de T zijn, maar ook een X,S,$,Z (dan is c1 resp. T,T,T,D);
       * verder kan de stam (na de beginletter) 4 of 5 tekens lang zijn */
      strcpy(sCore, sH + 1);
      iStam= S____;
      if (endsWith(sH, "E")){
        iStam= S___E;
        /* 'E' afknippen */
        sCore[strlen(sCore) - 1]= '\0';
      }
    }

    bool bA1= c1=='A';
    bool bI1= c1=='I';
    bool bN1= (c1=='N') && (c2!='W'); // NWX verbuigen als bW2, niet als bN1
    bool bN13= (c1=='N') && (c3=='N'); // alleen NTN (geven)?
    bool bW2= c2=='W';
    bool bI2= c2=='I';
    bool b23= c2==c3;
    bool bA3= c3=='A';
    bool bA2= c2=='A'; // variatie op regelmatig, bijv. CAL
    bool bE3= c3=='E';
    if (iForm == F_NIF){ // (alleen) afwijkingen van bovenstaande volgen hieronder:
      bI1= c1=='W';
      bN1= c1=='I';
    }

    if (iForm == F_QAL
        || iForm == F_NIF
        || iForm == F_PIE
        || iForm == F_POE
        || iForm == F_HIF
        || iForm == F_HOE
        || iForm == F_HIT){
      /* verwerking verderop */
    } else{
      // vormen die we nog niet kunnen vertalen.
      continue;
    }

    char sPe1[12];
    char sPe2[12];
    char sPe3m[12];
    char sPe3f[12];
    char sPez[12]= "";
    char sPm1[12];
    char sPm2m[12];
    char sPm2f[12];
    char sPm3[12];

    /* perfectum (voltooide tijd) */
    if (iForm == F_QAL){
      if (!strcmp(sH, "BWA")){ // zwak, problematisch door -WA ?
        sprintf(sPe1, "%c%cTI", c1,     c3);
        sprintf(sPe2, "%c%cT",  c1,     c3);
        sprintf(sPe3m,"%c%c",   c1,     c3);
        sprintf(sPe3f,"%c%cT",  c1,     c3);
        sprintf(sPez, "E%c%c",  c1,     c3);
        sprintf(sPm1, "%c%cNW", c1,     c3);
        sprintf(sPm2m,"%c%cTM", c1,     c3);
        sprintf(sPm2f,"%c%cTN", c1,     c3);
        sprintf(sPm3, "%c%cW",  c1,     c3);
      } else if (bE3){
        sprintf(sPe1, "%c%cITI", c1, c2    );
        sprintf(sPe2, "%c%cIT",  c1, c2    );
        sprintf(sPe3m,"%c%cE",   c1, c2    );
        sprintf(sPe3f,"%c%cTE",  c1, c2    );
        sprintf(sPez, "E%c%cE",  c1, c2    );
        sprintf(sPm1, "%c%cINW", c1, c2    );
        sprintf(sPm2m,"%c%cITM", c1, c2    );
        sprintf(sPm2f,"%c%cITN", c1, c2    );
        sprintf(sPm3, "%c%cW",   c1, c2    );
      } else if (bW2 || bI2){
        /* middelste stamletter 'W', bijvoorbeeld K(W)M (opstaan) */
        sprintf(sPe1, "%c%cTI",  c1,     c3);
        sprintf(sPe2, "%c%cT",   c1,     c3);
        sprintf(sPe3m,"%c%c",    c1,     c3);
        sprintf(sPe3f,"%c%cE",   c1,     c3);
        sprintf(sPez, "E%c%c",   c1,     c3);
        //printf"%cW%c",   c1, c3); // perfectum 3 // = geb. wijs
        sprintf(sPm1, "%c%cNW",  c1,     c3);
        sprintf(sPm2m,"%c%cTM",  c1,     c3);
        sprintf(sPm2f,"%c%cTN",  c1,     c3);
        sprintf(sPm3, "%c%cW",   c1,     c3);
      } else if (bN13){
        sprintf(sPe1, "%c%cTI",  c1, c2    );
        sprintf(sPe2, "%c%cT",   c1, c2    );
        sprintf(sPe3m,"%c%c%c",  c1, c2, c3);
        sprintf(sPe3f,"%c%c%cE", c1, c2, c3);
        sprintf(sPez, "E%c%c%c", c1, c2, c3);
        sprintf(sPm1, "%c%c%cNW",c1, c2, c3);
        sprintf(sPm2m,"%c%c%cTM",c1, c2, c3);
        sprintf(sPm2f,"%c%c%cTN",c1, c2, c3);
        sprintf(sPm3, "%c%c%cW", c1, c2, c3);
      } else{ // ook bI1, b23, bN1
        sprintf(sPe1, "%sTI",    sH); // perfectum 1
        sprintf(sPe2, "%sT",     sH); // perfectum 2
        sprintf(sPe3m,"%s",      sH); // perfectum 3
        sprintf(sPe3f,"%sE",     sH); // perfectum 3 v
        sprintf(sPez, "E%s",     sH); // zelfst.
        sprintf(sPm1, "%sNW",    sH); // perfectum 1m
        sprintf(sPm2m,"%sTM",    sH); // perfectum 2m m
        sprintf(sPm2f,"%sTN",    sH); // perfectum 2m v
        sprintf(sPm3, "%sW",     sH); // perfectum 3m
      } // einde F_QAL
    } else if (iForm == F_NIF){
      if (c3==c2){
        sprintf(sPe1, "%sWTI",   sH); // perfectum 1
        sprintf(sPe2, "%sWT",    sH); // perfectum 2
        sprintf(sPe3m,"%s",      sH); // perfectum 3
        sprintf(sPe3f,"%sE",     sH); // perfectum 3 v
        sprintf(sPm1, "%sWNW",   sH); // perfectum 1m
        sprintf(sPm2m,"%sWTM",   sH); // perfectum 2m m
        sprintf(sPm2f,"%sWTN",   sH); // perfectum 2m v
        sprintf(sPm3, "%sW",     sH); // perfectum 3m
      } else if (bE3){
        sprintf(sPe1, "%sITI",   s1); // perfectum 1
        sprintf(sPe2, "%sIT",    s1); // perfectum 2
        sprintf(sPe3m,"%sE",     s1); // perfectum 3
        sprintf(sPe3f,"%sTE",    s1); // perfectum 3 v
        sprintf(sPm1, "%sINW",   s1); // perfectum 1m
        sprintf(sPm2m,"%sITM",   s1); // perfectum 2m m
        sprintf(sPm2f,"%sITN",   s1); // perfectum 2m v
        sprintf(sPm3, "%sW",     s1); // perfectum 3m
      } else{ // c1=='W' en regelmatig; TODO: andere stamformaties
        sprintf(sPe1, "N%sTI",   sH + 1); // perfectum 1
        sprintf(sPe2, "N%sT",    sH + 1); // perfectum 2
        sprintf(sPe3m,"N%s",     sH + 1); // perfectum 3
        sprintf(sPe3f,"N%sE",    sH + 1); // perfectum 3 v
        sprintf(sPm1, "N%sNW",   sH + 1); // perfectum 1m
        sprintf(sPm2m,"N%sTM",   sH + 1); // perfectum 2m m
        sprintf(sPm2f,"N%sTN",   sH + 1); // perfectum 2m v
        sprintf(sPm3, "N%sW",    sH + 1); // perfectum 3m
      } // einde F_NIF
    } else if (iForm == F_PIE || iForm == F_POE){
      /* poe'al en pi'eel lijken veel op elkaar, behalve de 'vulletter' */
      char sVul[2]= "";
      if (strlen(sH) > 3){
        sVul[0]= sH[1];
        sVul[1]= '\0';
      }
      if (sH[strlen(sH) - 1]=='E'){
        sprintf(sPe1, "%c%s%cITI",    c1, sVul, c2); // perfectum 1
        sprintf(sPe2, "%c%s%cIT",     c1, sVul, c2); // perfectum 2
        sprintf(sPe3m,"%c%s%cE",      c1, sVul, c2); // perfectum 3
        sprintf(sPe3f,"%c%s%cTE",     c1, sVul, c2); // perfectum 3 v
        sprintf(sPm1, "%c%s%cINW",    c1, sVul, c2); // perfectum 1m
        sprintf(sPm2m,"%c%s%cITM",    c1, sVul, c2); // perfectum 2m m
        sprintf(sPm2f,"%c%s%cITN",    c1, sVul, c2); // perfectum 2m v
        sprintf(sPm3, "%c%s%cW",      c1, sVul, c2); // perfectum 3m
      } else /* overig en regelmatig */{
        sprintf(sPe1, "%c%s%c%cTI",    c1, sVul, c2, c3); // perfectum 1
        sprintf(sPe2, "%c%s%c%cT",     c1, sVul, c2, c3); // perfectum 2
        sprintf(sPe3m,"%c%s%c%c",      c1, sVul, c2, c3); // perfectum 3
        sprintf(sPe3f,"%c%s%c%cE",     c1, sVul, c2, c3); // perfectum 3 v
        sprintf(sPm1, "%c%s%c%cNW",    c1, sVul, c2, c3); // perfectum 1m
        sprintf(sPm2m,"%c%s%c%cTM",    c1, sVul, c2, c3); // perfectum 2m m
        sprintf(sPm2f,"%c%s%c%cTN",    c1, sVul, c2, c3); // perfectum 2m v
        sprintf(sPm3, "%c%s%c%cW",     c1, sVul, c2, c3); // perfectum 3m
      } // einde F_PIE en F_POE
    } else if (iForm == F_HIF){
      if (iStam==S__23){
        sprintf(sPe1, "E%sI%cWTI",     s1, c3    );
        sprintf(sPe2, "E%sI%cWT",      s1, c3    );
        sprintf(sPe3m,"E%s%c",         s1, c3    );
        sprintf(sPe3f,"E%s%cE",        s1, c3    );
        sprintf(sPm1, "E%sI%cWNW",     s1, c3    );
        sprintf(sPm2m,"E%sI%cWTM",     s1, c3    );
        sprintf(sPm2f,"E%sI%cWTN",     s1, c3    );
        sprintf(sPm3, "E%s%cW",        s1, c3    );
      } else if (iStam==S___E){
        sprintf(sPe1, "E%sITI",      s1    );
        sprintf(sPe2, "E%sIT",       s1    );
        sprintf(sPe3m,"E%sE",        s1    );
        sprintf(sPe3f,"E%sTE",       s1    );
        sprintf(sPm1, "E%sINW",      s1    );
        sprintf(sPm2m,"E%sITM",      s1    );
        sprintf(sPm2f,"E%sITN",      s1    );
        sprintf(sPm3, "E%sW",        s1    );
      } else{ // niet-gedefinieerd en regelmatig
        sprintf(sPe1, "E%s%cTI",     s1, c3); // perfectum 1
        sprintf(sPe2, "E%s%cT",      s1, c3); // perfectum 2
        sprintf(sPe3m,"E%sI%c",      s1, c3); // perfectum 3
        sprintf(sPe3f,"E%sI%cE",     s1, c3); // perfectum 3 v
        sprintf(sPm1, "E%s%cNW",     s1, c3); // perfectum 1m
        sprintf(sPm2m,"E%s%cTM",     s1, c3); // perfectum 2m m
        sprintf(sPm2f,"E%s%cTN",     s1, c3); // perfectum 2m v
        sprintf(sPm3, "E%sI%cW",     s1, c3); // perfectum 3m
      } // einde F_HIF
    } else if (iForm == F_HOE){
      if (false){
      } else{ // niet-gedefinieerd en regelmatig
        sprintf(sPe1, "EW%sTI",    sH + 2); // perfectum 1
        sprintf(sPe2, "EW%sT",     sH + 2); // perfectum 2
        sprintf(sPe3m,"EW%s",      sH + 2); // perfectum 3
        sprintf(sPe3f,"EW%sE",     sH + 2); // perfectum 3 v
        sprintf(sPm1, "EW%sNW",    sH + 2); // perfectum 1m
        sprintf(sPm2m,"EW%sTM",    sH + 2); // perfectum 2m m
        sprintf(sPm2f,"EW%sTN",    sH + 2); // perfectum 2m v
        sprintf(sPm3, "EW%sW",     sH + 2); // perfectum 3m
      } // einde F_HOE
    } else if (iForm == F_HIT){
      if (endsWith(sH, "E")){
        sprintf(sPe1, "E%sITI",  sCore); // perfectum 1
        sprintf(sPe2, "E%sIT",   sCore); // perfectum 2
        sprintf(sPe3m,"E%s%s",   sCore, endsWith(sCore, "W") ? "" : "E"); // perfectum 3
        /* (zoals bij STHW blijkt, verhindert de W het volgen van een E) */
        sprintf(sPe3f,"E%sTE",   sCore); // perfectum 3 v
        sprintf(sPm1, "E%sINW",  sCore); // perfectum 1m
        sprintf(sPm2m,"E%sITM",  sCore); // perfectum 2m m
        sprintf(sPm2f,"E%sITN",  sCore); // perfectum 2m v
        sprintf(sPm3, "E%sW",    sCore); // perfectum 3m
      } else /* overig en regelmatig */{
        sprintf(sPe1, "E%sTI",   sCore); // perfectum 1
        sprintf(sPe2, "E%sT",    sCore); // perfectum 2
        sprintf(sPe3m,"E%s",     sCore); // perfectum 3
        sprintf(sPe3f,"E%s%s",   sCore, endsWith(sCore, "W") ? "" : "E"); // perfectum 3 v
        sprintf(sPm1, "E%sNW",   sCore); // perfectum 1m
        sprintf(sPm2m,"E%sTM",   sCore); // perfectum 2m m
        sprintf(sPm2f,"E%sTN",   sCore); // perfectum 2m v
        sprintf(sPm3, "E%sW",    sCore); // perfectum 3m
      } // einde F_HIT
    } // einde Perfectum

    /* Nederlandse verbuigingen naast Hebreeuwse vebuigingen */
    /* De vormcode {xyz} is x=persoon, y=geslacht, z=aantal
    /* perfectum */
    printf("#%s\t%s\t{1s}%s\n",      sPe1,  wN.perf("1s"), sSrc);  // (ik) heb gedaan
    printf("#%s\t%s\t{2s}%s\n",      sPe2,  wN.perf("2s"), sSrc);  // (jij) hebt
    printf("#%s\t%s\t{3s}%s\n",      sPe3m, wN.perf("3s"), sSrc);  // (hij) heeft
    printf("#%s\t%s\t{3sf}%s\n",     sPe3f, wN.perf("3sf"), sSrc); // (zij) heeft
    //printf(".%s\thet %se\n",        sPez,       sDeelw); // zelfst.
    printf("#%s\t%s\t{1p}%s\n",      sPm1,  wN.perf("1p"), sSrc);  // (wij) hebben
    printf("#%s\t%s\t{2pm}%s\n",     sPm2m, wN.perf("2p"), sSrc);  // (jullie) hebben
    printf("#%s\t%s\t{2pf}%s\n",     sPm2f, wN.perf("2p"), sSrc); // (jullie) hebben
    printf("#%s\t%s\t{3p}%s\n",      sPm3,  wN.perf("3p"), sSrc);  // (zij) hebben
    /* perfectum consecutivum */
    /* dit laten we door Vertaler.java doen */
    /*
    printf("#W%s\ten %s\t{1s}%s\n",  sPe1,  wN.toek("1s"), sSrc); // en (ik) zal doen
    printf("#W%s\ten %s\t{2s}%s\n",  sPe2,  wN.toek("2s"), sSrc); //    (jij) zult
    printf("#W%s\ten %s\t{3s}%s\n",  sPe3m, wN.toek("3s"), sSrc); //    (hij) zal
    printf("#W%s\ten %s\t{3sf}%s\n", sPe3f, wN.toek("3sf"), sSrc);//    (zij) zal
    printf("#W%s\ten %s\t{1p}%s\n",  sPm1,  wN.toek("1p"), sSrc); //    (wij) zullen
    printf("#W%s\ten %s\t{2pm}%s\n", sPm2m, wN.toek("2p"), sSrc); //    (jullie) zullen
    printf("#W%s\ten %s\t{2pf}%s\n", sPm2f, wN.toek("2p"), sSrc); //    (jullie) zullen
    printf("#W%s\ten %s\t{3p}%s\n",  sPm3,  wN.toek("3p"), sSrc); //    (zij) zullen
    */

    /* tegenwoordige tijd */

    if (iForm == F_QAL){
      if (bE3){
        //(*** wat gebeurt er als ajin met waw samen gaat?
        printf("#%cW%cE\t%s\t{s}%s\n",        c1, c2, wN.tegenw("s"), sSrc);
        printf("#%cW%cIM\t%s\t{mp}%s\n",      c1, c2, wN.tegenw("p"), sSrc);
        printf("#%cW%cWT\t%s\t{fp}%s\n",      c1, c2, wN.tegenw("p"), sSrc);
      } else if (bW2 || bI2){
        printf("#%c%c\t%s\t{ms}%s\n",         c1, c3, wN.tegenw("s"), sSrc);
        printf("#%c%cE\t%s\t{fs}%s\n",        c1, c3, wN.tegenw("s"), sSrc);
        printf("#%c%cIM\t%s\t{mp}%s\n",       c1, c3, wN.tegenw("p"), sSrc);
        printf("#%c%cWT\t%s\t{fp}%s\n",       c1, c3, wN.tegenw("p"), sSrc);
      } else{ // ook bI1, bA1, b23, bN1
        printf("#%cW%s\t%s\t{ms}%s\n",        c1, sH + 1, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#%cW%sT\t%s\t{fs}%s\n",       c1, sH + 1, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#%cW%sIM\t%s\t{mp}%s\n",      c1, sH + 1, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#%cW%sWT\t%s\t{fp}%s\n",      c1, sH + 1, wN.tegenw("p"), sSrc); // tegenw 1m v
      } // einde F_QAL
    } else if (iForm == F_NIF){
      if (c3==c2){
        printf("#%s\t%s\t{ms}%s\n",      sH, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#%sE\t%s\t{fs}%s\n",     sH, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#%sIM\t%s\t{mp}%s\n",    sH, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#%sWT\t%s\t{fp}%s\n",    sH, wN.tegenw("p"), sSrc); // tegenw 1m v
      } else if (c1=='W' /* bI1 ! */){
        printf("#%s\t%s\t{ms}%s\n",      sH, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#%sT\t%s\t{fs}%s\n",     sH, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#%sIM\t%s\t{mp}%s\n",    sH, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#%sWT\t%s\t{fp}%s\n",    sH, wN.tegenw("p"), sSrc); // tegenw 1m v
      } else if (c1=='I' /* bN1 ! */){
        printf("#N%c%c%c\t%s\t{ms}%s\n",      c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#N%c%cW%c\t%s\t{ms}%s\n",     c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#N%c%c%cT\t%s\t{fs}%s\n",     c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#N%c%cW%cT\t%s\t{fs}%s\n",    c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#N%c%c%cIM\t%s\t{mp}%s\n",    c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#N%c%cW%cIM\t%s\t{mp}%s\n",   c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#N%c%c%cWT\t%s\t{fp}%s\n",    c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
        printf("#N%c%cW%cWT\t%s\t{fp}%s\n",   c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
      } else{ // TODO: andere stamformaties
        printf("#N%c%c%c\t%s\t{ms}%s\n",      c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#N%c%c%cT\t%s\t{fs}%s\n",     c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#N%c%c%cIM\t%s\t{mp}%s\n",    c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#N%c%c%cWT\t%s\t{fp}%s\n",    c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
      }
    } else if (iForm == F_PIE){
      if (true /* regelmatig */){
        printf("#M%c%c%c\t%s\t{ms}%s\n",      c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%c%c%cT\t%s\t{fs}%s\n",     c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%c%c%cIM\t%s\t{mp}%s\n",    c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%c%c%cWT\t%s\t{fp}%s\n",    c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
      }
    } else if (iForm == F_POE){
      if (true /* regelmatig */){
        printf("#M%cW%c%c\t%s\t{ms}%s\n",     c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%cW%c%cT\t%s\t{fs}%s\n",    c1, c2, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%cW%c%cIM\t%s\t{mp}%s\n",   c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%cW%c%cWT\t%s\t{fp}%s\n",   c1, c2, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
      }
    } else if (iForm == F_HIF){
      if (iStam==S__23){
        printf("#M%s%c\t%s\t{ms}%s\n",        s1, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%sI%cE\t%s\t{fs}%s\n",      s1, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%sI%cIM\t%s\t{mp}%s\n",     s1, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%sI%cWT\t%s\t{fp}%s\n",     s1, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
      } else if (iStam==S___E){
        printf("#M%sE\t%s\t{ms}%s\n",         s1, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%sE\t%s\t{fs}%s\n",         s1, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%sIM\t%s\t{mp}%s\n",        s1, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%sWT\t%s\t{fp}%s\n",        s1, wN.tegenw("p"), sSrc); // tegenw 1m v
      } else{ /* regelmatig en onbepaald */
        printf("#M%sI%c\t%s\t{ms}%s\n",       s1, c3, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%sI%cE\t%s\t{fs}%s\n",      s1, c3, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%sI%cIM\t%s\t{mp}%s\n",     s1, c3, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%sI%cWT\t%s\t{fp}%s\n",     s1, c3, wN.tegenw("p"), sSrc); // tegenw 1m v
      }
    } else if (iForm == F_HOE){
      if (false){
      } else{ /* regelmatig en onbepaald */
        printf("#MW%s\t%s\t{ms}%s\n",       sH + 2, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#MW%sT\t%s\t{fs}%s\n",      sH + 2, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#MW%sIM\t%s\t{mp}%s\n",     sH + 2, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#MW%sWT\t%s\t{fp}%s\n",     sH + 2, wN.tegenw("p"), sSrc); // tegenw 1m v
      }
    } else if (iForm == F_HIT){
      if (endsWith(sH, "E")){
        printf("#M%s%s\t%s\t{ms}%s\n",          sCore, endsWith(sCore, "W") ? "" : "E",
                                                     wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%sIT\t%s\t{fs}%s\n",          sCore, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%sIM\t%s\t{mp}%s\n",          sCore, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%sWT\t%s\t{fp}%s\n",          sCore, wN.tegenw("p"), sSrc); // tegenw 1m v
      } else /* overig en regelmatig */{
        printf("#M%s\t%s\t{ms}%s\n",            sCore, wN.tegenw("s"), sSrc); // tegenw 1 m
        printf("#M%sT\t%s\t{fs}%s\n",           sCore, wN.tegenw("s"), sSrc); // tegenw 1 v
        printf("#M%sIM\t%s\t{mp}%s\n",          sCore, wN.tegenw("p"), sSrc); // tegenw 1m m
        printf("#M%sWT\t%s\t{fp}%s\n",          sCore, wN.tegenw("p"), sSrc); // tegenw 1m v
      }
    }

    /* imperfectum (onvoltooide tijd, narrativus) */
    char sImp1[12];
    char sImp2m[12];
    char sImp2v[12];
    char sImp3m[12];
    char sImp3v[12];
    char sImp3m2[12]= "";
    char sImp3v2[12]= "";
    char sImp1p[12];
    char sImp2p[12];
    char sImppv[12]= ""; // vrouwelijk meervoud 2e en 3e persoon (in onbruik)
    char sImp3p[12];

    if (iForm == F_QAL){
      if (!strcmp(sH, "LQH")){ // onregelmatig
        sprintf(sImp1,  "A%c%c",          c2, c3); // tt 1
        sprintf(sImp2m, "T%c%c",          c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%c",          c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%c",          c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%c",          c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%c",          c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%cW",         c2, c3); // tt 2m
        sprintf(sImp3p, "I%c%cW",         c2, c3); // tt 3m
      } else if (!strcmp(sH, "ELK")){ ///(*** controleren
        sprintf(sImp1,  "A%c%c",          c2, c3); // tt 1
        sprintf(sImp2m, "T%c%c",          c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%c",          c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%c",          c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%c",          c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%c",          c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%cW",         c2, c3); // tt 2m
        sprintf(sImp3p, "I%c%cW",         c2, c3); // tt 3m
      } else if (!strcmp(sH, "NSA") || !strcmp(sH, "IßA")){ // zwak //(*** controleren
        sprintf(sImp1,  "A%cA",           c2    ); // tt 1
        sprintf(sImp2m, "T%cA",           c2    ); // tt 2 m
        sprintf(sImp2v, "T%cAI",          c2    ); // tt 2 v
        sprintf(sImp3m, "I%cA",           c2    ); // tt 3 m
        sprintf(sImp3v, "T%cA",           c2    ); // tt 3 v
        sprintf(sImp1p, "N%cA",           c2    ); // tt 1m
        sprintf(sImp2p, "T%cAW",          c2    ); // tt 2m
        sprintf(sImp3p, "I%cAW",          c2    ); // tt 3m
      } else if (bN13){ // zelf gecombineerd uit bN1 en bI1
        sprintf(sImp1,  "A%c%cE",         c2, c3); // tt 1
        sprintf(sImp2m, "T%c%cE",         c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%cI",         c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%cE",         c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%cE",         c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%cE",         c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%cW",         c2, c3); // tt 2m
        sprintf(sImppv, "T%cW%cNE",       c2, c3); // tt 2m v
        sprintf(sImp3p, "I%c%cW",         c2, c3); // tt 3m
      } else if (bN1){ // bij N&E blijkt de N zwaarder te wegen dan de E
        sprintf(sImp1,  "A%cW%c",         c2, c3); // tt 1
        sprintf(sImp2m, "T%cW%c",         c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%cI",         c2, c3); // tt 2 v
        sprintf(sImp3m, "I%cW%c",         c2, c3); // tt 3 m
        sprintf(sImp3v, "T%cW%c",         c2, c3); // tt 3 v
        sprintf(sImp1p, "N%cW%c",         c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%cW",         c2, c3); // tt 2m
        sprintf(sImppv, "T%cW%cNE",       c2, c3); // tt 2m v
        sprintf(sImp3p, "I%c%cW",         c2, c3); // tt 3m
      } else if (bE3){
        sprintf(sImp1,  "A%c%cE",     c1, c2    ); // tt 1
        sprintf(sImp2m, "T%c%cE",     c1, c2    ); // tt 2 m
        sprintf(sImp2v, "T%c%cI",     c1, c2    ); // tt 2 v
        sprintf(sImp3m, "I%c%cE",     c1, c2    ); // tt 3 m
        sprintf(sImp3m2,"I%c%c",      c1, c2    ); // tt 3 m
        sprintf(sImp3v, "T%c%cE",     c1, c2    ); // tt 3 v
        sprintf(sImp3v2,"T%c%c",      c1, c2    ); // tt 2 v
        sprintf(sImp1p, "N%c%cE",     c1, c2    ); // tt 1m
        sprintf(sImp2p, "T%c%cW",     c1, c2    ); // tt 2m
        sprintf(sImppv, "T%c%cINE",   c1, c2    ); // tt 2mv
        sprintf(sImp3p, "I%c%cW",     c1, c2    ); // tt 3m
      } else if (bW2 || bI2){
        sprintf(sImp1,  "A%c%c%c",    c1, c2, c3); // tt 1
        sprintf(sImp2m, "T%c%c%c",    c1, c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%c%c",    c1, c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%c%c",    c1, c2, c3); // tt 3 m
        sprintf(sImp3m2,"I%c%c",      c1,     c3); // tt 3 m alt.
        sprintf(sImp3v, "T%c%c%c",    c1, c2, c3); // tt 3 v
        sprintf(sImp3v2,"T%c%c",      c1,     c3); // tt 3 v alt.
        sprintf(sImp1p, "N%c%c%c",    c1, c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%c%cW",   c1, c2, c3); // tt 2m
        sprintf(sImppv, "T%c%c%cINE", c1, c2, c3); // tt 2m v
        sprintf(sImp3p, "I%c%c%cW",   c1, c2, c3); // tt 3m
      } else if (b23){
        sprintf(sImp1,  "A%cW%cE",    c1, c2    ); // tt 1
        sprintf(sImp2m, "TI%cW%c",    c1, c2    ); // tt 2 m
        sprintf(sImp2v, "TI%cW%cI",   c1, c2    ); // tt 2 v
        sprintf(sImp3m, "II%cW%c",    c1, c2    ); // tt 3 m
        sprintf(sImp3v, "TI%cW%c",    c1, c2    ); // tt 3 v
        sprintf(sImp1p, "NI%cW%c",    c1, c2    ); // tt 1m
        sprintf(sImp2p, "TI%cW%cW",   c1, c2    ); // tt 2m
        sprintf(sImppv, "T%cW%cINE",  c1, c2    ); // tt 2m v
        sprintf(sImp3p, "II%cW%cW",   c1, c2    ); // tt 3m
      } else if (bI1 && bA3){
        sprintf(sImp1,  "A%s",          sH); // tt 1
        sprintf(sImp2m, "T%s",          sH); // tt 2 m
        sprintf(sImp2v, "T%sI",         sH); // tt 2 v
        sprintf(sImp3m, "I%s",          sH); // tt 3 m
        sprintf(sImp3v, "T%s",          sH); // tt 3 v
        sprintf(sImp1p, "N%s",          sH); // tt 1m
        sprintf(sImp2p, "T%sW",         sH); // tt 2m
        sprintf(sImppv, "T%sNE",        sH); // tt 2m v
        sprintf(sImp3p, "I%sW",         sH); // tt 3m
      } else if (bI1){
        sprintf(sImp1,  "A%c%c",          c2, c3); // tt 1
        sprintf(sImp2m, "T%c%c",          c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%cI",         c2, c3); // tt 2 v
        sprintf(sImp3m, "II%c%c",         c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%c",          c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%c",          c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%cW",         c2, c3); // tt 2m
        sprintf(sImppv, "T%c%cNE",        c2, c3); // tt 2m v
        sprintf(sImp3p, "II%c%cW",        c2, c3); // tt 3m
      } else if (bA3){
        sprintf(sImp1,  "A%c%cA",     c1, c2    ); // tt 1
        sprintf(sImp2m, "T%c%cA",     c1, c2    ); // tt 2 m
        sprintf(sImp2v, "T%c%cAI",    c1, c2    ); // tt 2 v
        sprintf(sImp3m, "I%c%cA",     c1, c2    ); // tt 3 m
        sprintf(sImp3v, "T%c%cA",     c1, c2    ); // tt 3 v
        sprintf(sImp1p, "N%c%cA",     c1, c2    ); // tt 1m
        sprintf(sImp2p, "T%c%cAW",    c1, c2    ); // tt 2m
        sprintf(sImppv, "T%c%cANE",   c1, c2    ); // tt 2m v
        sprintf(sImp3p, "I%c%cAW",    c1, c2    ); // tt 3m
      } else if (bA1){
        sprintf(sImp1,  "A%c%c",          c2, c3); // tt 1
        sprintf(sImp2m, "TA%c%c",         c2, c3); // tt 2 m
        sprintf(sImp2v, "TA%c%cI",        c2, c3); // tt 2 v
        sprintf(sImp3m, "IA%c%c",         c2, c3); // tt 3 m
        sprintf(sImp3v, "TA%c%c",         c2, c3); // tt 3 v
        sprintf(sImp1p, "NA%c%c",         c2, c3); // tt 1m
        sprintf(sImp2p, "TA%c%cW",        c2, c3); // tt 2m
        sprintf(sImppv, "TA%c%cNE",       c2, c3); // tt 2m v
        sprintf(sImp3p, "IA%c%cW",        c2, c3); // tt 3m
      } else if (bA2){ // W wordt opgelost door de A
        sprintf(sImp1,  "A%c%c%c",    c1, c2, c3); // tt 1
        sprintf(sImp2m, "T%c%c%c",    c1, c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%c%cI",   c1, c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%c%c",    c1, c2, c3); // tt 3 m
      //sprintf(sImp3m2,"I%c%c%c",    c1, c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%c%c",    c1, c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%c%c",    c1, c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%c%cW",   c1, c2, c3); // tt 2m
        sprintf(sImppv, "T%c%c%cNE",  c1, c2, c3); // tt 2m v
        sprintf(sImp3p, "I%c%c%c",    c1, c2, c3); // tt 3m
      } else if (endsWith(sH, "O") // "WO" vervangen door "O"
          || endsWith(sH, "ZB")){  // "ZWB" vervangen door "ZB" // TODO: +alle eindigend op B?
        sprintf(sImp1,  "A%c%c%c",    c1, c2, c3); // tt 1
        sprintf(sImp2m, "T%c%c%c",    c1, c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%c%cI",   c1, c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%c%c",    c1, c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%c%c",    c1, c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%c%c",    c1, c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%c%cW",   c1, c2, c3); // tt 2m
        sprintf(sImppv, "T%c%cW%cNE", c1, c2, c3); // tt 2m v // TODO: W%c -> %c ?
        sprintf(sImp3p, "I%c%c%cW",   c1, c2, c3); // tt 3m
      } else{
        sprintf(sImp1,  "A%c%cW%c",   c1, c2, c3); // tt 1
        sprintf(sImp2m, "T%c%cW%c",   c1, c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%c%cI",   c1, c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%cW%c",   c1, c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%cW%c",   c1, c2, c3); // tt 3 v
        if (indexOf("BEHKMOP", sH[0]) >= 0
        ||  indexOf("BEHKMOPDC", sH[1]) >= 0){
          sprintf(sImp3m2,"I%c%c%c",    c1, c2, c3); // tt 3 m // lijkt op intensiefvorm
          sprintf(sImp3v2,"T%c%c%c",    c1, c2, c3); // tt 3 v // lijkt op intensiefvorm
        }
        sprintf(sImp1p, "N%c%cW%c",   c1, c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%c%cW",   c1, c2, c3); // tt 2m
        sprintf(sImppv, "T%c%cW%cNE", c1, c2, c3); // tt 2m v
        sprintf(sImp3p, "I%c%c%cW",   c1, c2, c3); // tt 3m
      } // einde F_QAL
    } else if (iForm == F_NIF){
      if (c1=='W' /* bI1 ! */){
        sprintf(sImp1,  "AIW%s",   sH + 1); // tt 1
        sprintf(sImp2m, "TIW%s",   sH + 1); // tt 2 m
        sprintf(sImp2v, "TIW%sI",  sH + 1); // tt 2 v
        sprintf(sImp3m, "IIW%s",   sH + 1); // tt 3 m
        sprintf(sImp3v, "TIW%s",   sH + 1); // tt 3 v
        sprintf(sImp1p, "NIW%s",   sH + 1); // tt 1m
        sprintf(sImp2p, "TIW%sW",  sH + 1); // tt 2m
        sprintf(sImppv, "TIW%sNE", sH + 1); // tt 2m v
        sprintf(sImp3p, "IIW%sW",  sH + 1); // tt 3m
      } else if (c1=='I' /* bN1 ! */){
        sprintf(sImp1,  "AN%s",    sH + 2); // tt 1
        sprintf(sImp2m, "TIN%s",   sH + 2); // tt 2 m
        sprintf(sImp2v, "TIN%sI",  sH + 2); // tt 2 v
        sprintf(sImp3m, "IIN%s",   sH + 2); // tt 3 m
        sprintf(sImp3v, "TIN%s",   sH + 2); // tt 3 v
        sprintf(sImp1p, "NIN%s",   sH + 2); // tt 1m
        sprintf(sImp2p, "TIN%sW",  sH + 2); // tt 2m
        sprintf(sImppv, "TIN%sNE", sH + 2); // tt 2m v
        sprintf(sImp3p, "IIN%sW",  sH + 2); // tt 3m
      } else if (true || c3==c2){
        sprintf(sImp1,  "A%s",     sH + 1); // tt 1
        sprintf(sImp2m, "TI%s",    sH + 1); // tt 2 m
        sprintf(sImp2v, "TI%sI",   sH + 1); // tt 2 v
        sprintf(sImp3m, "II%s",    sH + 1); // tt 3 m
        sprintf(sImp3v, "TI%s",    sH + 1); // tt 3 v
        sprintf(sImp1p, "NI%s",    sH + 1); // tt 1m
        sprintf(sImp2p, "TI%sW",   sH + 1); // tt 2m
        sprintf(sImppv, "TI%sNE",  sH + 1); // tt 2m v
        sprintf(sImp3p, "II%sW",   sH + 1); // tt 3m
      } //TODO: andere stamformaties
    } else if (iForm == F_PIE && c3=='E'){
        sprintf(sImp1,  "A%c%cE",    c1, c2); // tt 1
        sprintf(sImp2m, "T%c%cE",    c1, c2); // tt 2 m
        sprintf(sImp2v, "T%c%cI",    c1, c2); // tt 2 v
        sprintf(sImp3m, "I%c%cE",    c1, c2); // tt 3 m
        sprintf(sImp3m2,"I%c%c",     c1, c2); // tt 3 m
        sprintf(sImp3v, "T%c%cE",    c1, c2); // tt 3 v
        sprintf(sImp3v2,"T%c%c",     c1, c2); // tt 3 v
        sprintf(sImp1p, "N%c%cE",    c1, c2); // tt 1m
        sprintf(sImp2p, "T%c%cW",    c1, c2); // tt 2m
        sprintf(sImppv, "T%c%cINE",  c1, c2); // tt 2m v
        sprintf(sImp3p, "I%c%cW",    c1, c2); // tt 3m
    } else if (iForm == F_PIE || iForm == F_POE){
      const char *sVul= (iForm == F_POE ? "W" : "");
      if (true /* regelmatig */){
        sprintf(sImp1,  "A%c%s%c%c",    c1, sVul, c2, c3); // tt 1
        sprintf(sImp2m, "T%c%s%c%c",    c1, sVul, c2, c3); // tt 2 m
        sprintf(sImp2v, "T%c%s%c%cI",   c1, sVul, c2, c3); // tt 2 v
        sprintf(sImp3m, "I%c%s%c%c",    c1, sVul, c2, c3); // tt 3 m
        sprintf(sImp3v, "T%c%s%c%c",    c1, sVul, c2, c3); // tt 3 v
        sprintf(sImp1p, "N%c%s%c%c",    c1, sVul, c2, c3); // tt 1m
        sprintf(sImp2p, "T%c%s%c%cW",   c1, sVul, c2, c3); // tt 2m
        sprintf(sImppv, "T%c%s%c%cNE",  c1, sVul, c2, c3); // tt 2m v
        sprintf(sImp3p, "I%c%s%c%cW",   c1, sVul, c2, c3); // tt 3m
      } // einde F_PIE en F_POE
    } else if (iForm == F_HIF){
      if (iStam==S__23){
        sprintf(sImp1,  "A%s%c",      s1, c3); // tt 1
        sprintf(sImp2m, "T%s%c",      s1, c3); // tt 2 m
        sprintf(sImp2v, "T%s%cI",     s1, c3); // tt 2 v
        sprintf(sImp3m, "I%s%c",      s1, c3); // tt 3 m
        sprintf(sImp3v, "T%s%c",      s1, c3); // tt 3 v
        sprintf(sImp1p, "N%s%c",      s1, c3); // tt 1m
        sprintf(sImp2p, "T%s%cW",     s1, c3); // tt 2m
        sprintf(sImppv, "T%s%cNE",    s1, c3); // tt 2m v
        sprintf(sImp3p, "I%s%cW",     s1, c3); // tt 3m
      } else if (iStam==S___E){
        sprintf(sImp1,  "A%s%c",      s1, c3); // tt 1
        sprintf(sImp2m, "T%s%c",      s1, c3); // tt 2 m
        sprintf(sImp2v, "T%sI",       s1    ); // tt 2 v
        sprintf(sImp3m, "I%s%c",      s1, c3); // tt 3 m
        sprintf(sImp3m2,"I%s",        s1    ); // tt 3 m    // net als bij F_QAL
        sprintf(sImp3v, "T%s%c",      s1, c3); // tt 3 v
        sprintf(sImp3v2,"T%s",        s1    ); // tt 3 v    // net als bij F_QAL
        sprintf(sImp1p, "N%s%c",      s1, c3); // tt 1m
        sprintf(sImp2p, "T%sW",       s1    ); // tt 2m
        sprintf(sImppv, "T%sINE",     s1    ); // tt 2m v
        sprintf(sImp3p, "I%sW",       s1    ); // tt 3m
      } else { // niet-gedefinieerd en regelmatig
        sprintf(sImp1,  "A%sI%c",     s1, c3); // tt 1
        sprintf(sImp2m, "T%sI%c",     s1, c3); // tt 2 m
        sprintf(sImp2v, "T%sI%cI",    s1, c3); // tt 2 v
        sprintf(sImp3m, "I%sI%c",     s1, c3); // tt 3 m
        sprintf(sImp3v, "T%sI%c",     s1, c3); // tt 3 v
        sprintf(sImp1p, "N%sI%c",     s1, c3); // tt 1m
        sprintf(sImp2p, "T%sI%cW",    s1, c3); // tt 2m
        sprintf(sImppv, "T%sI%cNE",   s1, c3); // tt 2m v
        sprintf(sImp3p, "I%sI%cW",    s1, c3); // tt 3m
      } // einde F_HIF
    } else if (iForm == F_HOE){
      if (false){
      } else { // niet-gedefinieerd en regelmatig
        sprintf(sImp1,  "AW%s",     sH + 2); // tt 1
        sprintf(sImp2m, "TW%s",     sH + 2); // tt 2 m
        sprintf(sImp2v, "TW%sI",    sH + 2); // tt 2 v
        sprintf(sImp3m, "IW%s",     sH + 2); // tt 3 m
        sprintf(sImp3v, "TW%s",     sH + 2); // tt 3 v
        sprintf(sImp1p, "NW%s",     sH + 2); // tt 1m
        sprintf(sImp2p, "TW%sW",    sH + 2); // tt 2m
        sprintf(sImppv, "TW%sNE",   sH + 2); // tt 2m v
        sprintf(sImp3p, "IW%sW",    sH + 2); // tt 3m
      } // einde F_HOE
    } else if (iForm == F_HIT){
      if (iStam == S___E){
        sprintf(sImp1,  "A%s%s",  sCore, endsWith(sCore, "W") ? "" : "E"); // tt 1
        sprintf(sImp2m, "T%s%s",  sCore, endsWith(sCore, "W") ? "" : "E"); // tt 2 m
        sprintf(sImp2v, "T%sI",   sCore); // tt 2 v
        sprintf(sImp3m, "I%s%s",  sCore, endsWith(sCore, "W") ? "" : "E"); // tt 3 m
        sprintf(sImp3v, "T%s%s",  sCore, endsWith(sCore, "W") ? "" : "E"); // tt 3 v
        sprintf(sImp1p, "N%s%s",  sCore, endsWith(sCore, "W") ? "" : "E"); // tt 1m
        sprintf(sImp2p, "T%sW",   sCore); // tt 2m
        sprintf(sImppv, "T%sINE", sCore); // tt 2m v
        sprintf(sImp3p, "I%sW",   sCore); // tt 3m
      } else /* overig en regelmatig */{
        sprintf(sImp1,  "A%s",    sCore); // tt 1
        sprintf(sImp2m, "T%s",    sCore); // tt 2 m
        sprintf(sImp2v, "T%sI",   sCore); // tt 2 v
        sprintf(sImp3m, "I%s",    sCore); // tt 3 m
        sprintf(sImp3v, "T%s",    sCore); // tt 3 v
        sprintf(sImp1p, "N%s",    sCore); // tt 1m
        sprintf(sImp2p, "T%sW",   sCore); // tt 2m
        sprintf(sImppv, "T%sNE",  sCore); // tt 2m v
        sprintf(sImp3p, "I%sW",   sCore); // tt 3m
      } // einde F_HIT
    }

    /* Narrativus of Imperfectum consecutivum doen we sinds 20060114 niet meer */
    /* In plaats daarvan: onvoltooid verleden tijd naast toekomende tijd */
    printf("#%s\t%s\t{1s}%s\n",           sImp1,   wN.ovt("1s"),  sSrc);
    printf("#%s\t%s\t{1s}%s\n",           sImp1,   wN.toek("1s"), sSrc);
    if (!strcmp(sImp2m, sImp3v)){
      printf("#%s\t%s\t{2sm}%s\n",        sImp2m,  wN.ovt("2s"),  sSrc); // tt 2 m
      printf("#%s\t%s\t{2sm}%s\n",        sImp2m,  wN.toek("2s"), sSrc); // tt 2 m
      printf("#%s\t%s\t{3sf}%s\n",        sImp2m,  wN.ovt("3sf"), sSrc); // tt 3 v
      printf("#%s\t%s\t{3sf}%s\n",        sImp2m,  wN.toek("3sf"),sSrc); // tt 3 v
    } else{
      printf("#%s\t%s\t{2sm}%s\n",        sImp2m,  wN.ovt("2s"),  sSrc); // tt 2 m
      printf("#%s\t%s\t{2sm}%s\n",        sImp2m,  wN.toek("2s"), sSrc); // tt 2 m
      printf("#%s\t%s\t{3sf}%s\n",        sImp3v,  wN.ovt("3sf"), sSrc); // tt 3 v
      printf("#%s\t%s\t{3sf}%s\n",        sImp3v,  wN.toek("3sf"),sSrc); // tt 3 v
    }
    printf("#%s\t%s\t{2sf}%s\n",          sImp2v,  wN.ovt("2s"),  sSrc); // tt 2 v
    printf("#%s\t%s\t{2sf}%s\n",          sImp2v,  wN.toek("2s"), sSrc); // tt 2 v
    //if (strcmp(sImp3m, "IEWE")){ // de Naam!
      printf("#%s\t%s\t{3sm}%s\n",        sImp3m,  wN.ovt("3s"),  sSrc); // tt 3 m
      printf("#%s\t%s\t{3sm}%s\n",        sImp3m,  wN.toek("3s"), sSrc); // tt 3 m
    //}
    if (sImp3m2[0]){
      printf("#%s\t%s\t{3sm}%s\n",        sImp3m2, wN.ovt("3s"),  sSrc); // tt 3 m
      printf("#%s\t%s\t{3sm}%s\n",        sImp3m2, wN.toek("3s"), sSrc); // tt 3 m
    }
    if (sImp3v2[0]){
      printf("#%s\t%s\t{3sf}%s\n",        sImp3v2, wN.ovt("3sf"),  sSrc); // tt 3 v
      printf("#%s\t%s\t{3sf}%s\n",        sImp3v2, wN.toek("3sf"), sSrc); // tt 3 v
    }
    printf("#%s\t%s\t{1p}%s\n",           sImp1p,  wN.ovt("1p"),  sSrc); // tt 1m
    printf("#%s\t%s\t{1p}%s\n",           sImp1p,  wN.toek("1p"), sSrc); // tt 1m
    printf("#%s\t%s\t{2p}%s\n",           sImp2p,  wN.ovt("2p"),  sSrc); // tt 2m
    printf("#%s\t%s\t{2p}%s\n",           sImp2p,  wN.toek("2p"), sSrc); // tt 2m
    if (sImppv[0]){
      printf("#%s\t%s\t{2pf}%s\n",        sImppv,  wN.ovt("2p"),  sSrc); // tt 2m v
      printf("#%s\t%s\t{2pf}%s\n",        sImppv,  wN.toek("2p"), sSrc); // tt 2m v
    }
    printf("#%s\t%s\t{3p}%s\n",           sImp3p,  wN.ovt("3p"),  sSrc); // tt 3m
    printf("#%s\t%s\t{3p}%s\n",           sImp3p,  wN.toek("3p"), sSrc); // tt 3m


    /* gebiedende wijs */

    if (iForm == F_NIF){
      if (c1=='W' /* bI1 ! */){
        printf("#EIW%s\t%s\t{2ms}%s\n",   sH + 1, wN.geb("s"), sSrc);
        printf("#EIW%sI\t%s\t{2fs}%s\n",  sH + 1, wN.geb("s"), sSrc);
        printf("#EIW%sW\t%s\t{2mp}%s\n",  sH + 1, wN.geb("p"), sSrc);
        printf("#EIW%sNE\t%s\t{2fp}%s\n", sH + 1, wN.geb("p"), sSrc);
      } else if (c1=='I' /* bN1 ! */){
        printf("#EIN%s\t%s\t{2ms}%s\n",   sH + 2, wN.geb("s"), sSrc);
        printf("#EIN%sI\t%s\t{2fs}%s\n",  sH + 2, wN.geb("s"), sSrc);
        printf("#EIN%sW\t%s\t{2mp}%s\n",  sH + 2, wN.geb("p"), sSrc);
        printf("#EIN%sNE\t%s\t{2fp}%s\n", sH + 2, wN.geb("p"), sSrc);
      } else{ // regelmatig & c2==c3
        printf("#EI%s\t%s\t{2ms}%s\n",    sH + 1, wN.geb("s"), sSrc);
        printf("#EI%sI\t%s\t{2fs}%s\n",   sH + 1, wN.geb("s"), sSrc);
        printf("#EI%sW\t%s\t{2mp}%s\n",   sH + 1, wN.geb("p"), sSrc);
        printf("#EI%sNE\t%s\t{2fp}%s\n",  sH + 1, wN.geb("p"), sSrc);
      }
    } else if (iForm == F_PIE){
      printf("#%c%c%c\t%s\t{2ms}%s\n",      c1, c2, c3, wN.geb("s"), sSrc); // geb 2 m
      printf("#%c%c%cI\t%s\t{2fs}%s\n",     c1, c2, c3, wN.geb("s"), sSrc); // geb 2 v
      printf("#%c%c%cW\t%s\t{2mp}%s\n",     c1, c2, c3, wN.geb("p"), sSrc); // geb 2m m
      printf("#%c%cW%cNE\t%s\t{2fp}%s\n",   c1, c2, c3, wN.geb("p"), sSrc); // geb 2m v
    } else if (iForm == F_POE){
      /* bestaat niet */
    } else if (iForm == F_HIF){
      if (iStam==S__23){
        printf("#E%s%c\t%s\t{2ms}%s\n",     s1, c3, wN.geb("s"), sSrc);
        printf("#E%s%cI\t%s\t{2fs}%s\n",    s1, c3, wN.geb("s"), sSrc);
        printf("#E%s%cW\t%s\t{2mp}%s\n",    s1, c3, wN.geb("p"), sSrc);
        printf("#E%s%cNE\t%s\t{2fp}%s\n",   s1, c3, wN.geb("p"), sSrc);
      } else if (iStam==S___E){
        printf("#E%sE\t%s\t{2ms}%s\n",      s1, wN.geb("s"), sSrc);
        printf("#E%sI\t%s\t{2fs}%s\n",      s1, wN.geb("s"), sSrc);
        printf("#E%sW\t%s\t{2mp}%s\n",      s1, wN.geb("p"), sSrc);
        printf("#E%sINE\t%s\t{2fp}%s\n",    s1, wN.geb("p"), sSrc);
      } else{ /* regelmatig of overig */
        printf("#E%s%c\t%s\t{2ms}%s\n",     s1, c3, wN.geb("s"), sSrc);
        printf("#E%sI%cI\t%s\t{2fs}%s\n",   s1, c3, wN.geb("s"), sSrc);
        printf("#E%sI%cW\t%s\t{2mp}%s\n",   s1, c3, wN.geb("p"), sSrc);
        printf("#E%s%cNE\t%s\t{2fp}%s\n",   s1, c3, wN.geb("p"), sSrc);
      }
    } else if (iForm == F_HOE){
      /* bestaat niet */
    } else if (iForm == F_HIT){
      if (iStam == S___E){
        printf("#E%s%s\t%s\t{2ms}%s\n",     sCore, endsWith(sCore, "W") ? "" : "E",
                                                 wN.geb("s"), sSrc);
        printf("#E%sI\t%s\t{2fs}%s\n",      sCore, wN.geb("s"), sSrc);
        printf("#E%sW\t%s\t{2mp}%s\n",      sCore, wN.geb("p"), sSrc);
        printf("#E%sINE\t%s\t{2fp}%s\n",    sCore, wN.geb("p"), sSrc);
      } else /* overig en regelmatig */{
        printf("#E%s\t%s\t{2ms}%s\n",       sCore, wN.geb("s"), sSrc);
        printf("#E%sI\t%s\t{2fs}%s\n",      sCore, wN.geb("s"), sSrc);
        printf("#E%sW\t%s\t{2mp}%s\n",      sCore, wN.geb("p"), sSrc);
        printf("#E%sNE\t%s\t{2fp}%s\n",     sCore, wN.geb("p"), sSrc);
      }
    /* hierna: QAL-stammen */
    } else if (!strcmp(sH, "LQH")){
      printf("#%c%c\t%s\t{2s}%s\n",      c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cI\t%s\t{2mp}%s\n",    c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cW\t%s\t{2fp}%s\n",    c2, c3, wN.geb("p"), sSrc);
    } else if (!strcmp(sH, "NSA") || !strcmp(sH, "IßA")){ // verliest 'N' resp. "I"
      printf("#%c%c\t%s\t{2s}%s\n",      c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cI\t%s\t{2mp}%s\n",    c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cW\t%s\t{2fp}%s\n",    c2, c3, wN.geb("p"), sSrc);
    } else if (!strcmp(sH, "ELK")){
      printf("#%c%c\t%s\t{2ms}%s\n",     c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cI\t%s\t{2fs}%s\n",    c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cW\t%s\t{2mp}%s\n",    c2, c3, wN.geb("p"), sSrc);
      printf("#%c%cNE\t%s\t{2fp}%s\n",   c2, c3, wN.geb("p"), sSrc);
    } else if (!strcmp(sH, "NTN")){
      printf("#%c%cE\t%s\t{2ms}%s\n",    c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cI\t%s\t{2fs}%s\n",    c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cW\t%s\t{2mp}%s\n",    c2, c3, wN.geb("p"), sSrc);
      //printf("#%c%cNE\t%s\t{2fp}%s\n",   c2, c3, wN.geb("p")); // onzeker
    } else if (bN1 && bE3){
      printf("#E%cE\t%s\t{2ms}%s\n",     c2, wN.geb("s"), sSrc);
      printf("#E%cI\t%s\t{2fs}%s\n",     c2, wN.geb("s"), sSrc);
      printf("#E%cW\t%s\t{2mp}%s\n",     c2, wN.geb("p"), sSrc);
      printf("#E%cINE\t%s\t{2fp}%s\n",   c2, wN.geb("p"), sSrc);
    } else if (bE3){
      printf("#%c%cE\t%s\t{2ms}%s\n",    c1, c2, wN.geb("s"), sSrc);
      printf("#%c%cI\t%s\t{2fs}%s\n",    c1, c2, wN.geb("s"), sSrc);
      printf("#%c%cW\t%s\t{2mp}%s\n",    c1, c2, wN.geb("p"), sSrc);
      printf("#%c%cINE\t%s\t{2fp}%s\n",  c1, c2, wN.geb("p"), sSrc);
    } else if (bW2 || bI2 || b23 || bA3){
      printf("#%c%c%c\t%s\t{2ms}%s\n",   c1, c2, c3, wN.geb("s"), sSrc);
      printf("#%c%c%cI\t%s\t{2fs}%s\n",  c1, c2, c3, wN.geb("s"), sSrc);
      printf("#%c%c%cW\t%s\t{2mp}%s\n",  c1, c2, c3, wN.geb("p"), sSrc);
      printf("#%c%c%cNE\t%s\t{2fp}%s\n", c1, c2, c3, wN.geb("p"), sSrc);
    } else if (bI1){
      printf("#%c%c\t%s\t{2ms}%s\n",     c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cI\t%s\t{2fs}%s\n",    c2, c3, wN.geb("s"), sSrc);
      printf("#%c%cW\t%s\t{2mp}%s\n",    c2, c3, wN.geb("p"), sSrc);
      printf("#%c%cNE\t%s\t{2fp}%s\n",   c2, c3, wN.geb("p"), sSrc);
    } else{ // ook bN1
      printf("#%c%cW%c\t%s\t{2ms}%s\n",  c1, c2, c3, wN.geb("s"), sSrc); // geb 2 m
      printf("#%c%c%cI\t%s\t{2fs}%s\n",  c1, c2, c3, wN.geb("s"), sSrc); // geb 2 v
      printf("#%c%c%cW\t%s\t{2mp}%s\n",  c1, c2, c3, wN.geb("p"), sSrc); // geb 2m m
      printf("#%c%cW%cNE\t%s\t{2fp}%s\n",c1, c2, c3, wN.geb("p"), sSrc); // geb 2m v
    }

    /* onbepaalde wijs */

    if (iForm == F_NIF){
      if (c1=='I' /* bN1 ! */){
        printf("#LEIN%s\t%s\t{}%s\n",    sH + 2, wN.onbep(), sSrc);
        printf("#MEIN%s\tom %s\t{}%s\n", sH + 2, wN.onbep(), sSrc);
      } else if(c1=='W' /* bI1 ! */){
        printf("#LEIW%s\t%s\t{}%s\n",    sH + 1, wN.onbep(), sSrc);
        printf("#MEIW%s\tom %s\t{}%s\n", sH + 1, wN.onbep(), sSrc);
      } else{
        printf("#LEI%s\t%s\t{}%s\n",     sH + 1, wN.onbep(), sSrc);
        printf("#MEI%s\tom %s\t{}%s\n",  sH + 1, wN.onbep(), sSrc);
      }
    } else if (iForm == F_PIE){
      printf("#L%c%c%c\t%s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
      printf("#M%c%c%c\tom %s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
    } else if (iForm == F_POE){
      /* bestaat niet */
    } else if (iForm == F_HIF){
      if (iStam == S__23){
        printf("#LE%s%c\t%s\t{}%s\n",    s1, c3, wN.onbep(), sSrc);
        printf("#ME%s%c\tom %s\t{}%s\n", s1, c3, wN.onbep(), sSrc);
      } if (iStam == S___E){
        printf("#LE%sWT\t%s\t{}%s\n",    s1,     wN.onbep(), sSrc);
        printf("#ME%sWT\tom %s\t{}%s\n", s1,     wN.onbep(), sSrc);
      } else{
        printf("#LE%sI%c\t%s\t{}%s\n",   s1, c3, wN.onbep(), sSrc);
        printf("#ME%sI%c\tom %s\t{}%s\n",s1, c3, wN.onbep(), sSrc);
      }
    } else if (iForm == F_HOE){
      /* bestaat niet */
    } else if (iForm == F_HIT){
      char* sEnd= "";
      if (iStam == S___E){
        if (endsWith(sCore, "W")){
          sEnd= "T";
        } else{
          sEnd= "WT";
        }
      }
      if (startsWith(sCore, "ST")){
        printf("#LE%s%s\t%s\t{}%s\n",   sCore, sEnd, wN.onbep(), sSrc);
        printf("#ME%s%s\tom %s\t{}%s\n",   sCore, sEnd, wN.onbep(), sSrc);
      } else if (startsWith(sCore, "T")){
        printf("#LE%s%s\t%s\t{}%s\n",  sCore, sEnd, wN.onbep(), sSrc);
        printf("#ME%s%s\tom %s\t{}%s\n",  sCore, sEnd, wN.onbep(), sSrc);
      } else{
        printf("#LET%s%s\t%s\t{}%s\n",  sCore, sEnd, wN.onbep(), sSrc);
        printf("#MET%s%s\tom %s\t{}%s\n",  sCore, sEnd, wN.onbep(), sSrc);
      }
    /* hierna: QAL-stammen */
    } else if (!strcmp(sH, "AMR")){
      printf("#L%c%c%c\t%s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
      printf("#M%c%c%c\tom %s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
    } else if (bN13){
      printf("#L%cT\t%s\t{}%s\n",     c2, wN.onbep(), sSrc);
      printf("#M%cT\tom %s\t{}%s\n",     c2, wN.onbep(), sSrc);
    } else if (bE3){
      printf("#L%c%cWT\t%s\t{}%s\n",  c1, c2, wN.onbep(), sSrc);
      printf("#M%c%cWT\tom %s\t{}%s\n",  c1, c2, wN.onbep(), sSrc);
    } else if (bW2 || bI2 || b23){
      printf("#L%c%c%c\t%s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
      printf("#M%c%c%c\tom %s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
    } else if (bI1 || !strcmp(sH, "NSA")){
      printf("#L%c%cT\t%s\t{}%s\n",   c2, c3, wN.onbep(), sSrc);
      printf("#M%c%cT\tom %s\t{}%s\n",   c2, c3, wN.onbep(), sSrc);
    } else if (bA3){
      printf("#L%c%cW%c\t%s\t{}%s\n", c1, c2, c3, wN.onbep(), sSrc);
      printf("#L%c%c%c\t%s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
      printf("#M%c%cW%c\tom %s\t{}%s\n", c1, c2, c3, wN.onbep(), sSrc);
      printf("#M%c%c%c\tom %s\t{}%s\n",  c1, c2, c3, wN.onbep(), sSrc);
    } else{ // ook bN1
      printf("#L%c%cW%c\t%s\t{}%s\n", c1, c2, c3, wN.onbep(), sSrc);
      printf("#M%c%cW%c\tom %s\t{}%s\n", c1, c2, c3, wN.onbep(), sSrc);
    }
  }
  if (pfLog){
    fflush(pfLog);
    fclose(pfLog);
  }
} // main(void)

//------------------------------------------------------------------------------
