/****************************************************************************
** Leistungsorientierte Krankenanstaltenfinanzierung (LKF)                 **
** Scoring-C-Sourcen V2026.1                                               **
** (C) 2026 BMASGPK                                                        **
****************************************************************************
 ** xrecords.c - Routinen zur Interpretation der X-Satzarten                **
 **                                                                         **
 **		 Alex.Holzer@chello.at                                              **
 **       Bernhard.Pesec@dothealth.at                                       **
 ****************************************************************************/



#include "lkfint5.h"
#include "lkfstru5.h"
#include <ctype.h>

#define LKFLINEX_CHANGEBUFFERCHARS   4
#define AMB_A01_FIELDANZ           28
#define AMB_A02_FIELDANZ           10
#define AMB_A03_FIELDANZ           13


extern SATZART_FELD FeldSatzart, MBDSFeldKANR, MBDSFeldPATID, MBDSFeldABTPOS;

extern const LKF_SATZART_ERRORDEF LKFErrorX01fehlt, LKFErrorX02fehlt, LKFErrorSatzartKZfalsch, LKFErrorSatzartKZfehlt,
LKFErrorX01AUFNRmehrfach, LKFErrorX02PosMehrfach, LKFErrorX05FCmehrfach, LKFErrorX07FCmehrfach;


_SCORING_EXPORT int lkf_add_xline (LKF_CONTEXT *pContext, const char *line)
{ /* V2024.0 */
    return lkf_addOrReplace_xlineIdent (pContext, line, 0, 0);
}

_SCORING_EXPORT int lkf_replace_xline (LKF_CONTEXT *pContext, const char *line, const char *ident)
{ /* V2024.0 */
    return lkf_addOrReplace_xlineIdent(pContext, line, 0, ident);
}

_SCORING_EXPORT int lkf_delete_xline (LKF_CONTEXT *pContext, const char *ident) {
    return lkf_addOrReplace_xlineIdent(pContext, 0, 0, ident);
}

_SCORING_EXPORT int lkf_add_xlineIdent (LKF_CONTEXT *pContext, const char *line, char *ident)
{
    if (ident) {
        *ident = 0;
    }
    return lkf_addOrReplace_xlineIdent(pContext, line, ident, 0);
}

int lkf_addOrReplace_xlineIdent (LKF_CONTEXT *pContext, const char *line, char *addIdent, const char *ident)
{ /* V2024.0 */
    LKF_EXPANDED_LINE_INFO info;
    int ret;
    if (!line || !line[0] || line[0] == 10 || line[0] == 13 || line[0] == ' ')
        return -1;
    
    
    if (!pContext->pStamm2001)
    {
        if (!pContext->modelljahr)
            strcpy (pContext->errortext, "Modelljahr muss gesetzt sein, um diese Funktion aufzurufen");
        else
            sprintf (pContext->errortext, "Stammdaten fuer Modelljahr %d sind nicht geladen", pContext->modelljahr);
        return -3;
    }
    
    if (IsEmpty (line, 3))
    {
        if (IsEmpty (line, (int) strlen(line))) return -1;
        pContext->nReplaceSummensatz = 0;
        if (ident == 0) {
            lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &FeldSatzart, &LKFErrorSatzartKZfehlt, 0);
        }
        return -1;
    }
    
    if (!pContext->pSatzartDefs) {
        pContext->pSatzartDefs = SatzartDef_Init (pContext->modelljahr);
    }
    
    memset (&info, 0, sizeof (LKF_EXPANDED_LINE_INFO));
    info.addIdent = addIdent; /* V2024.0 */
    info.replaceIdent = ident; /* V2024.0 */
    
    switch (line[0])
    {
        case 'X':
            if (lkf_add_xline_aufX (pContext, line, &info)) ret = 0;
            else ret = -1;
            break;
        case 'I':
            ret = lkf_add_xline_intensiv (pContext, line, &info);
            break;
        case 'K':
            ret = lkf_add_xline_andere (pContext, line, &info);
            break;
        case 'A':
            if (pContext->modelljahr >= SATZART_A_MODEL || pContext->modelljahr == 0)
                ret = lkf_add_xline_andere(pContext, line, &info);
            else
                ret = 0;
            break;
        case 'G':
            ret = lkf_add_xline_andere(pContext, line, &info);
            break;
        case 'B':
            ret = lkf_add_xline_andere(pContext, line, &info);
            break;
        case 'L':
            ret = lkf_add_xline_andere(pContext, line, &info);
            break;
        case 'O': /* V2021.3 */
            if (pContext->modelljahr >= SATZART_O_MODEL || pContext->modelljahr == 0)
                ret = lkf_add_xline_andere(pContext, line, &info);
            else
                ret = 0;
            break;
        case 'S':
            return 0;
		case 'U': case 'V': case 'W':
		case 'Y': case 'Z':	/* V22.2 - private Satzarten */
			lkf_add_context_linebuf_line (pContext, line);
			return 0;

        default:
            return -2;
    }
    
    if (info.pError && ident == 0) {
        lkf_context_addimporterrorEx (pContext, lkf_add_context_linebuf_line_error (pContext, line), info.pFeld, info.pError, info.pSatzart, info.fieldPos, info.fieldLen);
    }
    
    return ret;
}

static int lkf_getSatzartNr (const char *ascii_nr)
{
    return ((ascii_nr[0]-'0') * 10 + (ascii_nr[1]-'0'));
}

static const SATZART_INFO *lkf_getSatzartInfo (LKF_CONTEXT *pContext, const char *line, int nSatzartNr)
{
    
    if (!pContext || !pContext->pSatzartDefs)
        return 0;
    
    switch (*line) {
        case 'X':
            switch (nSatzartNr) {
                case 1:
                    return pContext->pX01;
                case 2:
                    return pContext->pX02;
                case 3:
                    return pContext->pX03;
                case 4:
                    return pContext->pX04;
                case 5:
                    return pContext->pX05;
                case 6:
                    return pContext->pX06;
                case 7:
                    return pContext->pX07;
                default:
                    return 0;
            }
            break;
        case 'I':
            if (!pContext->pSatzartDefs->ppI || nSatzartNr < 0 || nSatzartNr > MAX_I_SATZART_NUM2011) return 0;
            return pContext->pSatzartDefs->ppI[nSatzartNr];
        case 'K':
            if (!pContext->pSatzartDefs->ppK || nSatzartNr < 0 || nSatzartNr > MAX_K_SATZART_NUM) return 0;
            return pContext->pSatzartDefs->ppK[nSatzartNr];
        case 'G':
            if (!pContext->pSatzartDefs->ppG || nSatzartNr < 0 || nSatzartNr > MAX_G_SATZART_NUM) return 0;
            return pContext->pSatzartDefs->ppG[nSatzartNr];
        case 'B':
            if (!pContext->pSatzartDefs->ppB || nSatzartNr < 0 || nSatzartNr > MAX_B_SATZART_NUM) return 0;
            return pContext->pSatzartDefs->ppB[nSatzartNr];
        case 'L':
            if (!pContext->pSatzartDefs->ppL || nSatzartNr < 0 || nSatzartNr > MAX_L_SATZART_NUM) return 0;
            return pContext->pSatzartDefs->ppL[nSatzartNr];
        case 'O':
            if (pContext->modelljahr < SATZART_O_MODEL)
                return 0;
            if (!pContext->pSatzartDefs->ppO || nSatzartNr < 0 || nSatzartNr > MAX_O_SATZART_NUM) return 0;
            return pContext->pSatzartDefs->ppO[nSatzartNr];
        case 'A':
            if (pContext->modelljahr < SATZART_A_MODEL)
                return 0;
            if (!pContext->pSatzartDefs->ppA || nSatzartNr < 0 || nSatzartNr > MAX_A_SATZART_NUM) return 0;
            return pContext->pSatzartDefs->ppA[nSatzartNr];
        default:
            return 0;
    }
}

static int lkf_getFeldAnzahl (LKF_CONTEXT *pContext, char typ, int nr)
{
    if (typ == 'X' && pContext->pSatzartDefs && pContext->pSatzartDefs->ppX && nr >= 0 && nr < MAX_X_SATZART_NUM) {
        return (int) pContext->pSatzartDefs->ppX[nr]->pSatzart->nCount;
    }
    else if (typ == 'I') {
        
        if (pContext->pSatzartDefs->ppI[nr] && nr < MAX_I_SATZART_NUM2011 && nr >= 0)
            return (int) pContext->pSatzartDefs->ppI[nr]->pSatzart->nCount;
        else
            return -1;
    }
    else if (typ == 'A') {
        switch (nr) {
            case 1:
                return AMB_A01_FIELDANZ;
            case 2:
                return AMB_A02_FIELDANZ;
            case 3:
                return AMB_A03_FIELDANZ;
            default:
                return 1;
        }
    }
    return 0;
}

static void lkf_toupper_string (char *key) {
    while (*key) {
        if (islower(*key)) *key = (char) toupper(*key);
        ++key;
    }
}

const char *lkf_aufenthalt_key_bm (char *key, const char *datensatzid, const char *aufdat) {
    if (!aufdat) aufdat = "";
    sprintf (key, "%-64.64s%-8.8s", datensatzid, aufdat);
    /* lkf_toupper_string(key); V21.3: weg */
    return key;
}

const char *lkf_aufenthalt_key_lf (char *key, const char *aufnr, const char *aufdat) {
    if (!aufdat) aufdat = "";
    
    sprintf(key, "%-12.12s%-8.8s", aufnr, aufdat);
    lkf_toupper_string(key);
    return key;
}

const char *lkf_aufenthalt_key (LKF_CONTEXT *pContext, LKF_EXPANDED_LINE *pLine, char *key) {
    if (pContext->isBM) {
        return lkf_aufenthalt_key_bm (key, pLine->fieldsById[X01_DATENSATZID], pLine->fieldsById[X01_AUFNAHMEDATUM]);
    }
    else if (pLine->fieldsById) {
        return lkf_aufenthalt_key_lf (key, pLine->fieldsById[GEN_AUFNR], pLine->fieldsById[X01_AUFNAHMEDATUM]);
    }
    else
        return 0;
}

static char *lkf_strncpy (char *dest, const char *src, unsigned long len)
{
    unsigned long srclen = (unsigned long) strlen(src);
    if (srclen > len) {
        return 0;
    }
    else if (srclen == len) {
        memcpy (dest, src, len);
    }
    else {
        memcpy (dest, src, srclen);
        memset (dest + srclen, ' ', len - srclen);
    }
    return dest;
}

static char lkf_getCharacter (LKF_EXPANDED_LINE *pLine, int fieldIndex)
{
    const char *v = pLine->fieldsById[fieldIndex];
    if (*v) return *v;
    return ' ';
}

char *lkf_getXLine_FieldValue (LKF_EXPANDED_LINE *pLine, int fieldIndex, char *buffer, unsigned long bufferLength) {
    return lkf_strncpy(buffer, pLine->fieldsById[fieldIndex], bufferLength);
}

int lkf_setXLine_FieldValue (LKF_EXPANDED_LINE *pLine, int fieldIndex, char *value) {
    int curLen;
    curLen = (int) strlen(pLine->fieldsById[fieldIndex]);
    strncpy (pLine->fieldsById[fieldIndex], value, curLen);
    return 0;
}


static int lkf_fill_xline_auf_exp (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{
    lkf_getXLine_FieldValue(pLine, X01_AUFNAHMEUHRZEIT, pAufenthalt->AUFZEIT, 4);
    pAufenthalt->BEHANDLUNGSART = lkf_getCharacter(pLine, X01_BEHANDLUNGSART);
    lkf_getXLine_FieldValue(pLine, X01_GEBURTSDATUM, pAufenthalt->GEBDAT, 8);
    lkf_getXLine_FieldValue(pLine, X01_ALTERSGRUPPE, pAufenthalt->ALTERSGRUPPE, 4);
    pAufenthalt->GESCHL = lkf_getCharacter(pLine, X01_GESCHLECHT);
    lkf_getXLine_FieldValue(pLine, X01_STAATB, pAufenthalt->STAATB, 3);
    lkf_getXLine_FieldValue(pLine, X01_STAATW, pAufenthalt->STAATW, 3);
    lkf_getXLine_FieldValue(pLine, X01_PLZW, pAufenthalt->PLZW, 6);
    lkf_getXLine_FieldValue(pLine, X01_GEMEINDECODE, pAufenthalt->GEMEINDEZIFFER, 5);
    pAufenthalt->AUFART = lkf_getCharacter(pLine, X01_AUFART1);
    pAufenthalt->AUFART2 = lkf_getCharacter(pLine, X01_AUFART2);
    pAufenthalt->TRANSPORTART = lkf_getCharacter(pLine, X01_TRANSPORTART);
    lkf_getXLine_FieldValue(pLine, X01_ZUGEWIESEN_AN, pAufenthalt->KANR_AN, 6);
    lkf_getXLine_FieldValue(pLine, X01_ZUGEWIESEN_VON, pAufenthalt->KANR_VON, 6);
    pAufenthalt->ENTART = lkf_getCharacter(pLine, X01_ENTART);
    lkf_getXLine_FieldValue(pLine, X01_ENTDAT, pAufenthalt->ENTDAT, 8);
    lkf_getXLine_FieldValue(pLine, X01_ENTZEIT, pAufenthalt->ENTZEIT, 4);
    lkf_getXLine_FieldValue(pLine, X01_LEIST_KOST, pAufenthalt->KOST, 2);
    pAufenthalt->ABRECH_RELEVANT = lkf_getCharacter(pLine, X01_ABRECHNUNGSRELEVANZ);
    pAufenthalt->FLAG = lkf_getCharacter(pLine, X01_PLAUSKZ);
    pAufenthalt->ORIG_PLAUS = pAufenthalt->FLAG; /* V21.2 */
    lkf_getXLine_FieldValue(pLine, X01_UEBERMITTLUNG_KOST, pAufenthalt->KOST_UE, 2);
    lkf_getXLine_FieldValue(pLine, X01_ABRECHQUARTAL, pAufenthalt->ABRECH_QUARTAL, 5);
    pAufenthalt->nM01ExtOffset = pLine->postFix ? lkf_auf_add_ext(pAufenthalt, pLine->postFix) : 0;
    return 0;
}

static unsigned int lkf_add_xline_abt (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{
	char abtposbuf[4];
    unsigned int i;
    LKF_AUFENTHALT_ABT *pAbt;
    pAufenthalt->nStatus = 0;
    
    if (pAufenthalt->abt_anz == pAufenthalt->abt_alloc) {
        pAufenthalt->abt_alloc += LKF_AUFENTHALT_EXTEND_ABT;
        pAufenthalt->abt = (LKF_AUFENTHALT_ABT *) LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_xline_abt", pAufenthalt->abt, sizeof (LKF_AUFENTHALT_ABT) * pAufenthalt->abt_alloc);
        if (!pAufenthalt->abt) {
            pAufenthalt->abt_alloc = pAufenthalt->abt_anz = 0;
            return LKF_OUTOFMEMORY_UINTERROR;
        }
    }
    
    i = pAufenthalt->abt_anz++;
    
    pAbt = pAufenthalt->abt + i;
    memset (pAbt, 0, sizeof (LKF_AUFENTHALT_ABT));
    
    lkf_getXLine_FieldValue(pLine, X02_POSITIONSNUMMER, abtposbuf, 3);
	abtposbuf[3] = 0;
	pAbt->abtposNumeric = (unsigned int) atoi(abtposbuf);
	memcpy(pAbt->ABTPOS, abtposbuf, 3);
    lkf_getXLine_FieldValue(pLine, X02_ABTFC, pAbt->ABTFC, 8);
    lkf_getXLine_FieldValue(pLine, X02_AUFDAT, pAbt->ABTDAT, 8);
    lkf_getXLine_FieldValue(pLine, X02_AUFZEIT, pAbt->ABTZEIT, 4);
    pAbt->PHYS_ANW = lkf_getCharacter(pLine, X02_PHYSANW);
    lkf_getXLine_FieldValue(pLine, X02_ENTDAT, pAbt->ENTDAT, 8);
    lkf_getXLine_FieldValue(pLine, X02_ENTZEIT, pAbt->ENTZEIT, 4);
    pAbt->ENTART = lkf_getCharacter(pLine, X02_ENTART);
    lkf_getXLine_FieldValue(pLine, X02_FACH_FC, pAbt->FACHFC, 8);
    lkf_getXLine_FieldValue(pLine, X02_PFLEG_FC, pAbt->PFLEGFC, 8);
    pAbt->ISNEONAT = lkf_getCharacter(pLine, X02_NEONAT);
    lkf_getXLine_FieldValue(pLine, X02_ALTERSGRUPPE, pAbt->ALTERSGRUPPE, 4);
    lkf_getXLine_FieldValue(pLine, X02_AUFNAHME_FUCO, pAbt->FUCOAUFNR, 12);
    
    if (pLine->postFix) {
        int ident_len;
        const char *trenn = strchr (pLine->postFix, '|');
        if (trenn)
            ident_len = (int) (trenn - pLine->postFix);
        else
            ident_len = (int) strlen (pLine->postFix);
        
        if (ident_len > 15)
            ident_len = 15;
        
        if (ident_len > 0)
            strncpy (pAbt->ABT_IDENT, pLine->postFix, ident_len);
        pAbt->ABT_IDENT[ident_len] = 0;
    }
    
    pAbt->nExtOffset = pLine->postFix ? lkf_auf_add_ext(pAufenthalt, pLine->postFix) : 0;
    return i;
}

static int lkf_add_xline_diag (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{
    LKF_AUFENTHALT_DIAG *pDiag;
    int index;
    const char *diagtyp = pLine->fieldsById[X03_DIAGTYP];
        
    if (pAufenthalt->diag_anz == pAufenthalt->diag_alloc) {
        pAufenthalt->diag_alloc += LKF_AUFENTHALT_EXTEND_DIAG;
        pAufenthalt->diag = (LKF_AUFENTHALT_DIAG *) LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_xline_diag", pAufenthalt->diag, sizeof (LKF_AUFENTHALT_DIAG) * pAufenthalt->diag_alloc);
        if (!pAufenthalt->diag) {
            pAufenthalt->diag_anz = pAufenthalt->diag_alloc = pAufenthalt->hdiag_anz = 0;
            return LKF_OUTOFMEMORY_ERROR;
        }
    }
    index = pAufenthalt->diag_anz;
    pDiag = pAufenthalt->diag + pAufenthalt->diag_anz++;
    memset (pDiag, 0, sizeof (LKF_AUFENTHALT_DIAG));
    lkf_getXLine_FieldValue(pLine, X03_DIAG, pDiag->DIAG, 7);
    lkf_getXLine_FieldValue(pLine, X03_DIAGTYP, pDiag->DIAGTYP, 2);
    pDiag->DIAGART = lkf_getCharacter(pLine, X03_DIAGART);
    pDiag->DIAGSTAT = lkf_getCharacter(pLine, X03_DIAGSTATIONAER);

    if (diagtyp[0] == 'H') {
        if (pAufenthalt->hdiag_anz == 0) {
            memcpy (pAufenthalt->HD, pDiag->DIAG, 6);
        }
        pAufenthalt->hdiag_anz++;
        pDiag->isHD = 1;
    }

        
    if (pLine->postFix) {
        
        const char *trenn;
        pDiag->nExtOffset = lkf_auf_add_ext(pAufenthalt, pLine->postFix);
        trenn = strchr(pLine->postFix, '|');
        
        if (trenn) {
            const char *nextTrenn = 0;
            int identlen;
            int diagposlen = (int) (trenn - pLine->postFix);
            
            if (!diagposlen)
                pDiag->DIAGPOS[0] = 0;
            else {
                if (diagposlen > 4) {
                    if (SAFEIS2018ORLATER(pAufenthalt)) { /* V2019.0 */
                        pDiag->DIAGPOS[0] = 0;
                        nextTrenn = trenn;
                    }
                    else {
                        diagposlen = 4;
                        strncpy (pDiag->DIAGPOS, pLine->postFix, diagposlen);
                        if (diagposlen < 4) pDiag->DIAGPOS[diagposlen] = 0;
                    }
                }
                
            }
            if (!nextTrenn)
                nextTrenn = strchr(++trenn, '|');
            if (nextTrenn)
                identlen = (int) (nextTrenn - trenn);
            else
                identlen = (int) strlen(trenn);
            
            if (identlen > 0) {
                if (identlen > 15) identlen = 15;
                if (identlen)
                    strncpy (pDiag->DIAG_IDENT, trenn, identlen);
                pDiag->DIAG_IDENT[identlen] = 0;
            }
        }
        else {
            strncpy(pDiag->DIAGPOS, pLine->postFix, 4);
        }
    }
    else
        pDiag->nExtOffset = 0;
    
    lkf_getXLine_FieldValue(pLine, X03_AUFNAHME_FUCO, pDiag->FUCOAUFNR, 12);

    return index;
}

static int lkf_add_xline_mel (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{
    LKF_AUFENTHALT_MEL *pMel;
    int index;
    pAufenthalt->nStatus = 0; /* V12.0 */
    
    if (pAufenthalt->mel_anz == pAufenthalt->mel_alloc) {
        pAufenthalt->mel_alloc += LKF_AUFENTHALT_EXTEND_MEL;
        pAufenthalt->mel = (LKF_AUFENTHALT_MEL *) LKF_REALLOC (pAufenthalt->pScoringContext, "lkf_add_xline_mel", pAufenthalt->mel, sizeof (LKF_AUFENTHALT_MEL) * pAufenthalt->mel_alloc);
        if (!pAufenthalt->mel) {
            pAufenthalt->mel_anz = pAufenthalt->mel_alloc = 0;
            return LKF_OUTOFMEMORY_ERROR;
        }
    }
    index = pAufenthalt->mel_anz;
    pMel = pAufenthalt->mel + pAufenthalt->mel_anz++;
    
    memset (pMel, 0, sizeof (LKF_AUFENTHALT_MEL));
    
    lkf_getXLine_FieldValue(pLine, X04_MEL, pMel->MEL, 10);
    pMel->cSeite = lkf_getCharacter(pLine, X04_SEITE);
    if (pMel->cSeite == ' ') pMel->cSeite = 0; /* V21.2 */
    pMel->MEL_RELEVANT = lkf_getCharacter(pLine, X04_ABRECHNUNGSRELEVANZ);
    lkf_getXLine_FieldValue(pLine, X04_ANZAHL, pMel->MELANZ, 4);
    lkf_getXLine_FieldValue(pLine, X04_DATUM, pMel->MELDAT, 8);
    lkf_getXLine_FieldValue(pLine, X04_UHRZEIT, pMel->MELZEIT, 5);
    lkf_getXLine_FieldValue(pLine, X04_FCLEIST, pMel->FCLEIST, 8);
    lkf_getXLine_FieldValue(pLine, X04_KALEIST, pMel->KALEIST, 6);
    memcpy (pMel->ORIG_MEL, pMel->MEL, 10);
    memcpy (pMel->ORIG_MELANZ, pMel->MELANZ, 4);
    pMel->mel_nr = -1;
    pMel->nMelAbtIndex = -1;
    
    if (pLine->postFix) {
        
        const char *trenn;
        pMel->nExtOffset = lkf_auf_add_ext(pAufenthalt, pLine->postFix);
        trenn = strchr(pLine->postFix, '|');
        
        if (trenn) {
            const char *nextTrenn = 0;
            int identlen;
            int melposlen = (int) (trenn - pLine->postFix);
            
            if (!melposlen)
                pMel->MELPOS[0] = 0;
            else {
                if (melposlen > 4) {
                    if (SAFEIS2018ORLATER(pAufenthalt)) { /* V2019.0 */
                        pMel->MELPOS[0] = 0;
                        nextTrenn = trenn;
                    }
                    else {
                        melposlen = 4;
                        strncpy (pMel->MELPOS, pLine->postFix, melposlen);
                        if (melposlen < 4) pMel->MELPOS[melposlen] = 0;
                    }
                }
				else { /* V2019.0 */
					strncpy(pMel->MELPOS, pLine->postFix, melposlen);
					if (melposlen < 4) pMel->MELPOS[melposlen] = 0;
				}
            }
            if (!nextTrenn) {
                nextTrenn = strchr(++trenn, '|');
            }
            
            if (nextTrenn)
                identlen = (int) (nextTrenn - trenn);
            else
                identlen = (int) strlen(trenn);

            if (identlen > 0) {
                if (identlen > 15) identlen = 15;
                if (identlen)
                    strncpy (pMel->MEL_IDENT, trenn, identlen);
                pMel->MEL_IDENT[identlen] = 0;
            }
        }
        else {
            strncpy (pMel->MELPOS, pLine->postFix, 4);
        }
    }
    else
        pMel->nExtOffset = 0;
    
    lkf_getXLine_FieldValue(pLine, X04_AUFNAHME_FUCO, pMel->FUCOAUFNR, 12);
    
    return index;
}

static int lkf_add_xline_scoring (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{ /* V21.2 */
    LKF_AUFENTHALT_SCORING_ORIG *pOrig;
    char buf[12];
    if (!pAufenthalt->pOrig) {
        pAufenthalt->pOrig = (LKF_AUFENTHALT_SCORING_ORIG *) LKF_CALLOC (pAufenthalt->pScoringContext, "lkf_add_xline_scoring", sizeof (LKF_AUFENTHALT_SCORING_ORIG), 1);
        if (!pAufenthalt->pOrig) {
            return LKF_OUTOFMEMORY_ERROR;
        }
    }
    pOrig = pAufenthalt->pOrig;
    
    lkf_getXLine_FieldValue(pLine, X05_INTENSIV, buf, 8);
    pOrig->INTZU = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_LEIST, buf, 8);
    pOrig->LDFPLK = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_TAG, buf, 8);
    pOrig->LDFPTK = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_MELZU, buf, 8);
    pOrig->MELZU = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_SUMME, buf, 8);
    pOrig->SCGES = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_SPEZ, buf, 8);
    pOrig->SCSPEZ = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_LEIST_UNT, buf, 8);
    pOrig->SCULK = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_TAG_UNT, buf, 8);
    pOrig->SCUTK = (long) lkf_GetInt(buf, 8, 0);
    lkf_getXLine_FieldValue(pLine, X05_TAG_OBEN, buf, 8);
    pOrig->VDZU = (long) lkf_GetInt(buf, 8, 0);
    
    return 0;
}

static const char *lkf_trimmed_kommentar (const char *komm) {
    if (!*komm) return 0;
    return komm;
}

static int lkf_add_xline_komm (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{
    unsigned int i;
    const char *komm[6];
    komm[0] = lkf_trimmed_kommentar(pLine->fieldsById[X07_KOMM1]);
    komm[1] = lkf_trimmed_kommentar(pLine->fieldsById[X07_KOMM2]);
    komm[2] = lkf_trimmed_kommentar(pLine->fieldsById[X07_KOMM3]);
    komm[3] = lkf_trimmed_kommentar(pLine->fieldsById[X07_KOMM4]);
    komm[4] = lkf_trimmed_kommentar(pLine->fieldsById[X07_KOMM5]);
    komm[5] = lkf_trimmed_kommentar(pLine->fieldsById[X07_KOMM6]);
    
    for (i = 0; i < 6; i++) {
        if (komm[i]) {
            lkf_add_komm(pAufenthalt, komm[i]);
        }
    }
    
    return 0;
}

static int lkf_add_xline_akwarn (LKF_AUFENTHALT *pAufenthalt, LKF_EXPANDED_LINE *pLine)
{
    unsigned int index = lkf_add_akwarn (pAufenthalt, pLine->fieldsById[X06_CODE], pLine->fieldsById[X06_WERT], pLine->fieldsById[X06_KOMMENTAR]);
    if (index == LKF_OUTOFMEMORY_UINTERROR) return LKF_OUTOFMEMORY_ERROR;
    if (index == 0xFFFFFFFF) {
        return -1;
    }
    return (int) index;
}


int lkf_add_xline_auf (LKF_AUFENTHALT *pAufenthalt, const char *line, LKF_EXPANDED_LINE_INFO *pInfo) {

    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    LKF_EXPANDED_LINE *expLine = lkf_create_expandLine(pContext, line, LKFLINEX_CHANGEBUFFERCHARS, pInfo, "lkf_add_xline_auf");
    
    if (expLine == 0)
        return -1;
    
    if (expLine->satzartNr == 1) {
        pContext->Count_X[0]++;
        
        lkf_strncpy (pAufenthalt->KANR, expLine->fieldsById[GEN_KANR], LKF_AUFENTHALT_KANR_LEN);
        lkf_strncpy (pAufenthalt->PATID, expLine->fieldsById[GEN_AUFNR], LKF_AUFENTHALT_PATID_LEN_AB2017);
        lkf_strncpy(pAufenthalt->AUFDAT, expLine->fieldsById[X01_AUFNAHMEDATUM], 8);
        
        if (pContext->isBM) {
            if (pContext->isBM == 2) {
                lkf_aufenthalt_key_bm(pAufenthalt->UCASE_PATID, pAufenthalt->PATID, pAufenthalt->AUFDAT);
                memset (pAufenthalt->PATID, ' ', 10);
            }
            else {
                lkf_aufenthalt_key_bm(pAufenthalt->UCASE_PATID, expLine->fieldsById[X01_DATENSATZID], pAufenthalt->AUFDAT);
            }
        }
        else
        {
            lkf_aufenthalt_key_lf(pAufenthalt->UCASE_PATID, pAufenthalt->PATID, pAufenthalt->AUFDAT);
            
        }
        
        lkf_fill_xline_auf_exp (pAufenthalt, expLine);
        lkf_free_expandLine(pContext, expLine);
        return 0;
    }
    else
    {
        switch (expLine->satzartNr) {
            case 2:
                pContext->Count_X[1]++;
                lkf_add_xline_abt(pAufenthalt, expLine);
                break;
            case 3:
                pContext->Count_X[2]++;
                lkf_add_xline_diag(pAufenthalt, expLine);
                break;
            case 4:
                pContext->Count_X[3]++;
                lkf_add_xline_mel(pAufenthalt, expLine);
                break;
            case 5:
                pContext->Count_X[4]++;
                lkf_add_xline_scoring(pAufenthalt, expLine);
                break;
            case 6:
                pContext->Count_X[5]++;
                if (lkf_add_xline_akwarn(pAufenthalt, expLine) < 0) {
                    // BPE: ok to ignore?
                }
                break;
            case 7:
                pContext->Count_X[6]++;
                lkf_add_xline_komm(pAufenthalt, expLine);
                break;
            default:
                return -1;
        }
    }
    return 0;
}

_SCORING_EXPORT int lkf_replace_aufenthalt (LKF_AUFENTHALT *pAufenthalt, const char *x01)
{ /* V2025.0 */
    int ret;
    ret = lkf_auf_replaceLine(pAufenthalt, x01, "AUF:X01");
    if (ret) {
        return ret;
    }
    lkf_reset_aufenthalt_internal(pAufenthalt, 1);
    return 0;
}

_SCORING_EXPORT int lkf_delete_aufenthalt (LKF_AUFENTHALT *pAufenthalt)
{ /* V2025.0 */
    LKF_CONTEXT *pContext;
    unsigned int i;
    
    pContext = pAufenthalt->pScoringContext;
    if (pContext == 0) {
        return -1; // NO CONTEXT
    }
    
    for (i = 0; i < pContext->patient_anz; i++) {
        if (pContext->ppAufenthalt[i] == pAufenthalt) {
            lkf_free_aufenthalt(pAufenthalt);
            pContext->patient_anz -= 1;
            if (i < pContext->patient_anz) {
                memmove (pContext->ppAufenthalt + i, pContext->ppAufenthalt + i + 1, (pContext->patient_anz - i) * sizeof (LKF_AUFENTHALT *));
            }
            return 0;
        }
    }
    return -2; // NOT FOUND
}

_SCORING_EXPORT LKF_AUFENTHALT *lkf_auf_addCopy (LKF_AUFENTHALT *pAufenthalt, const char *x01) 
{ /* V2025.0 */
    LKF_AUFENTHALT *pAufenthaltCopy;
    unsigned int i, lineCount;
    char line[1024];
    
    pAufenthaltCopy = lkf_alloc_aufenthalt_context(pAufenthalt->pScoringContext);
    if (pAufenthaltCopy == 0) {
        strcpy (pAufenthalt->pScoringContext->errortext, "lkf_auf_addCopy: OUTOFMEMORY");
        return 0;
    }
    
    if (lkf_add_xline_auf(pAufenthaltCopy, x01, 0)) {
        lkf_free_aufenthalt(pAufenthalt);
        return 0;
    }
    
    lineCount = lkf_auf_getlineanz(pAufenthalt);
    for (i = 1; i < lineCount; i++) {
        lkf_auf_getline(pAufenthalt, i, line);
        lkf_add_xline_auf(pAufenthaltCopy, line, 0);
    }
    
    lineCount = lkf_auf_getintlineanz(pAufenthalt);
    for (i = 0; i < lineCount; i++) {
        lkf_auf_getintline(pAufenthalt, i, line);
        lkf_add_xline_auf(pAufenthalt, line, 0);
    }
    
    return pAufenthaltCopy;
}

_SCORING_EXPORT int lkf_auf_replaceLine (LKF_AUFENTHALT *pAufenthalt, const char *line, const char *ident) {
    LKF_EXPANDED_LINE *expLine;
    int index;
    int indexToReplace;
    if (memcmp (ident, "AUF:X0", 6)) {
        if (!memcmp (ident, "INX:", 4)) {
            return lkf_auf_replaceIntLine(pAufenthalt, line, ident);
        }
        return LKFCERROR_INVALIDID;
    }
    
    expLine = lkf_create_expandLine(pAufenthalt->pScoringContext, line, LKFLINEX_CHANGEBUFFERCHARS, 0, "lkf_auf_replaceLine");
    if (expLine == 0) {
        return LKFCERROR_INVALIDFORMAT;
    }

    switch (ident[6]) {
        case '1':
            lkf_fill_xline_auf_exp (pAufenthalt, expLine);
            break;
        case '2':
             indexToReplace = atoi (ident + 8);
             index = lkf_add_xline_abt(pAufenthalt, expLine);
             if (index == LKF_OUTOFMEMORY_UINTERROR) return LKF_OUTOFMEMORY_ERROR;
             memcpy (pAufenthalt->abt + indexToReplace, pAufenthalt->abt + index, sizeof(LKF_AUFENTHALT_ABT));
             pAufenthalt->abt_anz--;
             return 0;
         case '3':
            indexToReplace = atoi (ident + 8);
            if (pAufenthalt->diag[indexToReplace].isHD) {
                if (--pAufenthalt->hdiag_anz == 0) {
                    memset (pAufenthalt->HD, 0, LKF_AUFENTHALT_DIAG_LEN);
                }
                else if (!memcmp (pAufenthalt->diag[indexToReplace].DIAG, pAufenthalt->HD, LKF_AUFENTHALT_DIAG_LEN)) {
                    unsigned int i;
                    memset (pAufenthalt->HD, 0, LKF_AUFENTHALT_DIAG_LEN);
                    for (i = 0; i < pAufenthalt->diag_anz; i++) {
                        if (pAufenthalt->diag[i].isHD) {
                            memcpy(pAufenthalt->HD, pAufenthalt->diag[i].DIAG, LKF_AUFENTHALT_DIAG_LEN);
                            break;
                        }
                    }
                }
            }
            index = lkf_add_xline_diag(pAufenthalt, expLine);
            if (index == LKF_OUTOFMEMORY_ERROR) return LKF_OUTOFMEMORY_ERROR;
            memcpy (pAufenthalt->diag + indexToReplace, pAufenthalt->diag + index, sizeof(LKF_AUFENTHALT_DIAG));
             pAufenthalt->diag_anz --;
             break;
         case '4':
             indexToReplace = atoi (ident + 8);
             index = lkf_add_xline_mel(pAufenthalt, expLine);
             if (index == LKF_OUTOFMEMORY_ERROR) return LKF_OUTOFMEMORY_ERROR;
             memcpy (pAufenthalt->mel + indexToReplace, pAufenthalt->abt + index, sizeof(LKF_AUFENTHALT_MEL));
             memcpy (pAufenthalt->mel + indexToReplace, pAufenthalt->mel + index, sizeof(LKF_AUFENTHALT_MEL));
             pAufenthalt->mel_anz--;
             return 0;
             break;
         case '5':
             index = lkf_add_xline_scoring(pAufenthalt, expLine);
             if (index == LKF_OUTOFMEMORY_ERROR) return LKF_OUTOFMEMORY_ERROR;
             break;
         case '6':
             indexToReplace = atoi (ident + 8);
             index = lkf_add_xline_akwarn(pAufenthalt, expLine);
             if (index == LKF_OUTOFMEMORY_ERROR) return LKF_OUTOFMEMORY_ERROR;

             memcpy (pAufenthalt->akwarn + indexToReplace, pAufenthalt->akwarn + index,
                     sizeof(LKF_AUFENTHALT_AKWARN));
             pAufenthalt->akwarn_anz--;
             break;
        case '7':
            index = lkf_add_xline_komm(pAufenthalt, expLine);
            if (index == LKF_OUTOFMEMORY_ERROR) return LKF_OUTOFMEMORY_ERROR;

        default:
            return LKFCERROR_INVALIDID;
    }
    return LKFCERROR_OK;
}

int lkf_add_xline_auf_intensiv (LKF_AUFENTHALT *pAufenthalt, const char *line, LKF_EXPANDED_LINE_INFO *pInfo) {
    LKF_EXPANDED_LINE *pAmbLine;
    LKF_CONTEXT *pContext;
    
    pContext = pAufenthalt->pScoringContext;
    
    if (pContext->pSatzartDefs == 0) {
        pContext->pSatzartDefs = lkf_Satzart_getDefinition((unsigned int) pContext->modelljahr);
    }
    
    pAmbLine = lkf_create_expandLine(pContext, line, 0, pInfo, "lkf_add_xline_auf_intensiv");
    
    if (pAmbLine == 0) {
        if (*pContext->outOfMemory) return LKF_OUTOFMEMORY_ERROR;
        return -1;
    }
		
    
    if (pAmbLine->pSatzartInfo != 0) {
        unsigned int ret;
        if (!pAufenthalt->pIntensiv) {
            pAufenthalt->pIntensiv = lkf_create_expandedLines(pContext, 10);
            if (!pAufenthalt->pIntensiv) {
                lkf_set_outOfMemory(pContext, "lkf_add_xline_auf_intensiv", 0);
                return LKF_OUTOFMEMORY_ERROR;
            }
        }

        ret = lkf_add_expandLine(pAufenthalt->pIntensiv, pAmbLine);
        if (ret == LKF_OUTOFMEMORY_UINTERROR) {
            return LKF_OUTOFMEMORY_ERROR;
        }
        return 0;
    }
    return -2;
}

LKF_AUFENTHALT *lkf_add_xline_aufX (LKF_CONTEXT *pContext, const char *line, LKF_EXPANDED_LINE_INFO *pInfo)
{
    const LKF_SATZART_ERRORDEF *pErrorDef;
    
    int aufenthalt_index;
    
    LKF_AUFENTHALT *pAufenthalt;
    LKF_EXPANDED_LINE *expLine = lkf_create_expandLine(pContext, line, LKFLINEX_CHANGEBUFFERCHARS, pInfo, "lkf_add_xline_aufX");
    
    if (expLine == 0) {
        if (pInfo && pInfo->pError) {
            lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), pInfo->pFeld, pInfo->pError, pInfo->pSatzart);
        }
        return 0;
    }
    
    if (expLine->fieldsById == 0)
        return 0;
    
    if (!pContext->noStamm) {
        pErrorDef = lkf_importcheck_kanr (pContext, expLine->fieldsById[GEN_KANR], 0);
        if (pErrorDef)
        {
            lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &MBDSFeldKANR, pErrorDef, 0);
            lkf_free_expandLine(pContext, expLine);
            return 0;
        }
    }

    if (expLine->satzartNr == 1) {
        pContext->Count_X[0]++;
        
        pAufenthalt = lkf_alloc_aufenthalt ();
        if (!pAufenthalt) {
            lkf_set_outOfMemory(pContext, "lkf_add_xline_aufX", 0);
            return 0;
        }
        pAufenthalt->pScoringContext = pContext;
        lkf_strncpy (pAufenthalt->KANR, expLine->fieldsById[GEN_KANR], LKF_AUFENTHALT_KANR_LEN);
        lkf_strncpy (pAufenthalt->PATID, expLine->fieldsById[GEN_AUFNR], LKF_AUFENTHALT_PATID_LEN_AB2017);
        lkf_strncpy(pAufenthalt->AUFDAT, expLine->fieldsById[X01_AUFNAHMEDATUM], 8);
        
        if (pContext->isBM) {
            if (pContext->isBM == 2) {
                lkf_aufenthalt_key_bm(pAufenthalt->UCASE_PATID, pAufenthalt->PATID, pAufenthalt->AUFDAT);
                memset (pAufenthalt->PATID, ' ', 12);
            }
            else {
                lkf_aufenthalt_key_bm(pAufenthalt->UCASE_PATID, expLine->fieldsById[X01_DATENSATZID], pAufenthalt->AUFDAT);
            }
        }
        else
        {
            lkf_aufenthalt_key_lf(pAufenthalt->UCASE_PATID, pAufenthalt->PATID, pAufenthalt->AUFDAT);
            
        }
        
        aufenthalt_index = lkf_insert_aufenthalt(pContext, pAufenthalt);
        if (aufenthalt_index < 0) {
            lkf_free_aufenthalt (pAufenthalt);
            
            if (aufenthalt_index != LKF_OUTOFMEMORY_ERROR) {
                unsigned int lineBufError;
                
                lineBufError = lkf_add_context_linebuf_line_error (pContext, line);
                if (lineBufError != LKF_OUTOFMEMORY_UINTERROR) {
                    if (pContext->isBM)
                        lkf_context_addimporterror (pContext, lineBufError, pContext->patidPos[1], &LKFErrorX01AUFNRmehrfach, 0);
                    else
                        lkf_context_addimporterror (pContext, lineBufError, &MBDSFeldPATID, &LKFErrorX01AUFNRmehrfach, 0);
                }
                lkf_free_expandLine(pContext, expLine);
            }
            return 0;
        }
        
        if (!pContext->cmb_jahr && (pContext->flags & LKFCONTEXT_IMPLICIT_YEAR))
        {
            int nYear;
            char sYear[5];
            strncpy (sYear, line + 67, 4);
            sYear[4] = 0;
            nYear = atoi (sYear);
            if (nYear >= LKF_YEAR_FIRST && nYear <= LKF_YEAR_LATEST )
                pContext->cmb_jahr = nYear;
        }
        
        lkf_fill_xline_auf_exp (pAufenthalt, expLine);
        
        lkf_free_expandLine(pContext, expLine);
        return pAufenthalt;
    }
    else
    {
        char key[LKF_AUFENTHALT_LONGID_LEN_AB2017+2];
        int ret;
        lkf_aufenthalt_key(pContext, expLine, key);
        pAufenthalt = lkf_find_aufenthalt (pContext, 0, key);
 
         if (pAufenthalt != 0) {
        
            switch (expLine->satzartNr) {
                case 2:
                    pContext->Count_X[1]++;
                    ret = (int) lkf_add_xline_abt(pAufenthalt, expLine);
                    if (ret == LKF_OUTOFMEMORY_UINTERROR) return 0;
                    break;
                case 3:
                    pContext->Count_X[2]++;
                    ret = lkf_add_xline_diag(pAufenthalt, expLine);
                    if (ret == LKF_OUTOFMEMORY_ERROR) return 0;
                    break;
                case 4:
                    pContext->Count_X[3]++;
                    ret = lkf_add_xline_mel(pAufenthalt, expLine);
                    if (ret == LKF_OUTOFMEMORY_ERROR) return 0;
                    break;
                case 5:
                    pContext->Count_X[4]++;
                    ret = lkf_add_xline_scoring(pAufenthalt, expLine);
                    if (ret == LKF_OUTOFMEMORY_ERROR) return 0;
                    break;
                case 6:
                    pContext->Count_X[5]++;
                    ret = lkf_add_xline_akwarn(pAufenthalt, expLine);
                    if (ret == LKF_OUTOFMEMORY_ERROR) return 0;
                    break;
                case 7:
                    pContext->Count_X[6]++;
                    ret = lkf_add_xline_komm(pAufenthalt, expLine);
                    if (ret == LKF_OUTOFMEMORY_ERROR) return 0;
                    break;
                default:
                    lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &FeldSatzart, &LKFErrorSatzartKZfalsch, 0);
                    lkf_free_expandLine(pContext, expLine);
                    return 0;
            }
        } else {
            if (pContext->isBM) {
                lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &MBDSFeldPATID, &LKFErrorX01fehlt, 0);
            }
            else {
                lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &MBDSFeldPATID, &LKFErrorX01fehlt, 0);
            }
            lkf_free_expandLine(pContext, expLine);
            return 0;
        }
    }
    lkf_free_expandLine(pContext, expLine);
    return pAufenthalt;
}

int lkf_add_xline_andere (LKF_CONTEXT *pContext, const char *line, LKF_EXPANDED_LINE_INFO *pInfo)
{
    int ret;
    LKF_EXPANDED_LINE *pAmbLine;
    const char *kanrbuf;
    const LKF_SATZART_ERRORDEF *pErrorDef;
    const SATZART_INFO* pSatzartInfo;
    int nSatzartNr;
    if (line == 0 && pInfo->replaceIdent) {
        unsigned int index = atoi (pInfo->replaceIdent + 8);
        return lkf_delete_addLine(pContext, index);
    }
    
    nSatzartNr = lkf_getSatzartNr(line + 1);
    pSatzartInfo = lkf_getSatzartInfo(pContext, line, nSatzartNr);
    
    if (!pSatzartInfo && (line[0] == 'O' || line[0] == 'A')) {
        unsigned int ret = lkf_add_context_linebuf_line (pContext, line);
        if (ret == LKF_OUTOFMEMORY_UINTERROR) return LKF_OUTOFMEMORY_ERROR;
        return (int) ret;
    }
    
    if (!pSatzartInfo) {
        pErrorDef = &LKFErrorSatzartKZfalsch;
        lkf_context_addimporterror(pContext, lkf_add_context_linebuf_line_error(pContext, line), 0, pErrorDef, 0);
        return -2;
    }
    
#ifdef SUPPORT_PRE2017
    if (pContext->modelljahr == 2017 && (pContext->flags & LKFCONTEXT_SATZART_INPUT_M)) {
        pAmbLine = lkf_create_expandLineWithPre2017Compatibility (pContext, line, pSatzartInfo, 0, pInfo);
    } else {
        pAmbLine = lkf_create_expandLine(pContext, line, 0, pInfo);
    }
#else
    pAmbLine = lkf_create_expandLine(pContext, line, 0, pInfo, "lkf_add_xline_andere");
#endif
    
    if (pAmbLine == 0)
        return -1;
    
    if (pInfo && pInfo->replaceIdent) {
        unsigned int index = atoi (pInfo->replaceIdent + 8);
        return lkf_replace_addLine(pContext, pAmbLine, index);
    }
    
    
    if (line[0] == 'O') { /* V2021.3 */
        
    }
    else if (line[0] != 'L' || pContext->modelljahr < 2019 || pAmbLine->fieldsById[L01_LEISTUNGSBEREICH] == 0 || strcmp (pAmbLine->fieldsById[L01_LEISTUNGSBEREICH],"M") ) {
    
        kanrbuf = pAmbLine->fieldsById[GEN_KANR];
        
        pErrorDef = lkf_importcheck_kanr (pContext, kanrbuf, line[0] == 'B' ? 1 : 0);
        if (pErrorDef)
        {
            if (line[0] != 'L') {
                lkf_context_addimporterror(pContext, lkf_add_context_linebuf_line_error(pContext, line), pSatzartInfo->ppRef[GEN_KANR], pErrorDef, pSatzartInfo);
            }
            return -2;
        }
    }
    
    switch (line[0]) {
        case 'K':
            pContext->Count_K[nSatzartNr-1]++;
            break;
        case 'L':
            pContext->Count_L[nSatzartNr-1]++;
            break;
        case 'B':
            pContext->Count_B[nSatzartNr-1]++;
            break;
        case 'G':
            pContext->Count_G[nSatzartNr-1]++;
            break;
        case 'O':
            pContext->Count_O[nSatzartNr-1]++;
            break;
        case 'A':
            pContext->Count_A[nSatzartNr-1]++;
        default:
            break;
    }
    
    if (!pContext->cmb_jahr && (pContext->flags & LKFCONTEXT_IMPLICIT_YEAR))
    {
        int nYear = 0;
        if (Satzart_GetValueIntExp (pAmbLine, pSatzartInfo->ppRef[GEN_JAHR],&nYear) != LKF_FIELD_ERROR && nYear >= LKF_YEAR_FIRST && nYear <= LKF_YEAR_LATEST )
            pContext->cmb_jahr = nYear;
    }
    
    if (line[0] == 'L') {
        switch (nSatzartNr) {
            case 1:
                ret = lkf_add_xline_spez(pContext, pAmbLine, line);
                break;
            case 2:
                ret = lkf_add_xline_kost(pContext, pAmbLine);
                break;
            case 3:
                ret = lkf_add_xline_melka(pContext, pAmbLine);
                break;
            case 4:
                ret = lkf_add_xline_melkatkl(pContext, pAmbLine);
                break;
            default:
                ret = 0;
                break;
        }
        if (ret == LKF_OUTOFMEMORY_ERROR) return ret;
    }
    else if (line[0] == 'O') {
        switch (nSatzartNr) {
            case 2:
                ret = lkf_add_xline_oemelka (pContext, pAmbLine);
                break;
            default:
                ret = 0;
                break;
        }
        if (ret == LKF_OUTOFMEMORY_ERROR) return ret;
    }
    
    lkf_add_context_expLine (pContext, pAmbLine);
    
    return 0;
}

int lkf_add_xline_intensiv (LKF_CONTEXT *pContext, const char *line, LKF_EXPANDED_LINE_INFO *pInfo) {
    
    LKF_EXPANDED_LINE *pAmbLine;

#ifdef SUPPORT_PRE2017
    if (pContext->modelljahr == 2017 && (pContext->flags & LKFCONTEXT_SATZART_INPUT_M)) {
        const SATZART_INFO *pSatzartInfo = lkf_getSatzartInfo(pContext, line, lkf_getSatzartNr(line + 1));
        pAmbLine = lkf_create_expandLineWithPre2017Compatibility (pContext, line, pSatzartInfo, 0, pInfo);
    } else {
        pAmbLine = lkf_create_expandLine(pContext, line, 0, pInfo);
    }
#else
    pAmbLine = lkf_create_expandLine(pContext, line, 0, pInfo, "lkf_add_xline_intensiv");
#endif
    
	if (pAmbLine == 0) {
		pContext->failedILines++;
		return -1;
	}
    
    if (pAmbLine->pSatzartInfo != 0) {
        LKF_AUFENTHALT *pAufenthalt;
        char key[LKF_AUFENTHALT_LONGID_LEN_AB2017+2];
        unsigned int ret;

        if (pContext->isBM) {
            lkf_aufenthalt_key_bm(key, pAmbLine->fieldsById[I11_DATENSATZID], pAmbLine->fieldsById[I11_AUFNAHMEDATUM]);
        }
        else {
            lkf_aufenthalt_key_lf(key, pAmbLine->fieldsById[GEN_AUFNR], pAmbLine->fieldsById[I11_AUFNAHMEDATUM]);
        }
        
        pAufenthalt = lkf_find_aufenthalt (pContext, 0, key);
        
        if (pAufenthalt == 0) {
            if (pContext->isBM) {
                lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &MBDSFeldPATID, &LKFErrorX01fehlt, 0);
            }
            else {
                lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &MBDSFeldPATID, &LKFErrorX01fehlt, 0);
            }
			pContext->zuordnungILine++;

			lkf_free_expandLine(pContext, pAmbLine);
            return -2;
        }
        else
        { /* V021.2 */
            const char *abtPos = pAmbLine->fieldsById[GEN_ABTPOS];
            if (abtPos) {
                unsigned int i;
                for (i = 0; i < pAufenthalt->abt_anz && memcmp (pAufenthalt->abt[i].ABTPOS, abtPos, 3); i++) ;
                if (i >= pAufenthalt->abt_anz)
                {
                    int abtPosNumeric = atoi(abtPos);
                    if (abtPos > 0)
                    {   /* V2021.3: numerisch idente Intensiv-AbtPos akzeptieren */
                        i = 0;
                        for (i = 0; i < pAufenthalt->abt_anz && abtPosNumeric != pAufenthalt->abt[i].abtposNumeric; i++) ;
                    }

                    if (i >= pAufenthalt->abt_anz)
                    {
                        lkf_context_addimporterror  (pContext, lkf_add_context_linebuf_line_error (pContext, line), &MBDSFeldABTPOS, &LKFErrorX02fehlt, 0);
                        return -3;
                    }
                }
            }
        }

        if (!pAufenthalt->pIntensiv) {
            pAufenthalt->pIntensiv = lkf_create_expandedLines(pContext, 10);
            if (!pAufenthalt->pIntensiv) {
                lkf_set_outOfMemory(pContext, "lkf_add_xline_auf_intensiv", 0);
                return LKF_OUTOFMEMORY_ERROR;
            }
        }
		pContext->importedILines++;
        ret = lkf_add_expandLine(pAufenthalt->pIntensiv, pAmbLine);
        if (ret == LKF_OUTOFMEMORY_UINTERROR) {
            return LKF_OUTOFMEMORY_ERROR;
        }
    } else {
        lkf_free_expandLine(pContext, pAmbLine);
		pContext->failedILines++;
        lkf_context_addimporterror (pContext, lkf_add_context_linebuf_line_error (pContext, line), &FeldSatzart, &LKFErrorSatzartKZfalsch, 0);
    }
    return 0;
}

/************************************************************************
 ** lkf_add_line_pat_bypass_check: Wie add_line_pat (siehe unten), nur  **
 ** dass KANR und PATID nicht mehr ¸berpr¸ft werden.                    **
 ************************************************************************/

#define LKF_TRENN '|'

static int lkf_auf_write_xline_feld (char *line, const SATZART_FELD *feld, const char *wert, int sourcelen) {
    
    int len;
    
    if (!wert) {
        *line = LKF_TRENN;
        return 1;
    }
    len = (int) feld->nLen;
    if (sourcelen && sourcelen < len) len = sourcelen;
    while (len > 0 && *wert == ' ') {
        --len;
        ++wert;
    }
    if (len == 0) {
        *line = LKF_TRENN;
        return 1;
    }
    
    strncpy (line, wert, len);
    line[len] = 0;
    len = (int) strlen(line);
    while (len && line[len-1] == ' ') --len;
    line[len] = LKF_TRENN;
    return len + 1;
}

int lkf_auf_write_satzart (LKF_AUFENTHALT *pAufenthalt, const SATZART_INFO *pSatzart, unsigned int count, const int *feldIndices, const char **feldWerte, const char *ext, char *line)
{
    return lkf_write_satzart(pAufenthalt->pScoringContext, pSatzart, count, feldIndices, feldWerte, ext, line);
}

int lkf_write_satzart (LKF_CONTEXT *pContext, const SATZART_INFO *pSatzart, unsigned int count, const int *feldIndices, const char **feldWerte, const char *ext, char *line) {
    unsigned int i;
    const char *f[100];
    char resultBuf[1024];
    int resultBufPos, pos, terminatorPos, curPos;
    resultBufPos = 0;

    if (!pSatzart) return 0;

    memset((void *) f, 0, sizeof(f));
    sprintf (line, "%3.3s%c", pSatzart->pSatzart->sPrefix, LKF_TRENN);
    for (i = 0; i < count; i++) {
        if (feldIndices[i] >= 0) {
            const SATZART_FELD *pFeld = pSatzart->ppRef[feldIndices[i]];
            if (pFeld) {
                const SATZART_FELD *pFeld = pSatzart->ppRef[feldIndices[i]];
                if (pFeld) {
                    f[pFeld->nFieldNum] = feldWerte[i];
                }
            }
        }
        else {
            resultBufPos += sprintf (resultBuf + resultBufPos, "%s|", feldWerte[i]);
        }
    }
    
    pos = 4;

    for (i = 0; i < pSatzart->pSatzart->nSignificantCount; i++) {
        const SATZART_FELD *pFeld = pSatzart->pSatzart->Felder + i;
        pos += lkf_auf_write_xline_feld(line + pos, pFeld, f[pFeld->nFieldNum], 0);
    }
    terminatorPos = pos - 1;
    
    for (; i < pSatzart->pSatzart->nCount; i++) {
        const SATZART_FELD *pFeld = pSatzart->pSatzart->Felder + i;
        curPos = lkf_auf_write_xline_feld(line + pos, pFeld, f[pFeld->nFieldNum], 0);
        pos += curPos;
        if (curPos > 1) {
            terminatorPos = pos - 1;
        }
    }
    
    if (resultBufPos) {
        strcpy (line + pos, resultBuf);
        pos += resultBufPos;
        terminatorPos += resultBufPos;
    }
    
    if (ext && *ext) {
        strcpy (line + pos, ext);
    }
    else
        line[terminatorPos] = 0; /* V21.2 - kein End Delimiter */
    return 1; /* V21.1 */
}

int lkf_auf_xline_root (LKF_AUFENTHALT *pAufenthalt, char *line)
{
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_GEBURTSDATUM, X01_AUFNAHMEDATUM, X01_AUFNAHMEUHRZEIT, X01_BEHANDLUNGSART, X01_GESCHLECHT, X01_STAATB, X01_STAATW, X01_PLZW, X01_GEMEINDECODE, X01_AUFART1, X01_AUFART2, X01_TRANSPORTART, X01_ZUGEWIESEN_VON, X01_ZUGEWIESEN_AN, X01_ENTART, X01_ENTDAT, X01_ENTZEIT, X01_LEIST_KOST, X01_ABRECHNUNGSRELEVANZ, X01_PLAUSKZ, X01_UEBERMITTLUNG_KOST, X01_ABRECHQUARTAL, X01_ALTERSGRUPPE};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_ALTERSGRUPPE, X01_AUFNAHMEDATUM, X01_AUFNAHMEUHRZEIT, X01_BEHANDLUNGSART, X01_GESCHLECHT, X01_STAATB, X01_STAATW, X01_PLZW, X01_GEMEINDECODE, X01_AUFART1, X01_AUFART2, X01_TRANSPORTART, X01_ZUGEWIESEN_VON, X01_ZUGEWIESEN_AN, X01_ENTART, X01_ENTDAT, X01_ENTZEIT, X01_LEIST_KOST, X01_ABRECHNUNGSRELEVANZ, X01_PLAUSKZ, X01_UEBERMITTLUNG_KOST, X01_ABRECHQUARTAL};
    
    const char *felder[30];
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    const char *sAdditional;
    
    if (!pContext || !pContext->pX01) return -1;

    felder[ 0] = pAufenthalt->KANR;
    felder[ 3] = pAufenthalt->AUFDAT;
    felder[ 4] = pAufenthalt->AUFZEIT;
    
    felder[ 5] = &pAufenthalt->BEHANDLUNGSART;
    felder[ 6] = &pAufenthalt->GESCHL;
    felder[ 7] = pAufenthalt->STAATB;
    felder[ 8] = pAufenthalt->STAATW;
    felder[ 9] = pAufenthalt->PLZW;
    felder[10] = pAufenthalt->GEMEINDEZIFFER;
    felder[11] = &pAufenthalt->AUFART;
    felder[12] = &pAufenthalt->AUFART2;
    felder[13] = &pAufenthalt->TRANSPORTART;
    felder[14] = pAufenthalt->KANR_VON;
    felder[15] = pAufenthalt->KANR_AN;
    felder[16] = &pAufenthalt->ENTART;
    felder[17] = pAufenthalt->ENTDAT;
    felder[18] = pAufenthalt->ENTZEIT;
    felder[19] = pAufenthalt->KOST;
    felder[20] = &pAufenthalt->ABRECH_RELEVANT;
    felder[21] = &pAufenthalt->FLAG;
    felder[22] = pAufenthalt->KOST_UE;
    felder[23] = pAufenthalt->ABRECH_QUARTAL;
    
    if (pAufenthalt->nM01ExtOffset)
        sAdditional = lkf_auf_get_ext (pAufenthalt, pAufenthalt->nM01ExtOffset);
    else
        sAdditional = 0;

    if (pContext->isBM) {
        felder[1] = pAufenthalt->UCASE_PATID;
        felder[2] = pAufenthalt->ALTERSGRUPPE;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX01, sizeof(feldIndicesBM)/sizeof (const int), feldIndicesBM /* V22.1 */, felder, sAdditional, line);
    }
    else {
        felder[1] = pAufenthalt->PATID;
        felder[2] = pAufenthalt->GEBDAT;
        if (FILL_ALTERSGRUPPE(pAufenthalt))
            felder[24] = pAufenthalt->ALTERSGRUPPE;
        else
            felder[24] = "";
        
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX01, sizeof(feldIndices)/sizeof (const int), feldIndices, felder, sAdditional, line);
    }
}

int lkf_auf_xline_abt (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X02_POSITIONSNUMMER, X02_ABTFC, X02_AUFDAT, X02_AUFZEIT, X02_PHYSANW, X02_ENTDAT, X02_ENTZEIT, X02_ENTART, X02_FACH_FC, X02_PFLEG_FC, X02_AUFNAHME_FUCO, X02_NEONAT, X02_ALTERSGRUPPE};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X02_POSITIONSNUMMER, X02_ABTFC, X02_AUFDAT, X02_AUFZEIT, X02_PHYSANW, X02_ENTDAT, X02_ENTZEIT, X02_ENTART, X02_FACH_FC, X02_PFLEG_FC, X02_AUFNAHME_FUCO, X02_NEONAT, X02_ALTERSGRUPPE};
    
    const char *felder[30];
    const char *sAdditional;
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    LKF_AUFENTHALT_ABT *pAbt;
    
    if (i >= pAufenthalt->abt_anz) return 0;
    
    pAbt = pAufenthalt->abt + i;
    
    felder[ 0] = pAufenthalt->KANR;
    felder[ 2] = pAufenthalt->AUFDAT;
    felder[ 3] = pAbt->ABTPOS;
    felder[ 4] = pAbt->ABTFC;
    felder[ 5] = pAbt->ABTDAT;
    felder[ 6] = pAbt->ABTZEIT;
    felder[ 7] = &pAbt->PHYS_ANW;
    felder[ 8] = pAbt->ENTDAT;
    felder[ 9] = pAbt->ENTZEIT;
    felder[10] = &pAbt->ENTART;
    felder[11] = pAbt->FACHFC;
    felder[12] = pAbt->PFLEGFC;
    felder[13] = pAbt->FUCOAUFNR;
    
    sAdditional = pAbt->nExtOffset ? lkf_auf_get_ext(pAufenthalt, pAbt->nExtOffset) : 0;
    
    if (pContext->isBM) {
        felder[1] = pAufenthalt->UCASE_PATID;
        felder[14] = &pAbt->ISNEONAT;
        felder[15] = pAbt->ALTERSGRUPPE;

        return lkf_auf_write_satzart (pAufenthalt, pContext->pX02, sizeof(feldIndicesBM)/sizeof (const int), feldIndicesBM /* V22.1 */, felder, sAdditional, line);
    }
    else {
        felder[1] = pAufenthalt->PATID;
        if (FILL_ALTERSGRUPPE(pAufenthalt)) {
            felder[14] = &pAbt->ISNEONAT;
            felder[15] = pAbt->ALTERSGRUPPE;            
        }
        else {
            felder[14] = "";
            felder[15] = "";
        }
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX02, sizeof(feldIndices)/sizeof (const int), feldIndices, felder, sAdditional, line);
    }
}

int lkf_write_expLine (char *line, const LKF_EXPANDED_LINE *pLine) {
    unsigned int i;
    int pos = 0, terminatorPos, curPos;
    for (i = 0; i < pLine->significantFieldCount + 1; i++) 
	{
        pos += sprintf (line + pos, "%s|", pLine->fields[i]);
    }
	if (!pos)
		return 0;

	terminatorPos = pos - 1;

	for (; i < pLine->fieldCount + 1; i++)
	{
		curPos = sprintf (line + pos, "%s|", pLine->fields[i]);
		pos += curPos;
		if (curPos > 1) {
            terminatorPos = pos - 1;
        }

	}

    line[terminatorPos] = 0;
    return terminatorPos;
}

int lkf_write_expLineFields (char *line, unsigned int fieldCount, const char **fields)
{
    unsigned int i;
    int pos = 0;
    for (i = 0; i < fieldCount; i++) {
        pos += sprintf (line + pos, "%s|", fields[i]);
    }
    return pos;
}

int lkf_auf_xline_diag (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X03_DIAG, X03_DIAGTYP, X03_DIAGART, X03_DIAGSTATIONAER, X03_AUFNAHME_FUCO};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X03_DIAG, X03_DIAGTYP, X03_DIAGART, X03_DIAGSTATIONAER, X03_AUFNAHME_FUCO};
    
    const char *felder[10];
    const char *diagtyp;
    const char *sAdditional;
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    LKF_AUFENTHALT_DIAG *pDiag;
    
    if (i >= pAufenthalt->diag_anz) return 0;
    pDiag = pAufenthalt->diag + i;
    diagtyp = pDiag->DIAGTYP;
    
    felder[ 0] = pAufenthalt->KANR;
    felder[ 2] = pAufenthalt->AUFDAT;
    felder[ 3] = pDiag->DIAG;
    felder[ 4] = diagtyp;
    felder[ 5] = &pDiag->DIAGART;
    felder[ 6] = &pDiag->DIAGSTAT;
    felder[ 7] = pDiag->FUCOAUFNR;
    
    sAdditional = pDiag->nExtOffset ? lkf_auf_get_ext(pAufenthalt, pDiag->nExtOffset) : 0;
    
    if (pContext->isBM) {
        felder[1] = pAufenthalt->UCASE_PATID;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX03, sizeof(feldIndicesBM)/sizeof (const int), feldIndicesBM /* V22.1 */, felder, sAdditional, line);
    }
    else {
        felder[1] = pAufenthalt->PATID;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX03, sizeof(feldIndices)/sizeof (const int), feldIndices, felder, sAdditional, line);
    }
}

int lkf_auf_xline_mel (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line)
{
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X04_MEL, X04_SEITE, X04_ABRECHNUNGSRELEVANZ, X04_ANZAHL, X04_DATUM, X04_UHRZEIT, X04_FCLEIST, X04_KALEIST, X04_AUFNAHME_FUCO};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X04_MEL, X04_SEITE, X04_ABRECHNUNGSRELEVANZ, X04_ANZAHL, X04_DATUM, X04_UHRZEIT, X04_FCLEIST, X04_KALEIST, X04_AUFNAHME_FUCO};
    static const int feldIndiceswithResult[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X04_MEL, X04_SEITE, X04_ABRECHNUNGSRELEVANZ, X04_ANZAHL, X04_DATUM, X04_UHRZEIT, X04_FCLEIST, X04_KALEIST, X04_AUFNAHME_FUCO, -1, -1, -1};
    static const int feldIndicesBMwithResult[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X04_MEL, X04_SEITE, X04_ABRECHNUNGSRELEVANZ, X04_ANZAHL, X04_DATUM, X04_UHRZEIT, X04_FCLEIST, X04_KALEIST, X04_AUFNAHME_FUCO, -1, -1, -1};

    char melgroupbuf[20];
    char melknt[4];
    char melpt[20];
    const char *felder[20];
    char melanz[8];
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    LKF_AUFENTHALT_MEL *pMel;
    
    const char *sAdditional;

    if (i >= pAufenthalt->mel_anz) return 0;
    
    pMel = pAufenthalt->mel + i;
    
    felder[ 0] = pAufenthalt->KANR;
    felder[ 2] = pAufenthalt->AUFDAT;
    felder[ 3] = pMel->ORIG_MEL;
    felder[ 4] = &pMel->cSeite;
    felder[ 5] = &pMel->MEL_RELEVANT;
    sprintf(melanz, "   %4.4s", pMel->ORIG_MELANZ);
    felder[ 6] = melanz;
    felder[ 7] = pMel->MELDAT;
    felder[ 8] = pMel->MELZEIT;
    felder[ 9] = pMel->FCLEIST;
    felder[10] = pMel->KALEIST;
    felder[11] = pMel->FUCOAUFNR;
    sAdditional = pMel->nExtOffset ? lkf_auf_get_ext(pAufenthalt, pMel->nExtOffset) : 0;
    
    if (pContext->flags & LKFCONTEXT_EXPORTX04RESULTS) {
        lkf_auf_get_mel_value(pAufenthalt, i, LKF_MELFIELD_GRUPPE, 20, melgroupbuf);
        lkf_auf_get_mel_value(pAufenthalt, i, LKF_MELFIELD_KNOTEN, 4, melknt);
        lkf_auf_get_mel_value(pAufenthalt, i, LKF_MELFIELD_LEIST, 20, melpt);
        felder[12] = melgroupbuf;
        felder[13] = melknt;
        felder[14] = melpt;
    }
    
    if (pContext->isBM) {
        felder[1] = pAufenthalt->UCASE_PATID;
        if (pContext->flags & LKFCONTEXT_EXPORTX04RESULTS) {
            return lkf_auf_write_satzart (pAufenthalt, pContext->pX04, sizeof(feldIndicesBMwithResult)/sizeof (const int), feldIndicesBMwithResult, felder, sAdditional, line);
        }
        else {
            return lkf_auf_write_satzart (pAufenthalt, pContext->pX04, sizeof(feldIndicesBM)/sizeof (const int), feldIndicesBM /* V22.1 */, felder, sAdditional, line);
        }
    }
    else if (pContext->flags & LKFCONTEXT_EXPORTX04RESULTS) {
        felder[1] = pAufenthalt->PATID;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX04, sizeof(feldIndiceswithResult)/sizeof (const int), feldIndiceswithResult, felder, sAdditional, line);

    }
    else {
        felder[1] = pAufenthalt->PATID;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX04, sizeof(feldIndices)/sizeof (const int), feldIndices, felder, sAdditional, line);
    }
}

static char *lkf_longToString8 (long value, char *buffer)
{
    if (value == 0)
        return 0;
    else if (value > 100000000)
        return "overflow";
    sprintf (buffer, "%ld", value);
    return buffer;
}

int lkf_auf_xline_scoring (LKF_AUFENTHALT *pAufenthalt, char *line)
{
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X05_GRUPPE, X05_KNOTEN, X05_LEIST, X05_TAG, X05_LEIST_UNT, X05_TAG_UNT, X05_TAG_OBEN, X05_INTENSIV, X05_MELZU, X05_SPEZ, X05_SUMME};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X05_GRUPPE, X05_KNOTEN, X05_LEIST, X05_TAG, X05_LEIST_UNT, X05_TAG_UNT, X05_TAG_OBEN, X05_INTENSIV, X05_MELZU, X05_SPEZ, X05_SUMME};
    
    const char *felder[14];

    
    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
    const char *gruppe;
    char knoten[3];
    char ldfplk_string[10];
    char ldfptk_string[10];
    char sculk_string[10];
    char scutk_string[10];
    char vdzu_string[10];
    char intzu_string[10];
    char melzu_string[10];
    char spez_string[10];
    char scges_string[10];
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;

    if (!pContext || !pContext->pX05) return -1;
    
    if (pAufenthalt->subgruppe)
        pSubgruppe = pAufenthalt->subgruppe + pAufenthalt->max_index;
    else
        pSubgruppe = 0;
    
    if (pSubgruppe) {
        gruppe = pSubgruppe->gruppe;
        sprintf (knoten, "%c", pSubgruppe->knoten_char);
    }
    else {
        gruppe = pAufenthalt->GRP;
        knoten[0] = pAufenthalt->KNT[0];
		knoten[1] = 0; /* V21.1 */
    }    
    
    felder[ 0] = pAufenthalt->KANR;
    felder[ 2] = pAufenthalt->AUFDAT;
    felder[ 3] = gruppe;
    felder[ 4] = knoten;
    felder[ 5] = lkf_longToString8 (pAufenthalt->LDFPLK, ldfplk_string);
    felder[ 6] = lkf_longToString8 (pAufenthalt->LDFPTK, ldfptk_string);
    felder[ 7] = lkf_longToString8 (pAufenthalt->SCULK, sculk_string);
    felder[ 8] = lkf_longToString8 (pAufenthalt->SCUTK_TKL,scutk_string);
    felder[ 9] = lkf_longToString8 (pAufenthalt->VDZU, vdzu_string);
    felder[10] = lkf_longToString8 (pAufenthalt->INTZU, intzu_string);
    felder[11] = lkf_longToString8 (pAufenthalt->MELZU, melzu_string);
    felder[12] = lkf_longToString8 (pAufenthalt->SCSPEZ, spez_string);
    felder[13] = lkf_longToString8 (pAufenthalt->SCGES_TKL, scges_string);
    
    if (pContext->isBM) {
        felder[1] = pAufenthalt->UCASE_PATID;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX05, sizeof(feldIndicesBM)/sizeof (const int), feldIndicesBM /* V22.1 */, felder, 0, line);
    }
    else {
        felder[1] = pAufenthalt->PATID;
        return lkf_auf_write_satzart (pAufenthalt, pContext->pX05, sizeof(feldIndices)/sizeof (const int), feldIndices, felder, 0, line);
    }

    
    return 1;
}

int lkf_auf_xline_akwarn (LKF_AUFENTHALT *pAufenthalt, unsigned int i, char *line, unsigned int *pHitCount)
{
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X06_WERT, X06_CODE, X06_KOMMENTAR};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X06_WERT, X06_CODE, X06_KOMMENTAR};
    unsigned int code;
    char sCode[6], sErrorIdent[6];
    LKF_AUFENTHALT_AKWARN *pAkWarn;
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    const char *felder[8];
    
    if (i >= pAufenthalt->akwarn_anz) return 0;
    pAkWarn = pAufenthalt->akwarn + i;
    
    code = (unsigned int) pAkWarn->code;
    
    if (code > 0)  /* V2024.2: fix WI-Codes */ {
        if (pAkWarn->severity & LKF_SEV_ERROR)
        {
            sprintf (sCode, "EX%2s", lkf_getErrorCodeFromInt (code, sErrorIdent));
        }
        else if (pAkWarn->severity & LKF_SEV_INFO)
        {
            sprintf (sCode, "HX%2s", lkf_getErrorCodeFromInt (code, sErrorIdent));
        }
        else
        {
            sprintf (sCode, "WX%2s", lkf_getErrorCodeFromInt (code, sErrorIdent));
        }
    }
    else {
        memcpy (sCode, pAufenthalt->akwarn[i].s4DigitCode, 4);
        sCode[4] = 0;
    }
    
    felder[ 0] = pAufenthalt->KANR;
    felder[ 2] = pAufenthalt->AUFDAT;
    
    if (pAkWarn->acceptedValue[0] && (pContext->flags & LKFCONTEXT_AKWARNREPLACEVALUE)) {
        felder[3] = pAkWarn->acceptedValue;
    }
    else {
        felder[3] = pAkWarn->value;
    }
    
    felder[ 4] = sCode;
    felder[ 5] = pAkWarn->kommentar;
    
    if (pHitCount)
        *pHitCount = pAkWarn->nHitCount;

    if (pContext->isBM) {
        felder[1] = pAufenthalt->UCASE_PATID;
        lkf_auf_write_satzart (pAufenthalt, pContext->pX06, sizeof(feldIndicesBM)/sizeof (const int), feldIndicesBM /* V22.1 */, felder, 0, line);
    }
    else {
        felder[1] = pAufenthalt->PATID;
        lkf_auf_write_satzart (pAufenthalt, pContext->pX06, sizeof(feldIndices)/sizeof (const int), feldIndices, felder, 0, line);
    }

    return 1;
}

int lkf_auf_xline_kommentar (LKF_AUFENTHALT *pAufenthalt, char *line)
{
    unsigned int i, count, fieldCount;
    static const int feldIndices[] = {GEN_KANR, GEN_AUFNR, X01_AUFNAHMEDATUM, X07_KOMM1, X07_KOMM2, X07_KOMM3, X07_KOMM4, X07_KOMM5, X07_KOMM6};
    static const int feldIndicesBM[] = {GEN_KANR, X01_DATENSATZID, X01_AUFNAHMEDATUM, X07_KOMM1, X07_KOMM2, X07_KOMM3, X07_KOMM4, X07_KOMM5, X07_KOMM6};

    const char *felder[9];
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    
    count = pAufenthalt->kommentar_anz;
    if (count > 6) count = 6;
    
    felder[ 0] = pAufenthalt->KANR;
    felder[ 2] = pAufenthalt->AUFDAT;
    
    for (i = 0; i < count; i++)
        felder[i+3] = pAufenthalt->kommentar[i].kommentar;
    
    
    if (pContext->isBM) {
        fieldCount = (unsigned int) sizeof(feldIndicesBM)/sizeof (const int);
        fieldCount -= 6 - i;
        felder[1] = pAufenthalt->UCASE_PATID;
        lkf_auf_write_satzart (pAufenthalt, pContext->pX07 /* V2025.0: fix pX06) */, fieldCount, feldIndicesBM /* V22.1 */, felder, 0, line);
    }
    else {
        fieldCount = (unsigned int) sizeof(feldIndices)/sizeof (const int);
        fieldCount -= 6 - i;
        felder[1] = pAufenthalt->PATID;
        lkf_auf_write_satzart (pAufenthalt, pContext->pX07, fieldCount, feldIndices, felder, 0, line);
    }
    return 1;
}

extern const LKF_SATZART_ERRORDEF LKFErrorFormat;

/*#define LKF_TRUNC_FIELDS*/

LKF_EXPANDED_LINE *lkf_create_expandLine (LKF_CONTEXT *pContext, const char *line, unsigned int modifyLen, LKF_EXPANDED_LINE_INFO *pInfo, const char *memoryKey)
{
    LKF_EXPANDED_LINE *pAmbLine;
    const char *trennPos;
    const SATZART_INFO *pSatzartInfo;
    long fieldLength;
    unsigned int i, bufLen;
    int fieldCount;
    char *bufPos;
    long len = (long) strlen (line);
    const char trenn = '|';
    int nSatzartNr = lkf_getSatzartNr (line + 1);
    pSatzartInfo = lkf_getSatzartInfo (pContext, line, nSatzartNr);
    fieldCount = pSatzartInfo ? (int) pSatzartInfo->pSatzart->nCount : lkf_getFeldAnzahl(pContext, line[0], nSatzartNr);
    
    if (fieldCount <= 0) /* V2022.1 */
        return 0;
    
    bufLen = (unsigned int) (sizeof (LKF_EXPANDED_LINE) + (unsigned int)len + (unsigned int)fieldCount + 1 + sizeof(const char *) * ((unsigned int)fieldCount + 1) + modifyLen);
    if (pSatzartInfo)
        bufLen += sizeof(const char *) * (unsigned int) (pSatzartInfo->nMaxIndex+1);

    bufPos = (char *)LKF_MALLOC(pContext, memoryKey ? memoryKey : "lkf_create_expandLine", bufLen);
    if (bufPos == 0) return 0;

    pAmbLine = (LKF_EXPANDED_LINE *) bufPos;
    pAmbLine->bufLen = bufLen;
    bufPos += sizeof (LKF_EXPANDED_LINE);
    pAmbLine->satzartNr = nSatzartNr;
    pAmbLine->fieldCount = (unsigned int) fieldCount;
	if (pSatzartInfo && fieldCount > (int) pSatzartInfo->pSatzart->nSignificantCount) 
	{
		pAmbLine->significantFieldCount = pSatzartInfo->pSatzart->nSignificantCount;
	}
	else 
	{
		pAmbLine->significantFieldCount = (unsigned int) fieldCount;
	}
    pAmbLine->fields = (char **) bufPos;
    pAmbLine->pSatzartInfo = pSatzartInfo;
    memset (pAmbLine->fields, 0, sizeof(char *) * (unsigned int) fieldCount);
    
    bufPos += sizeof(const char *) * ((unsigned int) fieldCount + 1);
 
    if (pSatzartInfo)
    {
        pAmbLine->fieldsById = (char **) bufPos;
        bufPos += sizeof(const char *) * (unsigned int) (pSatzartInfo->nMaxIndex + 1);
    }
    else
        pAmbLine->fieldsById = 0;
    
    pAmbLine->fieldBuf = bufPos;
    for (i = 0; i <= (unsigned int) fieldCount && line; i++) {
        while (*line == ' ') ++line;
        trennPos = strchr(line, trenn);
        if (trennPos) fieldLength = (long) (trennPos - line);
        else fieldLength = (long) strlen (line);
        
        while (fieldLength > 0 && (line[fieldLength-1] == ' ' || line[fieldLength-1] == 10 || line[fieldLength-1] == 13)) --fieldLength;
        
        if (pSatzartInfo && fieldLength > 0 && ((i == 0 && fieldLength > 3) || (i > 0 && pSatzartInfo->pSatzart->Felder[i-1].nLen < (unsigned int) fieldLength))) {

            if (i > 0 /* V2024.1 */ && pSatzartInfo->pSatzart->Felder[i-1].nType == TYP_ALPHA_TRUNC) {
                fieldLength = pSatzartInfo->pSatzart->Felder[i-1].nLen - 10;
                if (fieldLength < 0) {
                    fieldLength = pSatzartInfo->pSatzart->Felder[i-1].nLen - 1;
                }
            }
            else {
                if (pInfo) {
                    pInfo->pError = &LKFErrorFormat;
                    pInfo->pSatzart = pSatzartInfo;
                    if (i == 0)
                        pInfo->pFeld = &FeldSatzart;
                    else
                        pInfo->pFeld = pSatzartInfo->pSatzart->Felder + i - 1;
                    pInfo->fieldLen = fieldLength;
                    pInfo->fieldPos = line;
                }
                LKF_FREE (pContext, memoryKey ? memoryKey : "lkf_create_expandLine", (void *) pAmbLine);
                return 0;
            }
        }
        
        if (fieldLength > 0) {
            memcpy (bufPos, line, fieldLength);
            bufPos[fieldLength] = 0;
            pAmbLine->fields[i] = bufPos;
            bufPos += fieldLength + 1;
        } else {
            pAmbLine->fields[i] = "";
        }
        if (trennPos) line = trennPos+1;
        else line = 0;
    }
    
    for(;i<= (unsigned int) fieldCount;i++) {
        pAmbLine->fields[i] = "";
    }
    
    pAmbLine->bufPos = (unsigned int)(bufPos - pAmbLine->fieldBuf);
    if (line) {
        fieldLength = (long) strlen (line);
        while (fieldLength > 0 && (line[fieldLength-1] == ' ' || line[fieldLength-1] == 10 || line[fieldLength-1] == 13)) --fieldLength;
        if (fieldLength) {
            memcpy (bufPos, line, fieldLength);
            bufPos[fieldLength] = 0;
            pAmbLine->postFix = bufPos;
        } else pAmbLine->postFix = 0;
    } else {
        pAmbLine->postFix = 0;
        for (;i < (unsigned int) fieldCount; i++) pAmbLine->fields[i] = 0;
    }
    
    if (pSatzartInfo) {
		int j;
        for (j = 0; j <= pSatzartInfo->nMaxIndex; j++) {
            const SATZART_FELD *pFeld = pSatzartInfo->ppRef[j];
            if (pFeld) {
                char *c = pAmbLine->fields[pSatzartInfo->feldIndex[pFeld->nFieldNum] + 1];
                pAmbLine->fieldsById[j] = c ? c :  "";
            }
        }
    }
    
    pAmbLine->pContext = pContext;
    return pAmbLine;
}

void lkf_free_expandLine (LKF_CONTEXT *pContext, LKF_EXPANDED_LINE *ambLine) {
    LKF_FREE (pContext, "lkf_free_expandline", ambLine);
}

LKF_EXPANDED_LINES *lkf_create_expandedLines (LKF_CONTEXT *pContext, unsigned int initialSize)
{
    LKF_EXPANDED_LINES *expandedLinesBuffer = (LKF_EXPANDED_LINES *) LKF_MALLOC (pContext, "lkf_create_expandedLines", sizeof(LKF_EXPANDED_LINES));
    if (!expandedLinesBuffer) return 0;
    expandedLinesBuffer->pContext = pContext;
    expandedLinesBuffer->lineAlloc = initialSize;
    expandedLinesBuffer->lineExtend = initialSize;
    expandedLinesBuffer->lineCount = 0;
    expandedLinesBuffer->lines = (LKF_EXPANDED_LINE **) LKF_CALLOC(pContext, "lkf_create_expandedLines.2", sizeof(LKF_EXPANDED_LINE *), initialSize);
    if (!expandedLinesBuffer->lines) {
        LKF_FREE(pContext, "lkf_create_expandedLines", expandedLinesBuffer);
        return 0;
    }
    return expandedLinesBuffer;
}

void lkf_free_expandedLines (LKF_EXPANDED_LINES *expandedLines)
{
    if (expandedLines) {
        unsigned int i;
        for (i = 0; i < expandedLines->lineCount; i++)
        {
            lkf_free_expandLine(expandedLines->pContext, expandedLines->lines[i]);
        }
		LKF_FREE(expandedLines->pContext, "lkf_create_expandedLines.2", expandedLines->lines); /* V2019.3 */
        LKF_FREE (expandedLines->pContext, "lkf_create_expandedLines", expandedLines);
    }
}

unsigned int lkf_add_expandLine (LKF_EXPANDED_LINES *expandedLines, LKF_EXPANDED_LINE *expandLine)
{
    if (expandedLines->lineCount == expandedLines->lineAlloc) {
        LKF_EXPANDED_LINE **old = expandedLines->lines;
        expandedLines->lineAlloc += expandedLines->lineExtend;
        expandedLines->lines = (LKF_EXPANDED_LINE **) LKF_CALLOC (expandedLines->pContext, "lkf_add_expandLine", sizeof (LKF_EXPANDED_LINE *), expandedLines->lineAlloc);

        if (expandedLines->lines == 0) {
            expandedLines->lineAlloc = expandedLines->lineCount = 0;
            LKF_FREE (expandedLines->pContext, "lkf_add_expandLine", old);
            return LKF_OUTOFMEMORY_UINTERROR;
        }
        memcpy (expandedLines->lines, old, sizeof(LKF_EXPANDED_LINE *) * expandedLines->lineCount);
        LKF_FREE (expandedLines->pContext, "lkf_add_expandLine", old);
    }
    expandedLines->lines[expandedLines->lineCount] = expandLine;
    return expandedLines->lineCount++;
}

unsigned int lkf_replace_expandLine (LKF_EXPANDED_LINES *pExpandLines, LKF_EXPANDED_LINE *pLine, unsigned int index)
{ /* V2024.0 */
    LKF_EXPANDED_LINE *pOld;
    if (!pExpandLines || pExpandLines->lineCount <= index) {
        return LKFCERROR_OUTOFBOUNDS;
    }
    pOld = pExpandLines->lines[index];
    if (pOld) {
        lkf_free_expandLine (pExpandLines->pContext, pOld);
    }
    pExpandLines->lines[index] = pLine;
    return LKFCERROR_OK;
}

unsigned int lkf_replace_addLine (LKF_CONTEXT *pContext, LKF_EXPANDED_LINE *pLine, unsigned int index)
{ /* V2024.0 */
    return lkf_replace_expandLine (pContext->pExpLineBuffer, pLine, index);
}

unsigned int lkf_delete_expandLine (LKF_EXPANDED_LINES *pExpandLines, unsigned int index)
{ /* V2024.0 */
    LKF_EXPANDED_LINE *pOld;
    if (!pExpandLines || pExpandLines->lineCount <= index) {
        return LKFCERROR_OUTOFBOUNDS;
    }
    pOld = pExpandLines->lines[index];
    if (pOld) {
        lkf_free_expandLine (pExpandLines->pContext, pOld);
    }
    pExpandLines->lines[index] = 0;
    return LKFCERROR_OK;
}

unsigned int lkf_delete_addLine (LKF_CONTEXT *pContext, unsigned int index)
{
    return lkf_delete_expandLine(pContext->pExpLineBuffer, index);
}

LKF_EXPANDED_LINE *lkf_create_expandLineWithPre2017Compatibility (LKF_CONTEXT *pContext, const char *line, const SATZART_INFO *pSatzartInfo, int modifyChars, LKF_EXPANDED_LINE_INFO *pInfo) {
    
    unsigned int lineLen;
    unsigned int i;
    const char *fieldValue[100];
    unsigned int maxLen[100];
    char targetLine[1024];
    char aufdat[10];
    unsigned int targetPos;
    const SATZART_INFO *pSourceSatzartInfo = pSatzartInfo;
    const SATZART *pSatzart;
    
    if (pSatzartInfo == 0)
        return 0;
    
    if (pSatzartInfo->pCompatibility)
        pSourceSatzartInfo = pSatzartInfo->pCompatibility;
    
    lineLen = (unsigned int) strlen (line);
    memset ((void *) fieldValue, 0, sizeof(const char *) * 100);
    
    pSatzart = pSourceSatzartInfo->pSatzart;
    for (i = 0; i < pSatzart->nCount; i++) {
        
        const SATZART_FELD *pFeld = pSatzart->Felder + i;
        if (pFeld->nPos < lineLen && !strchr ("\r\n", line[pFeld->nPos -1])) {
            unsigned int fieldLen = lineLen - pFeld->nPos;
            const char *fieldStart = line + pFeld->nPos - 1;
            if (fieldLen > pFeld->nLen) fieldLen = pFeld->nLen;
            while (fieldLen && (fieldStart[fieldLen-1] == '\r' || fieldStart[fieldLen - 1] == '\n')) {
                --fieldLen;
            }
            if (fieldLen > 0) {
                fieldValue[pFeld->nFieldNum] = line + pFeld->nPos - 1;
                maxLen[pFeld->nFieldNum] = fieldLen;
            }
        }
    }
    
    aufdat[0] = 0;
    pSatzart = pSatzartInfo->pSatzart;
    sprintf (targetLine, "%3s%c", pSatzart->sPrefix, LKF_TRENN);
    targetPos = 4;
    for (i = 0; i < pSatzart->nCount; i++) {
        const SATZART_FELD *pFeld = pSatzart->Felder + i;
        const char *w = fieldValue[pFeld->nFieldNum];
        unsigned int fieldMaxLen;
        
        if (w && *w && (pFeld->nFieldNum == GEN_AUFNR || pFeld->nFieldNum == I11_DATENSATZID)) {
            int exm;
            unsigned int index = lkf_search_aufenthalt_2017(pContext, w, &exm, maxLen[pFeld->nFieldNum]);
            
            if (exm) {
                sprintf (aufdat, "%8.8s", pContext->ppAufenthalt[index]->AUFDAT);
            }
        } else if (pFeld->nFieldNum == I11_AUFNAHMEDATUM) {
            w = aufdat;
        }
        
        switch (pFeld->nFieldNum) {
            case I11_DATENSATZID:
                fieldMaxLen = pFeld->nLen;
                break;
            case I11_AUFNAHMEDATUM:
                fieldMaxLen = pFeld->nLen;
                break;
            default:
                fieldMaxLen = maxLen[pFeld->nFieldNum];
                break;
                
        }
        
        if (w) {
            targetPos += (unsigned int) lkf_auf_write_xline_feld(targetLine + targetPos, pFeld, w, (int) fieldMaxLen);
        }
        else {
            targetLine[targetPos++] = LKF_TRENN;
        }
    }
    targetLine[targetPos] = 0;
    return lkf_create_expandLine (pContext, targetLine, (unsigned int) modifyChars, pInfo, "lkf_create_expandLineWithPre2017Compatibility");
}

int lkf_auf_getintxline (LKF_AUFENTHALT *pAufenthalt, unsigned int index, char *l, char *ident)
{
    
    if (pAufenthalt->pIntensiv && pAufenthalt->pIntensiv->lineCount > index) {
        const LKF_EXPANDED_LINE *pLine = pAufenthalt->pIntensiv->lines[index];
        lkf_write_expLine (l, pLine);
        if (ident) {
            sprintf(ident, "INX:%3.3s:%d", pLine->fields[0], index);
        }
    }
    else {
        if (ident) {
            *ident = 0;
        }
        *l = 0;
    }
    return 0;
}


extern const SATZART L01SatzartInternal;
extern const LKF_SATZART_ERRORDEF LKFErrorSPEZAbt;

_SCORING_EXPORT unsigned int lkf_get_context_l_count (LKF_CONTEXT *pContext, unsigned int satzart, int copyFlag) {
    switch (satzart) {
        case 1:
            if (copyFlag) {
                if ((copyFlag & LKF_COPYADDLINE_ADDL01) && pContext->spez_gesamt == 0) {
                    return pContext->pStamm2001->spez_gesamt;
                }
                return 0;
            }
            return lkf_get_spez_anz(pContext);
        case 2:
            if (copyFlag) {
                if ((copyFlag & LKF_COPYADDLINE_ADDL02) && pContext->kost_gesamt == 0) {
                    return pContext->pStamm2001->kost_gesamt;
                }
                return 0;
            }
            return lkf_get_kost_anz(pContext);
        case 3:
            if (copyFlag) {
                if ((copyFlag & LKF_COPYADDLINE_ADDL03) && pContext->mel_ka_gesamt == 0) {
                    return pContext->pStamm2001->mel_ka_gesamt;
                }
                return 0;
            }
            return lkf_get_melka_anz(pContext);
        case 4:
            if (copyFlag) {
                if ((copyFlag & LKF_COPYADDLINE_ADDL04) && pContext->mel_tkl_gesamt == 0) {
                    return pContext->pStamm2001->mel_tkl_gesamt;
                }
                return 0;
            }
            return lkf_get_meltkl_anz(pContext);
        default:
            return 0;
    }
}

_SCORING_EXPORT unsigned int lkf_get_context_l (LKF_CONTEXT *pContext, unsigned int satzart, unsigned int index, char *buf, unsigned int buflen)
{ /* V2024.1 */
    const char *source;
    char returnbuffer[1024];
    unsigned int returnLength;
    
    switch (satzart) {
        case 1:
            if (pContext->spez_gesamt) {
                source = (const char *) pContext->spez_list + index * sizeof (SPEZ_LIST_STRING);
            }
            else {
                source = (const char *) pContext->pStamm2001->spez_list + index * sizeof (SPEZ_LIST_STRING);
            }
            sprintf (returnbuffer, "L01|%d|%4.4s|%8.8s|%c|%2.2s|%6.6s", pContext->modelljahr, source + 5, source + 9, source[0], source + 27, source + 29);
            break;
        case 2:
            if (pContext->kost_gesamt) {
                source = (const char *) pContext->kost_list + index * sizeof (KOST_LIST_STRING);
            }
            else {
                source = (const char *) pContext->pStamm2001->kost_list + index * sizeof (KOST_LIST_STRING);
            }
            sprintf (returnbuffer, "L02|%d|%4.4s|%3.3s|%c", pContext->modelljahr, pContext->KANR, source + 5, source[8]);
            break;
        case 3:
            if (pContext->mel_ka_gesamt) {
                source = (const char *) pContext->mel_ka + index * sizeof (MEL_KA_STRING);
            }
            else {
                source = (const char *) pContext->pStamm2001->mel_ka + index * sizeof (SPEZ_LIST_STRING);
            }
            sprintf (returnbuffer, "L03|%d|%4.4s|%5.5s", pContext->modelljahr, source, source + 5);
            break;
        case 4:
            if (pContext->mel_tkl_gesamt) {
                source = (const char *) pContext->mel_tkl + index * sizeof (SPEZ_LIST_STRING);
            }
            else {
                source = (const char *) pContext->pStamm2001->mel_tkl + index * sizeof (SPEZ_LIST_STRING);
            }
            sprintf (returnbuffer, "L04|%d|%4.4s|%5.5s", pContext->modelljahr, source, source + 5);
            break;
        default:
            return 0;
    }
    
    returnLength = (unsigned int) strlen(returnbuffer);
    if (returnLength < buflen) {
        strcpy (buf, returnbuffer);
    }
    return returnLength;
    
    
}


int lkf_add_xline_spez (LKF_CONTEXT *pContext, const LKF_EXPANDED_LINE *line, const char *origline)
{
    const char *lb;
    char buf[36];
    if (!pContext->spez_list)
    {
        pContext->spez_alloc = 100;
        pContext->spez_list = (SPEZ_LIST_STRING *) lkf_alloc_stamm_array (pContext, sizeof (SPEZ_LIST_STRING), pContext->spez_alloc, "alloc: lkf_add_xline_spez");
    }
    else if (pContext->spez_alloc == pContext->spez_gesamt)
    {
        pContext->spez_alloc *= 2;
        pContext->spez_list = (SPEZ_LIST_STRING *) lkf_realloc_stamm_array (pContext, sizeof (SPEZ_LIST_STRING), pContext->spez_alloc, (char *) pContext->spez_list, pContext->spez_gesamt, "realloc: lkf_add_xline_spez");

    }
    if (!pContext->spez_list) {
        pContext->spez_alloc = pContext->spez_gesamt = 0;
        return LKF_OUTOFMEMORY_ERROR;
    }

    lb = line->fieldsById[L01_LEISTUNGSBEREICH];
    sprintf (buf, "%c%-4.4s%-4.4s%8.8s          %-2.2s%6.6s", lb ? *lb : ' ',
             line->fieldsById[GEN_JAHR], line->fieldsById[GEN_KANR], line->fieldsById[GEN_ABTFC], line->fieldsById[L01_GRUPPE_STUFE], line->fieldsById[L01_PUNKTE]);
    
    if ((pContext->modelljahr >= 2018 && pContext->modelljahr < 2024) && (!lb || *lb != 'M'))
    { /* V2019.0 */
        
        unsigned int i;
        for (i = 0; i < pContext->spez_gesamt; i++) {
            const char *pSpez = (const char *) pContext->spez_list[i];
            if (*pSpez != 'M' && !memcmp (pSpez + 9, line->fieldsById[GEN_ABTFC], 8)) {
                const SATZART_INFO *l01S = lkf_GetSatzartL01Internal (pContext);
                const SATZART_FELD *abt = l01S ? l01S->ppRef[GEN_ABTFC] : 0;
                lkf_context_addimporterror(pContext, lkf_add_context_linebuf_line_error (pContext, origline), abt, &LKFErrorSPEZAbt, l01S);
                return -1;
            }
        }
    }

    memcpy (pContext->spez_list[pContext->spez_gesamt], buf, 35);
    pContext->spez_sorted = 0;
    return (int) pContext->spez_gesamt++;
}

int lkf_add_xline_kost (LKF_CONTEXT *pContext, const LKF_EXPANDED_LINE *line)
{
    const char *rel;
    if (!pContext->kost_list)
    {
        pContext->kost_alloc = 100;
        pContext->kost_list  = (KOST_LIST_STRING *) lkf_alloc_stamm_array (pContext, sizeof (KOST_LIST_STRING), pContext->kost_alloc, "alloc: lkf_add_xline_kost");
        if (!pContext->kost_list) pContext->kost_list2 = 0;
        else {
            pContext->kost_list2 = (char **) lkf_alloc_stamm_array (pContext, sizeof (char *), pContext->kost_alloc, "alloc: lkf_add_xline_kost");
        }
    }
    else if (pContext->kost_gesamt == pContext->kost_alloc)
    {
        pContext->kost_alloc *= 2;
        pContext->kost_list = (KOST_LIST_STRING *) lkf_realloc_stamm_array (pContext, sizeof (KOST_LIST_STRING), pContext->kost_alloc, (char *) pContext->kost_list, pContext->kost_gesamt, "realloc: lkf_add_xline_kost");
        if (pContext->kost_list) {
            pContext->kost_list2 = (char **) lkf_realloc_stamm_array (pContext, sizeof (char *), pContext->kost_alloc, (char *) pContext->kost_list2, pContext->kost_gesamt, "realloc: lkf_add_xline_kost");
        }
    }
    
    if (!pContext->kost_list || !pContext->kost_list2) {
        if (pContext->kost_list) {
            LKF_FREE(pContext, "lkf_add_xline_kost", pContext->kost_list);
            pContext->kost_list = 0;
        }
        if (pContext->kost_list2) {
            LKF_FREE(pContext, "lkf_add_xline_kost", pContext->kost_list2);
            pContext->kost_list2 = 0;
        }
        return LKF_OUTOFMEMORY_ERROR;
    }
        
    
    rel = line->fieldsById[L02_LKF_RELEVANZ];
    
    sprintf (pContext->kost_list[pContext->kost_gesamt], "K%4.4s%3.3s%c",  line->fieldsById[GEN_KANR], line->fieldsById[L02_KOSTENTRAEGER_CODE], rel ? *rel : ' ');
    
    if (pContext->kost_list[pContext->kost_gesamt][7] == ' ')
    { /* V9.4 */
        char *sBuf = pContext->kost_list[pContext->kost_gesamt];
        sBuf[7] = sBuf[6];
        sBuf[6] = sBuf[5];
        sBuf[5] = ' ';
    }
    
    memset (pContext->kost_list[pContext->kost_gesamt] + 9, ' ', 50);
    pContext->kost_sorted = 0;
    return (int) pContext->kost_gesamt++;
}

int lkf_add_xline_melkatkl (LKF_CONTEXT *pContext, const LKF_EXPANDED_LINE *line)
{
    char buf[12]; /* V14.1 */
    if (!pContext->mel_tkl)
    {
        pContext->mel_tkl_alloc = 1000;
        pContext->mel_tkl = (MEL_KA_STRING *) lkf_alloc_stamm_array (pContext, sizeof (MEL_KA_STRING), pContext->mel_tkl_alloc, "alloc: lkf_add_xline_melkatkl");
    }
    else if (pContext->mel_tkl_gesamt == pContext->mel_tkl_alloc) {
        pContext->mel_tkl_alloc *= 2;
        pContext->mel_tkl = (MEL_KA_STRING *) lkf_realloc_stamm_array (pContext, sizeof (MEL_KA_STRING), pContext->mel_tkl_alloc, (char *) pContext->mel_tkl, pContext->mel_tkl_gesamt, "realloc: lkf_add_xline_melkatkl");
    }
    if (!pContext->mel_tkl) {
        pContext->mel_tkl_alloc = pContext->mel_tkl_gesamt = 0;
        return 0;
    }
    
    sprintf (buf, "%4.4s %5.5s", line->fieldsById[GEN_KANR], line->fieldsById[L03_MEL]);
    memcpy (pContext->mel_tkl[pContext->mel_tkl_gesamt], buf, sizeof(MEL_KA_STRING));
    pContext->mel_tkl_sorted = 0;
    return (int) pContext->mel_tkl_gesamt++;
}

int lkf_add_xline_melka (LKF_CONTEXT *pContext, const LKF_EXPANDED_LINE *line)
{
    char buf[12];
    if (!pContext->mel_ka)
    {
        pContext->mel_ka_alloc = 200;
        pContext->mel_ka = (MEL_KA_STRING *) lkf_alloc_stamm_array (pContext, sizeof (MEL_KA_STRING), pContext->mel_ka_alloc, "alloc: lkf_add_xline_melka");
    }
    else if (pContext->mel_ka_gesamt == pContext->mel_ka_alloc)
    {
        pContext->mel_ka_alloc *= 2;
        pContext->mel_ka = (MEL_KA_STRING *) lkf_realloc_stamm_array (pContext, sizeof (MEL_KA_STRING), pContext->mel_ka_alloc, (char *) pContext->mel_ka, pContext->mel_ka_gesamt, "realloc: lkf_add_xline_melka");
    }
    if (!pContext->mel_ka) {
        pContext->mel_ka_alloc = pContext->mel_ka_gesamt = 0;
        return LKF_OUTOFMEMORY_ERROR;
    }
    sprintf (buf, "%4.4s %5.5s", line->fieldsById[GEN_KANR], line->fieldsById[L03_MEL]);
    memcpy (pContext->mel_ka[pContext->mel_ka_gesamt], buf, sizeof(MEL_KA_STRING));
    pContext->mel_ka_sorted = 0;
    return (int) pContext->mel_ka_gesamt++;
}

int lkf_add_xline_oemelka (LKF_CONTEXT *pContext, const LKF_EXPANDED_LINE *line)
{
    const char *rel;
    if (!pContext->oemelka)
    {
        pContext->oemelka_alloc = 100;
        pContext->oemelka = (OEMELKA_STRING *) lkf_alloc_stamm_array (pContext, sizeof (OEMELKA_STRING), pContext->oemelka_alloc, "alloc: lkf_add_xline_oemelka");
    }
    else if (pContext->oemelka_alloc  == pContext->oemelka_gesamt)
    {
        pContext->oemelka_alloc *= 2;
        pContext->oemelka = (OEMELKA_STRING *) lkf_realloc_stamm_array (pContext, sizeof (OEMELKA_STRING), pContext->oemelka_alloc, (char *) pContext->oemelka, pContext->oemelka_gesamt, "realloc: lkf_add_xline_oemelka");
    }
    if (!pContext->oemelka) {
        pContext->oemelka_alloc = pContext->oemelka_gesamt = 0;
        return LKF_OUTOFMEMORY_ERROR;
    }
    
    rel = line->fieldsById[O02_GESAMT];
    
    sprintf (pContext->oemelka[pContext->oemelka_gesamt], "%-6.6s%5.5s%c",  line->fieldsById[GEN_KANR], line->fieldsById[O02_MEL], rel ? *rel : ' ');
    
    pContext->oemelka_sorted = 0;
    return (int) pContext->oemelka_gesamt++;
}

_SCORING_EXPORT LKF_AUFENTHALT *lkf_getAufenthaltFromLine (LKF_CONTEXT *pContext, const char *line) {
    LKF_EXPANDED_LINE_INFO info;
    LKF_AUFENTHALT *pAufenthalt;
    char key[LKF_AUFENTHALT_LONGID_LEN_AB2017+2];

    LKF_EXPANDED_LINE *expLine = lkf_create_expandLine(pContext, line, LKFLINEX_CHANGEBUFFERCHARS, &info, "lkf_getAufenthaltFromLine");

    if (expLine == 0)
        return 0;

    lkf_aufenthalt_key(pContext, expLine, key);
    pAufenthalt = lkf_find_aufenthalt (pContext, 0, key);
    lkf_free_expandLine(pContext, expLine);
    return pAufenthalt;
}

