/****************************************************************************
** Leistungsorientierte Krankenanstaltenfinanzierung (LKF)                 **
** Scoring-C-Sourcen V2026.1                                               **
** (C) 2026 BMASGPK                                                        **
*****************************************************************************
** scoring5.c - LKF-Punkteberechnung                                       **
**                                                                         **
**		 Alex.Holzer@chello.at                                             **
**       Bernhard.Pesec@dothealth.at                                       **
***************************************************************************/
#include "lkfint5.h"

typedef char SCORING_MELSTRING[LKF_AUFENTHALT_NEWMEL_LEN];
typedef char SCORING_STRING4[4];
typedef char SCORING_STRING2[2];

#define IS_TRACE_INFO(pContext) (lkf_isTraceInfo (pContext, LKF_FAC_MBDS))
#define IS_TRACE_DETAIL(pContext) (lkf_isTraceDetail (pContext, LKF_FAC_MBDS))
#define IS_TRACE_INPUT(pContext) (lkf_isTraceInput (pContext, LKF_FAC_MBDS))

#define TRACE_INFO(pAufenthalt,nAbtFC,sLine) (lkf_addTraceAufenthaltLine ((pAufenthalt)->pScoringContext, pAufenthalt, nAbtFC, sLine, LKF_FAC_MBDS, LKF_TRACE_INFO)) 
#define TRACE_DETAIL(pAufenthalt,nAbtFC,sLine) (lkf_addTraceAufenthaltLine ((pAufenthalt)->pScoringContext, pAufenthalt, nAbtFC, sLine, LKF_FAC_MBDS, LKF_TRACE_DETAIL))

static int isGrpMel (MEL_ARRAY_STRUC *pMel, LKF_AUFENTHALT *pAufenthalt)
{
	if (!pMel)
		return 0;
    if (pAufenthalt && pAufenthalt->isAmb == 1 && pAufenthalt->pScoringContext->modelljahr >= 2026) { /* V2026.0 */
        return !CompareUCase (pMel->sAmbGruppe, "MEL", 3) || !CompareUCase (pMel->sAmbGruppe, "APG", 3) || !CompareUCase (pMel->sAmbGruppe, "AMG", 3);
    }
    return !CompareUCase (pMel->sGruppe, "MEL", 3);
}

static int isGrpMelNr2009 (LKF_AUFENTHALT *pAufenthalt, int nMelId)
{
	MEL_ARRAY_STRUC *pMel;
	
	pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[nMelId].MEL);
	
	if (pMel)
        return isGrpMel (pMel, pAufenthalt);
	else
		return 0;
}

#ifdef SUPPORT_PRE2017
static int scoring_split_2009 (LKF_AUFENTHALT *pAufenthalt, const LKF_KNOTEN *pKnoten, int act_knoten, const char *act_subgruppe, int *agr01, const char *hd, int nMelId, char *sTraceLine)
{
	int val, val2;
	int i, j;

	int erfuellt;
	int agr01_bd;
	int agr01_found;

	int act_typ;
	int pat_grp;
	char tmp_spez_list[20];

	int splitmel;
	size_t comp_len;
	const SPEZ_LIST_STRING *pSpez;
    char c = 0;

	MEL_ARRAY_STRUC *pMel;
	ICD_LIST_STRING *pDiag;

	char act_grplgr[6];

	char sMel[6];

	act_typ = pKnoten->merkmals_typ[act_knoten];
	erfuellt = 0;
	val = 0;

	if (act_typ < 100)
	{
		switch (act_typ)
		{
			case  1: /* SPEZMEL */
				splitmel = 1;
				memcpy (sMel, pKnoten->splitmerkmal[act_knoten], LKF_AUFENTHALT_NEWMEL_LEN);
				sMel[LKF_AUFENTHALT_NEWMEL_LEN] = 0;
				
				if (sTraceLine) sprintf (sTraceLine, "SPEZMEL: MEL=%s", sMel);

				for (i = 0; i < (int)pAufenthalt->mel_anz; i++) {

					pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[i].MEL);

                    if (!pMel || (i != nMelId && isGrpMel (pMel, pAufenthalt)))
						continue;

					if (!memcmp (pAufenthalt->mel[i].MEL, sMel, LKF_AUFENTHALT_NEWMEL_LEN)) {
					
						for (j = 0; j < (int) pAufenthalt->pat_subgruppen; j++) {

							if (!memcmp (pAufenthalt->mel[i].MEL, pAufenthalt->subgruppe[j].gruppe + 8, LKF_AUFENTHALT_NEWMEL_LEN)) {
							
								if (memcmp (pAufenthalt->mel[i].MEL, act_subgruppe + 8, LKF_AUFENTHALT_NEWMEL_LEN)) splitmel = 0;
								j = (int) pAufenthalt->pat_subgruppen;
							
							}
						
						}
						if (splitmel) erfuellt = 1;
					}
				}
				break;
			case  2: /* SPEZHDG4 */
				if (sTraceLine) sprintf (sTraceLine, "SPEZHDG4: Diagnose=%5.5s", pKnoten->splitmerkmal[act_knoten]);
				if (!memcmp (pKnoten->splitmerkmal[act_knoten], hd, 5)) erfuellt = 1;
				break;
			case  3: /* SPEZHDG */
				if (sTraceLine) sprintf (sTraceLine, "SPEZHDG: Diagnose=%3.3s", pKnoten->splitmerkmal[act_knoten]);

				if (!memcmp (hd, pKnoten->splitmerkmal[act_knoten], 3)) erfuellt = 1;
				break;
			case  4: /* SPEZDG4 */
			case  5: /* SPEZDG */
				if (sTraceLine)
				{
					if (act_typ == 5)
					{
						sprintf (sTraceLine, "SPEZDG: Diagnose=%3.3s", pKnoten->splitmerkmal[act_knoten]);
					}
					else
					{
						sprintf (sTraceLine, "SPEZDG4: Diagnose=%5.5s", pKnoten->splitmerkmal[act_knoten]);
					}
				}

				if (act_typ == 5) comp_len = 3;
				else comp_len = 5;

				if (!memcmp (pAufenthalt->HD, pKnoten->splitmerkmal[act_knoten], comp_len)) erfuellt = 1;
				else {
					for (i = 0; !erfuellt && i < (int) pAufenthalt->diag_anz; i++) {
						if (!memcmp (pAufenthalt->diag[i].DIAG, pKnoten->splitmerkmal[act_knoten], comp_len)) erfuellt = 1;
					}
				}
				break;

			case  6: /* ALTER */
                GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val);
				if (sTraceLine) sprintf (sTraceLine, "ALTER: Vergleichswert=%d", pKnoten->Intervall[0][((val<0)?-val:val) - 1]);

				if (val < 0) {
					if (pAufenthalt->Alter <= pKnoten->Intervall[0][-val - 1]) erfuellt = 1;
				}
				else if (pAufenthalt->Alter > pKnoten->Intervall[0][val - 1]) erfuellt = 1;

				break;
			case  7: /* AGR01 */
			case 12: /* AGR02 */
				if (sTraceLine) sprintf (sTraceLine, (act_typ == 7 ? "AGR01" : "AGR02"));

				agr01_bd = 0;
				agr01_found = 0;
				for (i = 0; i < (int) pAufenthalt->abt_anz; i++) {
					if (!IsBlank (pAufenthalt->abt[i].ABTFC, LKF_AUFENTHALT_ABTFC_LEN)) {
					
						sprintf (tmp_spez_list,".....%4.4s%8.8s", pAufenthalt->KANR, pAufenthalt->abt[i].ABTFC);
						
						pSpez = SpezInArray (pAufenthalt->pScoringContext, tmp_spez_list);
						if (pSpez && !ABTFC_Spez_Check (pAufenthalt, i, pSpez, 0)) pSpez = 0;
						if (pSpez) {
						
							switch ((*pSpez)[0]) {
							
								default:	pSpez = 0;
											break;

								case 'P':   if ((*pSpez)[27] != 'A') pSpez = 0;
											else if (act_typ == 7 && (*pSpez)[28] != '1') pSpez = 0;
											else if (act_typ == 12 && (*pSpez)[28] != '2') pSpez = 0;
											break;
								case 'J':   

											if (pAufenthalt->pScoringContext->modelljahr >= 2013)
											{ /* V17.0 */
												pSpez = 0;
											}
											else
											{
												if (act_typ == 12) pSpez = 0;
												else if ((*pSpez)[27] == ' ') c = (*pSpez)[28];
												else if ((*pSpez)[28] == ' ') c = (*pSpez)[27];
												else c = 0;
												if (pSpez && (c == 'I' || c == 'R')) pSpez = 0;
											}
											break;

								case 'O':   /* V15.0 */
                                            if ((*pSpez)[27] != '0') pSpez = 0;
                                            else if (act_typ == 7 && (*pSpez)[28] != '1') pSpez = 0;
                                            else if (act_typ == 12 && (*pSpez)[28] != '2') pSpez = 0;
											break;
								case 'A':	
											if (pAufenthalt->pScoringContext->modelljahr < 2010 || act_typ != 7)
												pSpez = 0;
											break;
							}
						}

						if (pSpez) {
							agr01_bd += pAufenthalt->abt[i].ABTVD;
							agr01_found = 1;
						}
					}
				}

				if (agr01_bd > pAufenthalt->GESVD / 2 ||
					(agr01_found && agr01_bd == 0 && pAufenthalt->GESVD == 0)) {
					*agr01 = 1;
					erfuellt = 1;
				}
				break;
		}
	}

	else if (act_typ >= 101 && act_typ <= 199)
	{
		sprintf (act_grplgr, "HGR%02d", act_typ - 100);
		pat_grp = 0;

		pDiag = FindDiag (pAufenthalt->pScoringContext->pStamm2001, hd);

		if (pDiag && !memcmp ((*pDiag) + 18, act_grplgr, 5)) pat_grp = 1;

		GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val);
		if (sTraceLine) sprintf (sTraceLine, "%-8.8s: PATGRP: %d", act_grplgr, pat_grp);
		if (val < 0) {
			if (pat_grp <= pKnoten->Intervall[1][-val - 1]) erfuellt = 1;
		}
		else if (pat_grp > pKnoten->Intervall[1][val - 1]) erfuellt = 1;
	}
	else if (act_typ <= 299)
	{
		sprintf (act_grplgr, "DGR%02d", act_typ - 200);
		pat_grp = 0;

		if (sTraceLine) sprintf (sTraceLine, "%s", act_grplgr);

		for (i = 0; i < (int) pAufenthalt->diag_anz + 1; i++) {
		
			if (!i) 
				pDiag = FindDiag (pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->HD);
			else
				pDiag = FindDiag (pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->diag[i-1].DIAG);


			if (pDiag && !memcmp ((*pDiag) + 24, act_grplgr, 5)) ++pat_grp;
			
		}

		GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val2);

		if (val2 < 0) {
			if (pat_grp <= pKnoten->Intervall[1][-val2 -1]) erfuellt = 1;
		}
		else {
			if (pat_grp > pKnoten->Intervall[1][val2 - 1]) erfuellt = 1;
		}
	}
	else if (act_typ <= 399)
	{
		sprintf (act_grplgr, "LGR%02d", act_typ - 300);

		pat_grp = 0;

		for (i = 0; i < (int) pAufenthalt->mel_anz; i++)
		{
			pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[i].MEL);	
			
			if (!pMel)
				continue; 

			if (i != nMelId && isGrpMel (pMel, pAufenthalt))
				continue;

			if (!memcmp (pMel->sLGR, act_grplgr, 5)) {
				for (j = 0; j < i && (isGrpMelNr2009 (pAufenthalt, j) || memcmp (pAufenthalt->mel[i].MEL, pAufenthalt->mel[j].MEL, LKF_AUFENTHALT_NEWMEL_LEN)); j++) ; /* V14.2 */
				if (j == i) pat_grp++;
			}
		}

		GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val2);
		if (sTraceLine) sprintf (sTraceLine, "%-8.8s: PATGRP: %d", act_grplgr, pat_grp);
		if (val2 < 0) {
			if (pat_grp <= pKnoten->Intervall[1][-val2 - 1]) erfuellt = 1;
		}
		else {
			if (pat_grp > pKnoten->Intervall[1][val2 - 1]) erfuellt = 1;
		}
	}

	return erfuellt;
}
#endif

static int scoring_split_isMinus (const char *buf) {
    return (buf[0]=='-' || buf[1]=='-' || buf[2]=='-' || buf[3]=='-');
        
}

static int scoring_afg_split(LKF_AUFENTHALT *pAufenthalt, const char *grp) 
{
	unsigned int i;

    if (pAufenthalt->abt_anz) {
        for (i = 0; i < pAufenthalt->abt_anz; i++)
        {
            FUNK_LIST_STRING *funk = FunkInArray(pAufenthalt->pScoringContext->pStamm2001, pAufenthalt->abt[i].ABTFC);
            if (!funk || memcmp(((const char *)funk) + 107, grp, 5))
                return 0;
        }
        return 1;
    }
    return 0; /* V2021.2 - Quickscore ohne Abt trifft Kriterium nicht */
}

static int scoring_split_2017 (LKF_AUFENTHALT *pAufenthalt, const LKF_KNOTEN *pKnoten, int act_knoten, const char *act_subgruppe, const char *hd, int nMelId, char *sTraceLine)
{ /* V21.0 - neue Funktion fuer Modelle 2017+ */
    int val, val2;
    int i, j;
    
    int erfuellt;
    int agr01_bd;
    int agr01_found;
    
    int act_typ;
    int pat_grp;
    char tmp_spez_list[20];
    
    int splitmel;
    size_t comp_len;
    const SPEZ_LIST_STRING *pSpez;
    char c = 0;
    
    MEL_ARRAY_STRUC *pMel;
    ICD_LIST_STRING *pDiag;
    
    char act_grplgr[6];
    
    char sMel[6];
    
    if (sTraceLine) {
        *sTraceLine = 0;
    }
    
    act_typ = pKnoten->merkmals_typ[act_knoten];
    erfuellt = 0;
    val = 0;
    
    if (act_typ < 100)
    {
        switch (act_typ)
        {
            case  1: /* SPEZMEL */
                splitmel = 1;
                memcpy (sMel, pKnoten->splitmerkmal[act_knoten], LKF_AUFENTHALT_NEWMEL_LEN);
                sMel[LKF_AUFENTHALT_NEWMEL_LEN] = 0;
                
                if (sTraceLine) sprintf (sTraceLine, "SPLIT(SPEZMEL): MEL=%s", sMel);
                
                for (i = 0; i < (int)pAufenthalt->mel_anz; i++) {
                    
                    pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[i].MEL);
                    
                    if (!pMel || (i != nMelId && isGrpMel (pMel, pAufenthalt)))
                        continue;
                    
                    if (!memcmp (pAufenthalt->mel[i].MEL, sMel, LKF_AUFENTHALT_NEWMEL_LEN)) {
                        
                        for (j = 0; j < (int) pAufenthalt->pat_subgruppen; j++) {
                            
                            if (!memcmp (pAufenthalt->mel[i].MEL, pAufenthalt->subgruppe[j].gruppe + 8, LKF_AUFENTHALT_NEWMEL_LEN)) {
                                
                                if (act_subgruppe && memcmp (pAufenthalt->mel[i].MEL, act_subgruppe + 8, LKF_AUFENTHALT_NEWMEL_LEN)) splitmel = 0;
                                j = (int) pAufenthalt->pat_subgruppen;
                                
                            }
                            
                        }
                        if (splitmel) erfuellt = 1;
                    }
                }
                break;
            case  2: /* SPEZHDG4 */
                if (sTraceLine) sprintf (sTraceLine, "SPLIT(SPEZHDG4): Diagnose=%5.5s", pKnoten->splitmerkmal[act_knoten]);
                
                
                for (i = 0; !erfuellt && i < (int) pAufenthalt->diag_anz; i++) {
                    if (!pAufenthalt->diag[i].isHD)
                        continue;
                    if (!memcmp (pKnoten->splitmerkmal[act_knoten], pAufenthalt->diag[i].DIAG, 5)) erfuellt = 1;
                }
                
                break;
            case  3: /* SPEZHDG */
                if (sTraceLine) sprintf (sTraceLine, "SPLIT(SPEZHDG): Diagnose=%3.3s", pKnoten->splitmerkmal[act_knoten]);

                for (i = 0; !erfuellt && i < (int) pAufenthalt->diag_anz; i++) {
                    if (!pAufenthalt->diag[i].isHD)
                        continue;
                    if (!memcmp (pAufenthalt->diag[i].DIAG, pKnoten->splitmerkmal[act_knoten], 3)) erfuellt = 1;
                }

                break;
            case  4: /* SPEZDG4 */
            case  5: /* SPEZDG */
                if (sTraceLine)
                {
                    if (act_typ == 5)
                    {
                        sprintf (sTraceLine, "SPLIT(SPEZDG): Diagnose=%3.3s", pKnoten->splitmerkmal[act_knoten]);
                    }
                    else
                    {
                        sprintf (sTraceLine, "SPLIT(SPEZDG4): Diagnose=%5.5s", pKnoten->splitmerkmal[act_knoten]);
                    }
                }
                
                if (act_typ == 5) comp_len = 3;
                else comp_len = 5;
             
                for (i = 0; !erfuellt && i < (int) pAufenthalt->diag_anz; i++) {
                    if (!memcmp (pAufenthalt->diag[i].DIAG, pKnoten->splitmerkmal[act_knoten], comp_len)) erfuellt = 1;
                }
                break;
                
            case  6: /* ALTER */
                GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val);
                if (sTraceLine) sprintf (sTraceLine, "SPLIT(ALTER): Vergleichswert=%d", val);
                
                if (val == 0) {
                    const char *merkmal = pKnoten->splitmerkmal[act_knoten];
                    if (scoring_split_isMinus(merkmal)) {
                        if (pAufenthalt->Alter == 0) erfuellt = 1;
                    }
                    else if (pAufenthalt->Alter > 0) erfuellt = 1;
                }
                else if (val < 0) {
                    if (pAufenthalt->Alter <= -val) erfuellt = 1;
                }
                else if (pAufenthalt->Alter > val) erfuellt = 1;
                
                break;
            case  7: /* AGR01 */
            case 12: /* AGR02 */
                if (sTraceLine) sprintf (sTraceLine, (act_typ == 7 ? "SPLIT: AGR01" : "SPLIT: AGR02"));
                lkf_auf_add_category(pAufenthalt, act_typ == 7 ? "AGR01" : "AGR02", 0, 0);
                
                agr01_bd = 0;
                agr01_found = 0;
                for (i = 0; i < (int) pAufenthalt->abt_anz; i++) {
                    if (!IsBlank (pAufenthalt->abt[i].ABTFC, LKF_AUFENTHALT_ABTFC_LEN)) {
                        
                        sprintf (tmp_spez_list,".....%4.4s%8.8s", pAufenthalt->KANR, pAufenthalt->abt[i].ABTFC);
                        
                        pSpez = SpezInArray (pAufenthalt->pScoringContext, tmp_spez_list);
                        if (pSpez && !ABTFC_Spez_Check (pAufenthalt, i, pSpez, 0)) pSpez = 0;
                        if (pSpez) {
                            
                            switch ((*pSpez)[0]) {
                                    
                                default:	pSpez = 0;
                                    break;
                                    
                                case 'P':   if ((*pSpez)[27] != 'A') pSpez = 0;
                                else if (act_typ == 7 && (*pSpez)[28] != '1') pSpez = 0;
                                else if (act_typ == 12 && (*pSpez)[28] != '2') pSpez = 0;
                                    break;
                                case 'J':
                                    
                                    if (pAufenthalt->pScoringContext->modelljahr >= 2013)
                                    { /* V17.0 */
                                        pSpez = 0;
                                    }
                                    else
                                    {
                                        if (act_typ == 12) pSpez = 0;
                                        else if ((*pSpez)[27] == ' ') c = (*pSpez)[28];
                                        else if ((*pSpez)[28] == ' ') c = (*pSpez)[27];
                                        else c = 0;
                                        if (pSpez && (c == 'I' || c == 'R')) pSpez = 0;
                                    }
                                    break;
                                    
                                case 'O':   /* V15.0 */
                                    if (pAufenthalt->pScoringContext->modelljahr >= 2022) {
                                        pSpez = 0;
                                    }
                                    else {
                                        if ((*pSpez)[27] != '0') pSpez = 0;
                                        else if (act_typ == 7 && (*pSpez)[28] != '1') pSpez = 0;
                                        else if (act_typ == 12 && (*pSpez)[28] != '2') pSpez = 0;
                                    }
                                    break;
                            }
                        }
                        
                        if (pSpez) {
                            agr01_bd += pAufenthalt->abt[i].ABTVD;
                            agr01_found = 1;
                        }
                    }
                }
                
                if (agr01_bd > pAufenthalt->GESVD / 2 ||
                    (agr01_found && agr01_bd == 0 && pAufenthalt->GESVD == 0)) {
                    erfuellt = 1;
                }
                break;
        }
    }
    
    else if (act_typ >= 101 && act_typ <= 199)
    {
        sprintf (act_grplgr, "HG%03d", act_typ);
        pat_grp = 0;
        
        pDiag = FindDiag (pAufenthalt->pScoringContext->pStamm2001, hd);
        
        if (pDiag && !memcmp ((*pDiag) + 18, act_grplgr, 5)) pat_grp = 1;
        
        GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val);
        if (sTraceLine) sprintf (sTraceLine, "SPLIT(%-8.8s): PATGRP: %d", act_grplgr, pat_grp);
        if (val == 0) {
            if (pat_grp == 0) erfuellt = 1;
        }
        else {
            if (pat_grp > 0) erfuellt = 1;
        }
    }
    else if (act_typ > 300 && act_typ <= 400)
    { /* V21.0 - Ambulant */
        if (nMelId >= 0) {
            sprintf (act_grplgr, "ALG%02d", act_typ - 300);
            pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[nMelId].MEL);
            if (!memcmp (pMel->sAmbLeistGrp, act_grplgr, 5)) {
                erfuellt = 1;
            }
        }
    }
    else if (act_typ > 400 && act_typ <= 500)
    { /* V21.0 - Ambulant */
        sprintf (act_grplgr, "AFG%02d", act_typ - 400);
		erfuellt = scoring_afg_split(pAufenthalt, act_grplgr);
    }
    else if (act_typ <= 699)
    {
        sprintf (act_grplgr, "LG%03d", act_typ - 400);
        
        pat_grp = 0;
        
        for (i = 0; i < (int) pAufenthalt->mel_anz; i++)
        {
            pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[i].MEL);	
            
            if (!pMel)
                continue; 
            
            if (i != nMelId && isGrpMel (pMel, pAufenthalt))
                continue;
            
            if (!memcmp (pMel->sLGR, act_grplgr, 5)) {
                for (j = 0; j < i && (isGrpMelNr2009 (pAufenthalt, j) || memcmp (pAufenthalt->mel[i].MEL, pAufenthalt->mel[j].MEL, LKF_AUFENTHALT_NEWMEL_LEN)); j++) ;
                if (j == i) pat_grp++;
            }
        }
        
        GetInt (pKnoten->splitmerkmal[act_knoten], 5, &val2);
        if (sTraceLine) sprintf (sTraceLine, "SPLIT(%-8.8s): PATGRP: %d", act_grplgr, pat_grp);

        if (val2 == 0) {
            if (pat_grp == 0) erfuellt = 1;
        }
        else {
            if (pat_grp > 0) erfuellt = 1;
        }
    }
    
    return erfuellt;
}

static int compare_subgruppe_meldat (const void *pv1, const void *pv2)
{
	LKF_AUFENTHALT_SUBGRUPPE *p1, *p2;
	p1 = (LKF_AUFENTHALT_SUBGRUPPE *) pv1;
	p2 = (LKF_AUFENTHALT_SUBGRUPPE *) pv2;

    if (p1->lMelDat == p2->lMelDat) {
        if (p1->mel_id == p2->mel_id) return 0;
        return p1->mel_id > p2->mel_id ? 1 : -1;
    }
		
	else
		return p1->lMelDat > p2->lMelDat ? 1 : -1;

}

static void SortSubgruppeMelDat (unsigned int nCount, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe)
{
	qsort (pSubgruppe, nCount, sizeof(LKF_AUFENTHALT_SUBGRUPPE), compare_subgruppe_meldat);
}

_SCORING_EXPORT int lkf_scoring_abortable (LKF_CONTEXT *pContext, LKFEXECUTION_DELEGATE cb, unsigned int stepCount) {
    unsigned int i;

    pContext->scor_work_count = 0;
    pContext->scor_count = 0;

        
    for (i = 0; i < pContext->patient_anz; i++) {
        // error handling!
        i += lkf_context_scoring(pContext, stepCount);
        if (cb(pContext, "scoring", i)) {
            return -99;
        }
    }
        
    return (int) i;

}

_SCORING_EXPORT int lkf_context_scoring2 (LKF_CONTEXT *pContext, unsigned int anzahl, int reset) {
    if (reset) {
        pContext->scor_work_count = 0;
        pContext->scor_count = 0;
    }
    return lkf_context_scoring(pContext, anzahl);
}


_SCORING_EXPORT int lkf_context_scoring (LKF_CONTEXT *pContext, unsigned int anzahl)
{
	LKF_AUFENTHALT *pAufenthalt;
	int errorcode;
	unsigned int i;

    if (anzahl == 0) pContext->scor_work_count = 0;
	
    if (!pContext->scor_count) {
        for (i = 0; i < pContext->ka_gesamt; i++) {
            errorcode = lkf_init_ka (pContext, pContext->ka + i, 0, 0);
            if (errorcode == LKF_OUTOFMEMORY_ERROR) return errorcode;
        }
		lkf_context_sort_private_stamm (pContext);
	}
		
	for (i = 0; (!anzahl || i < anzahl) && pContext->scor_work_count < pContext->patient_anz; i++) { 

		pAufenthalt = pContext->ppAufenthalt[pContext->scor_work_count];
		++pContext->scor_work_count;
		if (!(pAufenthalt->mark & 1)) continue;

		errorcode = lkf_scoring (pContext, pAufenthalt);

		++pContext->scor_count;
		lkf_add_ka_stats (pContext, pAufenthalt, 4);


        if (errorcode) {
            pContext->executionCalled |= 32;
            return errorcode;
        }
	}
    pContext->executionCalled |= 64;
	return (int) i;
}

#ifdef SUPPORT_PRE2017
static void lkf_scoring_tkl_subgruppe (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe)
{ /* Modell 2012 - 2016 */
	unsigned int i;
	double tk_faktor;
	MEL_ARRAY_STRUC *pMel;
	int TKLMel;
	char tmp_mel_ka[12];
	long orig_scutk;

	TKLMel = 0;
	pSubgruppe->TKLModus = 0;
	if (pAufenthalt->GESVD == 0 && pAufenthalt->ENTART != 'S' && pAufenthalt->ENTART != 'T' && pAufenthalt->ENTART != LKF_ENTART_REVERS /* V18.0 */ &&
		pAufenthalt->SCSPEZ == 0 && memcmp (pSubgruppe->gruppe, "MEL22", 5)) {

		for (i = 0; i < pAufenthalt->mel_anz && !TKLMel; i++) {
		
			pMel = FindMel (pContext, pAufenthalt->mel[i].MEL);

			if (pMel && pMel->cTKL== 'J') {
				sprintf (tmp_mel_ka, "%4.4s %5.5s", pAufenthalt->KANR, pAufenthalt->mel[i].MEL);
				if (!GetMELKATKLContext (pContext, tmp_mel_ka)) TKLMel = 1;	
			}
		}
		if (TKLMel)
		{
			tk_faktor = 2;
			pSubgruppe->TKLModus = 2;
		}
		else
		{
            tk_faktor = 0.05;
            pSubgruppe->TKLModus = 1;
		}
	}
	else tk_faktor = 1;

	orig_scutk = pSubgruppe->SCUTK;
	pSubgruppe->SCUTK = simCLng (pSubgruppe->SCUTK_DOUBLE * tk_faktor);
	pSubgruppe->SCGES += pSubgruppe->SCUTK;
	pSubgruppe->SCGES -= orig_scutk;
}
#endif

static void lkf_scoring_fill_scges (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt)
{
    pAufenthalt->SCUTK_TKL = simCLng (pAufenthalt->SCUTK_DOUBLE);
    pAufenthalt->SCGES_TKL = pAufenthalt->LDFPTK + pAufenthalt->LDFPLK + pAufenthalt->SCUTK_TKL +
                  pAufenthalt->SCULK + pAufenthalt->VDZU + pAufenthalt->INTZU + pAufenthalt->MELZU + pAufenthalt->SCSPEZ;
}

#ifdef SUPPORT_PRE2017
static void lkf_scoring_tkl (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt)
{
	unsigned int i;
	double tk_faktor;
	MEL_ARRAY_STRUC *pMel;
	LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
	int TKLMel;
	char tmp_mel_ka[12];

	TKLMel = 0;
	pAufenthalt->TKLModus = 0;

	if (pAufenthalt->GESVD == 0 && pAufenthalt->ENTART != 'S' && pAufenthalt->ENTART != 'T' && pAufenthalt->ENTART != LKF_ENTART_REVERS &&
		pAufenthalt->SCSPEZ == 0 && memcmp (pAufenthalt->GRP, "MEL22", 5)) {

        for (i = 0; i < pAufenthalt->mel_anz && !TKLMel; i++) {
            
            pMel = FindMel (pContext, pAufenthalt->mel[i].MEL);
            
            if (pMel && pMel->cTKL== 'J') {
                sprintf (tmp_mel_ka, "%4.4s %5.5s", pAufenthalt->KANR, pAufenthalt->mel[i].MEL);
                if (!GetMELKATKLContext (pContext, tmp_mel_ka)) TKLMel = 1;
            }
        }

        if (TKLMel)
		{
            tk_faktor = 2;
			pAufenthalt->TKLModus = 2;
		}
		else
		{
			switch (pContext->modelljahr)
			{
				case 2010:
					tk_faktor = 0.05;	
					break;	
				case 2009:
					tk_faktor = 0.1;
					break;
				default:
					tk_faktor = 0.5;
					break;
			}
			pAufenthalt->TKLModus = 1;
		}
	}
	else tk_faktor = 1;

	pAufenthalt->SCUTK_TKL = simCLng (pAufenthalt->SCUTK_DOUBLE * tk_faktor);

	pAufenthalt->SCGES_TKL = pAufenthalt->LDFPTK + pAufenthalt->LDFPLK + pAufenthalt->SCUTK_TKL +
				  pAufenthalt->SCULK + pAufenthalt->VDZU + pAufenthalt->INTZU + pAufenthalt->MELZU + pAufenthalt->SCSPEZ;

	if (tk_faktor != 1)
	{
	
		long orig_scutk;

		for (i = 0; i < pAufenthalt->pat_subgruppen; i++) {
			pSubgruppe = pAufenthalt->subgruppe+i;
			orig_scutk = pSubgruppe->SCUTK;
			if (tk_faktor != 1) 
			{
                pSubgruppe->SCUTK = simCLng (pSubgruppe->SCUTK_DOUBLE * tk_faktor);
				pSubgruppe->SCGES += pSubgruppe->SCUTK;
				pSubgruppe->SCGES -= orig_scutk;
			}

		}
	}
}
#endif

static void lkf_quickscore_compute_abtdats (LKF_AUFENTHALT *pAufenthalt, int modelljahr, int *pAuf19_ok)
{
    int i, limit;
	int gesvd, abtvd, abtsum;
    int vd;

    if (pAufenthalt->AUFDAT[0] == '#') GetInt (pAufenthalt->AUFDAT + 1, 7, &vd);
    else {
        long lAufDat, lEntDat;
        lAufDat = lkf_dat2int (pAufenthalt->AUFDAT);
        lEntDat = lkf_dat2int (pAufenthalt->ENTDAT);

        if (lAufDat && lEntDat) vd = (int) (lEntDat - lAufDat);
        else vd = -1;
    }
    pAufenthalt->GESVD = (short) vd;
    pAufenthalt->GESVD_KORR = 0;

	if (pAufenthalt->abt_anz) {

		gesvd = (int) pAufenthalt->GESVD;
		abtsum = 0;
			
		for (i = (int) pAufenthalt->abt_anz - 1; i >= 0 && pAufenthalt->abt[i].ABTDAT[0] == '#'; i--) {
			GetInt (pAufenthalt->abt[i].ABTDAT + 1, 7, &abtvd);
			pAufenthalt->abt[i].ABTVD = abtvd;
			abtsum += abtvd;
		}

		if (i >= 0) {

			if (gesvd < 0) limit = i + 1;
			else limit = i;

			for (i = 0; i < limit; i++) {
				pAufenthalt->abt[i].ABTVD = Util_Diff_Tage(pAufenthalt, (short) i);
				abtsum += pAufenthalt->abt[i].ABTVD;
			}
			if (gesvd < 0) pAufenthalt->GESVD = abtsum;
			else {
				gesvd -= abtsum;
				if (gesvd < 0) {
					pAufenthalt->abt[limit].ABTVD = 0;
					pAufenthalt->GESVD -= gesvd;
				}
				else pAufenthalt->abt[limit].ABTVD = gesvd;
			}
		}
		else if (abtsum > pAufenthalt->GESVD) pAufenthalt->GESVD = abtsum;
	}
    if (pAufenthalt->abt_anz > 0) {
        *pAuf19_ok = 0;
        for (i = 0; i < (int) pAufenthalt->abt_anz; i++) {
            if (!memcmp (pAufenthalt->abt[i].ABTFC, "19", 2)) {
                pAufenthalt->GESVD -= pAufenthalt->abt[i].ABTVD;
                pAufenthalt->GESVD_KORR += pAufenthalt->abt[i].ABTVD;
                pAufenthalt->abt[i].ABTVD_KORR = pAufenthalt->abt[i].ABTVD;
                pAufenthalt->abt[i].ABTVD = 0;
            }
            else *pAuf19_ok = 1;

            if (modelljahr >= 2010 && !memcmp (pAufenthalt->abt[i].ABTFC, UNTERBRECHUNG_ABTFC, UNTERBRECHUNG_LEN))
            {
                pAufenthalt->GESVD -= pAufenthalt->abt[i].ABTVD;
                pAufenthalt->abt[i].ABTVD_KORR = pAufenthalt->abt[i].ABTVD;
                pAufenthalt->abt[i].ABTVD = 0;
            }
            pAufenthalt->abt[i].lp100 = pAufenthalt->abt[i].tp100 = 0;

        }
    }
    else *pAuf19_ok = 1;
}

static void lkf_compute_abtdats (LKF_AUFENTHALT *pAufenthalt, int modelljahr, int *pAuf19_ok)
{     
    unsigned int i;
    
    pAufenthalt->GESVD = 0;
    pAufenthalt->GESVD_KORR = 0;
    *pAuf19_ok = 0;

    if (pAufenthalt->isAmb && modelljahr >= 2020) {
        for (i = 0; i < pAufenthalt->abt_anz; i++)
        {
            pAufenthalt->abt[i].lp100 = pAufenthalt->abt[i].tp100 = 0;
        }
        *pAuf19_ok = 1;
    }
    else {
        for (i = 0; i < pAufenthalt->abt_anz; i++)
        {
            if (memcmp (pAufenthalt->abt[i].ABTFC, "19",2) && memcmp(pAufenthalt->abt[i].ABTFC, "        ", 8))
            {

                if (pAufenthalt->pScoringContext->modelljahr >= 2010 && !memcmp (pAufenthalt->abt[i].ABTFC, UNTERBRECHUNG_ABTFC, UNTERBRECHUNG_LEN))
                {
                    pAufenthalt->abt[i].ABTVD_KORR = pAufenthalt->abt[i].ABTVD;
                    pAufenthalt->abt[i].ABTVD = 0;
                }
                else
                {
                    *pAuf19_ok = 1;
                    pAufenthalt->abt[i].ABTVD = Util_Diff_Tage(pAufenthalt, (short) i);
                    pAufenthalt->GESVD += pAufenthalt->abt[i].ABTVD;
                }
            }
            else
            {
                pAufenthalt->GESVD_KORR += pAufenthalt->abt[i].ABTVD;
                pAufenthalt->abt[i].ABTVD_KORR = pAufenthalt->abt[i].ABTVD;
                pAufenthalt->abt[i].ABTVD = 0;
            }
            pAufenthalt->abt[i].lp100 = pAufenthalt->abt[i].tp100 = 0;
        }
    }
}



static void InactivateMel (LKF_AUFENTHALT *pAufenthalt, unsigned int i)
{
    memcpy (pAufenthalt->mel[i].MEL, "00000", LKF_AUFENTHALT_NEWMEL_LEN);
	memcpy (pAufenthalt->mel[i].MELANZ, "   0", 4);
}

static int isDuring19Aufenthalt (LKF_AUFENTHALT *pAufenthalt, int meldat)
{
	unsigned int i;
	int TageSeitAUFDAT;
	
	if (!meldat || !pAufenthalt->lAufDat) return 0; 
	TageSeitAUFDAT = (int) (meldat - pAufenthalt->lAufDat);


	for (i = 0; i < pAufenthalt->abt_anz; i++) {
		if (TageSeitAUFDAT < pAufenthalt->abt[i].ABTVD) {
			if (!memcmp (pAufenthalt->abt[i].ABTFC, "19", 2)) return 1;
		}
		else if (TageSeitAUFDAT == pAufenthalt->abt[i].ABTVD) {
			/* am Verlegungstag zählen zwei Abteilungen */
			if (memcmp (pAufenthalt->abt[i].ABTFC, "19", 2)) return 0;
		}
		else TageSeitAUFDAT -= pAufenthalt->abt[i].ABTVD;
	}
	return 0;
}

static int mel_during_abt19 (LKF_AUFENTHALT *pAufenthalt, int id)
{
	MEL_ARRAY_STRUC *pMel;

    pMel = FindMel (pAufenthalt->pScoringContext, pAufenthalt->mel[id].MEL);

	if (pMel && isDuring19Aufenthalt (pAufenthalt, pAufenthalt->mel[id].meldat_nr))
		return 1;
	return 0;
}


_SCORING_EXPORT int lkf_scoring (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt)
{

	int scoring_return;
	
	if (!pAufenthalt) {
		pContext->scor_count = 0;
		pContext->scor_work_count = 0;
        pContext->executionCalled |= 8;
		return lkf_context_scoring (pContext, 0);
	}

    pContext->executionCalled |= 16;
	scoring_return = lkf_scoring_compute (pContext, pAufenthalt);
	
	lkf_trace_finished (pContext);

	return scoring_return;
}

static int compute_dates (LKF_AUFENTHALT *pAufenthalt)
{
	int  i;
	long nEntDat;
	long nAufDat;
    long nCurDat = 0;
	long nNextDat;

    nAufDat = lkf_dat2int (pAufenthalt->AUFDAT);

    if (pAufenthalt->isAmb) {
        nEntDat = nAufDat;
    }
	else if (pAufenthalt->ENTART == 'V')
	{
		char sLastDate[10];
		sprintf (sLastDate, "%4d1231", pAufenthalt->pScoringContext->cmb_jahr);
		nEntDat = lkf_dat2int (sLastDate);
	}
	else
		nEntDat = lkf_dat2int (pAufenthalt->ENTDAT);

	
	if (!nEntDat || !nAufDat)
		return 0;

	if (pAufenthalt->abt_anz > 0)
	{
		nCurDat = lkf_dat2int (pAufenthalt->abt[0].ABTDAT);
		if (nCurDat != nAufDat)
			return 0;
	}

	pAufenthalt->GESVD = nEntDat - nAufDat;
	pAufenthalt->GESVD_KORR = 0;

	for (i = 0;i < (int)pAufenthalt->abt_anz; i++)
		pAufenthalt->abt[i].ABTVD_KORR = 0;

	for (i = 0; i < (int) pAufenthalt->abt_anz; i++)
	{
		if (i + 1 < (int) pAufenthalt->abt_anz)
			nNextDat = lkf_dat2int (pAufenthalt->abt[i+1].ABTDAT);
		else 
			nNextDat = nEntDat;
		if (nNextDat < nCurDat)
		{
			for (;i>=0;i--) pAufenthalt->abt[i].ABTVD = 0;
			pAufenthalt->GESVD = 0;
			return 0;
		}
		pAufenthalt->abt[i].ABTVD = nNextDat - nCurDat;
		if (pAufenthalt->pScoringContext->modelljahr >= 2010 && !memcmp (pAufenthalt->abt[i].ABTFC, UNTERBRECHUNG_ABTFC, UNTERBRECHUNG_LEN))
			pAufenthalt->GESVD -= pAufenthalt->abt[i].ABTVD; /* V14.0 */
		nCurDat = nNextDat;
	}
	return 1;

}

static unsigned int lkf_get_melreduziert_bonus (LKF_AUFENTHALT *pAufenthalt, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe, int nMELIndices, const int *pMelIndices, int nMELRelevant, const int *pRelevantIndices, MELMEL_OPT_DATA *pOptData, MELMEL_BOOST *pBoost)
{
	int i, k;
	int nNext;
	MELZU_DATA *pMelZuData;
    LKF_CONTEXT *pContext;
	unsigned int nMelZuBonus;
	unsigned int *pMelValid;
    int nMaxIndex = 0;
	long nMaxZuschlag;
	nNext = 0;
	nMelZuBonus = 0;

    pContext = pAufenthalt->pScoringContext;
    
	for (i = 0; i < nMELIndices; i++)
	{
		if (nNext < nMELRelevant && pRelevantIndices[nNext] == i)
		{
			++nNext;
			continue;
		}

		pMelZuData = pSubgruppe->pMelZu + pMelIndices[i];
		if (!pMelZuData->nDynMelId || pMelZuData->lDynMelDiff > 0)
			continue;

		nMaxZuschlag = 0;

		pMelValid = (unsigned int *) LKF_CALLOC (pContext, "lkf_get_melreduziert_bonus", pAufenthalt->mel_anz, sizeof(unsigned int));
        if (!pMelValid) return LKF_OUTOFMEMORY_UINTERROR;

		for (k = 0; k < (int) pAufenthalt->mel_anz; k++)
			pMelValid[k] = (pSubgruppe->pMelZu[k].nDynMelId == pMelZuData->nDynMelId) ? 1 : 0;
					
        for (k = 0; k < nMELIndices; k++) {
            pMelValid[pMelIndices[k]] |= 2;
        
            if (pBoost && pBoost[k].pAlternateIndices) {
                unsigned int l;
                for (l = 0; l < pBoost[k].alternateCount; l++) {
                    pMelValid[pBoost[k].pAlternateIndices[l]] |= 2;
                }
            }
        }

		for (k = 0; k < nMELRelevant; k++)
			pMelValid[pMelIndices[pRelevantIndices[k]]] |= 4;

		for (k = 0; k < (int) pAufenthalt->mel_anz; k++)
		{
			if (pSubgruppe->pMelZu[k].nDynMelId == pMelZuData->nDynMelId)
			{
				if ((pMelValid[k] & 1) && (!(pMelValid[k]&2) || (pMelValid[k]&4)))
				{
					if (pSubgruppe->pMelZu[k].lDynMelDiff > (long) nMaxZuschlag)
					{
						nMaxIndex = k;
						nMaxZuschlag = pSubgruppe->pMelZu[k].lDynMelDiff;
					}
				}
			}
		}
		if (nMaxZuschlag > 0)
		{
			pOptData[i].lDynMelBonus = nMaxZuschlag;
			pOptData[i].lDynMelBonusId = nMaxIndex;
			nMelZuBonus += pOptData[i].lDynMelBonus;
		}

		LKF_FREE (pContext, "lkf_get_melreduziert_bonus", pMelValid);
	}
    if (nMelZuBonus > 0) {
        return nMelZuBonus;
    }
	return nMelZuBonus;
}


void lkf_setMelMelInfo (LKF_AUFENTHALT *pAufenthalt, unsigned int melIndex) {
    unsigned int melgroupIndex = pAufenthalt->mel[melIndex].nMelMelIndexSep;
    if (melgroupIndex > 0 && !pAufenthalt->mel[melIndex].punkteRelevant) {
        
        if (pAufenthalt->mel[melIndex].melmelInfo[0] &&
            memcmp (pAufenthalt->mel[melIndex].melmelInfo, pAufenthalt->pMelMelInfo[melgroupIndex], 4)) {
            strcpy (pAufenthalt->mel[melIndex].melmelInfo, pAufenthalt->pMelMelInfo[melgroupIndex]);
            return;
        }
        if (!pAufenthalt->pMelMelInfo[melgroupIndex][0]) {
 /*
            unsigned int f, i;
            f = 0;
            for (i = 0; i < pAufenthalt->mel_anz; i++) {
                
                if (pAufenthalt->mel[i].nMelMelIndex == melgroupIndex) {
                    
                    if (pAufenthalt->isAmb && !IsBlank(pAufenthalt->mel[i].ambGruppe, 8)) {
                        f += 1;
                    }
                }
            }
            if (f < 2) {
                return;
            }
*/
            return;
        }
        
        strcpy (pAufenthalt->mel[melIndex].melmelInfo, pAufenthalt->pMelMelInfo[melgroupIndex]);
    }
}

/*
static void printrel (int melCount, int *relIndex, int curMelCount) {
    
    int i;
    printf("%3d -> ", curMelCount);
    for (i = 0; i < melCount; i++) {
        if (i < curMelCount)
            printf ("%3d ", relIndex[i]);
        else
            printf ("%3d*", relIndex[i]);
    }
    printf("\n");
}

static void printcomp (int index, int melIndex, int melCount, unsigned char *relIndex) {
    
    int i;
    printf("pr(%d/%d):", index, melIndex);
    for (i = 0; i < melCount; i++) {
        printf ("%c ", relIndex[i] ? '1' : '0');
    }
    printf("\n");
}
*/
static int lkf_aufenthalt_optimize_melmel (LKF_AUFENTHALT *pAufenthalt, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe, int nMelMelGroup, int bStaticOnly, int subgruppe_index, long *plCurMELZU)
{
	LKF_AUFENTHALT_SUBGRUPPE **ppSubgruppen;
    LKF_SCORINGDETAILS_GROUP *pScoringDetailsGroup;
    LKF_CONTEXT *pContext;
	int *pMelIndices;
	int *pMelRelevantIndices;
    int i, j, nMelCount = 0;
    int nMelRelevant;
	char sTraceLine[4096];
	int bTraceDetail;
    MELMEL_BOOST *pBoost;

    bTraceDetail = IS_TRACE_DETAIL (pAufenthalt->pScoringContext);
    
    if (pAufenthalt->pScoringDetails) {
        pScoringDetailsGroup = pAufenthalt->pScoringDetails->pCurrentGroup;
    }
    else {
        pScoringDetailsGroup = 0;
    }
    
    pContext = pAufenthalt->pScoringContext;
    
	/* Anzahl Subgruppen in der MEL-Gruppe ermitteln */
	for (i = 0; i < (int)pAufenthalt->pat_subgruppen; i++)
	{
		if (pAufenthalt->subgruppe[i].nMelMelGrp == nMelMelGroup) ++nMelCount;
	}

    /* Wenn weniger als 2 Subgruppen, ist keine Optimierung nötig */
    if (nMelCount < 2)
        return 1;

	ppSubgruppen = (LKF_AUFENTHALT_SUBGRUPPE **) LKF_CALLOC(pContext, "lkf_aufenthalt_optimize_melmel", (size_t)nMelCount, sizeof (LKF_AUFENTHALT_SUBGRUPPE *));
    if (!ppSubgruppen) return LKF_OUTOFMEMORY_ERROR;
	
    pMelIndices = (int *) LKF_CALLOC (pContext, "lkf_aufenthalt_optimize_melmel.indices", (size_t)nMelCount, sizeof (int));
    if (!pMelIndices) {
        LKF_FREE(pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
        return LKF_OUTOFMEMORY_ERROR;
    }
    
	pMelRelevantIndices = (int *) LKF_CALLOC (pContext, "lkf_aufenthalt_optimize_melmel.relindices",(size_t)nMelCount, sizeof (int));
    if (!pMelRelevantIndices) {
        LKF_FREE(pContext, "lkf_aufenthalt_optimize_melmel.indices", pMelIndices);
        LKF_FREE(pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
        return LKF_OUTOFMEMORY_ERROR;
    }
	nMelCount = 0;

	/* Ermitteln der MEL-Indices und der betreffenden Subgruppen */
	for (i = 0; i < (int)pAufenthalt->pat_subgruppen; i++)
	{
		if (pAufenthalt->subgruppe[i].nMelMelGrp == nMelMelGroup)
		{
			pMelIndices[nMelCount] = pAufenthalt->subgruppe[i].mel_id;
			ppSubgruppen[nMelCount++] = pAufenthalt->subgruppe + i;
		}
	}

	if (bTraceDetail)
	{
		sprintf (sTraceLine, "MELMEL-OPTIMIERUNG #%d: %5.5s %8.8s %c (MELMEL: %d)", subgruppe_index, pAufenthalt->mel[pSubgruppe->mel_id].MEL, pSubgruppe->gruppe, pSubgruppe->knoten_char, nMelMelGroup);
        TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
        TRACE_DETAIL(pAufenthalt,-1,"MELGRP   MEL     Anz    MELZU");
		for (i = 0; i < nMelCount; i++)
		{
			sprintf (sTraceLine, "%2d:      %5.5s %3d %8ld", i, pAufenthalt->mel[ppSubgruppen[i]->mel_id].MEL,
									 			       ppSubgruppen[i]->anz,
													   pSubgruppe->pMelZu[ppSubgruppen[i]->mel_id].lMelZu);
			TRACE_DETAIL(pAufenthalt,-1,sTraceLine);
        }
	}

	/* Alle Gruppen entfernen, die zumindest gegen eine andere Gruppe statisch "verlieren" */ 
	nMelRelevant = 0;

	for (i = 0; i < nMelCount; i++)
	{
		nMelRelevant++;
		pMelRelevantIndices[i] = 1;
		for (j = 0; j < nMelCount; j++)
		{
			if (i != j && pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,pMelIndices[i], pMelIndices[j])] == MELMELGROUP_LOSE)
			{

				if (bTraceDetail)
				{
					sprintf (sTraceLine, "MEL #%d (%5.5s) wird statisch ignoriert!", i, pAufenthalt->mel[pMelIndices[i]].MEL);
					TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
				}
				if (bStaticOnly)
					pSubgruppe->pMelZu[pMelIndices[i]].lMelZu = -1;
				pMelRelevantIndices[i] = 0;
				--nMelRelevant;
                
                lkf_setMelMelInfo (pAufenthalt, pMelIndices[i]);
				break;
			}
		}
	}

	/* Wenn alle Subgruppen zumindest einmal verlieren haben (statische Kreisdefinition), so werden alle statischen Definitionen verworfen */
	if (nMelRelevant == 0)
	{
		if (bTraceDetail)
		{
			TRACE_DETAIL (pAufenthalt, -1, "Zirkulaere statische MEL-MEL-Referenz -> statische Definition wird ignoriert");
		}
		nMelRelevant = nMelCount;
		for (i = 0; i < nMelCount; i++)
		{
			pMelRelevantIndices[i] = 1;
			if (bStaticOnly)
				pSubgruppe->pMelZu[pMelIndices[i]].lMelZu = 0;
		}
	}

	for (i = 0; i < nMelCount; i++)
	{
		if (ppSubgruppen[i] == pSubgruppe)
		{
			/* wenn die aktuelle Subgruppe nicht relevant ist -> ignoriere Gruppe */
			if (!pMelRelevantIndices[i])
			{
				if (bTraceDetail)
				{
					TRACE_DETAIL (pAufenthalt, -1, "Aktuelle Gruppe ungültig, wird durch statische Referenz unterdrückt");
				}
                if (pScoringDetailsGroup) {
                    lkf_scoringdetails_addComment(pAufenthalt, "Aktuelle Gruppe ungueltig (statische MEL-MEL-Unterdrueckung)");
                }

				LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
				LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
				LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
				return 0; /* Gruppe ignorieren */
			}
			else /* V14.0 if (!bStaticOnly) */
			{
				/* wenn die aktuelle Subgruppe relevant ist -> eliminiere alle Subgruppen, die dynamisch mit dieser verbunden sind */
				for (j = 0; j < nMelCount; j++)
				{
					if (i != j && pMelRelevantIndices[j] && pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,pMelIndices[i], pMelIndices[j])])
					{
						if (bTraceDetail)
						{
							sprintf (sTraceLine, "MEL #%d (%5.5s) wird dynamisch ignoriert (gegen aktuelle Subgruppe)!", j, pAufenthalt->mel[ppSubgruppen[j]->mel_id].MEL);
							TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
						}
						pMelRelevantIndices[j] = 0;
						if (bStaticOnly)
							pSubgruppe->pMelZu[pMelIndices[j]].lMelZu = -1;
						else
						{
							pSubgruppe->MELZU -= pSubgruppe->pMelZu[pMelIndices[j]].lMelZu;
							pSubgruppe->pMelZu[pMelIndices[j]].lMelZu = 0;
                            if (plCurMELZU) plCurMELZU[pMelIndices[j]] -= pSubgruppe->pMelZu[pMelIndices[j]].lMelZu;
						}
					}
				}
			}
		}
	}

	if (bStaticOnly)
	{
		LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
		LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
		LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
		return 1;
	}

    if (pAufenthalt->pScoringContext->modelljahr >= LKF_MIN_MELMEL_BOOST_MODEL) {
        pBoost = (MELMEL_BOOST *) LKF_CALLOC (pContext, "lkf_aufenthalt_optimize_melmel.boost", sizeof(MELMEL_BOOST), nMelCount);
        if (!pBoost) {
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
            return LKF_OUTOFMEMORY_ERROR;
        }
    }
    else {
        pBoost = 0;
    }
        
	/* Entferne alle Gruppen, die nicht mehr relevant sind, die restlichen werden in pMelIndices verdichtet */
	nMelRelevant = 0;
	for (i = 0; i < nMelCount; i++)
	{
		if (!pMelRelevantIndices[i])
		{
			pSubgruppe->MELZU -= pSubgruppe->pMelZu[pMelIndices[i]].lMelZu;
            if (plCurMELZU) plCurMELZU[pMelIndices[i]] -= pSubgruppe->pMelZu[pMelIndices[i]].lMelZu;

			pSubgruppe->pMelZu[pMelIndices[i]].lMelZu = 0;
		}
        else if (ppSubgruppen[i] != pSubgruppe) {
            
            if (pBoost) {
                int j;
                int found = 0;
                MELZU_DATA *pCur;
                
                unsigned char *pMelMelForMel = pAufenthalt->pMelMel + (pAufenthalt->mel_anz * pMelIndices[i]);
                pCur = pSubgruppe->pMelZu + pMelIndices[i];
     /*          printcomp(i, pMelIndices[i], nMelCount, pMelMelForMel); */
                
                for (j = 0; j < nMelRelevant; j++) {
                    
                    if (!memcmp (pAufenthalt->pMelMel + (pAufenthalt->mel_anz * pBoost[j].mainMelId), pMelMelForMel, pAufenthalt->mel_anz)) {
                        if (pBoost[j].pMelzu->lDynMelDiff == pCur->lDynMelDiff) {
                            if (pBoost[j].pAlternateIndices == 0) {
                                pBoost[j].pAlternateIndices = (unsigned int *) LKF_CALLOC (pContext, "lkf_aufenthalt_optimize_melmel.alt", nMelCount, sizeof (unsigned int));
                                if (!pBoost[j].pAlternateIndices) {
                                    LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
                                    LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
                                    LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
                                    return LKF_OUTOFMEMORY_ERROR;
                                }
                            }
                            pBoost[j].pAlternateIndices[pBoost[j].alternateCount++] = pMelIndices[i];
                            found = 1;
                            break;
                        }
                    }
                }
                
                if (!found) {
                    pBoost[nMelRelevant].mainMelId = pMelIndices[i];
                    pBoost[nMelRelevant].alternateCount = 0;
                    pBoost[nMelRelevant].pAlternateIndices = 0;
                    pBoost[nMelRelevant].pMelzu = pSubgruppe->pMelZu + pMelIndices[i];
                    pMelIndices[nMelRelevant++] = pMelIndices[i];
                }
            }
            else {
                pMelIndices[nMelRelevant++] = pMelIndices[i];
            }
            
        }
			
	}


	/* Wenn noch immer mehr als eine MEL übrig ist -> dynamische Optimierung */
	if (nMelRelevant > 1)
	{
		int bSkip;
		unsigned int nMelZuMax;          /* maximaler MELZU-Wert */
		unsigned int nMelZu;             /* aktueller MEL-Zuschlagswert */
		int nCurrMelIndex;               /* aktueller MEL-Index */
		int nCurrMelCount;               /* aktuell gültige MEL-Anzahl in pMelRelevantIndices */
		int nCurrMelCountMax;            /* Anzahl MELs bei aktuell maximalem Zuschlagswert */
		int *pMelMax;           /* aktuell maximale MEL-Kombination */
		MELMEL_OPT_DATA *pMelMelOptData; /* V14.0: Dynamische MEL-Indices der einzelnen MELs */
		unsigned int *pMelBonus;         /* V14.0: MEL-Bonus */

        unsigned int nMelZuBonus;             /* V14.0: MEL-Zuschlag der sich aus dynamischen MEL-Reduktionen ergibt */
		unsigned int nMaxMelZuBonus;          /* V14.0 */
		int traceDetail;
        int tracePos = 0;

		pMelMax = 0;

        traceDetail = LKF_IS_TRACE_DETAIL (pAufenthalt->pScoringContext->nTraceAufenthalt);

		nCurrMelIndex = 0; 
		nCurrMelCount = 0;
        nCurrMelCountMax = 0;
		nMelZu = 0;        
		nMelZuMax = 0;     
		nMaxMelZuBonus = 0;

        pMelMelOptData = (MELMEL_OPT_DATA *) LKF_CALLOC(pContext, "lkf_aufenthalt_optimize_melmel.melopt", (size_t) nMelRelevant, sizeof(MELMEL_OPT_DATA));
        if (!pMelMelOptData) {
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
            return LKF_OUTOFMEMORY_ERROR;
        }
		pMelBonus = 0;
        
		if (traceDetail) {
			tracePos = sprintf (sTraceLine, "DYNAMISCHE MEL-MEL-OPTIMIERUNG (%d MELs): ", nMelRelevant);
		}
		for (i = 0; i < nMelRelevant; i++)
		{
			MELZU_DATA *pMelZuData = pSubgruppe->pMelZu + pMelIndices[i];
			pMelMelOptData[i].nDynMelId = pMelZuData->nDynMelId;

			if (traceDetail) {
				tracePos += sprintf (sTraceLine + tracePos, "%5.5s(%d),", pAufenthalt->mel[pMelIndices[i]].MEL, pMelZuData->nDynMelId);
			}
		}
		if (traceDetail) {
 			TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
			for (i = 0; i < (int) pAufenthalt->mel_anz; i++) {
				tracePos = sprintf (sTraceLine, "%5.5s: ", pAufenthalt->mel[i].MEL);
				for (j = 0; j < (int) pAufenthalt->mel_anz; j++) {
					tracePos += sprintf (sTraceLine + tracePos, "%2d ", pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,i,j)]);
				}
				TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
			}
		}

		for (i = 0; i < nMelRelevant; i++) pMelRelevantIndices[i] = 0;
		pMelMax = (int *) LKF_CALLOC (pContext, "lkf_aufenthalt_optimize_melmel.melmax", (size_t)nMelRelevant, sizeof (unsigned int));
        if (!pMelMax) {
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
            return LKF_OUTOFMEMORY_ERROR;
        }

		while (nCurrMelIndex < nMelRelevant || nCurrMelCount > 0)
		{
			/* Solange MELs vorhanden sind, untersuchen, ob sie hinzufügbar sind */
			while (nCurrMelIndex < nMelRelevant)
			{
				bSkip = 0;
				for (i = 0; !bSkip && i < nCurrMelCount; i++)
				{
					/* Wenn MEL aufgrund bereits selektierter MEL ausgeschlossen wird -> ignorieren */
					if (pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,pMelIndices[pMelRelevantIndices[i]],pMelIndices[nCurrMelIndex])])
						bSkip = 1;
				}
				/* MEL hinzufügen, wenn nicht ausgeschlossen */
				if (!bSkip)
				{
					pMelRelevantIndices[nCurrMelCount++] = nCurrMelIndex;
					nMelZu += pSubgruppe->pMelZu[pMelIndices[nCurrMelIndex]].lMelZu;
                    
                    if (pBoost && pBoost[nCurrMelIndex].alternateCount > 0) {
                        unsigned int k;
                        MELMEL_BOOST *pCurBoost = pBoost + nCurrMelIndex;
                        for (k = 0; k < pCurBoost->alternateCount; k++) {
                            nMelZu += pSubgruppe->pMelZu[pCurBoost->pAlternateIndices[k]].lMelZu;
                        }
                    }
                    
				}
				++nCurrMelIndex; /* naechste MEL untersuchen */
			}

        /*    printrel (nMelCount, pMelRelevantIndices, nCurrMelCount); */


			for (j = 0; j < nMelRelevant; j++) pMelMelOptData[j].lDynMelBonus = 0;

			nMelZuBonus = lkf_get_melreduziert_bonus (pAufenthalt, pSubgruppe, nMelRelevant, pMelIndices, nCurrMelCount, pMelRelevantIndices, pMelMelOptData, pBoost);
			if (traceDetail) {
				tracePos = sprintf (sTraceLine, "KOMBINATION: ");
				for (j = 0; j < nCurrMelCount; j++) tracePos += sprintf(sTraceLine + tracePos, "%5.5s,", pAufenthalt->mel[pMelIndices[pMelRelevantIndices[j]]].MEL);
				sprintf (sTraceLine + tracePos, " melzu=%ld", (long) nMelZuBonus);
				TRACE_DETAIL (pAufenthalt,-1, sTraceLine);
			}

			/* Aktuell gefundene MEL-Kombination mit bisher bester Kombination vergleichen */
			if (nMelZu + nMelZuBonus >= nMelZuMax)
			{
				nMelZuMax = nMelZu + nMelZuBonus;
				nCurrMelCountMax = nCurrMelCount;
				memcpy (pMelMax, pMelRelevantIndices, (size_t) (sizeof(unsigned int) * (unsigned int)nCurrMelCount));
			
				nMaxMelZuBonus = nMelZuBonus;

				if (nMaxMelZuBonus > 0)
				{
                    if (!pMelBonus) {
                        pMelBonus = (unsigned int *) LKF_CALLOC(pContext, "lkf_aufenthalt_optimize_melmel.melbonus", sizeof(unsigned int), pAufenthalt->mel_anz);
                        if (!pMelBonus) {
                            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
                            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
                            LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
                            return LKF_OUTOFMEMORY_ERROR;
                        }
                    }
					for (j = 0; j < (int) pAufenthalt->mel_anz; j++)
						pMelBonus[j] = 0;
					for (j = 0; j < nMelRelevant; j++)
					{
						if (pMelMelOptData[j].lDynMelBonus > 0)
							pMelBonus[pMelMelOptData[j].lDynMelBonusId] = (unsigned int) pMelMelOptData[j].lDynMelBonus;
					}
				}
			}

			/* höchsten MEL-Index entfernen */
			nMelZu -= pSubgruppe->pMelZu[pMelIndices[pMelRelevantIndices[--nCurrMelCount]]].lMelZu;
			nCurrMelIndex = pMelRelevantIndices[nCurrMelCount];
            
            if (pBoost && pBoost[nCurrMelIndex].alternateCount > 0) {
                unsigned int k;
                MELMEL_BOOST *pCurBoost = pBoost + nCurrMelIndex;
                for (k = 0; k < pCurBoost->alternateCount; k++) {
                    nMelZu -= pSubgruppe->pMelZu[pCurBoost->pAlternateIndices[k]].lMelZu;
                }
            }
            
			/* wenn höchster MEL-Index, weitere MEL-Indices entfernen */
			if (nCurrMelIndex + 1 == nMelRelevant)
			{
				while (nCurrMelCount > 0 && pMelRelevantIndices[nCurrMelCount-1]+1 == pMelRelevantIndices[nCurrMelCount])
				{	
					nMelZu -= pSubgruppe->pMelZu[pMelIndices[pMelRelevantIndices[--nCurrMelCount]]].lMelZu;			
					nCurrMelIndex = pMelRelevantIndices[nCurrMelCount];
				}
			}
			++nCurrMelIndex; /* mit nächster MEL weitermachen */
		}

		/* fuer alle MELs, die nicht im MEL-Relevant-Array sind, MELZU entfernen */
		nCurrMelIndex = 0;
		for (i = 0; i < nMelRelevant; i++)
		{
			if (nCurrMelIndex < nCurrMelCountMax && pMelMax[nCurrMelIndex] == i)
				nCurrMelIndex++;
			else
			{
				pSubgruppe->MELZU -= pSubgruppe->pMelZu[pMelIndices[i]].lMelZu;
                if (plCurMELZU) plCurMELZU[pMelIndices[i]] -= pSubgruppe->pMelZu[pMelIndices[i]].lMelZu;
				pSubgruppe->pMelZu[pMelIndices[i]].lMelZu = 0;
                
                if (pBoost && pBoost[nCurrMelIndex].alternateCount > 0) {
                    unsigned int k;
                    MELMEL_BOOST *pCurBoost = pBoost + nCurrMelIndex;
                    for (k = 0; k < pCurBoost->alternateCount; k++) {
                        pSubgruppe->MELZU -= pSubgruppe->pMelZu[pCurBoost->pAlternateIndices[k]].lMelZu;
                        if (plCurMELZU) plCurMELZU[pMelIndices[i]] -= pSubgruppe->pMelZu[pCurBoost->pAlternateIndices[k]].lMelZu;
                        pSubgruppe->pMelZu[pCurBoost->pAlternateIndices[k]].lMelZu = 0;
                    }
                }
			}
		}

		if (nMaxMelZuBonus > 0)
		{
			for (i = 0; i < (int) pAufenthalt->mel_anz; i++)
			{
				if (pMelBonus[i])
				{
					pSubgruppe->MELZU += pMelBonus[i];
                    if (plCurMELZU) plCurMELZU[i] += pMelBonus[i];

					pSubgruppe->pMelZu[i].lMelZu += pMelBonus[i];
				}
			}
		}

		LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelMax);
		if (pMelMelOptData)
			LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelMelOptData);
		if (pMelBonus)
			LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelBonus);
	}
    
    if (pBoost) {
        int i;
        for (i = 0; i < nMelRelevant; i++) {
            if (pBoost[i].pAlternateIndices) {
                LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pBoost[i].pAlternateIndices);
            }
        }
        LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pBoost);
    }

	LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelIndices);
	LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", pMelRelevantIndices);
	LKF_FREE (pContext, "lkf_aufenthalt_optimize_melmel", ppSubgruppen);
	return 1; /* Gruppe gültig */

}

typedef struct {
	long afg_punkte;
	long alter;
	long alter0_punkte;
	long alter1_punkte;
    long afg_leist_punkte;    /* V2025.0 */
    long alter0_leist_punkte; /* V2025.0 */
    long alter1_leist_punkte; /* V2025.0 */
} LKF_AMB_MINIMUM_OPTION;

typedef struct 
{
	long min_punkte;
	LKF_AMB_MINIMUM_OPTION apg0000;
	LKF_AMB_MINIMUM_OPTION apg0010;
} LKF_AMB_MINIMUM;

typedef struct {
    int  valid;
    unsigned int groupCount;
    unsigned int abtCount;
    char grp[LKF_MAX_AMB_GRP * 10];
    float mapApg[LKF_MAX_AMB_ABT * LKF_MAX_AMB_GRP];
    int apgcount[LKF_MAX_AMB_GRP];
    double lpg[LKF_MAX_AMB_GRP];
    double lpa[LKF_MAX_AMB_ABT];
    double lps[LKF_MAX_AMB_ABT];
    double lpall;
    double spall;
    
    long   ppl[LKF_MAX_AMB_GRP];
    long   pBonus[LKF_MAX_AMB_GRP];
    
} LKF_AUFENTHALT_SCORING_ABT;

static int lkf_scoring_amb_minimum_check(LKF_AUFENTHALT *pAufenthalt, const char *basisGruppe, int modelljahr, int donotapply)
{ /* V21.1: Minimum-Check APG00.00/APG00.10 | V2025.0: APG00.11 mit LP */
	static LKF_AMB_MINIMUM minimum2017 = { 50, {5, 14, 40, 25, 0, 0, 0}, {10, 14, 50, 30, 0, 0, 0} };
    static LKF_AMB_MINIMUM minimum2025 = { 49, {5, 14, 15, 10, 0, 0, 0}, {15, 14, 49, 42, 10, 27, 27} };
    LKF_AMB_MINIMUM *pMinimum = modelljahr >= 2025 ? &minimum2025 : &minimum2017;
	LKF_AMB_MINIMUM_OPTION *pOption;
	long min_punkte;
    long min_leist_punkte;
	char knoten;

	if (pAufenthalt->SCGES - pAufenthalt->SCSPEZ >= pMinimum->min_punkte) {
		return 0;
	}
	pOption = memcmp(basisGruppe, "APG00.00", 8) ? &pMinimum->apg0010 : &pMinimum->apg0000;

	if (scoring_afg_split(pAufenthalt, "AFG01")) {
		min_punkte = pOption->afg_punkte;
        min_leist_punkte = pOption->afg_leist_punkte;
		knoten = 'A';
	}
	else if (pAufenthalt->Alter <= pOption->alter) {
		min_punkte = pOption->alter0_punkte;
        min_leist_punkte = pOption->alter0_leist_punkte;
		knoten = 'B';
	}
	else {
		min_punkte = pOption->alter1_punkte;
        min_leist_punkte = pOption->alter1_leist_punkte;
		knoten = 'C';
	}

	if (pAufenthalt->SCGES - pAufenthalt->SCSPEZ < min_punkte) {
        
        if (donotapply) {
            return 1;
        }
        
        pAufenthalt->KNT[0] = knoten;
		pAufenthalt->KNT[1] = ' ';
		
        pAufenthalt->SCULK = 0;
		pAufenthalt->MELZU = 0;
        pAufenthalt->LDFPTK = min_punkte - min_leist_punkte;
        pAufenthalt->LDFPLK = min_leist_punkte;
        pAufenthalt->SCGES = min_punkte + pAufenthalt->SCSPEZ; /* V2019.2 */
		memcpy(pAufenthalt->GRP, basisGruppe, 8);
        pAufenthalt->maxMelIndex = -1;
        
        if (IS_TRACE_DETAIL(pAufenthalt->pScoringContext)) {
            char sTraceLine[1024];
            sprintf (sTraceLine, "GRP=%8.8s, KNT=%c, MINPUNKTE=%ld, SPEZ=%ld, GES=%ld", basisGruppe, knoten, min_punkte, pAufenthalt->SCSPEZ, pAufenthalt->SCGES);
            TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
        }

        
		return 1;
	}
	return 0;
}

static void lkf_scoring_amb_adjust (LKF_AUFENTHALT *pAufenthalt, LKF_AUFENTHALT_SCORING_ABT *pScoringAbt, long sumLst)
{
    unsigned int i, j;
    double allLP;
    long abt100[LKF_MAX_AMB_ABT];
    long sumP = sumLst * 100;
    long sumadd = 0;
    
    for (i = 0; i < pScoringAbt->groupCount; i++) {
        if (pScoringAbt->lpg[i] > 0) {
            unsigned int groupOffset = i * LKF_MAX_AMB_ABT;
            int count = pScoringAbt->apgcount[i];

            if (count > 0) {
                double part = (pScoringAbt->lpg[i] / count);
                
                for (j = 0; j < pScoringAbt->abtCount; j++) {
                    if (pScoringAbt->mapApg[j + groupOffset] > 0.001) {
                        pScoringAbt->lpa[j] += part * pScoringAbt->mapApg[j + groupOffset];
                    }
                }
            }
        }
    }
    
    allLP = pScoringAbt->lpall / pScoringAbt->abtCount;
    
    for (i = 0; i < pScoringAbt->abtCount; i++) {
        sumP -= pAufenthalt->abt[i].lp100;
        abt100[i] = simCLng((pScoringAbt->lpa[i] + allLP)*100);
        pAufenthalt->abt[i].lp100 += abt100[i] + (long) (pScoringAbt->lps[i] * 100);
        sumadd += abt100[i];
    }
    
    if (sumadd < sumP) {
        for (i = 0; i < pScoringAbt->abtCount; i++) {
            if (abt100[i] > 0) {
                pAufenthalt->abt[i].lp100++;
                if (++sumadd == sumP)
                    break;
            }
        }
    }
    else if (sumadd > sumP) {
        for (i = pScoringAbt->abtCount; i > 0; i--) {
            if (abt100[i-1] > 0) {
                pAufenthalt->abt[i-1].lp100--;
                if (--sumadd == sumP)
                    break;
            }
        }
    }
}


static void lkf_scoring_amb_divide (LKF_AUFENTHALT *pAufenthalt, long tp, long lp)
{
    
    long lpabt, tpabt, tdiff, ldiff, i, abtanz;

    abtanz = (long) pAufenthalt->abt_anz;
    
    /*
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        lp += pAufenthalt->mel[i].ambFixPunkte;
    }
    */
    
    lp *= 100;
    tp *= 100;
    
    lpabt = lp / abtanz;
    tpabt = tp / abtanz;
    
    ldiff = lp - lpabt * abtanz;
    tdiff = tp - tpabt * abtanz;
    
    for (i = 0; i < abtanz; i++) {
        pAufenthalt->abt[i].lp100 += (i < ldiff) ? lpabt + 1 : lpabt;
        pAufenthalt->abt[i].tp100 += (i < tdiff) ? tpabt + 1 : tpabt;
    }
}

static void lkf_scoring_tkl_adjust (LKF_AUFENTHALT *pAufenthalt, long sumlst) {
    unsigned int i;
    long lp;
    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe, *pMaxSubgruppe;
    LKF_AUFENTHALT_MEL *pMel;
    
    if (pAufenthalt->max_index >= 0 && (unsigned int) pAufenthalt->max_index < pAufenthalt->pat_subgruppen) {
        pMaxSubgruppe = pAufenthalt->subgruppe + pAufenthalt->max_index;
    }
    else {
        pMaxSubgruppe = 0;
    }
    
    for (i = 0; i < pAufenthalt->pat_subgruppen; i++) {
        pSubgruppe = pAufenthalt->subgruppe + i;
        
        if (i == pAufenthalt->max_index) {
            lp = pSubgruppe->SCULK + pAufenthalt->LDFPLK + pSubgruppe->MELZU_DIRECT;
        }
        else if (pMaxSubgruppe && pMaxSubgruppe->pMelZu && pSubgruppe->mel_id >= 0) {
            lp = pMaxSubgruppe->pMelZu[pSubgruppe->mel_id].lMelZu; /* V2020.3 */
        }
        else {
            lp = pSubgruppe->MELZU;
        }
        
        if (pSubgruppe->mel_id >= 0)
        {
            pMel = pAufenthalt->mel + pSubgruppe->mel_id;
        }
        else { /* V2022.2 */
            pMel = 0;
        }

        if (pMel && (IsBlank (pMel->KALEIST, 6) || !memcmp (pAufenthalt->KANR, pMel->KALEIST, 4))) {
            if (!IsBlank(pMel->FCLEIST, 8)) {
                unsigned int k;
                unsigned int melabt;
                LKF_AUFENTHALT_ABT *pAbt;
                melabt = 0;
                for (k = 0; k < pAufenthalt->abt_anz; k++) {
                    if (!memcmp (pAufenthalt->abt[k].ABTFC, pMel->FCLEIST, 8)) {
                        ++melabt;
                    }
                }
                if (melabt > 0) {
                    long lpabt, plus1count;
                    lpabt = lp * 100 / melabt;
                    plus1count = lp * 100 - lpabt * melabt;
                    for (k = 0; k < pAufenthalt->abt_anz; k++) {
                        pAbt = pAufenthalt->abt + k;
                        if (!memcmp (pAbt->ABTFC, pMel->FCLEIST, 8)) {
                            pAbt->lp100 += lpabt;
                            if (plus1count > 0) {
                                pAbt->lp100++;
                                plus1count--;
                            }
                        }
                    }
                }
                else {
                    lkf_scoring_amb_divide(pAufenthalt, 0, lp);
                }
            }
            else {
                lkf_scoring_amb_divide(pAufenthalt, 0, lp);
            }
        }
        else {
            lkf_scoring_amb_divide(pAufenthalt, 0, lp);
        }
    }
}

static void lkf_scoring_divide_lst (LKF_AUFENTHALT_SCORING_ABT *pScoringAbt, unsigned int melabt, const char *ambMap, double lp)
{
    unsigned int i;
    
    double ambP = lp / melabt;
    
    for (i = 0; i < pScoringAbt->abtCount; i++) {
        if (ambMap[i]) {
            pScoringAbt->lpa[i] += ambP;
        }
    }
}

static void lkf_scoring_divide_special (LKF_AUFENTHALT_SCORING_ABT *pScoringAbt, unsigned int melabt, const char *ambMap, double lp)
{ /* V2019.0 */
    unsigned int i;
    
    double ambP = lp / melabt;
    
    for (i = 0; i < pScoringAbt->abtCount; i++) {
        if (ambMap[i]) {
            pScoringAbt->lps[i] += ambP;
        }
    }
}

static void lkf_adjust_melzu_pkt (LKF_AUFENTHALT *pAufenthalt) {
    
    unsigned int i, j;
    unsigned int hauptmelindex;
    LKF_AUFENTHALT_SUBGRUPPE *pSubGruppe;
    if (pAufenthalt->subgruppe && pAufenthalt->max_index >= 0) {
        pSubGruppe = pAufenthalt->subgruppe + pAufenthalt->max_index;
        hauptmelindex  = (unsigned int) pSubGruppe->mel_id;
    }
    else {
        pSubGruppe = 0;
        hauptmelindex = 0;
    }
    
    
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        if (pAufenthalt->mel[i].punkteIndex != i)
            pAufenthalt->mel[i].punkteIndex = pAufenthalt->mel[pAufenthalt->mel[i].punkteIndex].punkteIndex;
    }
    
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        
        if (pAufenthalt->mel[i].punkteIndex != i) {
            
            long lcount = 0, lmelzu, lmelzuSum = 0, lmelzuBonus;
            unsigned int sumPunkteIndex = pAufenthalt->mel[i].punkteIndex;
            int melanz;
            
            for (j = 0; j < pAufenthalt->mel_anz; j++) {
                if (pAufenthalt->mel[j].punkteIndex == sumPunkteIndex) {
                    if (GetInt (pAufenthalt->mel[j].ORIG_MELANZ, LKF_AUFENTHALT_MELANZ_LEN, &melanz)) {
                        lmelzuSum += pAufenthalt->mel[j].melzu;
                        lcount += melanz;
                        //if (pSubGruppe && j == hauptmelindex) --lcount;
                    }
                }
            }
            
            if (lcount > 1) {
                lmelzu = lmelzuSum / lcount;
                lmelzuBonus = lmelzuSum - lmelzu * lcount;
                
                for (j = 0; j < pAufenthalt->mel_anz; j++) {
                    if (pAufenthalt->mel[j].punkteIndex == sumPunkteIndex) {
                        
                        if (GetInt (pAufenthalt->mel[j].ORIG_MELANZ, LKF_AUFENTHALT_MELANZ_LEN, &melanz)) {
                            //if (pSubGruppe && j == hauptmelindex) --melanz;
                            pAufenthalt->mel[j].melzu = melanz * lmelzu;
                            if (lmelzuBonus >= melanz) {
                                pAufenthalt->mel[j].melzu += melanz;
                                lmelzuBonus -= melanz;
                            }
                            else if (lmelzuBonus > 0) {
                                pAufenthalt->mel[j].melzu += lmelzuBonus;
                                lmelzuBonus = 0;
                            }
                            pAufenthalt->mel[j].punkteIndex = j;
                        }
                    }
                }
            }
        }
    }
}


// #define LKF_SCORING_AMB_ABT_CHECK 1


#ifdef LKF_SCORING_AMB_ABT_CHECK
static int lkf_scoring_amb_check (LKF_AUFENTHALT *pAufenthalt) {
    
    char trace_line[1024];
    long lp = 0;
    long tp = 0;
    char abtpos[10];
    long lpabt100, tpabt100;
	unsigned int i;
    int ok = 1;
    
    for (i = 0; i < pAufenthalt->abt_anz; i++) {
        lkf_auf_get_abtscor100(pAufenthalt, i, abtpos, &tpabt100, &lpabt100);
        lp += lpabt100;
        tp += tpabt100;
        sprintf (trace_line, "abt %3.3s %8.8s TP:%5ld.%02ld, LP:%5ld.%02ld", pAufenthalt->abt[i].ABTPOS, pAufenthalt->abt[i].ABTFC, tpabt100 / 100, tpabt100 % 100, lpabt100 / 100, lpabt100 % 100);
        TRACE_DETAIL(pAufenthalt, i, trace_line);
    }
    sprintf (trace_line, "sum              TP:%5ld.%02ld, LP:%5ld.%02ld", tp/100, tp%100, lp/100, lp%100);
    TRACE_DETAIL(pAufenthalt, i, trace_line);
    sprintf (trace_line, "aufenthalt       TP:%5ld.00, LP:%5ld.00 (LP:%5ld, SCULK:%5ld, MELZU:%5ld)", pAufenthalt->LDFPTK, (pAufenthalt->LDFPLK + pAufenthalt->SCULK + pAufenthalt->MELZU), pAufenthalt->LDFPLK, pAufenthalt->SCULK, pAufenthalt->MELZU);
    TRACE_DETAIL(pAufenthalt, i, trace_line);
    
    if (tp != pAufenthalt->LDFPTK * 100) {
        ok = 0;
    }
    
    if (lp != (pAufenthalt->LDFPLK + pAufenthalt->MELZU) * 100) {
        ok = 0;
    }
    
    return ok;
    
}
#endif

static int lkf_has_amb_melmel (LKF_AUFENTHALT *pAufenthalt) {
    if (pAufenthalt->nMelMelCount == 0)
        return 0;
    return 1;
}

typedef struct {
    double mel_kp;
    double mel_lp;
    char gruppe[8];
    char knoten;
    int melanz;
} AMB_MELMEL;


typedef struct {
    unsigned int melAnz;
    unsigned int melAnzOpt;
    AMB_MELMEL *pAmbMelMel;
    char *melmel_relevant;
    unsigned int *melOptIndices;
    double points;
} AMB_MELMEL_OPT;

static int lkf_optimize_amb_melmel (LKF_AUFENTHALT *pAufenthalt, AMB_MELMEL_OPT *pOpt) {
    
    unsigned int i, j;
    unsigned int melIndexLeft, melIndexRight;
    
    double LP = 0;
    double KP = 0;
    double maxLP = 0;
    double maxGrpKP = 0;
    
	double mel_lp, mel_kp;

    char maxGrp[10];
    
    int ret;
    
    LKF_AUFENTHALT_SCORING_ABT scoringAbt;
    LKF_CONTEXT *pContext;
    
    pContext = pAufenthalt->pScoringContext;

	memset (&scoringAbt, 0, sizeof (LKF_AUFENTHALT_SCORING_ABT));
    
    for (i = 0; i < pOpt->melAnzOpt; i++) {
        
        melIndexLeft = pOpt->melOptIndices[i];
        if (!pOpt->melmel_relevant[melIndexLeft])
            continue;
        
        for (j = 0; j < pOpt->melAnzOpt; j++) {
            
            if (i == j)
                continue;
            
            melIndexRight = pOpt->melOptIndices[j];
            if (!pOpt->melmel_relevant[melIndexRight])
                continue;
        
            if (pAufenthalt->pMelMel[melIndexLeft*pOpt->melAnz + melIndexRight]) {
                
                AMB_MELMEL_OPT left;
                AMB_MELMEL_OPT right;
                char *melmel_relevant_left, *melmel_relevant_right;
                
                melmel_relevant_left = (char *) LKF_MALLOC(pContext, "lkf_optimize_amb_melmel", pOpt->melAnz);
                if (!melmel_relevant_left) return LKF_OUTOFMEMORY_ERROR;
                
                melmel_relevant_right = (char *) LKF_MALLOC(pContext, "lkf_optimize_amb_melmel", pOpt->melAnz);
                if (!melmel_relevant_right) {
                    LKF_FREE(pContext, "lkf_optimize_amb_melmel", melmel_relevant_left);
                    return LKF_OUTOFMEMORY_ERROR;
                }
                memcpy (melmel_relevant_left, pOpt->melmel_relevant, pOpt->melAnz);
                memcpy (melmel_relevant_right, pOpt->melmel_relevant, pOpt->melAnz);
                
                memcpy (&left, pOpt, sizeof (AMB_MELMEL_OPT));
                memcpy (&right, pOpt, sizeof (AMB_MELMEL_OPT));
                
                left.melmel_relevant = melmel_relevant_left;
                right.melmel_relevant = melmel_relevant_right;
                
                melmel_relevant_left[melIndexRight] = 0;
                melmel_relevant_right[melIndexLeft] = 0;
                
                ret = lkf_optimize_amb_melmel(pAufenthalt, &left);
                if (ret >= 0)
                    ret = lkf_optimize_amb_melmel(pAufenthalt, &right);
                if (ret < 0) {
                    LKF_FREE(pContext, "lkf_optimize_amb_melmel", melmel_relevant_left);
                    LKF_FREE(pContext, "lkf_optimize_amb_melmel", melmel_relevant_right);
                    return LKF_OUTOFMEMORY_ERROR;
                }
                
                if (left.points >= right.points) {
                    pOpt->points = left.points;
                    memcpy (pOpt->melmel_relevant, melmel_relevant_left, pOpt->melAnz);
                }
                else {
                    pOpt->points = right.points;
                    memcpy (pOpt->melmel_relevant, melmel_relevant_right, pOpt->melAnz);
                }
                
                LKF_FREE (pContext, "lkf_optimize_amb_melmel", melmel_relevant_left);
                LKF_FREE (pContext, "lkf_optimize_amb_melmel", melmel_relevant_right);
                return 0;
            }
        }
    }
    
    KP = 0;
    LP = 0;
    memset (maxGrp, ' ', 8);
    
    for (i = 0; i < pOpt->melAnz; i++) {
        
        if (!pOpt->melmel_relevant[i] || !pOpt->pAmbMelMel[i].gruppe[0])
            continue;
        
        
        if (i == 0 || KP < pOpt->pAmbMelMel[i].mel_kp)
        {
            KP = pOpt->pAmbMelMel[i].mel_kp;
        }
        
        mel_lp = pOpt->pAmbMelMel[i].mel_lp;
        mel_kp = pOpt->pAmbMelMel[i].mel_kp;
        
        if (i == 0 || mel_lp > maxLP || (mel_lp == maxLP && mel_kp > maxGrpKP ) || (mel_lp == maxLP && mel_kp == maxGrpKP  && memcmp (maxGrp, pOpt->pAmbMelMel[i].gruppe,8)>0)) {
            maxLP = mel_lp;
            maxGrpKP = mel_kp;
            memcpy (maxGrp, pOpt->pAmbMelMel[i].gruppe, 8);
        }

        
        if (!memcmp (pOpt->pAmbMelMel[i].gruppe, "APG", 3)) {
            int found = 0;
            char cur[10];
            unsigned int g;

            sprintf (cur, "%8.8s%c", pOpt->pAmbMelMel[i].gruppe, pOpt->pAmbMelMel[i].knoten);
            
            for (g = 0; g < scoringAbt.groupCount; g++) {
                if (!memcmp (scoringAbt.grp + 10 * g, cur, 9)) {
                    found = 1;
                    break;
                }
            }
            
            if (!found) {
                if (scoringAbt.groupCount < LKF_MAX_AMB_GRP - 1) {
                    memcpy (scoringAbt.grp + scoringAbt.groupCount++ * 10, cur, 10);
                }
                LP += pOpt->pAmbMelMel[i].mel_lp;
            }
        }
        else
        {
            double v = pOpt->pAmbMelMel[i].mel_lp * pOpt->pAmbMelMel[i].melanz;
            LP += v;
        }
    }
    
    pOpt->points = KP + LP;
    
    
//    printf ("%12.12s/%8.8s: %8.2lf %8.2lf %8.2lf\n", pAufenthalt->PATID, pAufenthalt->AUFDAT, KP, LP, pOpt->points);
    
    return 1;
}

static int lkf_compute_amb_melmel (LKF_AUFENTHALT *pAufenthalt, char *melmel_relevant) {
    
    unsigned int i, j;
    unsigned int *melmel_opt;
    unsigned int optCount = 0;
    char errbuf[1024];
    AMB_MELMEL *ambMelMel;
    LKF_CONTEXT *pContext;
    MEL_ARRAY_STRUC *pMelDef;
    const LKF_KNOTEN *pKnoten;
    short act_knoten;
    int nSplitSteps;
    int scoring_split_result;
    int success;
    unsigned int melAnz;
    int modelljahr;
    AMB_MELMEL_OPT melmelOpt;
    unsigned int nMelMelGroup;
    success = 1;
    
    pContext = pAufenthalt->pScoringContext;
    
    melAnz = pAufenthalt->mel_anz;
    pContext = pAufenthalt->pScoringContext;
    modelljahr = pContext->modelljahr;
    
    melmel_opt = (unsigned int*) LKF_CALLOC (pContext, "lkf_compute_amb_melmel.opt", sizeof (unsigned int), melAnz);
    if (!melmel_opt) return LKF_OUTOFMEMORY_ERROR;
    
    memset (melmel_relevant, 1, melAnz);
    
    ambMelMel = (AMB_MELMEL *) LKF_CALLOC(pContext, "lkf_compute_amb_melmel.melmel", sizeof (AMB_MELMEL), melAnz);
    if (!ambMelMel) {
        LKF_FREE(pContext, "lkf_compute_amb_melmel.opt", melmel_opt);
        return LKF_OUTOFMEMORY_ERROR;
    }
    lkf_auf_add_category(pAufenthalt, "AMBMELMEL", 0, 0);
    
    for (i = 0; i < pAufenthalt->mel_anz; i++) {

        LKF_AUFENTHALT_MEL *pMel = pAufenthalt->mel + i;
        if (pMel->MEL_RELEVANT == 'N' || pMel->MEL_RELEVANT == 'K') {
            melmel_relevant[i] = 0;
            continue;
        }
        
        if (modelljahr >= 2021 && pMel->nIgnoreMel) {
            melmel_relevant[i] = 0;
            continue;
        }
        
        if (pMel->nTagMelAnzRelevant == 0) /* V22.2 */
        {
            melmel_relevant[i] = 0;
            continue;
        }
        
        pMelDef = FindMel(pContext, pMel->MEL);
        if (pMelDef && pMelDef->ambFixPunkte > 0)
        { /* V2019.0 */
            melmel_relevant[i] = 0;
            continue;
        }

        nMelMelGroup = pAufenthalt->mel[i].nMelMelIndex;
        if (nMelMelGroup > 0) {
            
            for (j = 0; j < melAnz; j++) {
                
				LKF_AUFENTHALT_MEL *pOtherMel;
                if (i == j)
                    continue;
                
                pOtherMel = pAufenthalt->mel + j;
                if (pOtherMel->MEL_RELEVANT == 'N' || pOtherMel->MEL_RELEVANT == 'K')
                    continue;
                
                if (modelljahr >= 2021 && pOtherMel->nIgnoreMel)
                    continue;
                
                if (pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,i, j)] == MELMELGROUP_LOSE) {
                    melmel_relevant[i] = 0;
                    lkf_setMelMelInfo (pAufenthalt, i);
                    break;
                }
            }
            
            if (melmel_relevant[i])
                melmel_opt[optCount++] = i;
            else
                continue;
        }
        
        if (pAufenthalt->psych_flag) {
        
            
            // TODO: check relevant fŸr MELMEL ?
            
            int melindex = pMel->nMelIndex;
            
            if (IsConstMEL (pContext, CONSTMEL_AM060_7596, melindex)) {
                if (!(pAufenthalt->psych_flag & 2)) continue;
            }
            else if (IsConstMEL (pContext, CONSTMEL_AM070_7597, melindex)) {
                if (!(pAufenthalt->psych_flag & 4)) continue;
            }
            else if (IsConstMEL (pContext, CONSTMEL_AM080_7598, melindex)) {
                if (!(pAufenthalt->psych_flag & 8)) continue;
            }
            else if (IsConstMEL (pContext, CONSTMEL_AM090_7601, melindex)) {
                if (!(pAufenthalt->psych_flag & 16)) continue;
            }
            else if (IsConstMEL (pContext, CONSTMEL_AM110, melindex)) {
                if (!(pAufenthalt->psych_flag & 32)) continue;
            }
            else if (modelljahr >= 2022 && IsConstMEL (pContext, CONSTMEL_AM150, melindex)) {
                if (!(pAufenthalt->psych_flag & 256)) continue;
            }
            else if (IsConstMEL (pContext, CONSTMEL_AM120, melindex)) {
                if (!(pAufenthalt->psych_flag & 64)) continue;
            }
            else if (IsConstMEL (pContext, CONSTMEL_AM130, melindex)) {
                if (pContext->modelljahr >= 2017) {
                    if (!(pAufenthalt->psych_flag & 192)) continue;
                }
                else if (!(pAufenthalt->psych_flag & 128)) continue;
            }
            else
                continue;
            
        }
        
        if (!pMelDef || !pMelDef->sAmbGruppe[0] || IsEmpty(pMelDef->sAmbGruppe, 8)) {
            if (modelljahr >= 2025) {
                memcpy (ambMelMel[i].gruppe, "APG00.11", 8);
            }
            else {
                memcpy (ambMelMel[i].gruppe, "APG00.10", 8);
            }
            continue;
        }
        
        pKnoten = GetAMBKnoten (pContext->pStamm2001, pMelDef->sAmbGruppe, errbuf);
        if (!pKnoten)
        {
            success = -5;
            sprintf (pContext->errortext, "FEHLER beim Einlesen des Files '%8.8s': %s",
                     pMelDef->sAmbGruppe, errbuf);
            break;
        }
        
        act_knoten = 0;
        
        nSplitSteps = 0;
        
        while (pKnoten->nfl[act_knoten] != -99)
        {
            if (++nSplitSteps > 20)
            {
                /* Nach 20 Schritten abbrechen - vermutlich Fehler im Stammdaten-File */
                sprintf (pContext->errortext, "FEHLER beim Scoring-Split von '%8.8s', Abbruch nach 20 Schritten, vermutlich Fehler im Stammdaten-File",
                         pMelDef->sAmbGruppe);
                success = -6;
                break;
            }
            
            scoring_split_result = scoring_split_2017(pAufenthalt, pKnoten, act_knoten, 0, pAufenthalt->HD, (int) i, 0);
            if (scoring_split_result)
                act_knoten = pKnoten->nfl[act_knoten]-1;
            else act_knoten = pKnoten->nfl[act_knoten];
            
        }
        
        ambMelMel[i].mel_kp = pKnoten->tk_anteil[act_knoten];
        ambMelMel[i].mel_lp = pKnoten->lk_anteil[act_knoten];
        
        if (IsBlank(pMelDef->sAmbGruppe, 8))
            ambMelMel[i].gruppe[0] = 0;
        else {
            memcpy (ambMelMel[i].gruppe, pMelDef->sAmbGruppe, 8);
            pMel->ambKnoten = pKnoten->knoten_char[act_knoten];
            strcpy (pMel->ambGruppe, pMelDef->sAmbGruppe);
        }
        if (pContext->modelljahr >= 2017)
            ambMelMel[i].melanz = pMel->nTagMelAnzRelevant;
        else
            ambMelMel[i].melanz = atoi(pMel->MELANZ);
        ambMelMel[i].knoten = pKnoten->knoten_char[act_knoten];
        
    }
    
    if (success < 0) {
        LKF_FREE (pContext, "lkf_compute_amb_melmel", melmel_opt);
        LKF_FREE (pContext, "lkf_compute_amb_melmel", ambMelMel);
        return success;
    }
    
    melmelOpt.melAnz = melAnz;
    melmelOpt.pAmbMelMel = ambMelMel;
    melmelOpt.melOptIndices = melmel_opt;
    melmelOpt.melAnzOpt = optCount;
    melmelOpt.melmel_relevant = melmel_relevant;
    
    success = lkf_optimize_amb_melmel(pAufenthalt, &melmelOpt);
    if (success < 0) {
        LKF_FREE (pContext, "lkf_compute_amb_melmel", melmel_opt);
        LKF_FREE (pContext, "lkf_compute_amb_melmel", ambMelMel);
        return success;
    }
    for (j = 0; j < pAufenthalt->mel_anz; j++) {
        lkf_setMelMelInfo(pAufenthalt, j);
    }
    
    
    LKF_FREE (pContext, "lkf_compute_amb_melmel", melmel_opt);
    LKF_FREE (pContext, "lkf_compute_amb_melmel", ambMelMel);
    return 1;
}

static unsigned int lkf_scoring_check_fcleist_index (LKF_AUFENTHALT_SCORING_ABT *pScoringAbt, const LKF_AUFENTHALT *pAufenthalt, const LKF_AUFENTHALT_MEL *pMel, char *ambabtmap)
{ /* V2019.0 */
    unsigned int melabt = 0;
    if (pScoringAbt->valid) {
        melabt = 0;
        if (IsBlank (pMel->KALEIST, 6) || !memcmp (pAufenthalt->KANR, pMel->KALEIST, 4)) {
            if (!IsBlank(pMel->FCLEIST, 8)) {
                unsigned int k;
                memset (ambabtmap, 0, pScoringAbt->abtCount);
                for (k = 0; k < pScoringAbt->abtCount; k++) {
                    if (!memcmp (pAufenthalt->abt[k].ABTFC, pMel->FCLEIST, 8)) {
                        ambabtmap[k] = 1;
                        ++melabt;
                    }
                }
            }
        }
    }
    return melabt;
}

static int lkf_scoring_compute_amb (LKF_AUFENTHALT *pAufenthalt)
{
    int bTraceInfo;
    int bTraceDetail;
    int ret;
    unsigned int countedMELs = 0;
    
    double LP = 0;
    double KP = 0;
    double SP = 0; /* V2019.0 */
    double maxLP = 0;
    double maxGrpKP = 0;
    unsigned int maxMelIndex = 0;
    
    LKF_AUFENTHALT_SCORING_ABT scoringAbt;
    
    short act_knoten;
    int nSplitSteps;
    int scoring_split_result;
    
    char sTraceLine[1024];
    
    const char *basisGruppe;
    /* int skipMinimumCheck; */
    
    MEL_ARRAY_STRUC *pMelDef;
    const LKF_KNOTEN *pKnoten;
    
    LKF_CONTEXT *pContext = pAufenthalt->pScoringContext;
    STAMM2001 *pStamm = pContext->pStamm2001;
    
    char ambabtmap[LKF_MAX_AMB_ABT];
    unsigned int melabt = 0;
    
    char *melmel_relevant = 0;
    unsigned int i;
    int *melgrpIndex;
    
    int modelljahr;
    
    modelljahr = pContext->modelljahr;
    
    bTraceInfo = IS_TRACE_INFO (pContext);
    bTraceDetail = IS_TRACE_DETAIL (pContext);
    
    if (bTraceInfo)
        TRACE_INFO(pAufenthalt, -1, "Scoring Punkteberechnung (spitalsambulant)");

    basisGruppe = "APG00.00";
    /* skipMinimumCheck = 0; */
    
    memset (&scoringAbt, 0, sizeof (LKF_AUFENTHALT_SCORING_ABT));
    scoringAbt.abtCount = pAufenthalt->abt_anz;
    scoringAbt.valid = 1; // (scoringAbt.abtCount > 1);
    if (scoringAbt.valid) {
        scoringAbt.groupCount = 0;
        if (scoringAbt.abtCount > LKF_MAX_AMB_ABT) scoringAbt.abtCount = LKF_MAX_AMB_ABT;
    }
    
    melgrpIndex = 0;
    if (pAufenthalt->mel_anz) {
        unsigned int i;
        double mel_kp, mel_lp;

        if (lkf_has_amb_melmel(pAufenthalt)) {
            melmel_relevant = (char *) LKF_MALLOC (pContext, "lkf_scoring_compute_amb.rel", pAufenthalt->mel_anz);
            if (!melmel_relevant) return LKF_OUTOFMEMORY_ERROR;
            ret = lkf_compute_amb_melmel(pAufenthalt, melmel_relevant);
            if (ret < 0) return ret;
        }

        melgrpIndex = (int *) LKF_CALLOC(pContext, "lkf_scoring_compute_amb", pAufenthalt->mel_anz, sizeof(int));
        if (!melgrpIndex) {
            if (melmel_relevant) LKF_FREE(pContext, "lkf_scoring_compute_amb", melmel_relevant);
            return LKF_OUTOFMEMORY_ERROR;
        }
        
        for (i = 0; i < pAufenthalt->mel_anz; i++) {
         
            LKF_AUFENTHALT_MEL *pMel = pAufenthalt->mel + i;
            melgrpIndex[i] = -1;
            if (pMel->MEL_RELEVANT == 'N' || pMel->MEL_RELEVANT == 'K')
                continue;
            
            if (pMel->nIgnoreMel && modelljahr >= 2021)
                continue; /* V2021.2 */
            
            if (modelljahr >= 2017 && pMel->nTagMelAnzRelevant == 0)
                continue; /* V22.1 */
        
            pMelDef = FindMel(pContext, pMel->MEL);
            
            if (!pMelDef)
                continue;
            
            if (bTraceDetail) {
                sprintf (sTraceLine, "  mel: %5.5s (%4.4s/%8.8s)", pMel->MEL, pMel->MELANZ, pMel->MELDAT);
                TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
            }
            
            if (pMelDef->ambFixPunkte > 0)
            { /* V2019.0 */
				double fixPunkte;
                pMel->ambFixPunkte = pMelDef->ambFixPunkte * pMel->nTagMelAnzRelevant;
                fixPunkte = pMel->ambFixPunkte;
                SP += fixPunkte;
                melabt = lkf_scoring_check_fcleist_index (&scoringAbt, pAufenthalt, pMel, ambabtmap);
                                
                if (bTraceDetail) {
                    sprintf (sTraceLine, "  fixpunkte: %.2f, melabt: %d", fixPunkte, melabt);
                    TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                }
                
                lkf_auf_add_category(pAufenthalt, "AMBMELFIX", 0, 0);
                
                if (melabt > 0) {
                    lkf_scoring_divide_special (&scoringAbt, melabt, ambabtmap, fixPunkte);
                }
                else {
                    scoringAbt.spall += fixPunkte;
                }
                pMel->punkteRelevant = 1;
                continue;
            }
            
            if (melmel_relevant && !melmel_relevant[i])
                continue;
            
            if (modelljahr >= 2025 && pMelDef->cTKL == 'J') {
                continue; /* V2026.0 */
            }
            
            if (pAufenthalt->psych_flag) {
                
 
                int melindex = pMel->nMelIndex;
 
				if (bTraceDetail) {
					sprintf(sTraceLine, "  psych=%d (melindex=%d)", pAufenthalt->psych_flag, melindex);
					TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
				}

                if (IsConstMEL (pContext, CONSTMEL_AM060_7596, melindex)) {
                    if (!(pAufenthalt->psych_flag & 2)) continue;
                }
                else if (IsConstMEL (pContext, CONSTMEL_AM070_7597, melindex)) {
                    if (!(pAufenthalt->psych_flag & 4)) continue;
                }
                else if (IsConstMEL (pContext, CONSTMEL_AM080_7598, melindex)) {
                    if (!(pAufenthalt->psych_flag & 8)) continue;
                }
                else if (IsConstMEL (pContext, CONSTMEL_AM090_7601, melindex)) {
                    if (!(pAufenthalt->psych_flag & 16)) continue;
                }
                else if (IsConstMEL (pContext, CONSTMEL_AM110, melindex)) {
                    if (!(pAufenthalt->psych_flag & 32)) continue;
                }
                else if (modelljahr >= 2022 && IsConstMEL (pContext, CONSTMEL_AM150, melindex)) {
                    if (!(pAufenthalt->psych_flag & 256)) continue;
                }
                else if (IsConstMEL (pContext, CONSTMEL_AM120, melindex)) {
                    if (!(pAufenthalt->psych_flag & 64)) continue;
                }
                else if (IsConstMEL (pContext, CONSTMEL_AM130, melindex)) {
                    if (modelljahr >= 2017) {
                        if (!(pAufenthalt->psych_flag & 192)) continue;
                    }
                    else if (!(pAufenthalt->psych_flag & 128)) continue;
                }
                else
                    continue;
                
            }
            
            countedMELs++;
            
            if (!pMelDef)
                continue; /* sollte schon zuvor einen Fehler ausgeloest */
            
            if (!pMelDef->sAmbGruppe[0] || IsEmpty(pMelDef->sAmbGruppe, 8)) {
                
                if (modelljahr >= 2025) {
                    /*
                    if (bTraceDetail) {
                        sprintf (sTraceLine, "  keine AMBGRUPPE => Basisgruppe auf APG00.11");
                        TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                    }
                    basisGruppe = "APG00.11";
                    */
                    lkf_auf_add_category(pAufenthalt, "AMBMIN:00", 0, 0);
                    if (bTraceDetail) {
                        sprintf (sTraceLine, "  keine AMBGRUPPE => Basisgruppe bleibt auf APG00.00");
                        TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                    }
                }
                else {
                    if (bTraceDetail) {
                        sprintf (sTraceLine, "  keine AMBGRUPPE => Basisgruppe auf APG00.10");
                        TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                    }
                    basisGruppe = "APG00.10";
                }
                continue;
            }
            else if (modelljahr >= 2025) {
                basisGruppe = 0;
                /* skipMinimumCheck = 1; */
            }
            
            pKnoten = GetAMBKnoten (pStamm, pMelDef->sAmbGruppe, sTraceLine);
            if (!pKnoten)
            {
                sprintf (pContext->errortext, "FEHLER beim Einlesen des Files '%8.8s': %s",
                             pMelDef->sAmbGruppe, sTraceLine);
                if (melmel_relevant)
                    LKF_FREE (pContext, "lkf_scoring_compute_amb", melmel_relevant);
                if (bTraceInfo) {
                    TRACE_INFO(pAufenthalt, -1, pContext->errortext);
                }
                return -2;
            }
            else {
                if (bTraceDetail) {
                    sprintf (sTraceLine, "  AmbGruppe='%8.8s'", pMelDef->sAmbGruppe);
                    TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                }
            }
            
            act_knoten = 0;
            
            nSplitSteps = 0;
            
            while (pKnoten->nfl[act_knoten] != -99)
            {
                if (++nSplitSteps > 20)
                {
                    /* Nach 20 Schritten abbrechen - vermutlich Fehler im Stammdaten-File */
                    sprintf (pContext->errortext, "FEHLER beim Scoring-Split von '%8.8s', Abbruch nach 20 Schritten, vermutlich Fehler im Stammdaten-File",
                             pMelDef->sAmbGruppe);
                    if (melmel_relevant)
                        LKF_FREE (pContext, "lkf_scoring_compute_amb", melmel_relevant);
                    if (bTraceInfo) {
                        TRACE_INFO(pAufenthalt, -1, pContext->errortext);
                    }
                    return -3;
                }
                
                scoring_split_result = scoring_split_2017(pAufenthalt, pKnoten, act_knoten, 0, pAufenthalt->HD, (int) i, bTraceDetail ? sTraceLine : 0);
                
                if (bTraceDetail)
                {
                    sprintf (sTraceLine, "Scoring-AmbSplit, res=%d, neuer Knoten=%d", scoring_split_result, act_knoten);
                    TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                }
                if (scoring_split_result)
                    act_knoten = pKnoten->nfl[act_knoten]-1;
                else act_knoten = pKnoten->nfl[act_knoten];
                
            }

            strcpy (pAufenthalt->mel[i].ambGruppe, pMelDef->sAmbGruppe);
            pAufenthalt->mel[i].ambKnoten = pKnoten->knoten_char[act_knoten];
            
            mel_kp = pKnoten->tk_anteil[act_knoten];
            mel_lp = pKnoten->lk_anteil[act_knoten];
            
            if (i == 0 || KP < mel_kp)
            {
                KP = mel_kp;
            }
            
            if (i == 0 || mel_lp > maxLP || (mel_lp == maxLP && mel_kp > maxGrpKP ) || (mel_lp == maxLP && mel_kp == maxGrpKP  && memcmp (pAufenthalt->GRP, pMelDef->sAmbGruppe,8)>0)) {
                maxLP = mel_lp;
                maxGrpKP = mel_kp;
                maxMelIndex = i;
                pAufenthalt->maxMelIndex = (int) i;
                memcpy (pAufenthalt->GRP, pMelDef->sAmbGruppe, 8);
                pAufenthalt->KNT[0] = pKnoten->knoten_char[act_knoten];
                pAufenthalt->KNT[1] = ' ';
            
                if (bTraceDetail)
                {
                    sprintf (sTraceLine, "  #%d neuer Max-Index: lp = %5.1f, kp = %5.1f, KNT=%2.2s", i, mel_lp, mel_kp, pAufenthalt->KNT);
                    TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                }

            }
            else {
                if (bTraceDetail)
                {
                    sprintf (sTraceLine, "  #%d nicht MAX:       lp = %5.1f, kp = %5.1f, KNT=%c", i, mel_lp, mel_kp, pKnoten->knoten_char[act_knoten]);
                    TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                }
            }
            
            melabt = lkf_scoring_check_fcleist_index (&scoringAbt, pAufenthalt, pMel, ambabtmap);

            if (!memcmp (pMelDef->sAmbGruppe, "APG", 3)) {
                int found = 0;
                char cur[10];
                unsigned int g, k;
                int melanz;
                float hittingShare;

				if (modelljahr >= 2017)
                    melanz = pMel->nTagMelAnzRelevant;
                else
                    melanz = atoi(pMel->MELANZ);
                
                sprintf (cur, "%8.8s%c", pMelDef->sAmbGruppe, pKnoten->knoten_char[act_knoten]);
                
                for (g = 0; g < scoringAbt.groupCount; g++) {
                    if (!memcmp (scoringAbt.grp + 10 * g, cur, 9)) {
                        found = 1;
                        break;
                    }
                }
                
                if (!found) {
                    if (scoringAbt.groupCount < LKF_MAX_AMB_GRP - 1) {
                        if (scoringAbt.valid) {
                            memset (scoringAbt.mapApg + scoringAbt.groupCount * LKF_MAX_AMB_ABT, 0, sizeof(float) * scoringAbt.abtCount);

                            scoringAbt.apgcount[scoringAbt.groupCount] = melanz;
                            scoringAbt.lpg[scoringAbt.groupCount] = mel_lp;

                            if (melabt) {
                                
                                hittingShare = (float) melanz / melabt;
                                
                                for (k = 0; k < scoringAbt.abtCount; k++) {
                                    if (ambabtmap[k]) {
                                        scoringAbt.mapApg[scoringAbt.groupCount * LKF_MAX_AMB_ABT + k] = hittingShare;
                                    }
                                }
                            }
                            else if (pAufenthalt->abt_anz > 0){
                                hittingShare = (float) melanz / pAufenthalt->abt_anz;
                                
                                for (k = 0; k < scoringAbt.abtCount; k++) {
                                    scoringAbt.mapApg[scoringAbt.groupCount * LKF_MAX_AMB_ABT + k] = hittingShare;
                                }
                            }
                        }
                        melgrpIndex[i] = (int) scoringAbt.groupCount;
                        memcpy (scoringAbt.grp + scoringAbt.groupCount++ * 10, cur, 10);
                    }
                    LP += mel_lp;
          //          pAufenthalt->mel[i].melzu = mel_lp;
                }
                else if (scoringAbt.valid)
                {
                    melgrpIndex[i] = (int) g;
                    scoringAbt.apgcount[g] += melanz;

                    if (melabt) {
                        hittingShare = (float) melanz / melabt;

                        for (k = 0; k < scoringAbt.abtCount; k++) {
                            if (ambabtmap[k]) {
                                scoringAbt.mapApg[g * LKF_MAX_AMB_ABT + k] += hittingShare;
                            }
                        }
                    }
                    else if (pAufenthalt->abt_anz) {
                        hittingShare = (float) melanz / pAufenthalt->abt_anz;
                        for (k = 0; k < scoringAbt.abtCount; k++) {
                            scoringAbt.mapApg[g * LKF_MAX_AMB_ABT + k] += hittingShare;
                        }
                    }
                }
                pMel->punkteRelevant = 1;
            }
            else
            {
                double v;
                
                if (modelljahr >= 2017)
                    v = mel_lp * pMel->nTagMelAnzRelevant;
                else
                    v = mel_lp * atoi(pMel->MELANZ);
                
                LP += v;
                pAufenthalt->mel[i].melzu = (long) v;
                if (scoringAbt.valid) {
                    if (melabt > 0) {
                        lkf_scoring_divide_lst (&scoringAbt, melabt, ambabtmap, v);
                    }
                    else {
                        scoringAbt.lpall += v;
                    }
                }
                pMel->punkteRelevant = 1;
            }
        }
    }
    
    if (!countedMELs && basisGruppe) {
        char errbuf[1024];
        pKnoten = GetAMBKnoten (pStamm, basisGruppe, errbuf);
        if (!pKnoten)
        {
            sprintf (pContext->errortext, "FEHLER beim Einlesen des Files '%8.8s': %s", basisGruppe, errbuf);
            if (bTraceInfo)
            {
                TRACE_INFO (pAufenthalt, -1, pContext->errortext);
            }
            return -2;
        }
        if (bTraceDetail) {
            sprintf (sTraceLine, "keine Count-MEL => knoten '%8.8s'", basisGruppe);
            TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
        }
        
        act_knoten = 0;
        
        nSplitSteps = 0;
        
        while (pKnoten->nfl[act_knoten] != -99)
        {
            if (++nSplitSteps > 20)
            {
                /* Nach 20 Schritten abbrechen - vermutlich Fehler im Stammdaten-File */
                sprintf (pContext->errortext, "FEHLER beim Scoring-Split von '%8.8s', Abbruch nach 20 Schritten, vermutlich Fehler im Stammdaten-File",
                         basisGruppe);
                if (bTraceInfo)
                {
                    TRACE_INFO (pAufenthalt, -1, pContext->errortext);
                }
                return -3;
            }
            
            scoring_split_result = scoring_split_2017(pAufenthalt, pKnoten, act_knoten, 0, pAufenthalt->HD, -1, bTraceDetail ? sTraceLine : 0);
            
            if (bTraceDetail)
            {
                sprintf (sTraceLine, "Scoring-AmbSplit, res=%d, neuer Knoten=%d", scoring_split_result, act_knoten);
                TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            }
            if (scoring_split_result)
                act_knoten = pKnoten->nfl[act_knoten]-1;
            else act_knoten = pKnoten->nfl[act_knoten];
            
        }

        KP = pKnoten->tk_anteil[act_knoten];
        LP = pKnoten->lk_anteil[act_knoten];
        memcpy (pAufenthalt->GRP, basisGruppe, 8);
        pAufenthalt->maxMelIndex = -1;
        pAufenthalt->KNT[0] = pKnoten->knoten_char[act_knoten];
        pAufenthalt->KNT[1] = ' ';
        pAufenthalt->LDFPLK = simCLng(LP);
        pAufenthalt->MELZU = 0;
		pAufenthalt->LDFPTK = simCLng(KP);
        pAufenthalt->SCSPEZ = simCLng(SP); /* V2019.0 */
        pAufenthalt->SCGES = pAufenthalt->LDFPLK + pAufenthalt->LDFPTK + pAufenthalt->MELZU + pAufenthalt->SCSPEZ;
        
        if (bTraceDetail) {
            sprintf (sTraceLine, "GRP=%8.8s, KNT=%c, PLK=%ld, PTK=%ld, MELZU=%ld, SPEZ=%ld, GES=%ld", basisGruppe, pKnoten->knoten_char[act_knoten], pAufenthalt->LDFPLK, pAufenthalt->LDFPTK, pAufenthalt->MELZU, pAufenthalt->SCSPEZ, pAufenthalt->SCGES );
            TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
        }

        if (pAufenthalt->mel_anz) {
            int melanz = 0;
            for (i = 0; i < pAufenthalt->mel_anz; i++) {
                melanz += pAufenthalt->mel[i].nTagMelAnzRelevant;
            }
            if (melanz > 0) {
                for (i = 0; i < pAufenthalt->mel_anz; i++) {
                    pAufenthalt->mel[i].melzu = pAufenthalt->LDFPLK * pAufenthalt->mel[i].nTagMelAnzRelevant / melanz;
                    lkf_auf_add_category(pAufenthalt, "AMB-MELZU", 0, 0);
                }
            }
        }
	}
    else
    {
        int cma;
        pAufenthalt->MELZU = simCLng(LP-maxLP);
        pAufenthalt->LDFPLK = simCLng(maxLP);
		pAufenthalt->LDFPTK = simCLng(KP);
        pAufenthalt->SCSPEZ = simCLng(SP); /* V2019.0 */
        pAufenthalt->SCGES = pAufenthalt->LDFPLK + pAufenthalt->LDFPTK + pAufenthalt->MELZU + pAufenthalt->SCSPEZ;

        if (bTraceDetail) {
            sprintf (sTraceLine, "GRP=%8.8s, KNT=%c, PLK=%ld, PTK=%ld, MELZU=%ld, SPEZ=%ld, GES=%ld", pAufenthalt->GRP, pAufenthalt->KNT[0], pAufenthalt->LDFPLK, pAufenthalt->LDFPTK, pAufenthalt->MELZU, pAufenthalt->SCSPEZ, pAufenthalt->SCGES);
            TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
        }
        
        /*
        if (basisGruppe && skipMinimumCheck && lkf_scoring_amb_minimum_check(pAufenthalt, basisGruppe, modelljahr, 1)) {
            lkf_auf_add_category(pAufenthalt, "AMBMIN:NO", 0, 0);
            basisGruppe = 0;
        }
        */
        
        if (basisGruppe && lkf_scoring_amb_minimum_check(pAufenthalt, basisGruppe, modelljahr, 0)) {
            if (scoringAbt.valid) {
                scoringAbt.valid = 0;
                for (i = 0; i < pAufenthalt->abt_anz; i++) pAufenthalt->abt[i].lp100 = (long) (scoringAbt.lps[i] * 100);
            }
        }
        else {
            for (i = 0; i < scoringAbt.groupCount; i++) {
                scoringAbt.ppl[i] = (long) (scoringAbt.lpg[i] / scoringAbt.apgcount[i]);
                scoringAbt.pBonus[i] = (long) (scoringAbt.lpg[i] - scoringAbt.ppl[i] * scoringAbt.apgcount[i]);
            }
        }
        
        for (i = 0; i < pAufenthalt->mel_anz; i++) {
            if (melgrpIndex[i] >= 0) {
                long v;
                cma = pAufenthalt->mel[i].nTagMelAnzRelevant;
                
                v = scoringAbt.ppl[melgrpIndex[i]] * cma;
                if (cma <= scoringAbt.pBonus[melgrpIndex[i]]) {
                    v += cma;
                    scoringAbt.pBonus[melgrpIndex[i]] -= cma;
                }
                else if (scoringAbt.pBonus[melgrpIndex[i]] > 0) {
                    v += scoringAbt.pBonus[melgrpIndex[i]];
                    scoringAbt.pBonus[melgrpIndex[i]] = 0;
                }
                
                pAufenthalt->mel[i].melzu = (long) v;
            }
        }
        
        pAufenthalt->mel[maxMelIndex].punkteRelevant = 2;
	}
   
    lkf_adjust_melzu_pkt (pAufenthalt);
/*
    mz = 0;
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        mz += pAufenthalt->mel[i].melzu;
    }
    
    if (pAufenthalt->LDFPLK + pAufenthalt->MELZU != mz) {
        printf ("%12.12s %10ld %10ld %10d %2d %8.8s\n", pAufenthalt->PATID, pAufenthalt->LDFPLK, pAufenthalt->MELZU, mz, pAufenthalt->mel_anz, pAufenthalt->GRP);
        mz += 0;
    }
*/
    if (melgrpIndex)
        LKF_FREE (pContext, "lkf_scoring_compute_amb", melgrpIndex);
    
    
    pAufenthalt->SCGES_TKL = pAufenthalt->SCGES;
    
    if (pAufenthalt->abt_anz == 1)
    {
        pAufenthalt->abt[0].lp100 = (pAufenthalt->LDFPLK + pAufenthalt->MELZU + pAufenthalt->SCSPEZ /* V2019.2 */) * 100;
        pAufenthalt->abt[0].tp100 = pAufenthalt->LDFPTK * 100;
    }
    else if (pAufenthalt->abt_anz > 1) {
        if (scoringAbt.valid)
        {
            lkf_scoring_amb_divide(pAufenthalt, pAufenthalt->LDFPTK, 0);
            lkf_scoring_amb_adjust (pAufenthalt, &scoringAbt, pAufenthalt->LDFPLK + pAufenthalt->MELZU);
        }
        else {
            lkf_scoring_amb_divide(pAufenthalt, pAufenthalt->LDFPTK, pAufenthalt->LDFPLK + pAufenthalt->MELZU);
        }
    }
    
#ifdef LKF_SCORING_AMB_ABT_CHECK
    lkf_scoring_amb_check(pAufenthalt);
#endif
    
    if (pAufenthalt->pScoringDetails) {
        LKF_AUFENTHALT_ABT *pAbt;
        LKF_SCORINGDETAILS_ABT *pScoringAbt;
		unsigned int i;
        pAbt = pAufenthalt->abt;
        pScoringAbt = pAufenthalt->pScoringDetails->pAbt;
        
        for (i = 0; i < pAufenthalt->abt_anz; i++) {
            pScoringAbt->lp100 = pAbt->lp100;
            pScoringAbt->tp100 = pAbt->tp100;
            ++pAbt;
            ++pScoringAbt;
        }
    }
    
    if (melmel_relevant)
        LKF_FREE (pContext, "lkf_scoring_compute_amb", melmel_relevant);

    return 0;
}


static LKF_SCORINGDETAILS_GROUP *diagDetailsForSubgruppe (LKF_SCORINGDETAILS *pDetails, int diagSubgruppeIndex) {
    unsigned int i, count;
    count = pDetails->pAufenthalt->diag_anz;
    for (i = 0; i < count; i++) {
        if (pDetails->pDiagGroup[i].subgruppeIndex == diagSubgruppeIndex)
            return pDetails->pDiagGroup + i;
    }
    return 0;
}

static int lkf_scoring_entartv (LKF_AUFENTHALT *pAufenthalt, int modelljahr, char *sTraceLine) {
    if (pAufenthalt->FLAG >= '4' && (modelljahr >= 2024) && (!pAufenthalt->akerr_count || pAufenthalt->plaus_err)) {

        if (sTraceLine)
        {
            sprintf (sTraceLine, "Plaus-Flag '%c', keine Punkte wegen Plaus-Fehlers", pAufenthalt->FLAG);
            TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
        }

        memmove(pAufenthalt->GRP, "FEHLER  ", 8);
        return 0;
    }
    
    if (sTraceLine)
    {
        TRACE_DETAIL(pAufenthalt, -1, "Entlassungsart 'V' -> keine Punkte");
    }

    memcpy(pAufenthalt->GRP, "VERBLEIB", 8);
    return 0;
}

static void lkf_scoring_aufart_h (LKF_AUFENTHALT *pAufenthalt, int modelljahr, char *sTraceLine) {
    
    char tmp_spez_buf[20];
    const SPEZ_LIST_STRING *pSpez;
    
    sprintf (tmp_spez_buf, ".....%4.4s%8.8s", pAufenthalt->KANR, pAufenthalt->abt[0].ABTFC);
    
    pSpez = SpezInArray (pAufenthalt->pScoringContext, tmp_spez_buf);
    if (pSpez && !ABTFC_Spez_Check (pAufenthalt, 0, pSpez, 0)) pSpez = 0;
    if (pSpez) {
        if ((*pSpez)[0] == 'P') {
            if (!memcmp ((*pSpez) + 27, "TK", 2)) pAufenthalt->psych_mode = 1;
            else if (!memcmp ((*pSpez) + 27, "TS", 2)) {
                if (modelljahr == 2013)
                { /* V17.1 */
                    if (!memcmp (pAufenthalt->AUFDAT, "2013", 4)) pAufenthalt->psych_mode = 23;
                    else
                    {
                        if (!memcmp (pAufenthalt->abt[0].ABTFC + 4, "85", 2)) pAufenthalt->psych_mode = 2;
                        else if (!memcmp (pAufenthalt->abt[0].ABTFC + 4, "86", 2)) pAufenthalt->psych_mode = 3;
                        else pAufenthalt->psych_mode = 23;
                    }
                }
                else if (modelljahr > 2013) pAufenthalt->psych_mode = 23; /* V17.1 */
                else if (!memcmp (pAufenthalt->abt[0].ABTFC + 4, "85", 2)) pAufenthalt->psych_mode = 2;
                else pAufenthalt->psych_mode = 3;
            }
        }
        if ((*pSpez)[0] == 'G') {
            if (!memcmp ((*pSpez) + 27, "TK", 2)) pAufenthalt->psych_mode = 4;
        }
                        
        if (modelljahr >= 2011 && (*pSpez)[0] == 'O' && !memcmp ((*pSpez) + 27, "TK", 2))
            pAufenthalt->psych_mode = 5; /* V15.0: PSYCHOSOMATIK */

        if (modelljahr >= 2013 && (*pSpez)[0] == 'J' && !memcmp ((*pSpez) + 27, "TK", 2))
            pAufenthalt->psych_mode = 6; /* V17.0 */

        if (modelljahr >= 2017 && (*pSpez)[0] == 'J' && !memcmp ((*pSpez) + 27, "TS", 2))
            pAufenthalt->psych_mode = 7; /* V21.1 */
    }

    if (sTraceLine)
    {
        strcpy (sTraceLine, "Aufnahmeart HALBSTATIONAER");
        switch (pAufenthalt->psych_mode)
        {
            default:
            case 0:
                strcat (sTraceLine, ", aber keine spezielle halbstaetionaere Betreuung.");
                break;
            case 1:
                strcat (sTraceLine, ", tagesklinische Psych-Abteilung.");
                break;
            case 2:
                strcat (sTraceLine, ", tagesstrukturierende Psych-Abteilung (85).");
                break;
            case 3:
            case 23:
                strcat (sTraceLine, ", tagesstrukturierende Psych-Abteilung.");
                break;
            case 4:
                strcat (sTraceLine, ", AG/R-tagesklinische Abteilung.");
                break;
            case 5: /* V15.0 */
                strcat (sTraceLine, ", tagesklinische psychosomatische Abteilung.");
                break;

        }
        TRACE_DETAIL (pAufenthalt, 0, sTraceLine);
    }
}

static int lkf_scoring_checkDIAG0pkt (LKF_AUFENTHALT *pAufenthalt, LKF_CONTEXT *pContext, int bTraceDetail) {
    ICD_LIST_STRING *pDiaglist;
    char act_ambulant;
    unsigned int i;
    
    pDiaglist = FindDiag (pContext->pStamm2001, pAufenthalt->HD);
    act_ambulant = pDiaglist ? (*pDiaglist)[42] : ' ';
    if (act_ambulant == 'J') {
        short diag_ambulant = 1;

        if (pAufenthalt->mel_anz) {
            if (pContext->modelljahr >= 2017) {
                for (i = 0; i < pAufenthalt->mel_anz; i++) {
                    
                    MEL_ARRAY_STRUC *pMel;
                    if (pAufenthalt->mel[i].nMelIndex < 0)
                        continue;
                    
                    pMel = GetMELArrayFromIndex(pContext, pAufenthalt->mel[i].nMelIndex);
                    if (pMel->cStatVerpflichtend) {
                        diag_ambulant = 0;
                        break;
                    }
                }
            }
            else {
                diag_ambulant = 0;
            }
        }
        if (diag_ambulant) {
            for (i = 0; diag_ambulant && i < pAufenthalt->diag_anz; i++) {
                pDiaglist = FindDiag (pContext->pStamm2001, pAufenthalt->diag[i].DIAG);

                if (pDiaglist)
                {
                    act_ambulant = (*pDiaglist)[42];
                    if (act_ambulant != 'J' && !memcmp ((*pDiaglist) + 9, "HDG", 3))
                        diag_ambulant = 0;
                }
            }
            
            if (diag_ambulant) {
                if (bTraceDetail)
                {
                    TRACE_DETAIL(pAufenthalt,-1, "nur ambulante Diagnosen, daher keine Punkte (DIAG0PKT)");
                }
                memcpy (pAufenthalt->GRP, "DIAG0PKT", 8);
                return diag_ambulant;
            }
        }
    }
    return 0;
}

typedef struct {
    int m7501_ok;
    int m7506_ok;
    int m7316_ok;
    int m7321_ok;
    int mAM100_ok;
    int mAM140_ok;
    int m7401_ok;
    int m1255_ok;
    int mAJ140_ok;
    int mAK010_ok;
    int mDB020_ok;
    int mLH010_ok;
    int mLH021_ok;
    unsigned int palliativ_tage;
    unsigned int nAkutGeriatrieTage;
    unsigned int nRemobTage;
    int teil_akutpat;
    long spezial_tage;
} LKF_SPEZDATA;


static void lkf_scoring_spez_palliativ (LKF_AUFENTHALT *pAufenthalt, int modelljahr, unsigned int abtId, LKF_SPEZDATA *pSpezData, LKF_SCORINGDETAILS_ABT *pScoringAbtDetails, char *sTraceLine) {
    
    static const unsigned int add_palliativ_tagsatz_ab2009[20] = {462, 442, 424, 407, 391, 376, 363, 350, 339, 328, 318, 308, 299, 290, 282, 275, 267, 261, 254, 248};
    static const unsigned int add_palliativ_tagsatz_ab2017[20] = {655, 626, 600, 576, 554, 534, 515, 497, 480, 465, 450, 437, 424, 412, 400, 389, 379, 369, 360, 351};
    static const unsigned int add_palliativ_tagsatz_ab2025[20] = {641, 613, 587, 564, 542, 522, 503, 486, 470, 455, 440, 427, 414, 403, 391, 381, 371, 361, 352, 344};
    unsigned int nPalliativ_Tage_MaxPkt;
    unsigned int nPalliativ_Tage_MinPkt;
    unsigned int nPalliativ_Max_Zuschlag;
    unsigned int nPalliativ_Min_Zuschlag;
    const unsigned int *aPalliativ_Degressiv;
    unsigned int nPalliativDegressivPunkte;
    unsigned int nPalliativDegressivTage;
    unsigned int abtbd = (unsigned int) pAufenthalt->abt[abtId].ABTVD;

    nPalliativ_Tage_MaxPkt = 21;
    nPalliativ_Tage_MinPkt = 42;
    if (modelljahr >= 2025) { /* V2025.0 */
        nPalliativ_Max_Zuschlag = 671;
        nPalliativ_Min_Zuschlag = 336;
        aPalliativ_Degressiv = add_palliativ_tagsatz_ab2025;
    }
    else if (modelljahr >= 2017) {
        nPalliativ_Max_Zuschlag = 686;
        nPalliativ_Min_Zuschlag = 343;
        aPalliativ_Degressiv = add_palliativ_tagsatz_ab2017;
    }
    else {
        nPalliativ_Max_Zuschlag = 484;
        nPalliativ_Min_Zuschlag = 242;
        aPalliativ_Degressiv = add_palliativ_tagsatz_ab2009;
    }
    
    if (pSpezData->palliativ_tage < nPalliativ_Tage_MaxPkt) {

        unsigned int day_count;

        if (!pSpezData->palliativ_tage)  day_count = (abtbd > nPalliativ_Tage_MaxPkt ? nPalliativ_Tage_MaxPkt : abtbd);
        else if (abtbd > nPalliativ_Tage_MaxPkt - pSpezData->palliativ_tage) day_count = nPalliativ_Tage_MaxPkt - pSpezData->palliativ_tage;
        else day_count = abtbd;
        
        pAufenthalt->SCSPEZ += nPalliativ_Max_Zuschlag * day_count;

        if (pScoringAbtDetails)
            pScoringAbtDetails->spezPunkte = nPalliativ_Max_Zuschlag * day_count;
        
        if (sTraceLine)
        {
            sprintf (sTraceLine, "Max. Palliativzuschlag (%d Punkte) für %d Tage: %d (SpezGesamt=%ld)", nPalliativ_Max_Zuschlag, day_count, nPalliativ_Max_Zuschlag * day_count, pAufenthalt->SCSPEZ);
            TRACE_DETAIL (pAufenthalt, (int) abtId, sTraceLine);
        }
    }
    
    abtbd += pSpezData->palliativ_tage;
    
    if (abtbd > nPalliativ_Tage_MaxPkt) {
        unsigned int tag_limit;
        if (pSpezData->palliativ_tage >= nPalliativ_Tage_MaxPkt) tag_limit = pSpezData->palliativ_tage;
        else tag_limit = nPalliativ_Tage_MaxPkt;
        
        if (abtbd >= nPalliativ_Tage_MinPkt) {
            abtbd -= nPalliativ_Tage_MinPkt-1;

            if (abtbd > (unsigned int) pAufenthalt->abt[abtId].ABTVD)
                abtbd = (unsigned int) pAufenthalt->abt[abtId].ABTVD;
            
            pAufenthalt->SCSPEZ += abtbd * nPalliativ_Min_Zuschlag;
            if (pScoringAbtDetails)
                pScoringAbtDetails->spezPunkte += abtbd * nPalliativ_Min_Zuschlag;

            if (sTraceLine)
            {
                sprintf (sTraceLine, "Min. Palliativzuschlag (%d Punkte) für %d Tage: %d (SpezGesamt=%ld)", nPalliativ_Min_Zuschlag, abtbd, nPalliativ_Min_Zuschlag * abtbd, pAufenthalt->SCSPEZ);
                TRACE_DETAIL (pAufenthalt, (int) abtId, sTraceLine);
            }

            abtbd = nPalliativ_Tage_MinPkt - 1;
        }
        
        nPalliativDegressivTage = 0;
        nPalliativDegressivPunkte = 0;
        while (abtbd > tag_limit) {
            nPalliativDegressivPunkte += aPalliativ_Degressiv[abtbd - nPalliativ_Tage_MaxPkt - 1];
            --abtbd;
            nPalliativDegressivTage++;
        }
        pAufenthalt->SCSPEZ += nPalliativDegressivPunkte;
        if (pScoringAbtDetails)
            pScoringAbtDetails->spezPunkte += nPalliativDegressivPunkte;

        if (sTraceLine && nPalliativDegressivTage > 0)
        {
            sprintf (sTraceLine, "Degressiver Palliativzuschlag für %d Tage: %d (SpezGesamt=%ld)", nPalliativDegressivTage, nPalliativDegressivPunkte, pAufenthalt->SCSPEZ);
            TRACE_DETAIL (pAufenthalt, (int) abtId, sTraceLine);
        }
    }

    pSpezData->palliativ_tage += pAufenthalt->abt[abtId].ABTVD;
}

static int lkf_scoring_spez (LKF_AUFENTHALT *pAufenthalt, LKF_CONTEXT *pContext, int modelljahr, LKF_SCORINGDETAILS *pScoringDetails, LKF_SPEZDATA *pSpezData, char *sTraceLine) {
    unsigned int i;
    LKF_SCORINGDETAILS_ABT *pScoringAbtDetails;
    int tmp_add, tmp_found_spez;
    char tmp_spez_buf[20];
    const SPEZ_LIST_STRING *pSpez;
    char kjnp_typ[2];
    
    tmp_found_spez = 0;
    for (i = 0; i < pAufenthalt->abt_anz; i++) {
        pScoringAbtDetails =  pScoringDetails ? pScoringDetails->pAbt + i : 0;
        tmp_add = 1;
        if (!IsEmpty(pAufenthalt->abt[i].ABTFC, 8)) {

            sprintf (tmp_spez_buf, ".....%4.4s%8.8s", pAufenthalt->KANR, pAufenthalt->abt[i].ABTFC);
            pSpez = SpezInArray (pContext, tmp_spez_buf);

            if (pSpez && !ABTFC_Spez_Check (pAufenthalt, (int) i, pSpez, 0)) pSpez = 0;
            if (pSpez) {
                switch ((*pSpez)[0]) {

                    case 'N': /* (1) Neurorehab-Patient */
                        tmp_found_spez = 1;
                        memcpy (pAufenthalt->GRP, "NEURO   ", 8);
                        if (pScoringAbtDetails) {
                            strcpy (pScoringAbtDetails->spezBereich, "NEURO");
                        }
                        break;

                    case 'G': /* (2) Geriatrie-Patient */
                        
                        if (!memcmp ((*pSpez) + 27, "TK", 2) && modelljahr >= 2018) {
                            pSpez = 0;
                            break;
                        }
                        
                        if (pAufenthalt->psych_mode == 4) { pSpez = 0; break; }
                        memcpy (pAufenthalt->GRP, "GERIAT  ", 8);
                        tmp_found_spez = 1;
                        if (pScoringAbtDetails) {
                            strcpy (pScoringAbtDetails->spezBereich, "GERIAT");
                        }
                        break;

                    case 'J': /* (3) KJNP-Patient */

                        if (modelljahr >= 2017)
                        { /* V17.0 */
                            if (!memcmp ((*pSpez) + 27, "TK", 2) || !memcmp ((*pSpez) + 27, "TS", 2)) {
                                pSpez = 0;
                                break;
                            }
                        }
                        else if (modelljahr >= 2013)
                        { /* V17.0 */
                            if (!memcmp ((*pSpez) + 27, "TK", 2)) {
                                pSpez = 0;
                                break;
                            }
                        }

                        if (modelljahr >= 2010)
                            memcpy (pAufenthalt->GRP, "KJP     ", 8);
                        else
                            memcpy (pAufenthalt->GRP, "KJNP    ", 8);
                        if (pScoringAbtDetails) {
                            strcpy (pScoringAbtDetails->spezBereich, "KJP");
                        }

                        tmp_found_spez = 1;

                        if (modelljahr < 2013) {
                            kjnp_typ[0] = (*pSpez)[27];
                            kjnp_typ[1] = (*pSpez)[28];
                            
                            if (((kjnp_typ[0] != 'I' && kjnp_typ[0] != 'R') || kjnp_typ[1] != ' ') &&
                            ((kjnp_typ[1] != 'I' && kjnp_typ[1] != 'R') || kjnp_typ[0] != ' ')) {
                        
                                tmp_add = 0;
                                if (kjnp_typ[0] == '0') switch (kjnp_typ[1]) {
                                    case '3': pSpezData->m7506_ok = -1;
                                    case '1': pSpezData->m7501_ok = -1; break;
                                    case '2': pSpezData->m7506_ok = -1; break;
                                    default: break;
                                }
                            }
                        }
                        break;

                    case 'P': /* (4) PsychMEL-Patient */
                        
                        if (memcmp ((*pSpez) + 27, "TK", 2) && memcmp ((*pSpez) + 27, "TS", 2)) {
                            tmp_add = 0;
                        }
                        else pSpez = 0;

                        if (!memcmp (pAufenthalt->abt[i].ABTFC + 2, "6215", 4)) {
                            pSpezData->m7316_ok = pSpezData->m7321_ok = -1;
                        }

                        break;

                    case 'O': /* V15.0: Psychosomatik */
                        
                        if (modelljahr >= 2022) {
                            if (!memcmp ((*pSpez) + 27, "ET", 2)) {
                                pSpez = 0;
                                break;
                            }

                            if (pAufenthalt->psych_mode == 5) { pSpez = 0; break; }
                            
                            if (!memcmp ((*pSpez) + 27, "ES", 2))
                            {
                                tmp_add = 0;
                                pSpezData->mAM100_ok = 1;
                                break;
                            }
                            else if (!memcmp ((*pSpez) + 27, "KS", 2))
                            {
                                tmp_add = 0;
                                pSpezData->mAM140_ok = 1;
                                break;
                            }
                            memcpy (pAufenthalt->GRP, "       ", 8);
                            tmp_found_spez = 0;
                        }
                        else {
                            if (!memcmp ((*pSpez) + 27, "TK", 2) && modelljahr >= 2018) {
                                pSpez = 0;
                                break;
                            }

                            if (pAufenthalt->psych_mode == 5) { pSpez = 0; break; }
                            
                            if ( (*pSpez)[27] == '0' && ( (*pSpez)[28] == '1' || (*pSpez)[28] == '2'))
                            {
                                tmp_add = 0;
                                pSpezData->mAM100_ok = 1;
                                break;
                            }
                            memcpy (pAufenthalt->GRP, "       ", 8);
                            tmp_found_spez = modelljahr >= 2012 ? 0 : 1; /* V17.1 */
                        }

                        break;


                    case 'S': /* (5) stroke-unit Patient */
                        tmp_add = 0;

                        if (modelljahr >= 2010)
                        {
                            if ((pAufenthalt->abt[i].ABTVD > 0 || pAufenthalt->ENTART == 'S' || pAufenthalt->ENTART == 'T' || pAufenthalt->ENTART == LKF_ENTART_REVERS) && (*pSpez)[27] == '0' && (*pSpez)[28] == '1') pSpezData->m7401_ok = (-1);
                        }
                        else if ((*pSpez)[27] == '0' && (*pSpez)[28] == '1') pSpezData->m7401_ok = (-1);
                        break;
                
                    case 'M':
                        tmp_add = 0;
                        if (modelljahr >= 2010)
                        { /* Mehrfachnennungen in der Spezlist möglich */
                            tmp_spez_buf[0] = 'M';
                            pSpez = FirstSpezInArray (pContext, pSpez, tmp_spez_buf);

                            do
                            {
                                if ((*pSpez)[27] == '0')
                                {
                                    switch ((*pSpez)[28])
                                    {
                                    case '1':
                                        pSpezData->m1255_ok = (-1);
                                        break;
                                    case '2':
                                        pSpezData->mAJ140_ok = -1;
                                        break;
                                    case '3':
                                        pSpezData->mAK010_ok = -1;
                                        break;
                                    case '4':
                                        pSpezData->mDB020_ok = -1;
                                        break;
                                    case '5':
                                        pSpezData->mLH010_ok = -1;
                                        break;
                                    case '6':
                                        pSpezData->mLH021_ok = -1;
                                        break;
                                    default:
                                        break;
                                    }
                                }
                                pSpez = NextSpezInArray (pContext, pSpez, tmp_spez_buf);
                            } while (pSpez);
                        }
                        else
                            if ((*pSpez)[27] == '0' && (*pSpez)[28] == '1') pSpezData->m1255_ok = (-1);
                        break;

                    case 'L': /* (6) Palliativmedizinische Einrichtungen */
                        memcpy (pAufenthalt->GRP, "PALLIAT ", 8);
                        if (pScoringAbtDetails) {
                            strcpy (pScoringAbtDetails->spezBereich, "PALLIAT");
                        }
                        tmp_found_spez = 1;
                        tmp_add = 2; /* Spezialrechnung fuer degressiven Zuschlag */
                        break;

                    case  'A':
                        tmp_add = 0;
                        if ((*pSpez)[27] == '0') switch ((*pSpez)[28]) {
                            case '3': pSpezData->m7316_ok = -1;
                            case '2': pSpezData->m7321_ok = -1; break;
                            case '1': pSpezData->m7316_ok = -1; break;
                             default: break;
                        }
                        break;

                    case 'R':
                        if (!memcmp ((*pSpez) + 27, "RN", 2))
                        {
                            memcpy (pAufenthalt->GRP, "REMOB   ", 8); /* V18.0: 5 -> 8 */
                            if (pScoringAbtDetails) {
                                strcpy (pScoringAbtDetails->spezBereich, "REMOB");
                            }

                            tmp_add = 4;
                            tmp_found_spez = 1;
                        }
                        break;

                    default: pSpez = 0; break;
                }
            }

            if (pSpez && tmp_add) {
                long ngj_tagsatz;
                if (pScoringAbtDetails) {
                    if (!tmp_found_spez) {
                        pScoringAbtDetails->spezBereich[0] = (*pSpez)[0];
                    }
                }
                
                pSpezData->spezial_tage += pAufenthalt->abt[i].ABTVD;
                ngj_tagsatz = (long) simVal ((*pSpez) + 29, 6);
                if (pAufenthalt->abt[i].ABTVD == 0 && pAufenthalt->GESVD == 0) {
                
                    if (modelljahr >= 2025) {
                        if (pAufenthalt->SCSPEZ < ngj_tagsatz)
                        { /* V2025.0: nur der hoechste Zuschlag zaehlt bei mehreren Abteilungen */
                            pAufenthalt->SCSPEZ = ngj_tagsatz;
                        }
                    }
                    else {
                        pAufenthalt->SCSPEZ += ngj_tagsatz;
                    }
                }
                else {
            
                    if (tmp_add == 2)
                    {
                        lkf_scoring_spez_palliativ (pAufenthalt, modelljahr, i, pSpezData, pScoringAbtDetails, sTraceLine);
                    }
                    else if (tmp_add == 3)
                    { /* V11.0/doch nicht: Akutgeriatrie wird fuer max. 28 Tage bepunktet */
                        unsigned int nAbtVd = (unsigned int) pAufenthalt->abt[i].ABTVD + pSpezData->nAkutGeriatrieTage;
                        if (nAbtVd > 28) nAbtVd = 28;
                        if (nAbtVd > pSpezData->nAkutGeriatrieTage)
                        {
                            nAbtVd -= pSpezData->nAkutGeriatrieTage;
                            pSpezData->nAkutGeriatrieTage += nAbtVd;
                        }
                        else
                            nAbtVd = 0;

                        pAufenthalt->SCSPEZ += ngj_tagsatz * nAbtVd;
                        if (pScoringAbtDetails)
                            pScoringAbtDetails->spezPunkte += ngj_tagsatz * nAbtVd;;

                        if (sTraceLine)
                        {
                            sprintf (sTraceLine, "Spezialzuschlag (%ld Punkte) für %d Tage: %ld (SpezGesamt=%ld)", ngj_tagsatz, nAbtVd, ngj_tagsatz * nAbtVd, pAufenthalt->SCSPEZ);
                            TRACE_DETAIL (pAufenthalt, (int) i, sTraceLine);
                        }
                    }
                    else if (tmp_add == 4)
                    { /* Remob wird fuer max. 28 Tage bepunktet */
                        unsigned int nAbtVd = (unsigned int) pAufenthalt->abt[i].ABTVD + pSpezData->nRemobTage;
                        if (nAbtVd > 28) nAbtVd = 28;
                        if (nAbtVd > pSpezData->nRemobTage)
                        {
                            nAbtVd -= pSpezData->nRemobTage;
                            pSpezData->nRemobTage += nAbtVd;
                        }
                        else
                            nAbtVd = 0;

                        pAufenthalt->SCSPEZ += ngj_tagsatz * nAbtVd;
                        if (pScoringAbtDetails)
                            pScoringAbtDetails->spezPunkte += ngj_tagsatz * nAbtVd;;
                        if (sTraceLine)
                        {
                            sprintf (sTraceLine, "Spezialzuschlag (%ld Punkte) für %d Tage: %ld (SpezGesamt=%ld)", ngj_tagsatz, nAbtVd, ngj_tagsatz * nAbtVd, pAufenthalt->SCSPEZ);
                            TRACE_DETAIL (pAufenthalt, (int) i, sTraceLine);
                        }
                    }
                    else
                    {
                        pAufenthalt->SCSPEZ += ngj_tagsatz * pAufenthalt->abt[i].ABTVD;
                        if (pScoringAbtDetails)
                            pScoringAbtDetails->spezPunkte += ngj_tagsatz * pAufenthalt->abt[i].ABTVD;
                        if (sTraceLine)
                        {
                            sprintf (sTraceLine, "Spezialzuschlag (%ld Punkte) für %ld Tage: %ld (SpezGesamt=%ld)", ngj_tagsatz, pAufenthalt->abt[i].ABTVD, ngj_tagsatz * pAufenthalt->abt[i].ABTVD, pAufenthalt->SCSPEZ);
                            TRACE_DETAIL (pAufenthalt, (int) i, sTraceLine);
                        }
                    }
                }
            }
        }
    }
    
    if (tmp_found_spez) {
        if (pAufenthalt->GESVD - pSpezData->spezial_tage == 0 && !pSpezData->m7501_ok && !pSpezData->m7506_ok) {
            pAufenthalt->SCGES = pAufenthalt->SCSPEZ;
            lkf_scoring_fill_scges (pContext, pAufenthalt);
            if (pScoringDetails) {
                unsigned int i;
                for (i = 0; i < pAufenthalt->mel_anz; i++) {
                    pScoringDetails->pGroup[i].inactive = 1;
                }
            }
            return 0;
        }
        else {
            pAufenthalt->GESVD -= pSpezData->spezial_tage;
            pAufenthalt->GESVD_KORR += pSpezData->spezial_tage;
            pSpezData->teil_akutpat = -1;
        }
    }
    return 1;
}

static void lkf_scoring_inactivate_mel (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, LKF_SPEZDATA *pSpezData, LKF_SCORINGDETAILS *pScoringDetails, char *sTraceLine) {
    unsigned int i;
    short stroke_missing_fc, kjnp_missing_fc, psych_missing_fc, alk_missing_fc;
    int m7591_pkt, m7592_pkt;
    int modelljahr;
    
    kjnp_missing_fc = 0;
    psych_missing_fc = 0;
    stroke_missing_fc = 0;
    alk_missing_fc = 0;
    
    m7591_pkt = m7592_pkt = 0;
    modelljahr = pContext->modelljahr;
    
    for (i = 0; i < pAufenthalt->mel_anz; i++) {

        if (!(pContext->flags & LKFCONTEXT_ALLOWQUICKSCORE) && mel_during_abt19 (pAufenthalt, (int)i)) {
            InactivateMel (pAufenthalt, i);
        }
        else if ((pAufenthalt->mel[i].MEL_RELEVANT == 'N' || pAufenthalt->mel[i].MEL_RELEVANT == 'K')  && pAufenthalt->mel[i].nTagMelAnzRelevant == 0)
        {
            InactivateMel (pAufenthalt, i);
        }
        else if (pAufenthalt->mel[i].nIgnoreMel)
        {
            InactivateMel (pAufenthalt, i);
        }
        else
        {
            int nMelIndex = pAufenthalt->mel[i].nMelIndex;
            if (pAufenthalt->psych_mode) {
                if ((pAufenthalt->psych_mode == 1 && (!IsConstMEL (pContext, CONSTMEL_AM060_7596, nMelIndex) && (modelljahr < 2018 || (!IsConstMEL (pContext, CONSTMEL_AM070_7597, nMelIndex) && !IsConstMEL (pContext, CONSTMEL_AM080_7598, nMelIndex)))))  ||
                    (pAufenthalt->psych_mode == 2 && !IsConstMEL (pContext, CONSTMEL_AM070_7597, nMelIndex)) ||
                    (pAufenthalt->psych_mode == 3 && !IsConstMEL (pContext, CONSTMEL_AM080_7598, nMelIndex)) ||
                    (pAufenthalt->psych_mode == 23 && !IsConstMEL (pContext, CONSTMEL_AM070_7597, nMelIndex) && !IsConstMEL (pContext, CONSTMEL_AM080_7598, nMelIndex)) || /* V17.1 */
                    (pAufenthalt->psych_mode == 4 && !IsConstMEL (pContext, CONSTMEL_AM090_7601, nMelIndex)) ||
                    (pAufenthalt->psych_mode == 7 && !IsConstMEL (pContext, CONSTMEL_AM130, nMelIndex)) ||
                    (pAufenthalt->psych_mode == 6 && !IsConstMEL (pContext, CONSTMEL_AM120, nMelIndex) && (modelljahr < 2017 || !IsConstMEL (pContext, CONSTMEL_AM130, nMelIndex))) ||
                    (pAufenthalt->psych_mode == 5 && !IsConstMEL (pContext, CONSTMEL_AM110, nMelIndex)) ||
                    (pAufenthalt->psych_mode == 8 && !IsConstMEL (pContext, CONSTMEL_AM150, nMelIndex))) {

                    if (sTraceLine)
                    {
                        sprintf (sTraceLine, "Aufgrund des Psych-Modus wird MEL #%d (%5.5s) fuer die Punkteberechnung deaktiviert", i+1, pAufenthalt->mel[i].MEL);
                        TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                    }

                    InactivateMel (pAufenthalt, i);
                }
            }
            else if ((!pSpezData->m7501_ok && IsConstMEL (pContext, CONSTMEL_AM030_7501, nMelIndex)) ||
                     (!pSpezData->m7506_ok && IsConstMEL (pContext, CONSTMEL_AM020_7506, nMelIndex)))
            {
                InactivateMel (pAufenthalt, i);
                kjnp_missing_fc = -1;
            }
            else if ((!pSpezData->m7316_ok && IsConstMEL (pContext, CONSTMEL_AM040_7316, nMelIndex)) ||
                     (!pSpezData->m7321_ok && IsConstMEL (pContext, CONSTMEL_AM050_7321, nMelIndex)))
            {
                InactivateMel (pAufenthalt, i);
                alk_missing_fc = -1;
            }
            else if (modelljahr >= 2013 && IsConstMEL (pContext, CONSTMEL_AM120, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (modelljahr >= 2017 && IsConstMEL (pContext, CONSTMEL_AM110, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (modelljahr >= 2022 && IsConstMEL (pContext, CONSTMEL_AM150, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (modelljahr >= 2017 && IsConstMEL (pContext, CONSTMEL_AM130, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mAM100_ok && IsConstMEL (pContext, CONSTMEL_AM100, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mAM140_ok && IsConstMEL (pContext, CONSTMEL_AM140, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->m7401_ok && IsConstMEL (pContext, CONSTMEL_AA040_7401, nMelIndex))
            {
                InactivateMel (pAufenthalt, i);
                stroke_missing_fc = -1;
            }
            else if (MELInIndexList(pContext, CONSTMEL_LIST2, nMelIndex) && pAufenthalt->psych_mode == 0) {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->m1255_ok && IsConstMEL (pContext, CONSTMEL_LH020_1255, nMelIndex) && !(pAufenthalt->acceptedMEL & ACCEPTED_MEL_LH020))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mDB020_ok && IsConstMEL (pContext, CONSTMEL_DB020, nMelIndex) && !(pAufenthalt->acceptedMEL & ACCEPTED_MEL_DB020))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mAJ140_ok && IsConstMEL (pContext, CONSTMEL_AJ140, nMelIndex) && !(pAufenthalt->acceptedMEL & ACCEPTED_MEL_AJ140))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mAK010_ok && IsConstMEL (pContext, CONSTMEL_AK010, nMelIndex) && !(pAufenthalt->acceptedMEL & ACCEPTED_MEL_AK010))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mLH010_ok && IsConstMEL (pContext, CONSTMEL_LH010, nMelIndex) && !(pAufenthalt->acceptedMEL & ACCEPTED_MEL_LH010))
            {
                InactivateMel (pAufenthalt, i);
            }
            else if (!pSpezData->mLH021_ok && IsConstMEL (pContext, CONSTMEL_LH021, nMelIndex) && !(pAufenthalt->acceptedMEL & ACCEPTED_MEL_LH021))
            {
                InactivateMel (pAufenthalt, i);
            }
        }
        if (pScoringDetails && !memcmp (pAufenthalt->mel[i].MEL, "00000", 5)) {
            pScoringDetails->pGroup[i].inactive = 1;
        }
    }

}

#define TKLAPG_GRUPPEKNOTEN_LEN 12

static int lkf_scoring_tklapg (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe, LKF_SCORINGDETAILS *pScoringDetails, char *sTraceLine) {
    unsigned int i, j;
    MEL_ARRAY_STRUC *pMelDef;
    const LKF_KNOTEN *pKnoten;
    int act_knoten, nSplitSteps, scoring_split_result;
    double mel_lp;
    char *melmel_relevant;
    char *apgGroups;
    char gruppeKnoten[TKLAPG_GRUPPEKNOTEN_LEN];
    unsigned int apgGroupCount;
    
    if (pSubgruppe->TKLModus == 2) {
        return 2;
    }
    
    melmel_relevant = 0;
    
    if (lkf_has_amb_melmel(pAufenthalt)) {
        melmel_relevant = (char *) LKF_MALLOC (pContext, "lkf_scoring_tklapg", pAufenthalt->mel_anz);
        if (!melmel_relevant) return LKF_OUTOFMEMORY_ERROR;
        lkf_compute_amb_melmel(pAufenthalt, melmel_relevant);
    }
    
    apgGroups = LKF_MALLOC (pContext, "lkf_scoring_tklapg.groups", TKLAPG_GRUPPEKNOTEN_LEN * pAufenthalt->mel_anz);
    if (!apgGroups) {
        if (melmel_relevant) LKF_FREE(pContext, "lkf_scoring_tklapg", melmel_relevant);
        return LKF_OUTOFMEMORY_ERROR;
    }
    apgGroupCount = 0;
    
    for (i = 0; i < pAufenthalt->mel_anz; i++) {
        
        LKF_AUFENTHALT_MEL *pMel = pAufenthalt->mel + i;
        
        if (pMel->MEL_RELEVANT == 'N' || pMel->MEL_RELEVANT == 'K' || pMel->nIgnoreMel || pMel->nTagMelAnzRelevant == 0)
            continue;
        
        if (melmel_relevant && melmel_relevant[i] == 0) {
            continue;
        }
        
        pMelDef = FindMel(pContext, pMel->MEL);
        
        if (!pMelDef || memcmp (pMelDef->sAmbGruppe, "APG", 3)) {
            continue;
        }
    
        pKnoten = GetAMBKnoten (pContext->pStamm2001, pMelDef->sAmbGruppe, sTraceLine);
        if (!pKnoten)
        {
            sprintf (pContext->errortext, "TKLAPG-Zuschlag MEL='%5.5s': FEHLER beim Einlesen des Files '%8.8s': %s", pMel->MEL,
                         pMelDef->sAmbGruppe, sTraceLine);
            //if (melmel_relevant)
             //   LKF_FREE (melmel_relevant);
            if (sTraceLine) {
                TRACE_INFO(pAufenthalt, -1, pContext->errortext);
            }
            continue;
        }
        else {
            if (sTraceLine) {
                sprintf (sTraceLine, "TKLAPG-Zuschlag MEL='%5.5s' => AmbGruppe='%8.8s'", pMel->MEL, pMelDef->sAmbGruppe);
                TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
            }
        }
        
        act_knoten = 0;
        nSplitSteps = 0;
        
        while (pKnoten->nfl[act_knoten] != -99)
        {
            if (++nSplitSteps > 20)
            {
                /* Nach 20 Schritten abbrechen - vermutlich Fehler im Stammdaten-File */
                sprintf (pContext->errortext, "FEHLER beim Scoring-Split von '%8.8s', Abbruch nach 20 Schritten, vermutlich Fehler im Stammdaten-File",
                         pMelDef->sAmbGruppe);
                //if (melmel_relevant)
                //    LKF_FREE (melmel_relevant);
                if (sTraceLine) {
                    TRACE_INFO(pAufenthalt, -1, pContext->errortext);
                }
                break;
            }
            
            scoring_split_result = scoring_split_2017(pAufenthalt, pKnoten, act_knoten, 0, pAufenthalt->HD, (int) i, sTraceLine);
            
            if (sTraceLine)
            {
                sprintf (sTraceLine, "TKLAPG-AmbSplit: res=%d, neuer Knoten=%d", scoring_split_result, act_knoten);
                TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            }
            if (scoring_split_result)
                act_knoten = pKnoten->nfl[act_knoten]-1;
            else act_knoten = pKnoten->nfl[act_knoten];
            
        }

        strcpy (pAufenthalt->mel[i].ambGruppe, pMelDef->sAmbGruppe);
        pAufenthalt->mel[i].ambKnoten = pKnoten->knoten_char[act_knoten];
        
        sprintf (gruppeKnoten, "%8.8s/%c", pMelDef->sAmbGruppe, pAufenthalt->mel[i].ambKnoten);
        mel_lp = pKnoten->lk_anteil[act_knoten];
        
        for (j = 0; j < apgGroupCount; j++) {
            if (!strcmp (gruppeKnoten, apgGroups + j * TKLAPG_GRUPPEKNOTEN_LEN)) {
                if (sTraceLine)
                {
                    sprintf (sTraceLine, "MEL %5.5s, Gruppe %s: kein Leistungszuschlag von %.1f, weil fuer diese APG-Gruppe schon ein Zuschlag gewaehrt wurde", pMel->MEL, gruppeKnoten, mel_lp);
                    TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                }
                mel_lp = 0;
                break;
            }
        }
        
        if (mel_lp > 0) {
            pSubgruppe->MELZU += simCLng(mel_lp);
            pSubgruppe->MELZU_DIRECT += simCLng(mel_lp);
            
            if (pSubgruppe->plCurMELZU == 0) {
                pSubgruppe->plCurMELZU = LKF_CALLOC(pContext, "plCurMELZU", sizeof(long), pAufenthalt->mel_anz);
                if (!pSubgruppe->plCurMELZU) return 0;
            }
            pSubgruppe->plCurMELZU[i] = simCLng(mel_lp);
            
            strcpy (apgGroups + apgGroupCount++ * TKLAPG_GRUPPEKNOTEN_LEN, gruppeKnoten);
            
            if (sTraceLine)
            {
                sprintf (sTraceLine, "TKLAPG %8.8s/%c: LP %5.1f zu MELZU addiert", pMelDef->sAmbGruppe, pKnoten->knoten_char[act_knoten], mel_lp);
                TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            }
            lkf_auf_add_category(pAufenthalt, "AMBTKLAPG", 0, 0);
        }
    }
    
    if (melmel_relevant) {
        LKF_FREE(pContext, "lkf_scoring_tklapg", melmel_relevant);
    }
    LKF_FREE (pContext, "lkf_scoring_tklapg.groups", apgGroups);
    return 0;
}

static int lkf_scoring_result (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, int bMelZuModus, LKF_SCORINGDETAILS *pScoringDetails, char *sTraceLine) {
    
    long max_score;
    long max_scges;
    int bIgnoreSubgruppe;
    unsigned int lAktDatum;
    unsigned int lGrpMelDat;
    long lAktMaxZuschlag;
    long lAktMaxZuschlagOp;
    long *plMaxMELZU;
    long *plCurMELZU;

    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
    unsigned int i, j;
#ifdef SUPPORT_PRE2017
    int bModell2017p = (pContext->modelljahr >= 2017); /* V21.0 */
    int bSubgruppeTKL = (pContext->modelljahr >= 2011) ? !bModell2017p : 0;
#endif

    max_score = 0;
    max_scges = 0;
    
    plMaxMELZU = 0;
    
    for (i = 0; i < pAufenthalt->pat_subgruppen; i++)
    {
        pSubgruppe = pAufenthalt->subgruppe + i;
        
        if (pScoringDetails) {
            if (pScoringDetails->isDIAGGroup) {
                pScoringDetails->pCurrentGroup = diagDetailsForSubgruppe(pScoringDetails, i);
            }
            else {
                pScoringDetails->pCurrentGroup = pScoringDetails->pGroup + pSubgruppe->mel_id;
            }
        }
        plCurMELZU = pSubgruppe->plCurMELZU;
        /* TODO: 2025.1 CHECK */
        if (plCurMELZU) {
            memset (plCurMELZU, 0, sizeof(long) * pAufenthalt->mel_anz);
            if (pSubgruppe->mel_id >= 0) {
                plCurMELZU[pSubgruppe->mel_id] = pSubgruppe->MELZU;
            }
        }
        
        bIgnoreSubgruppe = 0;
        
        if (pAufenthalt->pMelMel) {
            lkf_auf_add_category(pAufenthalt, "MELMEL", 0, 0);
        }
        
        if (!pAufenthalt->optimizeable)
        {
            if (bMelZuModus)
            {
                int nActIndex;
                int nActIndexOp;
                long lCurrMelZu;
                long lCurrMelZuAnz;
                long lMelZu;
                long lActIndexOptValue, lActIndexOptValueOp, lCurrOptValue;
                char bOp;
                unsigned int nNextDynMelIndex = 0;

                lAktDatum = 0;
                lAktMaxZuschlag = 0;
                lAktMaxZuschlagOp = 0;
                lActIndexOptValueOp = 0;
                lActIndexOptValue = 0;


                if (pAufenthalt->pMelMel)
                {
                    for (j = 1; !bIgnoreSubgruppe && j <= pAufenthalt->nMelMelCount; j++)
                    {
                        if (!lkf_aufenthalt_optimize_melmel (pAufenthalt, pSubgruppe, (int) j, 1, i, plCurMELZU))
                            bIgnoreSubgruppe = 1;
                    }
                }

                if (!bIgnoreSubgruppe)
                {
                    /* Speziallogik, wenn die aktuelle MEL derart ist: nur die aktuelle MEL bekommt den Zuschlag */
                    if (!pSubgruppe->melzu_voll) /* V14.2 */
                        lGrpMelDat = (unsigned int) pSubgruppe->lMelDat;
                    else
                        lGrpMelDat = 0;

                    bOp = pAufenthalt->subgruppe[i].bOp; /* V14.0 */

                    nActIndex = -1;
                    nActIndexOp = -1;

                    for (j = 0; j < pAufenthalt->pat_subgruppen; j++)
                    {
                        if (i != j)
                        {
                            LKF_AUFENTHALT_SUBGRUPPE *pGrp = pAufenthalt->subgruppe + j;

                            if (pSubgruppe->pMelZu[pGrp->mel_id].lMelZu == -1)
                            {  /* V13.5 */
                                lCurrMelZu = 0;
                                lCurrMelZuAnz = 0;
                                pSubgruppe->pMelZu[pGrp->mel_id].lMelZu = 0;
                            }
                            else if (!pGrp->melzu_voll)
                            {
                                if (pContext->modelljahr >= 2010)
                                {
                                    if (pContext->modelljahr >= 2017)
                                        lCurrMelZu = simCLng(pGrp->melzu_reduziert);
                                    else
                                        lCurrMelZu = simCLng(pGrp->mel_median*pGrp->melzu_reduziert/100);
                                    
                                    if (pGrp->anz > 1)
                                        lCurrMelZuAnz = lCurrMelZu * (pGrp->anz-1);
                                    else
                                        lCurrMelZuAnz = 0;

                                    pSubgruppe->pMelZu[pGrp->mel_id].lDynMelDiff = pGrp->leistungs_anteil - lCurrMelZu;
                                    pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = 0;

                                    if (pGrp->lMelDat != lGrpMelDat || pGrp->bOp != bOp)
                                    {
                                        lMelZu = pGrp->leistungs_anteil + lCurrMelZuAnz;
                                        lCurrOptValue = pGrp->leistungs_anteil - lCurrMelZu;
                                        if (pGrp->lMelDat != lAktDatum)
                                        {
                                            if (nActIndex >= 0)
                                            {
                                                pSubgruppe->MELZU -= pSubgruppe->pMelZu[nActIndex].lMelZu;
                                                if (plCurMELZU) {
                                                    plCurMELZU[nActIndex] += lAktMaxZuschlag - pSubgruppe->pMelZu[nActIndex].lMelZu;
                                                }
                                                pSubgruppe->pMelZu[nActIndex].lMelZu = lAktMaxZuschlag;
                                                pSubgruppe->pMelZu[nActIndex].lDynMelDiff = 0;
                                                pSubgruppe->MELZU += lAktMaxZuschlag;
                                                nActIndex = -1;
                                                lAktMaxZuschlag = 0;
                                                lActIndexOptValue = 0;
                                            }
                                            if (nActIndexOp >= 0)
                                            {
                                                pSubgruppe->MELZU -= pSubgruppe->pMelZu[nActIndexOp].lMelZu;
                                                if (plCurMELZU) {
                                                    plCurMELZU[nActIndexOp] += lAktMaxZuschlagOp - pSubgruppe->pMelZu[nActIndexOp].lMelZu;
                                                }
                                                pSubgruppe->pMelZu[nActIndexOp].lMelZu = lAktMaxZuschlagOp;
                                                pSubgruppe->pMelZu[nActIndexOp].lDynMelDiff = 0;
                                                pSubgruppe->MELZU += lAktMaxZuschlagOp;
                                                nActIndexOp = -1;
                                                lAktMaxZuschlagOp = 0;
                                                lActIndexOptValueOp = 0;
                                            }

                                            lAktDatum = (unsigned int) pGrp->lMelDat;
                                        }

                                        if (pGrp->bOp)
                                        {
                                            if (nActIndexOp < 0)
                                                pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = (int) ++nNextDynMelIndex;
                                            else
                                                pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = pSubgruppe->pMelZu[nActIndexOp].nDynMelId;

                                            if (lCurrOptValue > lActIndexOptValueOp)
                                            {
                                                nActIndexOp = pGrp->mel_id;
                                                lAktMaxZuschlagOp = lMelZu;
                                                lActIndexOptValueOp = lCurrOptValue;
                                            }
                                        }
                                        else
                                        {
                                            if (nActIndex < 0)
                                                pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = (int) ++nNextDynMelIndex;
                                            else
                                                pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = pSubgruppe->pMelZu[nActIndex].nDynMelId;

                                            if (lCurrOptValue > lActIndexOptValue)
                                            {
                                                if (!lActIndexOptValue)
                                                    pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = (int) ++nNextDynMelIndex;
                                                nActIndex = pGrp->mel_id;
                                                lAktMaxZuschlag = lMelZu;
                                                lActIndexOptValue = lCurrOptValue;
                                            }
                                        }
                                    }
                                }
                                else
                                { /* Modell 2009 */
                                    lCurrMelZu = simCLng(pGrp->mel_median*pGrp->melzu_reduziert/100);
                                    if (pGrp->anz > 1)
                                        lCurrMelZuAnz = simCLng(pGrp->mel_median*pGrp->melzu_reduziert/100) * (pGrp->anz-1);
                                    else
                                        lCurrMelZuAnz = 0;

                                    pSubgruppe->pMelZu[pGrp->mel_id].lDynMelDiff = pGrp->leistungs_anteil - lCurrMelZu;
                                    pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = 0;

                                    if (pGrp->lMelDat != lGrpMelDat)
                                    {
                                        lMelZu = pGrp->leistungs_anteil + lCurrMelZuAnz;
                                        lCurrOptValue = pGrp->leistungs_anteil - lCurrMelZu;
                                        if (pGrp->lMelDat != lAktDatum)
                                        {
                                            if (nActIndex >= 0)
                                            {
                                                pSubgruppe->MELZU -= pSubgruppe->pMelZu[nActIndex].lMelZu;
                                                if (plCurMELZU) {
                                                    plCurMELZU[nActIndex] += lAktMaxZuschlag - pSubgruppe->pMelZu[nActIndex].lMelZu;
                                                }

                                                pSubgruppe->pMelZu[nActIndex].lMelZu = lAktMaxZuschlag;
                                                pSubgruppe->pMelZu[nActIndex].lDynMelDiff = 0;
                                                pSubgruppe->MELZU += lAktMaxZuschlag;
                                                nActIndex = -1;
                                                lAktMaxZuschlag = 0;
                                                lActIndexOptValue = 0;
                                            }
                                            lAktDatum = (unsigned int) pGrp->lMelDat;
                                        }

                                        if (nActIndex < 0)
                                            pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = (int) ++nNextDynMelIndex;
                                        else
                                            pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = pSubgruppe->pMelZu[nActIndex].nDynMelId;
                                        if (lCurrOptValue > lActIndexOptValue)
                                        {
                                            nActIndex = pGrp->mel_id;
                                            lAktMaxZuschlag = lMelZu;
                                            lActIndexOptValue = lCurrOptValue;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                lCurrMelZu = pGrp->leistungs_anteil * pGrp->anz;
                                lCurrMelZuAnz = 0;
                                pSubgruppe->pMelZu[pGrp->mel_id].nDynMelId = 0;
                            }

                            pSubgruppe->pMelZu[pGrp->mel_id].lMelZu = lCurrMelZu + lCurrMelZuAnz;
                            pSubgruppe->MELZU += pSubgruppe->pMelZu[pGrp->mel_id].lMelZu;
                            if (plCurMELZU) {
                                plCurMELZU[pGrp->mel_id] += pSubgruppe->pMelZu[pGrp->mel_id].lMelZu;
                            }

                        }
                    }
                    if (nActIndex >= 0)
                    {
                        pSubgruppe->MELZU -= pSubgruppe->pMelZu[nActIndex].lMelZu;
                        if (plCurMELZU) {
                            plCurMELZU[nActIndex] += lAktMaxZuschlag - pSubgruppe->pMelZu[nActIndex].lMelZu;
                        }

                        pSubgruppe->pMelZu[nActIndex].lMelZu = lAktMaxZuschlag;
                        pSubgruppe->pMelZu[nActIndex].lDynMelDiff = 0;
                        pSubgruppe->MELZU += lAktMaxZuschlag;
                    }
                    if (pContext->modelljahr >= 2010)
                    {
                        if (nActIndexOp >= 0)
                        {
                            pSubgruppe->MELZU -= pSubgruppe->pMelZu[nActIndexOp].lMelZu;
                            if (plCurMELZU) {
                                plCurMELZU[nActIndexOp] += lAktMaxZuschlagOp - pSubgruppe->pMelZu[nActIndexOp].lMelZu;
                            }

                            pSubgruppe->pMelZu[nActIndexOp].lMelZu = lAktMaxZuschlagOp;
                            pSubgruppe->pMelZu[nActIndexOp].lDynMelDiff = 0;
                            pSubgruppe->MELZU += lAktMaxZuschlagOp;
                        }
                    }

                    if (sTraceLine && pSubgruppe && pSubgruppe->pMelZu)
                    {
                        TRACE_DETAIL (pAufenthalt, -1, "MEL    MELZU DYNDIFF DYNID");

                        for (j = 0; j < pAufenthalt->mel_anz; j++)
                        {
                            MELZU_DATA *pData = pSubgruppe->pMelZu + j;
                            sprintf (sTraceLine, "%5.5s  %5ld   %5ld %5d", pAufenthalt->mel[j].MEL, pData->lMelZu, pData->lDynMelDiff, pData->nDynMelId);
                            TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                        }
                    }

                    if (pAufenthalt->pMelMel)
                    {
                        for (j = 1; !bIgnoreSubgruppe && j <= pAufenthalt->nMelMelCount; j++)
                        {
                            int ret = lkf_aufenthalt_optimize_melmel (pAufenthalt, pSubgruppe, (int) j, 0, i, plCurMELZU);
                            if (ret < 0) {
                                return ret;
                            }
                            if (!ret) bIgnoreSubgruppe = 1;
                        }
                    }
                }
                if (pContext->modelljahr >= 2025 && pAufenthalt->isAmb == 2) {
                    lkf_scoring_tklapg (pContext, pAufenthalt, pSubgruppe, pScoringDetails, sTraceLine);
                }

            }
            else
            {
                for (j = 0; j < pAufenthalt->pat_subgruppen; j++)
                {
                    if (i != j)
                    {
                        pSubgruppe->pMelZu[pAufenthalt->subgruppe[j].mel_id].lMelZu = pAufenthalt->subgruppe[j].leistungs_anteil * pAufenthalt->subgruppe[j].anz;
                        pSubgruppe->MELZU += pSubgruppe->pMelZu[pAufenthalt->subgruppe[j].mel_id].lMelZu;
                        if (plCurMELZU) {
                            plCurMELZU[pAufenthalt->subgruppe[j].mel_id] += pSubgruppe->pMelZu[pAufenthalt->subgruppe[j].mel_id].lMelZu;
                        }

                    }
                }
            }
        }

        if (bIgnoreSubgruppe)
            pSubgruppe->SCGES = 0;
        else
        {
            pSubgruppe->SCGES = pSubgruppe->LDFPTK + pSubgruppe->LDFPLK + pSubgruppe->SCUTK + pSubgruppe->SCULK +
                                pSubgruppe->VDZU + pSubgruppe->MELZU + pAufenthalt->INTZU + pAufenthalt->SCSPEZ;
#ifdef SUPPORT_PRE2017
            if (bSubgruppeTKL)
                lkf_scoring_tkl_subgruppe (pContext, pAufenthalt, pSubgruppe);
#endif
        }


        if (sTraceLine)
        {

            sprintf (sTraceLine, "Subgruppe #%02d, GRP/MEL=%14.14s, Knt=%c, SCGES=%08ld, MELZU=%08ld, VDZU=%08ld, melid=%2d", i, pSubgruppe->gruppe, pSubgruppe->knoten_char, pSubgruppe->SCGES, pSubgruppe->MELZU, pSubgruppe->VDZU, pSubgruppe->mel_id);
            TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            
            if (pSubgruppe->mel_id >= 0)
            {
                sprintf (sTraceLine, "Subgruppe #%02d, MEL=%5.5s, MELDAT=%8.8s, melmel=%d, tagmelanz=%d/%d", i, pAufenthalt->mel[pSubgruppe->mel_id].MEL, pAufenthalt->mel[pSubgruppe->mel_id].MELDAT,
                                                                                             pAufenthalt->mel[pSubgruppe->mel_id].nMelMelIndex,
                                                                                             pAufenthalt->mel[pSubgruppe->mel_id].nTagMelAnz, pAufenthalt->mel[pSubgruppe->mel_id].nTagMelAnzRelevant);
                TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            }
            
            if (pSubgruppe->pMelZu)
            {
                for (j = 0; j < pAufenthalt->pat_subgruppen; j++)
                {
                    int k = pAufenthalt->subgruppe[j].mel_id;
                    if (k >= 0)
                    {
                        sprintf (sTraceLine, "#%02d: MEL=%5.5s MELDAT=%8.8s Zuschlag=%5ld Anz=%d/%d", j,
                            pAufenthalt->mel[k].MEL,
                            pAufenthalt->mel[k].MELDAT,
                            pSubgruppe->pMelZu[k].lMelZu,
                            pAufenthalt->mel[k].nTagMelAnz,
                            pAufenthalt->mel[k].nTagMelAnzRelevant);
                        TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                    }
                }
            }
        }
        
        if (!pAufenthalt->optimizeable && ((pAufenthalt->pScoringContext->modelljahr >= 2017 && !(pContext->flags & LKFCONTEXT_SIM3)) ||
                                           (pAufenthalt->pScoringContext->modelljahr < 2017 && (pContext->flags & LKFCONTEXT_SIM3))))
        {
            long leist = pSubgruppe->leistungs_anteil;

            if (pSubgruppe->SCGES > 0 && (leist > max_score || (leist==max_score && pSubgruppe->SCGES > max_scges))) {
                if (i < pAufenthalt->pat_subgruppen - (unsigned int) pAufenthalt->optimizeable) {
                    max_score = leist;
                    max_scges = pSubgruppe->SCGES;
                    pAufenthalt->max_index = (short) i;
                    pAufenthalt->optimized_subgruppe = (int) i; /* V21.0 */
                    if (plCurMELZU) {
                        plMaxMELZU = plCurMELZU;
                    }
                }
            }
        }
        else if (pSubgruppe->SCGES > max_score) {

            if (i < pAufenthalt->pat_subgruppen - (unsigned int) pAufenthalt->optimizeable) {
                max_score = pSubgruppe->SCGES;
                pAufenthalt->max_index = (short) i;
            }
            pAufenthalt->optimized_subgruppe = (int) i;
            plMaxMELZU = pSubgruppe->plCurMELZU;
        }
    }
    
    pSubgruppe = pAufenthalt->subgruppe + pAufenthalt->max_index;
        
    
    if (plMaxMELZU) {
            
        for (i = 0; i < pAufenthalt->mel_anz; i++) {
            pAufenthalt->mel[i].melzu = plMaxMELZU[i];
            if (plMaxMELZU[i])
                pAufenthalt->mel[i].punkteRelevant = 1;
        }
        if (!pAufenthalt->optimizeable) {
            int maxmelId = pAufenthalt->subgruppe[pAufenthalt->max_index].mel_id;
            if (maxmelId >= 0) pAufenthalt->mel[maxmelId].punkteRelevant = 2;
        }

        lkf_adjust_melzu_pkt (pAufenthalt);
    }
    
    if (pAufenthalt->nMelMelCount > 0) {
        
        if (sTraceLine) {
            for (j = 0; j < pAufenthalt->mel_anz; j++) {
                lkf_setMelMelInfo (pAufenthalt, j);
                if (*(pAufenthalt->mel[j].melmelInfo)) {
                    sprintf (sTraceLine, "MELMEL-Info (%5.5s): %6.6s", pAufenthalt->mel[j].MEL, pAufenthalt->mel[j].melmelInfo);
                    TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
                }
            }
        }
        else {
            for (j = 0; j < pAufenthalt->mel_anz; j++) {
                lkf_setMelMelInfo (pAufenthalt, j);
            }
        }
    }

    if (pAufenthalt->optimizeable)
        pAufenthalt->optimized_percentage = (pAufenthalt->subgruppe[0].SCGES)*1.0 / pAufenthalt->subgruppe[pAufenthalt->optimized_subgruppe].SCGES;

    pAufenthalt->LDFPLK = pSubgruppe->LDFPLK;
    pAufenthalt->LDFPTK = pSubgruppe->LDFPTK;
    pAufenthalt->SCUTK = pSubgruppe->SCUTK;
    pAufenthalt->SCUTK_DOUBLE = pSubgruppe->SCUTK_DOUBLE;
    pAufenthalt->SCULK = pSubgruppe->SCULK;
    pAufenthalt->VDZU = pSubgruppe->VDZU;
    pAufenthalt->MELZU = pSubgruppe->MELZU;
    pAufenthalt->SCGES = pSubgruppe->SCGES;
    pAufenthalt->VDO = pSubgruppe->vd_o;
    pAufenthalt->VDU = pSubgruppe->vd_u;
    pAufenthalt->VDMW = pSubgruppe->vd_mw;

    if (pAufenthalt->isAmb == 2) { /* V2025.2 */
        unsigned int i;
        for (i = 0; i < pAufenthalt->mel_anz; i++) {
            long ambFixPunkte = pAufenthalt->mel[i].ambFixPunkte;
            if (ambFixPunkte > 0) {
                pAufenthalt->SCSPEZ += ambFixPunkte;
                pAufenthalt->SCGES += ambFixPunkte;
            }
        }
    }

    memcpy (pAufenthalt->GRP, pSubgruppe->gruppe, 8);
    pAufenthalt->maxMelIndex = pSubgruppe->mel_id;
    pAufenthalt->KNT[0] = pSubgruppe->knoten_char;


#ifdef SUPPORT_PRE2017
    if (bSubgruppeTKL)
    {
        pAufenthalt->TKLModus = pSubgruppe->TKLModus;
        pAufenthalt->SCGES_TKL = pAufenthalt->SCGES;
        pAufenthalt->SCUTK_TKL = pSubgruppe->SCUTK;
        pAufenthalt->SCUTK_NOTKL = simCLng(pSubgruppe->SCUTK_DOUBLE);
    }
    else if (pContext->modelljahr >= 2017) {
        pAufenthalt->TKLModus = pSubgruppe->TKLModus;
        pAufenthalt->SCGES_TKL = pAufenthalt->SCGES;
        pAufenthalt->SCUTK_TKL = pSubgruppe->SCUTK;
        pAufenthalt->SCUTK_NOTKL = simCLng(pSubgruppe->SCUTK_DOUBLE);
    }
    else
    {
        lkf_scoring_tkl (pContext, pAufenthalt);
        pAufenthalt->SCUTK_NOTKL = pAufenthalt->SCUTK;
        pAufenthalt->SCUTK = pAufenthalt->SCUTK_TKL;
    }
#else
    pAufenthalt->TKLModus = pSubgruppe->TKLModus;
    pAufenthalt->SCGES_TKL = pAufenthalt->SCGES;
    pAufenthalt->SCUTK_TKL = pSubgruppe->SCUTK;
    pAufenthalt->SCUTK_NOTKL = simCLng(pSubgruppe->SCUTK_DOUBLE);
#endif

    pAufenthalt->SCGES = pAufenthalt->SCGES_TKL;

    if (pAufenthalt->isAmb == 2) {
        if (pAufenthalt->abt_anz == 1)
         {
             pAufenthalt->abt[0].lp100 = (pAufenthalt->LDFPLK + pAufenthalt->SCULK + pAufenthalt->MELZU + pAufenthalt->SCSPEZ /* V2019.2 */) * 100;
             pAufenthalt->abt[0].tp100 = (pAufenthalt->LDFPTK + pAufenthalt->SCUTK) * 100;
         }
        else if (pAufenthalt->abt_anz > 1) {
            
            if (pAufenthalt->SCSPEZ > 0) {
                
                LKF_AUFENTHALT_MEL *pMel;
                long spezPunkte;
                spezPunkte = pAufenthalt->SCSPEZ;
                pMel = pAufenthalt->mel;
                
                for (i = 0; i < pAufenthalt->mel_anz; i++, pMel++) {
                    
                    if (!pMel->MEL_RELEVANT) continue;
                    
                    if (pMel->ambFixPunkte && !IsBlank(pMel->FCLEIST, 8)) {
                        
                        for (j = 0; j < pAufenthalt->abt_anz; j++) {
                            if (!memcmp (pAufenthalt->abt[j].ABTFC, pMel->FCLEIST, 8)) {
                                pAufenthalt->abt[j].lp100 += (pMel->ambFixPunkte * 100);
                                spezPunkte -= pMel->ambFixPunkte;
                                break;
                            }
                        }
                    }
                }
                
                lkf_scoring_amb_divide(pAufenthalt, pAufenthalt->LDFPTK + pAufenthalt->SCUTK, spezPunkte);
                lkf_scoring_tkl_adjust(pAufenthalt, pAufenthalt->LDFPLK + pAufenthalt->MELZU + pAufenthalt->SCULK);
            }
            else {
                lkf_scoring_amb_divide(pAufenthalt, pAufenthalt->LDFPTK + pAufenthalt->SCUTK, 0);
                lkf_scoring_tkl_adjust(pAufenthalt, pAufenthalt->LDFPLK + pAufenthalt->MELZU + pAufenthalt->SCULK);
            }
         }
    }
    return 0;
}

static int lkf_scoring_hasTKL (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, char *sTraceLine) {
    unsigned int k;
    MEL_ARRAY_STRUC *pTklMel;
    char tmp_mel_ka[12];
    
    for (k = 0; k < pAufenthalt->mel_anz; k++) {
            
        pTklMel = FindMel (pContext, pAufenthalt->mel[k].MEL);
            
        if (pTklMel) {
            if (pTklMel->cTKL== 'J') {
                sprintf (tmp_mel_ka, "%4.4s %5.5s", pAufenthalt->KANR, pAufenthalt->mel[k].MEL);
                if (!GetMELKATKLContext (pContext, tmp_mel_ka)) {
                    if (sTraceLine) {
                        sprintf (sTraceLine, "TKL0Tage: tklmel %5.5s -> TKLMEL gefunden", pAufenthalt->mel[k].MEL);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                    return k + 1;
                }
                else if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage: tklmel %5.5s, aber MELKATKL -> ignoriert", pAufenthalt->mel[k].MEL);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            else if (pTklMel->cBdgr0 == 'W') {
                if (pAufenthalt->mel[k].melPlausFlags & LKF_MELCHECKFLAG_WX3P_ACCEPTED) {
                    if (sTraceLine) {
                        sprintf (sTraceLine, "TKL0Tage: mel %5.5s ohne TKL, WX3P akzeptiert -> TKLMEL gefunden", pAufenthalt->mel[k].MEL);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                    return k + 1;
                }
            }
            /*
            else if (sTraceLine) {
                sprintf (sTraceLine, "TKL0Tage: mel %5.5s ist keine TKL-MEL -> ignoriert", pAufenthalt->mel[k].MEL);
                TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            }
            */
        }
        /*
        else if (sTraceLine) {
            sprintf (sTraceLine, "TKL0Tage: mel %5.5s not found -> ignoriert", pAufenthalt->mel[k].MEL);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
        }
        */
    }
    return 0;
}

static void lkf_scoring_compute_nta (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, int tklMel, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe, const LKF_KNOTEN *pKnoten, short act_knoten, char *sTraceLine) {
    
    pSubgruppe->TKLModus = 0;
    
    if (tklMel)
    {
        pSubgruppe->SCUTK_DOUBLE = pKnoten->tk_anteil[act_knoten] / pKnoten->vd_mw[act_knoten];
        pSubgruppe->SCUTK = simCLng(pSubgruppe->SCUTK_DOUBLE);
                
        if (sTraceLine) {
            sprintf (sTraceLine, "#NTA;%s;TKL;SCUTK;%5.1f;TK/VD_MW", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK_DOUBLE);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
        }
        if (!memcmp (pSubgruppe->gruppe, "HDG", 3)) {
            pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten] + pKnoten->lk_nichtFilter[act_knoten] * 0.55);
            if (sTraceLine) {
                sprintf (sTraceLine, "#NTA;%s;TKL;SCULK;%ld;HDG -> 100%% Split + 55%% NichtFilter", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK);
                TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            }
        }
        else {
            pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten] + pKnoten->lk_nichtFilter[act_knoten] * 0.3);
            if (sTraceLine) {
                sprintf (sTraceLine, "#NTA;%s;TKL;SCULK;%ld;NichtHDG -> 100%% FilterSplit + 30%% NichtFilter", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK);
                TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            }
        }
        
        pSubgruppe->TKLModus = 2;
    }
    else if (!memcmp(pSubgruppe->gruppe, "MEL22", 5))
    {
        if (!memcmp(pSubgruppe->gruppe, "MEL22.28", 8) || !memcmp(pSubgruppe->gruppe, "MEL22.29", 8)) {
            pSubgruppe->SCUTK = 475;
        }
        else {
            pSubgruppe->SCUTK = 275;
        }
        pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
        pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten]);
        if (sTraceLine) {
            sprintf (sTraceLine, "#NTA;%s;MEL22;SCUTK;%ld;%8.8s", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK, pSubgruppe->gruppe);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            sprintf (sTraceLine, "#NTA;%s;MEL22;SCULK;%ld;%8.8s", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK, pSubgruppe->gruppe);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
        }
    }
    else if (!memcmp(pSubgruppe->gruppe, "MEL24", 5) ||
             (!memcmp(pSubgruppe->gruppe, "MEL25", 5) &&
              ((pSubgruppe->gruppe[6] == '0' && strchr ("289", pSubgruppe->gruppe[7])) ||
               (pSubgruppe->gruppe[6] == '1' && pSubgruppe->gruppe[7] == '0')))) {
        pSubgruppe->SCUTK = 0;
        pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
        pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten]);
        if (sTraceLine) {
            sprintf (sTraceLine, "#NTA;%s;MEL24;SCUTK;%ld;%8.8s -> TK fix %ld", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK, pSubgruppe->gruppe, pSubgruppe->SCUTK);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            sprintf (sTraceLine, "#NTA;%s;MEL24;SCULK;%ld;%8.8s -> 100%% FilterSplit", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK, pSubgruppe->gruppe);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
        }
    }
    else { /* ENTART='4', BG020, BG030, GE010, HH020, QE010 */
        pSubgruppe->SCUTK = 50;
        pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
        pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten]);
        if (sTraceLine) {
            sprintf (sTraceLine, "#NTA;%s;OTHER;SCUTK;%ld;TK fix %ld", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK, pSubgruppe->SCUTK);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);

            sprintf (sTraceLine, "#NTA;%s;OTHER;SCULK;%ld;%8.8s -> 100%% FilterSplit", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK, pSubgruppe->gruppe);
            TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
        }
        pSubgruppe->TKLModus = 1;
    }
}

static void lkf_scoring_compute_nta_bis2024 (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, int tklMel, LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe, const LKF_KNOTEN *pKnoten, short act_knoten, int bMelZuModus, char *sTraceLine) {
    
    if (pAufenthalt->ENTART == 'S' || pAufenthalt->ENTART == 'T')
    {
        pSubgruppe->SCUTK = 490;
        pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
        pSubgruppe->SCULK = simCLng (pKnoten->lk_anteil[act_knoten]);
    }
    else {
        unsigned int k;
        pSubgruppe->TKLModus = 0;
        
        if (tklMel)
        {
            pSubgruppe->SCUTK_DOUBLE = pKnoten->tk_anteil[act_knoten] / pKnoten->vd_u[act_knoten];

            if (pContext->modelljahr >= 2020) {
                double maxpkt;
                double max_median_faktor = 1.5;
                maxpkt = pKnoten->tk_anteil[act_knoten] / pKnoten->vd_mw[act_knoten] * max_median_faktor;
                if (maxpkt < pSubgruppe->SCUTK_DOUBLE) {
                    if (sTraceLine) {
                        sprintf (sTraceLine, "TKL0Tage: SCUTK=%5.1f > 1.5*median -> SCUTK=%5.1f", pSubgruppe->SCUTK_DOUBLE, maxpkt);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                    pSubgruppe->SCUTK_DOUBLE = maxpkt;
                }
                else if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage: SCUTK=%5.1f", pSubgruppe->SCUTK_DOUBLE);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            pSubgruppe->SCUTK = simCLng (pSubgruppe->SCUTK_DOUBLE);

            pSubgruppe->SCULK = simCLng (pKnoten->lk_anteil [act_knoten]);
            pSubgruppe->TKLModus = 2;
        }
        else if (!bMelZuModus) {
            int found50mel = 0;
            pSubgruppe->SCUTK = 30;
            pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
            
            if (sTraceLine) {
                sprintf (sTraceLine, "TKL0Tage/!MELZU: SCUTK fix %5.1f", pSubgruppe->SCUTK_DOUBLE);
                TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            }
            
            for (k = 0; k < pAufenthalt->mel_anz; k++) {
                if (MELInIndexList(pAufenthalt->pScoringContext, MEL_LEIST50_LIST, pAufenthalt->mel[k].nMelIndex)) { /* V21.2 */
                    found50mel = 1;
                    break;
                }
            }
            
            if (found50mel) {
                pSubgruppe->SCULK = simCLng (pKnoten->lk_anteil [act_knoten]*0.5);
            }
            else
                pSubgruppe->SCULK = 0;
        }
        else if (!memcmp(pSubgruppe->gruppe, "MEL22", 5)) {
            pSubgruppe->SCUTK = 235;
            pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
            if (sTraceLine) {
                sprintf (sTraceLine, "TKL0Tage: SCUTK fuer MEL22 fix %5.1f", pSubgruppe->SCUTK_DOUBLE);
                TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
            }
            if (pSubgruppe->melzu_voll) {
                pSubgruppe->SCULK = simCLng (pKnoten->lk_anteil [act_knoten]);
                if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage: SCULK voll %5ld", pSubgruppe->SCULK);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            else {
                pSubgruppe->SCULK = simCLng (pSubgruppe->melzu_reduziert);
                if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage: SCULK reduziert %5ld", pSubgruppe->SCULK);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
        }
        else {
            if (pKnoten->tk_anteil[act_knoten] > 0) {
                pSubgruppe->SCUTK = 30;
                pSubgruppe->SCUTK_DOUBLE = pSubgruppe->SCUTK;
                if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage/MELZU: hat TK -> SCUTK fix %5.1f", pSubgruppe->SCUTK_DOUBLE);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            else {
                pSubgruppe->SCUTK = 0;
                pSubgruppe->SCUTK_DOUBLE = 0;
                if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage/MELZU: kein TK -> SCUTK fix %5.1f", pSubgruppe->SCUTK_DOUBLE);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            if (pSubgruppe->melzu_voll) {
                pSubgruppe->SCULK = simCLng (pKnoten->lk_anteil [act_knoten]);
                if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage: SCULK voll %5ld", pSubgruppe->SCULK);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            else {
                pSubgruppe->SCULK = simCLng (pSubgruppe->melzu_reduziert);
                if (sTraceLine) {
                    sprintf (sTraceLine, "TKL0Tage: SCULK reduziert %5ld", pSubgruppe->SCULK);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            pSubgruppe->TKLModus = 1;
        }
    }

}


static int lkf_scoring_compute_subgruppen (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt, LKF_SCORINGDETAILS *pScoringDetails, char *sTraceLine)
{
    unsigned int i, j;
    const char *diag;
    ICD_LIST_STRING *pICD;
    LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe;
    const LKF_KNOTEN *pKnoten;
    char errbuf[1024];
    short act_knoten;
    int nSplitSteps;
    int scoring_split_result;
    int is_agr01;
    int tklMel;
    double calc, day_mean;
    int bMelZuModus;
    long *plCurMELZU;
    
    bMelZuModus = pAufenthalt->pat_subgruppen != 0;
    
    
    if (!pAufenthalt->pat_subgruppen) {

        int zd_hdggruppe;
        int grpcnt;

        if (pContext->flags & LKFCONTEXT_OPTIMIZER) {
        
            zd_hdggruppe = 0;

            for (i = 1; i < pAufenthalt->diag_anz; i++) {
            
                diag = pAufenthalt->diag[i].DIAG;
                pICD = FindDiag (pContext->pStamm2001, diag); /* V13.3 */

                if (pICD && !memcmp ((*pICD) + 9, "HDG", 3)) {
                    ++zd_hdggruppe;
                    if (pScoringDetails) {
                        pScoringDetails->pDiagGroup[i].subgruppeIndex = zd_hdggruppe;
                    }
                }
                else if (pScoringDetails) {
                    pScoringDetails->pDiagGroup[i].inactive = 1;
                }
            }

        }
        else {
            if (pScoringDetails) {
                for (i = 1; i < pAufenthalt->diag_anz; i++) {
                    pScoringDetails->pDiagGroup[i].inactive = 1;
                }
            }
            zd_hdggruppe = 0;
        }
        if (!lkf_create_aufenthalt_subgruppen (pAufenthalt, 1 + (unsigned int) zd_hdggruppe)) {
            return LKF_OUTOFMEMORY_ERROR;
        }

        pAufenthalt->optimizeable = zd_hdggruppe;

        pICD = FindDiag (pContext->pStamm2001, pAufenthalt->HD); /* V13.3 */

        if (pICD && !memcmp ((*pICD) + 9, "HDG", 3)) {
            sprintf (pAufenthalt->subgruppe[0].gruppe, "%-8.8s    ", (*pICD) + 9);
            pAufenthalt->subgruppe[0].anz = 1;
            pAufenthalt->subgruppe[0].mel_id = -1; /* V13.0 */
            pAufenthalt->subgruppe[0].lMelDat = 0; /* V13.0 */
            sprintf (pAufenthalt->subgruppe[0].subgruppe_ident, "#00:%8.8s/%-6.6s", pAufenthalt->subgruppe[0].gruppe, pAufenthalt->diag[0].DIAG);
            pAufenthalt->subgruppe[0].subgruppeId = 0;
            sprintf (pAufenthalt->subgruppe[0].diag, "%-6.6sH %-4.4s",
                pAufenthalt->diag[0].DIAG, pAufenthalt->diag[0].DIAGPOS);
            pAufenthalt->pat_subgruppen = 1 + (unsigned int) pAufenthalt->optimizeable;

            if (pAufenthalt->optimizeable) {
            
                grpcnt = 0;

                for (i = 1; i < pAufenthalt->diag_anz; i++) {

                    diag = pAufenthalt->diag[i].DIAG;
                    pICD = FindDiag (pContext->pStamm2001, diag);

                    if (pICD && !memcmp ((*pICD) + 9, "HDG", 3)) {
                        ++grpcnt;
                        sprintf (pAufenthalt->subgruppe[grpcnt].gruppe, "%-8.8s      ", (*pICD) + 9);
                        pAufenthalt->subgruppe[grpcnt].anz = 1;
                        pAufenthalt->subgruppe[grpcnt].mel_id = -1; /* V13.0 */
                        sprintf (pAufenthalt->subgruppe[grpcnt].subgruppe_ident, "#%02d:%8.8s/%-6.6s", grpcnt, pAufenthalt->subgruppe[grpcnt].gruppe, diag);
                        pAufenthalt->subgruppe[grpcnt].subgruppeId = grpcnt;
                        sprintf (pAufenthalt->subgruppe[grpcnt].diag, "%-6.6sZ %-4.4s",
                            diag, pAufenthalt->diag[i].DIAGPOS);

                    }
                }
            }
        }
        if (pScoringDetails) {
            pScoringDetails->isDIAGGroup = 1;
            pScoringDetails->pDiagGroup[0].subgruppeIndex = 0;
            for (i = 1; i < pAufenthalt->hdiag_anz; i++) {
                pScoringDetails->pDiagGroup[i].inactive = 1;
            }
        }
    }
    else
    {
        if (pScoringDetails) {
            unsigned int i, j, currentIndex;
            
            int *originalIndexes = (int *) LKF_CALLOC (pContext, "lkf_scoring_compute_subgruppen", sizeof(int), pAufenthalt->mel_anz);
            if (!originalIndexes) return LKF_OUTOFMEMORY_ERROR;

            for (i = 0; i < pAufenthalt->mel_anz; i++) {
                originalIndexes[i] = pScoringDetails->pGroup[i].subgruppeIndex;
            }
            
            SortSubgruppeMelDat (pAufenthalt->pat_subgruppen, pAufenthalt->subgruppe);
            
            for (i = 0; i < pAufenthalt->mel_anz; i++) {
                currentIndex = originalIndexes[i];
                if (currentIndex >= 0) {
                    for (j = 0; j < pAufenthalt->pat_subgruppen; j++) {
                        if (pAufenthalt->subgruppe[j].originalIndex == currentIndex) {
                            pScoringDetails->pGroup[i].subgruppeIndex = (int) j;
                            break;
                        }
                    }
                }
            }
            LKF_FREE (pContext, "lkf_scoring_compute_subgruppen", originalIndexes);
        }
        else {
            SortSubgruppeMelDat (pAufenthalt->pat_subgruppen, pAufenthalt->subgruppe);
        }
    }
    
    tklMel = pContext->modelljahr >= 2017 && pAufenthalt->GESVD == 0;
    
    if (tklMel) {
        if (pContext->modelljahr >= 2025 && (pAufenthalt->ENTART == 'S' || pAufenthalt->ENTART == 'T')) {
            char buf[2];
            sprintf (buf, "%c", pAufenthalt->ENTART);
            lkf_auf_add_category(pAufenthalt, "0ENT", buf, 1);
        }
        else {
            int foundMel = lkf_scoring_hasTKL(pContext, pAufenthalt, sTraceLine);
            if (foundMel == 0) {
                tklMel = 0;
            }
            else {
                lkf_auf_add_category(pAufenthalt, "TKLMEL", pAufenthalt->mel[foundMel-1].MEL, 5);
            }
        }
    }
    
    for (i = 0; i < pAufenthalt->pat_subgruppen; i++) {

        pSubgruppe = pAufenthalt->subgruppe + i;
        plCurMELZU = pSubgruppe->plCurMELZU;
        
        pSubgruppe->pMelZu = (MELZU_DATA *) LKF_CALLOC (pContext, "lkf_scoring_compute_subgruppen", pAufenthalt->mel_anz, sizeof (MELZU_DATA));
        if (!pSubgruppe->pMelZu) {
            return LKF_OUTOFMEMORY_ERROR;
        }

        if (i && pAufenthalt->optimizeable) diag = pSubgruppe->diag;
        else diag = pAufenthalt->HD;

        if (pScoringDetails) {
            pScoringDetails->pCurrentGroup = pScoringDetails->isDIAGGroup ? diagDetailsForSubgruppe(pScoringDetails, i) : pScoringDetails->pGroup + pSubgruppe->mel_id;
        }
        
        if ((pKnoten = GetLKFKnoten (pContext->pStamm2001, pSubgruppe->gruppe, errbuf))) {
        
            if (sTraceLine)
            {
                sprintf (sTraceLine, "#Subgruppe;%s", pSubgruppe->subgruppe_ident);
                TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            }

            act_knoten = 0;
            is_agr01 = 0;

            nSplitSteps = 0;

            while (pKnoten->nfl[act_knoten] != -99)
            {
                if (++nSplitSteps > 20)
                {
                    /* Nach 20 Schritten abbrechen - vermutlich Fehler im Stammdaten-File */
                    sprintf (pContext->errortext, "FEHLER beim Scoring-Split von '%8.8s', Abbruch nach 20 Schritten, vermutlich Fehler im Stammdaten-File",
                            pAufenthalt->subgruppe[i].gruppe);
                    return -2;
                }
#ifdef SUPPORT_PRE2017
                scoring_split_result = pContext->modelljahr >= 2017 ? scoring_split_2017 (pAufenthalt, pKnoten, act_knoten, pSubgruppe->gruppe, diag, pSubgruppe->mel_id, sTraceLine)
                                                    : scoring_split_2009 (pAufenthalt, pKnoten, act_knoten, pSubgruppe->gruppe, &is_agr01, diag, pSubgruppe->mel_id, sTraceLine);
#else
                scoring_split_result = scoring_split_2017 (pAufenthalt, pKnoten, act_knoten, pSubgruppe->gruppe, diag, pSubgruppe->mel_id, sTraceLine);
#endif
                if (scoring_split_result)
                     act_knoten = pKnoten->nfl[act_knoten]-1;
                else act_knoten = pKnoten->nfl[act_knoten];

                if (sTraceLine)
                {
                    sprintf (sTraceLine, "Scoring-Split: Ergebnis=%d, Neuer Knoten=%d", scoring_split_result, act_knoten);
                    TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
                }
            }

            pSubgruppe->knoten_char = pKnoten->knoten_char[act_knoten];
            pSubgruppe->vd_u  = pKnoten->vd_u[act_knoten];
            pSubgruppe->vd_o  = pKnoten->vd_o[act_knoten];
            pSubgruppe->vd_mw = pKnoten->vd_mw[act_knoten];

            if (pSubgruppe->mel_id >= 0 && !MELInIndexList (pContext, MEL_NICHTREDUZIERT, pAufenthalt->mel[pSubgruppe->mel_id].nMelIndex))
            {
                pSubgruppe->melzu_voll = 0;
                pSubgruppe->melzu_reduziert = pKnoten->melzu_reduziert[act_knoten];
                if (pSubgruppe->melzu_reduziert == 0 && pContext->modelljahr < 2010)
                    pSubgruppe->melzu_voll = 1; /* Fehlerkorrektur reduzierte MEL 0 erst ab Modell 2010 */
            }
            else {
                if (pScoringDetails && pSubgruppe->mel_id >= 0) {
                    sprintf (sTraceLine, "Voller MEL-Zuschlag fuer %5.5s", pAufenthalt->mel[pSubgruppe->mel_id].MEL);
                    lkf_scoringdetails_addComment(pAufenthalt, sTraceLine);
                }
                pSubgruppe->melzu_reduziert = 0;
                pSubgruppe->melzu_voll = 1;
            }
            pSubgruppe->mel_median = pKnoten->median[act_knoten];

    /**************************************************/
    /*' Baum wurde abgearbeitet, merke das Maximum !! */
    /**************************************************/
            
            if (pContext->modelljahr >= 2017)
            {
                pSubgruppe->leistungs_anteil = simCLng(pKnoten->lk_anteil[act_knoten]);
            }
            else
            {
                calc = pKnoten->median[act_knoten]*pKnoten->lk_anteil[act_knoten]/100;
                pSubgruppe->leistungs_anteil = simCLng(calc);
            }
            

    /*************************************************************************************/
    /*' wenn gleiche Leistung mehrfach erbracht wurde, dann merke Leistungsanteile mit !!*/
    /*************************************************************************************/
            if (pSubgruppe->mel_id >= 0 && pAufenthalt->pMelMel && pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,pSubgruppe->mel_id,pSubgruppe->mel_id)])
                pSubgruppe->MELZU = 0;
            else if (pSubgruppe->anz > 1)
            {
                if (plCurMELZU && !pSubgruppe->melzu_voll) {
                    /* reduzierter MEL-Zuschlag bei Mehrfachnennung */
                
                    if (pContext->modelljahr >= 2017) {
                        pSubgruppe->MELZU = simCLng(pSubgruppe->melzu_reduziert) * (pSubgruppe->anz - 1);
                        if (plCurMELZU) plCurMELZU[pSubgruppe->mel_id] = simCLng(pSubgruppe->melzu_reduziert) * (pSubgruppe->anz - 1);
                        
                    }
                    else {
                        pSubgruppe->MELZU = simCLng(pSubgruppe->mel_median * pSubgruppe->melzu_reduziert/100) * (pSubgruppe->anz - 1);
                        if (plCurMELZU) plCurMELZU[pSubgruppe->mel_id] = simCLng(pSubgruppe->mel_median * pSubgruppe->melzu_reduziert/100) * (pSubgruppe->anz - 1);
                    }
                    
                }
                else {
                    pSubgruppe->MELZU = pSubgruppe->leistungs_anteil * (pSubgruppe->anz - 1);
                    if (plCurMELZU) plCurMELZU[pSubgruppe->mel_id] = pSubgruppe->leistungs_anteil * (pSubgruppe->anz - 1);
                }
            }
            else pSubgruppe->MELZU = 0;

            pSubgruppe->MELZU_DIRECT = pSubgruppe->MELZU;
            
            if (pSubgruppe->mel_id >= 0)
                pSubgruppe->pMelZu[pSubgruppe->mel_id].lMelZu = pSubgruppe->MELZU;

            pSubgruppe->LDFPLK = pSubgruppe->LDFPTK = pSubgruppe->VDZU = 0;
    /********************************/
    /*' wenn VD-Ausreißer nach unten*/
    /********************************/
#ifdef SUPPORT_PRE2017
            if (pContext->modelljahr < 2017 && (pAufenthalt->GESVD == 0 || pAufenthalt->GESVD < pKnoten->vd_u[act_knoten])) {
                calc = pKnoten->median[act_knoten] * pKnoten->tk_anteil[act_knoten] / 100 * (pAufenthalt->GESVD + 1);
                calc /= pKnoten->vd_u[act_knoten] + 1;
                pSubgruppe->SCUTK_DOUBLE = calc;
                pSubgruppe->SCUTK = simCLng (calc);
                calc = pKnoten->median[act_knoten] * pKnoten->lk_anteil [act_knoten] / 100;
                pSubgruppe->SCULK = simCLng (calc);

            }
            else 
#endif
            if (pAufenthalt->GESVD == 0) {
                lkf_auf_add_category(pAufenthalt, "NTA", 0, 0);
                if (pContext->modelljahr >= 2025) {
                    lkf_scoring_compute_nta (pContext, pAufenthalt, tklMel, pSubgruppe, pKnoten, act_knoten, sTraceLine);
                }
                else {
                    lkf_scoring_compute_nta_bis2024 (pContext, pAufenthalt, tklMel, pSubgruppe, pKnoten, act_knoten, bMelZuModus, sTraceLine);
                }
            }
            else if (pAufenthalt->GESVD == 1 && pContext->modelljahr >= 2025) {
                lkf_auf_add_category(pAufenthalt, "ETA", 0, 0);
                if (pKnoten->vd_mw[act_knoten] == 0) {
                    pSubgruppe->SCUTK_DOUBLE = pKnoten->tk_anteil[act_knoten];
                    if (sTraceLine) {
                        sprintf (sTraceLine, "#ETA;%s;ETA;SCUTK;%5.1f;VDMW=0 -> 100%% TK-Anteil", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK_DOUBLE);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                }
                else {
                    pSubgruppe->SCUTK_DOUBLE = pKnoten->tk_anteil[act_knoten] / pKnoten->vd_mw[act_knoten];
                    if (sTraceLine) {
                        sprintf (sTraceLine, "#ETA;%s;ETA;SCUTK;%5.1f;VDMW=%5.1f -> 100%% TK/VDMW", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK_DOUBLE, pKnoten->vd_mw[act_knoten]);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                }

                pSubgruppe->SCUTK = simCLng (pSubgruppe->SCUTK_DOUBLE);
                if (!memcmp (pSubgruppe->gruppe, "HDG", 3)) {
                    pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten] + pKnoten->lk_nichtFilter[act_knoten] * 0.55);
                    if (sTraceLine) {
                        sprintf (sTraceLine, "#ETA;%s;ETA;SCULK;%ld;HDG -> 100%% FilterSplit + 55%% NichtFilter", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                }
                else {
                    pSubgruppe->SCULK = simCLng (pKnoten->lk_filterSplit [act_knoten] + pKnoten->lk_nichtFilter[act_knoten] * 0.3);
                    if (sTraceLine) {
                        sprintf (sTraceLine, "#ETA;%s;ETA;SCULK;%ld;NichtHDG -> 100%% FilterSplit + 30%% NichtFilter", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK);
                        TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    }
                }
                pSubgruppe->TKLModus = 2;
            }
            else if (pAufenthalt->GESVD < pKnoten->vd_u[act_knoten]) {
                pSubgruppe->SCUTK_DOUBLE = pKnoten->tk_anteil[act_knoten] * pAufenthalt->GESVD / pKnoten->vd_u[act_knoten];
                pSubgruppe->SCUTK = simCLng (pSubgruppe->SCUTK_DOUBLE);
                pSubgruppe->SCULK = simCLng (pKnoten->lk_anteil [act_knoten]);
                if (sTraceLine) {
                    sprintf (sTraceLine, "#VDU;%s;ETA;SCUTK;%ld;TK * GESVD/VDU", pSubgruppe->subgruppe_ident, pSubgruppe->SCUTK);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                    sprintf (sTraceLine, "#VDU;%s;ETA;SCULK;%ld;100%% LK-Anteil", pSubgruppe->subgruppe_ident, pSubgruppe->SCULK);
                    TRACE_DETAIL(pAufenthalt,-1, sTraceLine);
                }
            }
            else
    /********************************/
    /*' der ganz normale Patient    */
    /********************************/
            {
                pSubgruppe->SCUTK = 0;
                pSubgruppe->SCULK = 0;
                pSubgruppe->SCUTK_DOUBLE = 0.0;

                if (pContext->modelljahr >= 2017) {
                    pSubgruppe->LDFPLK = simCLng (pKnoten->lk_anteil[act_knoten]);
                    pSubgruppe->LDFPTK = simCLng (pKnoten->tk_anteil[act_knoten]);
                }
                else {
                    calc = pKnoten->median[act_knoten] * pKnoten->lk_anteil[act_knoten] / 100;
                    pSubgruppe->LDFPLK = simCLng (calc);
                    pSubgruppe->LDFPTK = simCLng(pKnoten->median[act_knoten]) - pSubgruppe->LDFPLK;
                }

    /********************************/
    /*' VD-Ausreißer nach oben      */
    /********************************/

                if (!pAufenthalt->psych_mode && pAufenthalt->GESVD > pKnoten->vd_o[act_knoten]) {
                
                    short vdo_max = pKnoten->vd_o[act_knoten] * 2;

                    if (pContext->modelljahr >= 2017) {
                        calc = pKnoten->tk_anteil[act_knoten];
                    }
                    else {
                        calc = pKnoten->median[act_knoten] * pKnoten->tk_anteil[act_knoten] / 100;
                    }
                    calc /= pKnoten->vd_mw[act_knoten];
                    day_mean = calc;


                    for (j = (unsigned int) pKnoten->vd_o[act_knoten] + 1; j <= (unsigned int) pAufenthalt->GESVD; j++) {
                    
                        calc = pKnoten->vd_o[act_knoten] * day_mean;
                        
                        if (pContext->modelljahr < 2009)
                            calc /= j;
                        else
                        {
                            calc /= (j>(unsigned int)vdo_max)?vdo_max:j;
                        }
                        pSubgruppe->VDZU += simCLng (calc);
                    }
                }
            }
            
            if (sTraceLine)
            {
                sprintf (sTraceLine, "Knoten '%c' (vd_u=%3d, vd_o=%3d, vd_mw=%6.2f), SCUTK=%5ld, SCULK=%5ld, VDZU=%5ld, LDFPTK=%5ld, LKFPLK=%5ld, MELZU=%5ld",
                    pSubgruppe->knoten_char, pSubgruppe->vd_u, pSubgruppe->vd_o, pSubgruppe->vd_mw,
                    pSubgruppe->SCUTK, pSubgruppe->SCULK, pSubgruppe->VDZU, pSubgruppe->LDFPTK, pSubgruppe->LDFPLK, pSubgruppe->MELZU);
                TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
            }

        }
        else {
            sprintf (pContext->errortext, "FEHLER beim Einlesen des Files '%8.8s': %s",
                     pAufenthalt->subgruppe[i].gruppe, errbuf);
            return -2;
        }
    }
    return 0;
}

int lkf_scoring_compute (LKF_CONTEXT *pContext, LKF_AUFENTHALT *pAufenthalt)
{
	unsigned int i;
    
    LKF_SPEZDATA spezData;
	const SPEZ_LIST_STRING *pSpez;
	int tmp_found_spez;
	char tmp_spez_buf[20];

	int psych_7591, psych_7592;
	
	int quickscore_enabled;

	int melanz;
	MEL_ARRAY_STRUC *pMel = 0;

	int auf19_ok;

    int bTraceInfo;
    int bTraceDetail;
    int ret;

	char sTraceLine[1024];
    
    long *plCurMELZU;
    int bMelZuModus;

    int modelljahr = pContext->modelljahr;
#ifdef SUPPORT_PRE2017
    //int bModell2017p = (modelljahr >= 2017); /* V21.0 */
    //int bSubgruppeTKL = (modelljahr >= 2011) ? !bModell2017p : 0;
#endif
    int bAmb = (pAufenthalt->BEHANDLUNGSART == 'I') && pAufenthalt->isAmb != 2;
    
    LKF_SCORINGDETAILS *pScoringDetails;

    if (pContext->noStamm) {
        compute_dates(pAufenthalt); /* V2023.2 */
        return 0;
    }
        
    
	pAufenthalt->pScoringContext = pContext;
	pContext->errortext[0] = 0;		
    
	if (pContext->pTraceSettings && pContext->pTraceSettings->nMBDSSeverity)
	{
 		if (pContext->pTraceSettings->sPATID[0])
		{
			unsigned int nPatIdLen = (unsigned int) strlen (pContext->pTraceSettings->sPATID);

            if (pContext->isBM) {
                if (!memcmp (pContext->pTraceSettings->sPATID, pAufenthalt->UCASE_PATID, nPatIdLen))
                    pContext->nTraceAufenthalt = pContext->pTraceSettings->nMBDSSeverity;
            }
            else {
                if (!memcmp (pContext->pTraceSettings->sPATID, pAufenthalt->PATID, nPatIdLen))
                    pContext->nTraceAufenthalt = pContext->pTraceSettings->nMBDSSeverity;
            }
		}
		else
			pContext->nTraceAufenthalt = pContext->pTraceSettings->nMBDSSeverity;
	}
    
    if (pContext->nTraceAufenthalt) {
        lkf_scoringdetails_alloc (pAufenthalt);
        pScoringDetails = pAufenthalt->pScoringDetails;
    }
    else {
        pScoringDetails = 0;
    }

	pAufenthalt->LDFPTK = 0;
	pAufenthalt->LDFPLK = 0;

	pAufenthalt->SCUTK = 0;
    pAufenthalt->SCUTK_DOUBLE = 0.0;
	pAufenthalt->SCULK = 0;
	pAufenthalt->VDZU = 0;
	pAufenthalt->INTZU = 0;
	pAufenthalt->MELZU = 0;
	pAufenthalt->SCSPEZ = 0;
	pAufenthalt->SCGES = 0;

	pAufenthalt->SCGES_TKL = 0;
	pAufenthalt->SCUTK_TKL = 0;

    pAufenthalt->pat_subgruppen = 0;
    pAufenthalt->max_index = 0;
    pAufenthalt->optimized_subgruppe = 0;
    
	memset (pAufenthalt->GRP, ' ', sizeof(pAufenthalt->GRP));
    
    bTraceInfo = IS_TRACE_INFO (pContext);
    bTraceDetail = IS_TRACE_DETAIL (pContext);
    
    if (bTraceInfo) {
        if (bAmb)
            TRACE_INFO(pAufenthalt, -1, "Scoring Punkteberechnung (spitalsambulant)");
        else
            TRACE_INFO(pAufenthalt, -1, "Scoring Punkteberechnung");
    }
    
    pAufenthalt->status |= 2;

	quickscore_enabled = (pContext->flags & LKFCONTEXT_ALLOWQUICKSCORE);

    if (quickscore_enabled && pAufenthalt->GEBDAT[0] == '#') {
		int alter;
		GetInt (pAufenthalt->GEBDAT + 1, 7, &alter);
		pAufenthalt->Alter = (short) alter;
	}
    else if (pAufenthalt->pScoringContext->isBM) {
        pAufenthalt->Alter = (short) atoi (pAufenthalt->ALTERSGRUPPE);
    }
	else pAufenthalt->Alter = (short) Util_Alter(pAufenthalt);

	memset (pAufenthalt->KNT, ' ', sizeof (pAufenthalt->KNT));

	if (pAufenthalt->nStatus == 0)
	{
		pAufenthalt->GESVD = 0;
		pAufenthalt->GESVD_KORR = 0;

		memcpy(pAufenthalt->GRP, "        ", 8);

		if (bTraceInfo)
			TRACE_INFO (pAufenthalt, -1, "Programmfehler - fuer den Aufenthalt wurde kein Plaus-Check aufgerufen!");

		return -1;
	}
	else
		pAufenthalt->nStatus = 2;

	compute_dates (pAufenthalt);

	if (!bAmb && pAufenthalt->ENTART == 'V')
    {
        return lkf_scoring_entartv(pAufenthalt, modelljahr, bTraceDetail ? sTraceLine : 0);
    }

	pAufenthalt->psych_mode = 0;
    if (!bAmb && pAufenthalt->AUFART == 'H') { /* AUFART H gueltig bis inkl. Modell 2018 */
        lkf_scoring_aufart_h (pAufenthalt, modelljahr, bTraceDetail ? sTraceLine : 0);
    }

	if (quickscore_enabled) {
		lkf_quickscore_compute_abtdats (pAufenthalt, modelljahr, &auf19_ok);
	}
	else {
        lkf_compute_abtdats (pAufenthalt, modelljahr, &auf19_ok);
    }
    
    if (pScoringDetails) {
        for (i = 0; i < pAufenthalt->abt_anz; i++) {
            pScoringDetails->pAbt[i].abtVD = pAufenthalt->abt[i].ABTVD + pAufenthalt->abt[i].ABTVD_KORR;
        }
    }
    
    if (pAufenthalt->isAmb && pAufenthalt->pScoringContext->modelljahr >= 2018)
        pAufenthalt->GESVD = pAufenthalt->GESVD_KORR = 0;

	if (pAufenthalt->FLAG >= '4' && (!pAufenthalt->akerr_count || pAufenthalt->plaus_err)) {

		if (bTraceDetail)
		{
			sprintf (sTraceLine, "Plaus-Flag '%c', keine Punkte wegen Plaus-Fehlers", pAufenthalt->FLAG);
			TRACE_DETAIL (pAufenthalt, -1, sTraceLine);
		}

		memmove(pAufenthalt->GRP, "FEHLER  ", 8);
		return 0;
	}
    
    if (pContext->modelljahr >= 2018 && !memcmp (pAufenthalt->KOST, "BN", 2)) {
        memmove (pAufenthalt->GRP, "HKLE    ", 8);
        return 0;
    }

    if (bAmb) {
        return lkf_scoring_compute_amb (pAufenthalt);
    }
    
	if (auf19_ok == 0) {
		if (bTraceDetail)
		{
			TRACE_DETAIL (pAufenthalt, -1, "PFLEGE-Aufenthalt, keine Punkte");
		}
		memmove (pAufenthalt->GRP, "PFLEGE  ", 8);
		return 0;
	}
	
    if (pAufenthalt->FLAG > '1' && pAufenthalt->isAmb != 2) {
        if (lkf_scoring_checkDIAG0pkt(pAufenthalt, pContext, bTraceDetail)) {
            return 0;
        }
    }

	/* Gueltiger Patient mit speziellen Aufnahmearten H, P, L -> Beenden von Scoring_Pat */

	switch (pAufenthalt->AUFART) {

		case 'P':
			
			if (bTraceDetail)
			{
				TRACE_DETAIL(pAufenthalt, -1, "Aufnahmeart PFLEGE, keine weitere Scoring-Berechnung");
			}
			
			memcpy(pAufenthalt->GRP, "PFLEGE  ", 8);
            lkf_scoring_fill_scges (pContext, pAufenthalt);
			return 0;

		case 'L':
			if (bTraceDetail)
			{
				TRACE_DETAIL(pAufenthalt, -1, "Aufnahmeart LANGZEIT, keine weitere Scoring-Berechnung");
			}
			memcpy(pAufenthalt->GRP, "LANGZEIT", 8);
            lkf_scoring_fill_scges (pContext, pAufenthalt);
			return 0;
		default : ;/* alle anderen Aufnahmearten -> weitermachen */
	}

	/* Neurorehab/Geriatrie/KJNP-Patienten */
	/* LKF99: PsychMEL-Patienten */
    
    memset (&spezData, 0, sizeof(LKF_SPEZDATA));
	spezData.m1255_ok = (modelljahr < 2012) ? 0 : -1; /* V16.0 - anderer Check ab Modell 2012 */
    spezData.mAM100_ok = (modelljahr >= 2011) ? 0 : -1;
    spezData.mAM140_ok = (modelljahr >= 2022) ? 0 : -1;
    pSpez = 0;
	tmp_found_spez = 0;

    spezData.mAJ140_ok = spezData.mAK010_ok = spezData.mLH010_ok = spezData.mLH021_ok = spezData.mDB020_ok = (modelljahr == 2010 || modelljahr == 2011) ? 0 : (-1);

    if (SpezAnz (pContext)) {
        if (!lkf_scoring_spez(pAufenthalt, pContext, modelljahr, pScoringDetails, &spezData, bTraceInfo ? sTraceLine : 0)) {
            return 0;
        }
    }
        
    if (pScoringDetails) {
        pScoringDetails->vd = pAufenthalt->GESVD;
    }

    lkf_scoring_inactivate_mel (pContext, pAufenthalt, &spezData, pScoringDetails, bTraceDetail ? sTraceLine : 0);
    

	/* Intensiv-Zuschläge */

	if (SpezAnz (pContext)) for (i = 0; i < pAufenthalt->abt_anz; i++) {
		
		if (!IsEmpty (pAufenthalt->abt[i].ABTFC, 8)) {
			
			sprintf (tmp_spez_buf, "Ixxxx%4.4s%8.8s", pAufenthalt->KANR, pAufenthalt->abt[i].ABTFC);
			pSpez = SpezInArray (pContext, tmp_spez_buf);

			if (pSpez && !ABTFC_Spez_Check (pAufenthalt, (int) i, pSpez, 0)) pSpez = 0;

			if (pSpez && (*pSpez)[0] == 'I') {
				long int_zuschlag;
				int_zuschlag = (long) simVal ((*pSpez) + 29, 6);

				if (!pAufenthalt->abt[i].ABTVD && (pAufenthalt->ENTART == 'S' || pAufenthalt->ENTART == 'T' || (pAufenthalt->ENTART == LKF_ENTART_REVERS && modelljahr < 2019 /* V2019.2 */))) { /* Intensiv 0-Tage: wenn Intensivabteilung */
                    if (i == pAufenthalt->abt_anz - 1 || IsEmpty (pAufenthalt->abt[i+1].ABTFC, 8)) {
                        pAufenthalt->INTZU += int_zuschlag;
                        if (pScoringDetails) {
                            pScoringDetails->pAbt[i].spezPunkte += int_zuschlag;
                            strcpy (pScoringDetails->pAbt[i].spezBereich, "INTENSIV");
                        }

                    } /* entlassene Abteilung und Patient */
					else if (bTraceDetail)
					{
                        sprintf (sTraceLine, "Abteilungs-Intensivzuschlag %ld wird nicht addiert (Entlassungsabteilung mit Verweildauer = 0 Tage, ENTART S/T)", int_zuschlag);
                        if (pScoringDetails) {
                            lkf_scoringdetails_addComment(pAufenthalt, sTraceLine);
                        }
						TRACE_DETAIL(pAufenthalt, -1, sTraceLine);
					}
				}
                else {
                    pAufenthalt->INTZU += int_zuschlag * pAufenthalt->abt[i].ABTVD;
                    if (pScoringDetails) {
                        pScoringDetails->pAbt[i].spezPunkte += int_zuschlag * pAufenthalt->abt[i].ABTVD;
                        strcpy (pScoringDetails->pAbt[i].spezBereich, "INTENSIV");
                    }
                }
				if (bTraceDetail && int_zuschlag)
				{
					sprintf (sTraceLine, "Abteilungs-Intensivzuschlag: %ld, Gesamtzuschlag: %ld", int_zuschlag, pAufenthalt->INTZU);
					TRACE_DETAIL(pAufenthalt, (int) i, sTraceLine);
				}
			}
		}
	}

	/* Scoring_Filter */
	lkf_free_aufenthalt_subgruppen (pAufenthalt);

	if (pAufenthalt->mel_anz) {
        if (!lkf_create_aufenthalt_subgruppen (pAufenthalt, pAufenthalt->mel_anz)) {
            return LKF_OUTOFMEMORY_ERROR;
        }
		pAufenthalt->optimizeable = 0;
	}
    plCurMELZU = 0;

	psych_7591 = psych_7592 = 0;

	for (i = 0; i < pAufenthalt->mel_anz; i++) {

        melanz = (int) pAufenthalt->mel[i].nTagMelAnzRelevant;
        if (melanz == 0) {
            if (pScoringDetails) {
                pScoringDetails->pGroup[i].inactive = 2;
                pScoringDetails->pGroup[i].subgruppeIndex = -1;
                pScoringDetails->pGroup[i].originalMelIndex = pAufenthalt->mel[i].mel_nr;
            }
            continue;
        }
            
        pMel = FindMel (pContext, pAufenthalt->mel[i].MEL);
		
        if (pMel && melanz > 0) {
			
            if (isGrpMel (pMel, 0))
			{
                LKF_AUFENTHALT_SUBGRUPPE *pSubgruppe = pAufenthalt->subgruppe + pAufenthalt->pat_subgruppen;
                sprintf (pSubgruppe->gruppe, "%-8.8s%-5.5s",
							 pMel->sGruppe, pAufenthalt->mel[i].MEL);
                pSubgruppe->mel_id = (int) i;
                pSubgruppe->plCurMELZU = LKF_CALLOC(pContext, "plCurMELZU", sizeof(long), pAufenthalt->mel_anz);
                if (!pSubgruppe->plCurMELZU) return 0;
                pSubgruppe->subgruppeId = pAufenthalt->pat_subgruppen;
                sprintf (pSubgruppe->subgruppe_ident, "%02d:%8.8s/%5.5s", pAufenthalt->pat_subgruppen, pSubgruppe->gruppe, pAufenthalt->mel[i].MEL);
				pAufenthalt->subgruppe[pAufenthalt->pat_subgruppen].bOp = (pMel->cOp=='J');
				pAufenthalt->subgruppe[pAufenthalt->pat_subgruppen].lMelDat = lkf_dat2int (pAufenthalt->mel[i].MELDAT);
				if (pAufenthalt->mel[i].nMelMelNotAccepted)
					pAufenthalt->subgruppe[pAufenthalt->pat_subgruppen].nMelMelGrp = (int) pAufenthalt->mel[i].nMelMelIndex;
				else 
					pAufenthalt->subgruppe[pAufenthalt->pat_subgruppen].nMelMelGrp = 0;
				if (pAufenthalt->pMelMel && (pAufenthalt->pMelMel[AUFENTHALT_MELMELINDEX(pAufenthalt,(int)i,(int)i)]))
					melanz = 1; /* MEL-MEL mit sich selbst -> anzahl = 1 */

                if (pScoringDetails) {
                    pAufenthalt->subgruppe[pAufenthalt->pat_subgruppen].originalIndex = pAufenthalt->pat_subgruppen;
                    pScoringDetails->pGroup[i].subgruppeIndex = pAufenthalt->pat_subgruppen;
                    pScoringDetails->pGroup[i].originalMelIndex = pAufenthalt->mel[i].mel_nr;
                }
				pAufenthalt->subgruppe[pAufenthalt->pat_subgruppen++].anz = (unsigned int) melanz;
			}
            else if (pScoringDetails) {
                pScoringDetails->pGroup[i].inactive = 2;
                pScoringDetails->pGroup[i].subgruppeIndex = -1;
                pScoringDetails->pGroup[i].originalMelIndex = pAufenthalt->mel[i].mel_nr;
            }
		}
	}

    bMelZuModus = pAufenthalt->pat_subgruppen != 0;
    
    ret = lkf_scoring_compute_subgruppen(pContext, pAufenthalt, pScoringDetails, bTraceDetail ? sTraceLine : 0);

    if (ret < 0) {
        return ret;
    }

    ret = lkf_scoring_result (pContext, pAufenthalt, bMelZuModus, pScoringDetails, bTraceDetail ? sTraceLine : 0);
    if (ret < 0) {
        return ret;
    }
    
    if (spezData.teil_akutpat)
    {
        pAufenthalt->GESVD += spezData.spezial_tage;
        pAufenthalt->GESVD_KORR -= spezData.spezial_tage;
    }
    
    if (pAufenthalt->pScoringDetails) {
        LKF_AUFENTHALT_ABT *pAbt;
        LKF_SCORINGDETAILS_ABT *pScoringAbt;
		unsigned int i;
        pAbt = pAufenthalt->abt;
        pScoringAbt = pAufenthalt->pScoringDetails->pAbt;
        
        for (i = 0; i < pAufenthalt->abt_anz; i++) {
            pScoringAbt->lp100 = pAbt->lp100;
            pScoringAbt->tp100 = pAbt->tp100;
            ++pAbt;
            ++pScoringAbt;
        }
    }

#ifdef LKF_SCORING_AMB_ABT_CHECK
    lkf_scoring_amb_check(pAufenthalt);
#endif

	return 0;
}
