/*
 * SDK Pullenti Lingvo, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software.
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

package com.pullenti.ner.link;

/**
 * Анализатор связей (специфический анализатор)
 */
public class LinkAnalyzer extends com.pullenti.ner.Analyzer {

    /**
     * Имя анализатора ("LINK")
     */
    public static final String ANALYZER_NAME = "LINK";

    @Override
    public String getName() {
        return ANALYZER_NAME;
    }


    @Override
    public String getCaption() {
        return "Связи";
    }


    @Override
    public String getDescription() {
        return "Связи выделенных сущностй (досье)";
    }


    @Override
    public com.pullenti.ner.Analyzer clone() {
        return new LinkAnalyzer();
    }

    @Override
    public boolean isSpecific() {
        return true;
    }


    @Override
    public java.util.Collection<com.pullenti.ner.metadata.ReferentClass> getTypeSystem() {
        return java.util.Arrays.asList(new com.pullenti.ner.metadata.ReferentClass[] {MetaLink.GLOBALMETA});
    }


    @Override
    public java.util.HashMap<String, byte[]> getImages() {
        java.util.HashMap<String, byte[]> res = new java.util.HashMap<String, byte[]>();
        res.put(MetaLink.IMAGEID.toString(), com.pullenti.ner.core.internal.ResourceHelper3.getBytes("link.png"));
        return res;
    }


    @Override
    public com.pullenti.ner.Referent createReferent(String type) {
        if (com.pullenti.unisharp.Utils.stringsEq(type, LinkReferent.OBJ_TYPENAME)) 
            return new LinkReferent();
        return null;
    }

    @Override
    public int getProgressWeight() {
        return 1;
    }


    @Override
    public void process(com.pullenti.ner.core.AnalysisKit kit) {
        com.pullenti.ner.core.AnalyzerData ad = kit.getAnalyzerData(this);
        com.pullenti.ner.Token t0 = kit.firstToken;
        int cou = 10;
        for (com.pullenti.ner.Token t = t0; t != null && cou > 0; t = t.getNext()) {
            if (!t.isNewlineBefore()) 
                continue;
            cou--;
            com.pullenti.ner.core.ComplexNumToken num = com.pullenti.ner.core.ComplexNumToken.tryParse(t, null, false, false);
            if (num != null) 
                break;
            com.pullenti.ner.core.NounPhraseToken npt = com.pullenti.ner.core.NounPhraseHelper.tryParse(t, com.pullenti.ner.core.NounPhraseParseAttr.NO, 0, null);
            if (npt == null || !npt.isNewlineAfter()) 
                continue;
            if (npt.getEndToken().isValue("ЗАПИСКА", null) || npt.getEndToken().isValue("СПРАВКА", null) || npt.getEndToken().isValue("ОТЧЕТ", null)) {
                t0 = npt.getEndToken().getNext();
                break;
            }
        }
        com.pullenti.ner.person.PersonReferent mainPers = null;
        com.pullenti.ner.person.PersonReferent curPers = null;
        com.pullenti.ner._org.OrganizationReferent curOrg = null;
        com.pullenti.ner.resume.ResumeItemType curTyp = com.pullenti.ner.resume.ResumeItemType.UNDEFINED;
        java.util.ArrayList<com.pullenti.ner.ReferentToken> tmpOrgs = new java.util.ArrayList<com.pullenti.ner.ReferentToken>();
        for (com.pullenti.ner.Token t = t0; t != null; t = t.getNext()) {
            boolean nl = false;
            if (t.isNewlineBefore()) {
                nl = true;
                com.pullenti.ner.core.ComplexNumToken num = com.pullenti.ner.core.ComplexNumToken.tryParse(t, null, false, false);
                if (num != null && num.getEndToken().getNext() != null) {
                    t = num.getEndToken().getNext();
                    nl = true;
                }
            }
            if (curOrg != null && mainPers != null && curOrg.getOccurrence().size() > 0) {
                if ((t.getBeginChar() - curOrg.getOccurrence().get(curOrg.getOccurrence().size() - 1).endChar) > 100) 
                    curOrg = null;
            }
            com.pullenti.ner.Referent r = t.getReferent();
            com.pullenti.ner.person.PersonReferent p = (com.pullenti.ner.person.PersonReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.person.PersonReferent.class);
            if (p != null) {
                curOrg = null;
                if (_isObject(p)) {
                    curPers = p;
                    continue;
                }
                if (p == mainPers || p == curPers) 
                    continue;
                if (mainPers == null || nl) {
                    mainPers = p;
                    _processPerson(p, ad);
                    continue;
                }
                if (mainPers != null) {
                    String nam = p.getStringValue(com.pullenti.ner.person.PersonReferent.ATTR_FIRSTNAME);
                    if (nam == null || (nam.length() < 2)) 
                        continue;
                    _processPerson(p, ad);
                    LinkReferent li = LinkReferent._new2298(mainPers, p);
                    li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                    li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, t, t, null));
                    continue;
                }
                curPers = p;
                _processPerson(p, ad);
                continue;
            }
            p = (curPers != null ? curPers : mainPers);
            if (p == null) {
                if (r instanceof com.pullenti.ner._org.OrganizationReferent) {
                    curOrg = (com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner._org.OrganizationReferent.class);
                    _setObject(r);
                    continue;
                }
                else if (curOrg == null) 
                    continue;
            }
            else if (((p.isFemale() && !p.isMale())) || ((!p.isFemale() && p.isMale()))) {
            }
            else 
                com.pullenti.ner.person.internal.PersonHelper.createSex(p, t);
            com.pullenti.ner.geo.GeoReferent _geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.geo.GeoReferent.class);
            if (_geo != null && _geo.isCity() && p != null) {
                for (com.pullenti.ner.Token tt = t.getPrevious(); tt != null; tt = tt.getPrevious()) {
                    com.pullenti.ner.TextToken te = (com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(tt, com.pullenti.ner.TextToken.class);
                    if (te != null) {
                        if (te.term.startsWith("УР") || te.term.startsWith("РОДИ") || te.term.startsWith("РОЖД")) {
                            _setObject(_geo);
                            LinkReferent li = LinkReferent._new2299(LinkType.BORN, p, _geo);
                            li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                            li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, tt, t, null));
                            break;
                        }
                    }
                    if (tt.getReferent() instanceof com.pullenti.ner.date.DateReferent) 
                        continue;
                    if (tt.getLengthChar() > 1) 
                        break;
                }
            }
            if (p != null && p.findSlot(com.pullenti.ner.person.PersonReferent.ATTR_BORN, null, true) == null && (t.getReferent() instanceof com.pullenti.ner.date.DateReferent)) {
                for (com.pullenti.ner.Token tt = t.getPrevious(); tt != null; tt = tt.getPrevious()) {
                    com.pullenti.ner.TextToken te = (com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(tt, com.pullenti.ner.TextToken.class);
                    if (te != null) {
                        if (te.term.startsWith("УРОЖ") || te.term.startsWith("РОДИ") || te.term.startsWith("РОЖД")) {
                            p.addSlot(com.pullenti.ner.person.PersonReferent.ATTR_BORN, t.getReferent(), false, 0);
                            break;
                        }
                    }
                    if (tt.getReferent() instanceof com.pullenti.ner.geo.GeoReferent) 
                        continue;
                    if (tt.getLengthChar() > 1) 
                        break;
                }
                if (t.getNext() instanceof com.pullenti.ner.TextToken) {
                    if (((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term.startsWith("РОДИ") || ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term.startsWith("РОЖД")) 
                        p.addSlot(com.pullenti.ner.person.PersonReferent.ATTR_BORN, t.getReferent(), false, 0);
                }
            }
            if (r instanceof com.pullenti.ner.phone.PhoneReferent) {
                _setObject(r);
                LinkReferent li = LinkReferent._new2300(LinkType.CONTACT, r);
                if (curOrg != null) 
                    li.setObject1(curOrg);
                else 
                    li.setObject1(p);
                li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, t, t, null));
                continue;
            }
            if (r instanceof com.pullenti.ner.uri.UriReferent) {
                String sh = ((com.pullenti.ner.uri.UriReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.uri.UriReferent.class)).getScheme();
                if (com.pullenti.unisharp.Utils.stringsEq(sh, "http") || com.pullenti.unisharp.Utils.stringsEq(sh, "https") || com.pullenti.unisharp.Utils.stringsEq(sh, "www")) 
                    continue;
                _setObject(r);
                LinkReferent li = LinkReferent._new2299(LinkType.CONTACT, p, r);
                if (curOrg != null) 
                    li.setObject1(curOrg);
                else 
                    li.setObject1(p);
                li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, t, t, null));
                continue;
            }
            if (r instanceof com.pullenti.ner.person.PersonIdentityReferent) {
                if (p == null) 
                    continue;
                _setObject(r);
                LinkReferent li = LinkReferent._new2299(LinkType.DOCUMENT, p, r);
                for (com.pullenti.ner.Slot s : r.getSlots()) {
                    if (s.getValue() instanceof com.pullenti.ner.date.DateReferent) {
                        li.setDateFrom((com.pullenti.ner.date.DateReferent)com.pullenti.unisharp.Utils.cast(s.getValue(), com.pullenti.ner.date.DateReferent.class));
                        break;
                    }
                }
                li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, t, t, null));
                continue;
            }
            if ((r instanceof com.pullenti.ner.address.StreetReferent) || (r instanceof com.pullenti.ner.address.AddressReferent)) {
                _setObject(r);
                LinkReferent li = LinkReferent._new2300(LinkType.ADDRESS, r);
                if (curOrg != null) 
                    li.setObject1(curOrg);
                else 
                    li.setObject1(p);
                _corrAddrTyp(li, t);
                li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, t, t, null));
                continue;
            }
            if (r != null && p != null) {
                if (com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "WEAPON") || com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "TRANSPORT")) {
                    _setObject(r);
                    LinkReferent li = LinkReferent._new2298(p, r);
                    li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                    li.addOccurenceOfRefTok(new com.pullenti.ner.ReferentToken(li, t, t, null));
                    continue;
                }
            }
            if (t.isValue("ОБРАЗОВАНИЕ", null)) 
                curTyp = com.pullenti.ner.resume.ResumeItemType.STUDY;
            if ((t.isValue2("ОПЫТ", "РАБОТЫ") || t.isValue2("МЕСТО", "РАБОТЫ") || t.isValue2("ПЕРИОД", "РАБОТЫ")) || t.isValue("РАБОТАТЬ", null)) 
                curTyp = com.pullenti.ner.resume.ResumeItemType.ORGANIZATION;
            if (p == null) 
                continue;
            if (t.isNewlineBefore()) {
                com.pullenti.ner.ReferentToken rt = com.pullenti.ner.resume.ResumeAnalyzer._parseOrg(t, curTyp);
                if (rt != null) {
                    curTyp = ((com.pullenti.ner.resume.ResumeItemReferent)com.pullenti.unisharp.Utils.cast(rt.referent, com.pullenti.ner.resume.ResumeItemReferent.class)).getTyp();
                    LinkReferent li = _processResumeOrg(p, ad, rt);
                    if (li != null) {
                        ad.registerReferent(li);
                        li.addOccurenceOfRefTok(rt);
                        curOrg = (com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(li.getObject2(), com.pullenti.ner._org.OrganizationReferent.class);
                    }
                    t = rt.getEndToken();
                    continue;
                }
            }
            tmpOrgs.clear();
            com.pullenti.ner.resume.ResumeAnalyzer._parseOrg2(t, null, tmpOrgs);
            if (tmpOrgs.size() > 0) {
                for (com.pullenti.ner.ReferentToken rt1 : tmpOrgs) {
                    LinkReferent li = _processResumeOrg(p, ad, rt1);
                    if (li != null) {
                        ad.registerReferent(li);
                        li.addOccurenceOfRefTok(rt1);
                        curOrg = (com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(li.getObject2(), com.pullenti.ner._org.OrganizationReferent.class);
                    }
                    t = rt1.getEndToken();
                }
                continue;
            }
            if (r instanceof com.pullenti.ner._org.OrganizationReferent) {
                curOrg = (com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner._org.OrganizationReferent.class);
                _processOrg((com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner._org.OrganizationReferent.class), ad, 0);
                LinkReferent li = LinkReferent._new2298(p, r);
                com.pullenti.ner.ReferentToken rt1 = _corrOrgTyp(t, t, li);
                if (li.getTyp() != LinkType.UNDEFINED || li.getParam() != null) {
                    li = (LinkReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(li), LinkReferent.class);
                    li.addOccurenceOfRefTok(rt1);
                }
                continue;
            }
            if (r instanceof com.pullenti.ner.person.PersonPropertyReferent) {
                LinkReferent li = _processPersonAttr(p, (com.pullenti.ner.person.PersonPropertyReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.person.PersonPropertyReferent.class), ad);
                if (li != null) {
                    com.pullenti.ner.ReferentToken rt1 = _corrOrgTyp(t, t, li);
                    ad.registerReferent(li);
                    li.addOccurenceOfRefTok(rt1);
                    curOrg = (com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(li.getObject2(), com.pullenti.ner._org.OrganizationReferent.class);
                }
                continue;
            }
            com.pullenti.ner.person.internal.PersonAttrToken pat = com.pullenti.ner.person.internal.PersonAttrToken.tryAttach(t, com.pullenti.ner.person.internal.PersonAttrToken.PersonAttrAttachAttrs.NO);
            if (pat != null && pat.getPropRef() != null) {
                LinkReferent li = _processPersonAttr(p, pat.getPropRef(), ad);
                if (li != null) {
                    com.pullenti.ner.ReferentToken rt1 = _corrOrgTyp(t, pat.getEndToken(), li);
                    ad.registerReferent(li);
                    li.addOccurenceOfRefTok(rt1);
                    curOrg = (com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(li.getObject2(), com.pullenti.ner._org.OrganizationReferent.class);
                    t = pat.getEndToken();
                    continue;
                }
            }
        }
        for (com.pullenti.ner.Referent r : ad.getReferents()) {
            LinkReferent li = (LinkReferent)com.pullenti.unisharp.Utils.cast(r, LinkReferent.class);
            if (li == null) 
                continue;
            if (li.getTyp() != LinkType.BORN) 
                continue;
            if (!(li.getObject1() instanceof com.pullenti.ner.person.PersonReferent)) 
                continue;
            com.pullenti.ner.date.DateReferent dt = (com.pullenti.ner.date.DateReferent)com.pullenti.unisharp.Utils.cast(li.getObject1().getSlotValue(com.pullenti.ner.person.PersonReferent.ATTR_BORN), com.pullenti.ner.date.DateReferent.class);
            if (dt != null && li.getDateFrom() == null) 
                li.setDateFrom(dt);
        }
    }

    private static boolean _isObject(com.pullenti.ner.Referent r) {
        return com.pullenti.unisharp.Utils.stringsEq(r.getStringValue("OBJECT"), "true");
    }

    private static void _setObject(com.pullenti.ner.Referent r) {
        r.addSlot("OBJECT", "true", true, 0);
    }

    private static void _processPerson(com.pullenti.ner.person.PersonReferent p, com.pullenti.ner.core.AnalyzerData ad) {
        if (_isObject(p)) 
            return;
        _setObject(p);
        for (int i = p.getSlots().size() - 1; i >= 0; i--) {
            com.pullenti.ner.Slot sl = p.getSlots().get(i);
            com.pullenti.ner.Referent r = (com.pullenti.ner.Referent)com.pullenti.unisharp.Utils.cast(sl.getValue(), com.pullenti.ner.Referent.class);
            if ((r instanceof com.pullenti.ner.uri.UriReferent) || (r instanceof com.pullenti.ner.phone.PhoneReferent)) {
                _setObject(r);
                ad.registerReferent(LinkReferent._new2306(p, r, LinkType.CONTACT));
                p.getSlots().remove(i);
                continue;
            }
            if (r instanceof com.pullenti.ner.person.PersonPropertyReferent) {
                LinkReferent li = _processPersonAttr(p, (com.pullenti.ner.person.PersonPropertyReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.person.PersonPropertyReferent.class), ad);
                if (li != null) {
                    p.getSlots().remove(i);
                    ad.registerReferent(li);
                }
            }
        }
    }

    private static LinkReferent _processPersonAttr(com.pullenti.ner.person.PersonReferent p, com.pullenti.ner.person.PersonPropertyReferent pr, com.pullenti.ner.core.AnalyzerData ad) {
        String nam = pr.getName();
        if (pr.getHigher() != null) {
            String nam0 = com.pullenti.ner.core.MiscHelper.getTextMorphVarByCase(pr.getHigher().getName(), com.pullenti.morph.MorphCase.GENITIVE, false);
            nam = (nam + " " + ((nam0 != null ? nam0 : pr.getHigher().getName())));
            pr = pr.getHigher();
        }
        LinkReferent li = LinkReferent._new2307(p);
        com.pullenti.ner.Referent r = (com.pullenti.ner.Referent)com.pullenti.unisharp.Utils.cast(pr.getSlotValue(com.pullenti.ner.person.PersonPropertyReferent.ATTR_REF), com.pullenti.ner.Referent.class);
        if (r instanceof com.pullenti.ner._org.OrganizationReferent) {
            _processOrg((com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner._org.OrganizationReferent.class), ad, 0);
            li.setObject2(r);
            if (pr.getKind() == com.pullenti.ner.person.PersonPropertyKind.BOSS) 
                li.setTyp(LinkType.WORK);
        }
        else if (r instanceof com.pullenti.ner.person.PersonReferent) {
            _processPerson((com.pullenti.ner.person.PersonReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.person.PersonReferent.class), ad);
            li.setObject2(r);
            if (pr.getKind() == com.pullenti.ner.person.PersonPropertyKind.KIN) 
                li.setTyp(LinkType.FAMILY);
        }
        else if (r instanceof com.pullenti.ner.geo.GeoReferent) {
            if (((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.geo.GeoReferent.class)).isCity() && com.pullenti.unisharp.Utils.stringsEq(nam, "уроженец")) {
                _setObject(r);
                li.setObject2(r);
                li.setTyp(LinkType.BORN);
                return li;
            }
            else 
                return null;
        }
        else 
            return null;
        li.setParam(nam);
        return li;
    }

    private static LinkReferent _processResumeOrg(com.pullenti.ner.person.PersonReferent p, com.pullenti.ner.core.AnalyzerData ad, com.pullenti.ner.ReferentToken rt) {
        com.pullenti.ner.resume.ResumeItemReferent rr = (com.pullenti.ner.resume.ResumeItemReferent)com.pullenti.unisharp.Utils.cast(rt.referent, com.pullenti.ner.resume.ResumeItemReferent.class);
        if (!(rr.getRef() instanceof com.pullenti.ner._org.OrganizationReferent)) 
            return null;
        _processOrg((com.pullenti.ner._org.OrganizationReferent)com.pullenti.unisharp.Utils.cast(rr.getRef(), com.pullenti.ner._org.OrganizationReferent.class), ad, 0);
        LinkReferent li = LinkReferent._new2299((rr.getTyp() == com.pullenti.ner.resume.ResumeItemType.STUDY ? LinkType.STUDY : LinkType.WORK), p, rr.getRef());
        li.setParam(rr.getValue());
        com.pullenti.ner.date.DateRangeReferent dr = (com.pullenti.ner.date.DateRangeReferent)com.pullenti.unisharp.Utils.cast(rr.getDateRange(), com.pullenti.ner.date.DateRangeReferent.class);
        if (dr != null) {
            li.setDateFrom(dr.getDateFrom());
            li.setDateTo(dr.getDateTo());
        }
        if (rr.getDateRange() instanceof com.pullenti.ner.date.DateReferent) 
            li.setDateFrom(li.setDateTo((com.pullenti.ner.date.DateReferent)com.pullenti.unisharp.Utils.cast(rr.getDateRange(), com.pullenti.ner.date.DateReferent.class)));
        return li;
    }

    private static void _processOrg(com.pullenti.ner._org.OrganizationReferent _org, com.pullenti.ner.core.AnalyzerData ad, int lev) {
        if (lev > 4) 
            return;
        if (_isObject(_org)) 
            return;
        _setObject(_org);
        if (_org.getHigher() == null) 
            return;
        _processOrg(_org.getHigher(), ad, lev + 1);
        ad.registerReferent(LinkReferent._new2306(_org, _org.getHigher(), LinkType.UNIT));
        _org.setHigher(null);
    }

    private static com.pullenti.ner.ReferentToken _corrOrgTyp(com.pullenti.ner.Token tb, com.pullenti.ner.Token te, LinkReferent li) {
        com.pullenti.ner.date.DateReferent dt = null;
        com.pullenti.ner.date.DateRangeReferent dr = null;
        int cou = 5;
        com.pullenti.ner.Token t0 = tb;
        com.pullenti.ner.Token t1 = te;
        for (com.pullenti.ner.Token tt = tb.getPrevious(); tt != null && cou > 0; tt = tt.getPrevious()) {
            if (tt.isNewlineAfter()) 
                break;
            if (tt.getLengthChar() == 1) 
                continue;
            if (tt.getReferent() instanceof com.pullenti.ner.date.DateReferent) {
                dt = (com.pullenti.ner.date.DateReferent)com.pullenti.unisharp.Utils.cast(tt.getReferent(), com.pullenti.ner.date.DateReferent.class);
                t0 = tt;
            }
            else if (tt.getReferent() instanceof com.pullenti.ner.date.DateRangeReferent) 
                dr = (com.pullenti.ner.date.DateRangeReferent)com.pullenti.unisharp.Utils.cast(tt.getReferent(), com.pullenti.ner.date.DateRangeReferent.class);
            else if (tt instanceof com.pullenti.ner.ReferentToken) 
                break;
            else if ((tt.isValue("ОБРАЗОВАНИЕ", null) || tt.isValue("ОКОНЧИТЬ", null) || tt.isValue("ОБУЧАТЬСЯ", null)) || tt.isValue("ЗАКОНЧИТЬ", null)) 
                li.setTyp(LinkType.STUDY);
            else if (tt.isValue("РАБОТАТЬ", null) || tt.isValue2("ПРОХОДИТЬ", "ПРАКТИКА")) 
                li.setTyp(LinkType.WORK);
            else if (tt.isValue("ПОСТУПИТЬ", null)) {
                if (tt.getNext() != null && tt.getNext().isValue2("НА", "РАБОТА")) 
                    li.setTyp(LinkType.WORK);
                else 
                    li.setTyp(LinkType.STUDY);
            }
            else 
                cou--;
        }
        if (li.getTyp() != LinkType.UNDEFINED && dt == null && dr == null) {
            for (com.pullenti.ner.Token tt = te.getNext(); tt != null; tt = tt.getNext()) {
                if (tt.isNewlineBefore()) 
                    break;
                if (com.pullenti.ner.core.MiscHelper.canBeStartOfSentence(tt)) 
                    break;
                if (tt.getLengthChar() == 1 || tt.isValue("ПЕРИОД", null)) 
                    continue;
                if (tt.getReferent() instanceof com.pullenti.ner.date.DateReferent) {
                    dt = (com.pullenti.ner.date.DateReferent)com.pullenti.unisharp.Utils.cast(tt.getReferent(), com.pullenti.ner.date.DateReferent.class);
                    t1 = tt;
                    break;
                }
                else if (tt.getReferent() instanceof com.pullenti.ner.date.DateRangeReferent) {
                    dr = (com.pullenti.ner.date.DateRangeReferent)com.pullenti.unisharp.Utils.cast(tt.getReferent(), com.pullenti.ner.date.DateRangeReferent.class);
                    t1 = tt;
                    break;
                }
            }
        }
        if (dr != null) {
            li.setDateFrom(dr.getDateFrom());
            li.setDateTo(dr.getDateTo());
        }
        else if (dt != null) 
            li.setDateFrom(li.setDateTo(dt));
        return new com.pullenti.ner.ReferentToken(li, t0, t1, null);
    }

    private static void _corrAddrTyp(LinkReferent li, com.pullenti.ner.Token t) {
        boolean isOrg = li.getObject1() instanceof com.pullenti.ner._org.OrganizationReferent;
        String typ = _checkAddrTyp(((com.pullenti.ner.ReferentToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.ReferentToken.class)).getBeginToken(), isOrg);
        if (typ != null) {
            li.setParam(typ);
            return;
        }
        for (com.pullenti.ner.Token tt = t.getPrevious(); tt != null; tt = tt.getPrevious()) {
            typ = _checkAddrTyp(tt, isOrg);
            if (typ != null) {
                li.setParam(typ);
                return;
            }
            if (tt.isNewlineBefore() || com.pullenti.ner.core.MiscHelper.canBeStartOfSentence(tt) || tt.isComma()) 
                break;
        }
    }

    private static String _checkAddrTyp(com.pullenti.ner.Token t, boolean isOrg) {
        com.pullenti.ner.TextToken tt = (com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class);
        if (tt == null) 
            return null;
        if (tt.isValue("АДРЕС", null)) 
            return _checkAddrTyp(t.getNext(), isOrg);
        if (tt.term.startsWith("ЮР") && isOrg) 
            return "юридический";
        if (tt.term.startsWith("ФАКТ") && isOrg) 
            return "фактический";
        if (!isOrg) {
            if (tt.term.startsWith("ЗАРЕГ") || tt.term.startsWith("РЕГИСТР") || tt.term.startsWith("ПРОПИС")) 
                return "регистрация";
            if (tt.term.startsWith("ФАКТИЧ") || tt.term.startsWith("ПРОЖИВ")) 
                return "проживание";
        }
        return null;
    }

    private static boolean m_Initialized = false;

    private static Object m_Lock;

    public static void initialize() {
        synchronized (m_Lock) {
            if (m_Initialized) 
                return;
            m_Initialized = true;
            MetaLink.initialize();
            com.pullenti.ner.ProcessorService.registerAnalyzer(new LinkAnalyzer());
        }
    }

    public LinkAnalyzer() {
        super();
    }
    
    static {
        m_Lock = new Object();
    }
}
