def _expandOlemaVerbChains( clauseTokens, clauseID, foundChains ):
    '''
         Meetod, mis proovib laiendada 'olema'-l6pulisi (predikaadi) verbiahelaid, lisades 
        võimalusel nende otsa teisi verbe, nt 
            "on olnud" + "tehtud", "ei olnud" + "tehtud", "ei oleks" + "arvatud";
        Vastavalt leitud laiendustele t2iendab andmeid sisendlistis foundChains;
    '''
    verbOle       = WordTemplate({ROOT:'^ole$',POSTAG:'V'})
    verbOleJarel1 = WordTemplate({POSTAG:'V',FORM:'(nud)$'})
    verbOleJarel2 = WordTemplate({POSTAG:'V',FORM:'^(mas|tud)$'})
    verbMata      = WordTemplate({POSTAG:'V',FORM:'^(mata)$'})
    verbMaDa      = WordTemplate({POSTAG:'V',FORM:'^(da|ma)$'})
    # J22dvustame s6nad, mis kuuluvad juba mingi tuvastatud verbifraasi koosseisu
    annotatedWords = []
    for verbObj in foundChains:
        if verbObj[CLAUSE_IDX] != clauseID:
            continue
        if (len(verbObj[PATTERN])==1 and re.match('^(ei|ära|ega)$', verbObj[PATTERN][0])):
            # V2lja j22vad yksikuna esinevad ei/ära/ega, kuna need tõenäoliselt ei sega
            continue
        annotatedWords.extend( verbObj[PHRASE] )
    for verbObj in foundChains:
        if verbObj[CLAUSE_IDX] != clauseID:
            continue
        if verbObj[PATTERN][-1] == 'ole' and verbObj[OTHER_VERBS]:
            #
            #  Kui on tegemist 'olema' l6pulise verbiahelaga, mille kontekstis on teisi verbe,
            #  st saab veel laiendada ...
            #
            eiOlePattern = (len(verbObj[PATTERN])==2 and verbObj[PATTERN][0] == 'ei')
            lastVerbWID = verbObj[PHRASE][-1]
            lastTokIndex = [i for i in range(len(clauseTokens)) if clauseTokens[i][WORD_ID] == lastVerbWID]
            lastTokIndex = lastTokIndex[0]
            expansion   = None
            appliedRule = 0
            if not _isClauseFinal( lastVerbWID, clauseTokens ):
                maDaVerbsBetween = 0
                oleInfFollowing  = 0
                for i in range(lastTokIndex + 1, len(clauseTokens)):
                    token = clauseTokens[i]
                    tokenWID = token[WORD_ID]
                    if tokenWID in annotatedWords:
                        break
                    if verbMaDa.matches(token):
                        maDaVerbsBetween += 1
                    if (verbOleJarel1.matches(token)) or verbOleJarel2.matches(token):
                        #
                        #    Heuristik:
                        #      Kui olema j2rel, osalause l6pus on nud/tud/mas ja nende vahel pole yhtegi 
                        #     punktuatsioonim2rki, sides6na, adverbe aga/kuid/vaid, juba m2rgendatud verbiahelat
                        #     ega teist nud/tud/mas s6na, loeme selle s6na olema-fraasi laienduseks:
                        #
                        #           Pere ei_0 ole_0 Eestis toimuvast vaimustatud_0 .
                        #           " Viimasel ajal on_0 see asi jälle susisema hakanud_0 " ,
                        #           Esiteks ei_0 olnud_0 vajalikul ajal tavaliselt bussi tulemas_0
                        #
                        if _isClauseFinal(tokenWID, clauseTokens ) and \
                           not _isSeparatedByPossibleClauseBreakers( clauseTokens, verbObj[PHRASE][-1], \
                           tokenWID, True, True, True):
                           expansion = token
                           #   Veakoht: kui -mas j2rel on da/ma, pole kindel, et tegu otsese rektsiooniseosega:
                           #      Islamlannale on_0 harjumatu näha meest midagi maast korjamas_0 ,
                        elif verbOleJarel1.matches(token) and eiOlePattern and i-lastTokIndex<=2:
                           #
                           #   Heuristik: "ei"+"ole"-ahela j2rel "nud" ning nende vahel pole rohkem kui
                           #   yks muu s6na:
                           #            Tagantjärele mõeldes ei_0 oleks_0 ma pidanud_0 seda tegema .
                           #            Mina ei_0 ole_0 suutnud_0 siiani maad osta .
                           #
                           expansion = token
                        oleInfFollowing += 1
                        break
                    elif verbMata.matches(token) and maDaVerbsBetween == 0:
                        #
                        #    Heuristik:
                        #      Kui olema j2rel, osalause l6pus on mata ja nende vahel pole yhtegi 
                        #     punktuatsioonim2rki, sides6na, adverbe aga/kuid/vaid, juba m2rgendatud 
                        #     verbiahelat, m6nd nud/tud/mas/ma/da verbi, loeme selle s6na olema-fraasi 
                        #     laienduseks:
                        #
                        #           Maanaine on_0 veel leidmata_0 .
                        #           linnaarhitekti koht oli_0 aasta aega täitmata_0
                        #
                        if _isClauseFinal(tokenWID, clauseTokens ) and \
                           not _isSeparatedByPossibleClauseBreakers( clauseTokens, verbObj[PHRASE][-1], \
                           tokenWID, True, True, True):
                            expansion = token
                            break
                            #   Veakoht: kui vahel on 'ilma', siis see heuristik eksib t6en2oliselt:
                            #          on_0 lihtsalt tõlgendatavad ka ilma situatsioonis osalemata_0
                        oleInfFollowing += 1
                #
                #    Heuristik:
                #     Kui osalauses ei j2rgne 'olema'-verbiga yhilduvaid verbe, kyll aga eelneb vahetult 
                #    m6ni selline ning seda pole veel m2rgendatud, loeme selle potentsiaalselt olema-verbiga
                #    yhilduvaks, nt:
                #
                #                Unustatud_0 ei_0 ole_0 ka mänge .
                #                Tõhustatud_0 on_0 ka turvameetmeid .
                #                milleks looja ta maailma loonud_0 on_0 , nimelt soo jätkamiseks .
                #
                if oleInfFollowing == 0 and not expansion:
                    minWID = min( verbObj[PHRASE] )
                    lastTokIndex = [i for i in range(len(clauseTokens)) if clauseTokens[i][WORD_ID] == minWID]
                    lastTokIndex = lastTokIndex[0]
                    token = clauseTokens[lastTokIndex-1]
                    if lastTokIndex-1 > -1 and token[WORD_ID] not in annotatedWords:
                        if (verbOleJarel1.matches(token) or verbOleJarel2.matches(token)):
                            expansion = token
                            appliedRule = 1
                    
                #
                #    Eituse (aga ka vastavates jaatuse) fraasides j22vad siin eraldamata 
                #       ei + ole + Adv/Nom + Verb_da    
                #    mustrid, nt:
                #       Ei_0 ole_0 mõtet teha sellist söögikohta .
                #       Ei_0 ole_0 võimalik väiksema vastu vahetada .
                #       Ei_0 ole_0 pankuril vaja teada .
                #    Nendega proovime tegeleda hiljem.
                #
            else:
                #
                #   Leiame ahela alguspunkti (minimaalse ID-ga verbi)
                #
                minWID = min( verbObj[PHRASE] )
                lastTokIndex = [i for i in range(len(clauseTokens)) if clauseTokens[i][WORD_ID] == minWID]
                if lastTokIndex:
                    lastTokIndex = lastTokIndex[0]
                    if lastTokIndex-1 > -1 and clauseTokens[lastTokIndex-1][WORD_ID] not in annotatedWords:
                        #
                        #    Heuristik:
                        #   Kui "olema"-l6puline ahel on osalause l6pus, ning vahetult eelneb nud/tud/mas,
                        #  siis loeme selle olema juurde kuuluvaks, nt:
                        #          mis juba olnud ja veel tulemas_0 on_0 ,
                        #          Eesti selle alamprojektiga seotud_0 ei_0 ole_0 .
                        #          trombootilisi episoode kordunud_0 ei_0 ole_0 .
                        #  (Yldiselt paistab suhteliselt v2heproduktiivne reegel olevat)
                        # 
                        token = clauseTokens[lastTokIndex-1]
                        if (verbOleJarel1.matches(token) or verbOleJarel2.matches(token)):
                            expansion = token
            if expansion:
                tokenWID = expansion[WORD_ID]
                verbObj[PHRASE].append( tokenWID )
                verbObj[ANALYSIS_IDS].append( _getMatchingAnalysisIDs( expansion, [verbOleJarel1, verbOleJarel2, verbMata] ) )
                if verbOle.matches(expansion):
                    verbObj[PATTERN].append('ole')
                else:
                    verbObj[PATTERN].append('verb')
                annotatedWords.append( tokenWID )
Meetod, mis proovib laiendada 'olema'-l6pulisi (predikaadi) verbiahelaid, lisades 
        võimalusel nende otsa teisi verbe, nt 
            "on olnud" + "tehtud", "ei olnud" + "tehtud", "ei oleks" + "arvatud";
        Vastavalt leitud laiendustele t2iendab andmeid sisendlistis foundChains;