def _expandVerbChainsBySubcat( clauseTokens, clauseID, foundChains, verbSubcat, \
                                                        skipQuestionable=False, \
                                                        breakOnPunctuation=True ):
    ''' 
        Meetod, mis proovib laiendada (mitte-'olema') verbidega l6ppevaid predikaadifraase, 
        lisades nende lõppu rektsiooniseoste järgi uusi infiniitverbe, 
        nt "kutsub" + "langetama"
           "püütakse" + "keelustada" "või" "takistada"
           "ei julgenud" + "arvata", 
           "ei hakka" + "tülitama";

        Sisend 'clauseTokens' on list, mis sisaldab yhe osalause k6iki s6nu (pyvabamorfi poolt
        tehtud s6na-analyyse); Sisend 'verbSubcat' sisaldab andmeid verb-infiniitverb 
        rektsiooniseoste kohta;
        Tulemusena t2iendatakse olemasolevat verbijadade listi (foundChains), pikendades seal
        olevaid verbiga lõppevaid fraase, millal võimalik;
    '''
    global _breakerJaNingEgaVoi, _breakerKomaLopus, _breakerPunktuats
    verb      = WordTemplate({POSTAG:'V'})
    verbInf1  = WordTemplate({POSTAG:'V', FORM:'^(da|ma|maks|mas|mast|mata)$'})
    verbOlema = WordTemplate({POSTAG:'V', ROOT:'^(ole)$'})
    sonaMitte = WordTemplate({ROOT:'^mitte$',POSTAG:'D'})
    # J22dvustame s6nad, mis kuuluvad juba mingi tuvastatud verbifraasi koosseisu
    annotatedWords = []
    for verbObj in foundChains:
        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] )
    # Leiame, millised verbid on veel vabad (st v6ivad potentsiaalselt liituda)
    freeVerbsWIDs = [t[WORD_ID] for t in clauseTokens if verbInf1.matches(t) and t[WORD_ID] not in annotatedWords]
    for verbObj in foundChains:
        # Leiame, kas fraas kuulub antud osalausesse ning on laiendatav
        if _isVerbExpansible(verbObj, clauseTokens, clauseID):
            # Leiame viimasele s6nale vastava token'i, selle lemma ja vormitunnuse
            lastToken = [token for token in clauseTokens if token[WORD_ID] == verbObj[PHRASE][-1]]
            lastIndex = [i for i in range(len(clauseTokens)) if clauseTokens[i][WORD_ID] == verbObj[PHRASE][-1]]
            lastToken = lastToken[0]
            lastIndex = lastIndex[0]
            mainVerb  = [(analysis[ROOT], analysis[FORM]) for analysis in verb.matchingAnalyses(lastToken)]
            mainVerbLemma = mainVerb[0][0]
            mainVerbForm  = mainVerb[0][1]
            positivePhrase = (verbObj[POLARITY] == 'POS')
            egaPhrase      = (verbObj[PATTERN][0] == 'ega')
            #  Teeme kindlaks, kas verbi lemma on ylesm2rgitud rektsiooniseoste leksikoni
            if mainVerbLemma in verbSubcat:
                subcatForms = verbSubcat[ mainVerbLemma ]
                for subcatForm in subcatForms:
                    foundSubcatChain = []
                    addingCompleted = False
                    #  Kui on tegu vaieldava rektsiooniseosega: j2tame vahele v6i, kui vaieldavad
                    #  on lubatud, eemaldame vaieldavuse m2rgi 
                    if re.match("^.+\?$", subcatForm):
                        if skipQuestionable:
                            continue
                        else:
                            subcatForm = subcatForm.replace('?', '')
                    #
                    #  1) Otsime sobivat verbi v6i verbifraasi s6na tagant, osalause teisest poolest
                    #
                    j = lastIndex + 1
                    while (j < len(clauseTokens)):
                        token = clauseTokens[j]
                        tokenWID = token[WORD_ID]
                        #  Katkestame kui:
                        #  *) satume juba m2rgendatud s6nale;
                        #  *) satume punktuatsioonile;
                        if tokenWID in annotatedWords:
                            break
                        if breakOnPunctuation and _breakerPunktuats.matches(token):
                            break
                        #  Lisame kui:
                        #  *) satume konjunktsioonile;
                        #  *) satume sobivas vormis verbile;
                        if _breakerJaNingEgaVoi.matches(token):
                            foundSubcatChain.append(('&', token))
                        if verb.matches(token):
                            tokenForms = [analysis[FORM] for analysis in verb.matchingAnalyses(token)]
                            if subcatForm in tokenForms:
                                foundSubcatChain.append( (subcatForm, token) )
                        #  Katkestame kui:
                        #  *) satume komale (kuna koma v6ib kinnituda sobiva s6na l6ppu);
                        if _breakerKomaLopus.matches(token):
                            break
                        j += 1
                    #
                    #     Kui osalause teisest poolest midagi ei leidnud, vaatame 
                    #     osalause esimest poolt:
                    #
                    #  2) Otsime sobivat verbi v6i verbifraasi vahetult s6na algusest
                    #     (seda vaid siis, kui tegemist pole nö 'ega'-verbifraasiga - 
                    #      nondele midagi eelneda ei saagi);
                    #     ( NB! 'ega' fraaside puhul tuleks tegelikult ka tagasi vaadata,
                    #       aga ainult verbi ja 'ega' vahele, ja mitte mingil juhul 
                    #       'ega'-st ettepoole );
                    #
                    if not _suitableVerbExpansion( foundSubcatChain ) and not egaPhrase:
                        minWid = min( verbObj[PHRASE] )
                        j = lastIndex - 1
                        while (j > -1):
                            token = clauseTokens[j]
                            tokenWID = token[WORD_ID]
                            #  Katkestame kui:
                            #  *) satume juba m2rgendatud s6nale (mis pole sellest fraasist);
                            #  *) satume komale v6i muule punktuatsioonile;
                            #  *) satume s6nale, mis on k6ige esimesest fraasiliikmest tagapool kui 2 s6na;
                            if tokenWID in annotatedWords and tokenWID not in verbObj[PHRASE]:
                                break
                            if _breakerKomaLopus.matches(token) or (breakOnPunctuation and _breakerPunktuats.matches(token)):
                                break
                            if token[WORD_ID]+1 < minWid:
                                break
                            #  Lisame kui:
                            #  *) satume konjunktsioonile;
                            #  *) satume sobivas vormis verbile;
                            if _breakerJaNingEgaVoi.matches(token):
                                foundSubcatChain.append(('&', token))
                            if verb.matches(token):
                                tokenForms = [analysis[FORM] for analysis in verb.matchingAnalyses(token)]
                                if subcatForm in tokenForms:
                                    foundSubcatChain.append( (subcatForm, token) )
                            j -= 1
                    suitablePhrase = _suitableVerbExpansion( foundSubcatChain )
                    if suitablePhrase:
                        #
                        #   Kui sobiv fraasikandidaat leidus, teostamine liitmise
                        #
                        for token in suitablePhrase:
                            tokenWID = token[WORD_ID]
                            verbObj[PHRASE].append( tokenWID )
                            annotatedWords.append( tokenWID )
                            if _breakerJaNingEgaVoi.matches(token):
                                verbObj[PATTERN].append('&')
                                verbObj[ANALYSIS_IDS].append( _getMatchingAnalysisIDs( token, _breakerJaNingEgaVoi ) )
                            elif len(suitablePhrase) == 1 and verbOlema.matches(token):
                                verbObj[PATTERN].append('ole')
                                verbObj[ANALYSIS_IDS].append( _getMatchingAnalysisIDs( token, verbOlema ) )
                                freeVerbsWIDs.remove( tokenWID )
                            else:
                                verbObj[PATTERN].append('verb')
                                analysisIDs = [i for i in range(len(token[ANALYSIS])) if subcatForm == token[ANALYSIS][i][FORM]]
                                assert len(analysisIDs) > 0
                                verbObj[ANALYSIS_IDS].append( analysisIDs )
                                freeVerbsWIDs.remove( tokenWID )
                        if not freeVerbsWIDs:
                            verbObj[OTHER_VERBS] = False
                        addingCompleted = True
                    if addingCompleted:
                        break