/*
 * 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.geo.internal;

public class OrgItemToken extends com.pullenti.ner.ReferentToken {

    public OrgItemToken(com.pullenti.ner.Referent r, com.pullenti.ner.Token b, com.pullenti.ner.Token e) {
        super(r, b, e, null);
    }

    public boolean isDoubt;

    public boolean hasTerrKeyword;

    public boolean keywordAfter;

    public boolean isGsk;

    public boolean notOrg;

    public boolean notGeo;

    public boolean isBuilding;

    public void setGsk() {
        isGsk = false;
        if (notOrg) {
            isGsk = true;
            return;
        }
        if (isBuilding) 
            return;
        for (com.pullenti.ner.Slot s : referent.getSlots()) {
            if (com.pullenti.unisharp.Utils.stringsEq(s.getTypeName(), "TYPE") && (s.getValue() instanceof String)) {
                String ty = (String)com.pullenti.unisharp.Utils.cast(s.getValue(), String.class);
                if (((((((((ty.indexOf("товарищество") >= 0) || (ty.indexOf("кооператив") >= 0) || (ty.indexOf("коллектив") >= 0)) || com.pullenti.morph.LanguageHelper.endsWithEx(ty, "поселок", " отдыха", " часть", null) || (ty.indexOf("партнерство") >= 0)) || (ty.indexOf("объединение") >= 0) || (ty.indexOf("бизнес") >= 0)) || (ty.indexOf("офисн") >= 0) || (((ty.indexOf("станция") >= 0) && !(ty.indexOf("заправоч") >= 0)))) || (ty.indexOf("аэропорт") >= 0) || (ty.indexOf("пансионат") >= 0)) || (ty.indexOf("санаторий") >= 0) || (ty.indexOf("база") >= 0)) || (ty.indexOf("урочище") >= 0) || (ty.indexOf("кадастровый") >= 0)) || (ty.indexOf("лесничество") >= 0)) {
                    isGsk = true;
                    return;
                }
                if (com.pullenti.unisharp.Utils.stringsEq(ty, "АОЗТ") || com.pullenti.unisharp.Utils.stringsEq(ty, "пядь")) {
                    isGsk = true;
                    return;
                }
                if ((ty.indexOf("хозяйство") >= 0)) {
                    if ((ty.indexOf("кресьян") >= 0) || (ty.indexOf("фермер") >= 0)) {
                        isGsk = true;
                        return;
                    }
                }
            }
            else if (com.pullenti.unisharp.Utils.stringsEq(s.getTypeName(), "NAME") && (s.getValue() instanceof String)) {
                String nam = (String)com.pullenti.unisharp.Utils.cast(s.getValue(), String.class);
                if (com.pullenti.morph.LanguageHelper.endsWithEx(nam, "ГЭС", "АЭС", "ТЭС", null)) {
                    isGsk = true;
                    return;
                }
            }
        }
    }

    @Override
    public String toString() {
        StringBuilder tmp = new StringBuilder();
        if (isDoubt) 
            tmp.append("? ");
        if (hasTerrKeyword) 
            tmp.append("Terr ");
        if (isGsk) 
            tmp.append("Gsk ");
        if (notOrg) 
            tmp.append("NotOrg ");
        if (notGeo) 
            tmp.append("NotGeo ");
        if (isBuilding) 
            tmp.append("Building ");
        tmp.append(referent.toString());
        return tmp.toString();
    }

    public static boolean SPEEDREGIME = false;

    public static void prepareAllData(com.pullenti.ner.Token t0) {
        if (!SPEEDREGIME) 
            return;
        GeoAnalyzerData ad = com.pullenti.ner.geo.GeoAnalyzer.getData(t0);
        if (ad == null) 
            return;
        ad.oRegime = false;
        for (com.pullenti.ner.Token t = t0; t != null; t = t.getNext()) {
            GeoTokenData d = (GeoTokenData)com.pullenti.unisharp.Utils.cast(t.tag, GeoTokenData.class);
            OrgItemToken _org = tryParse(t, ad);
            if (_org != null) {
                if (d == null) 
                    d = new GeoTokenData(t);
                d._org = _org;
                if (!t.isValue("НП", null)) {
                    if ((_org.hasTerrKeyword || _org.notGeo || _org.isBuilding) || (((_org.isGsk && !_org.keywordAfter && !_org.notOrg) && MiscLocationHelper.isUserParamAddress(_org)))) {
                        for (com.pullenti.ner.Token tt = _org.getBeginToken(); tt != null && tt.getEndChar() <= _org.getEndChar(); tt = tt.getNext()) {
                            GeoTokenData dd = (GeoTokenData)com.pullenti.unisharp.Utils.cast(tt.tag, GeoTokenData.class);
                            if (dd == null) 
                                dd = new GeoTokenData(tt);
                            dd.noGeo = true;
                        }
                        if (!_org.hasTerrKeyword) 
                            t = _org.getEndToken();
                    }
                }
            }
        }
        ad.oRegime = true;
    }

    public static OrgItemToken tryParse(com.pullenti.ner.Token t, GeoAnalyzerData ad) {
        if (!(t instanceof com.pullenti.ner.TextToken)) 
            return null;
        if (ad == null) 
            ad = com.pullenti.ner.geo.GeoAnalyzer.getData(t);
        if (ad == null) 
            return null;
        if (SPEEDREGIME && ((ad.oRegime || ad.allRegime))) {
            if ((t instanceof com.pullenti.ner.TextToken) && t.isChar('м')) {
            }
            else {
                GeoTokenData d = (GeoTokenData)com.pullenti.unisharp.Utils.cast(t.tag, GeoTokenData.class);
                if (d != null) 
                    return d._org;
                return null;
            }
        }
        if (ad.oLevel > 1) 
            return null;
        ad.oLevel++;
        OrgItemToken res = _TryParse(t, false, 0, ad);
        if (res != null) 
            res._tryParseDetails();
        ad.oLevel--;
        return res;
    }

    private static OrgItemToken _TryParse(com.pullenti.ner.Token t, boolean afterTerr, int lev, GeoAnalyzerData ad) {
        if (lev > 3 || t == null || t.isComma()) 
            return null;
        com.pullenti.ner.Token tt2 = MiscLocationHelper.checkTerritory(t);
        if (tt2 != null && tt2.getNext() != null) {
            tt2 = tt2.getNext();
            boolean br = false;
            if (com.pullenti.ner.core.BracketHelper.isBracket(tt2, true)) {
                br = true;
                tt2 = tt2.getNext();
            }
            if (tt2 == null || lev > 3) 
                return null;
            OrgItemToken re2 = _TryParse(tt2, true, lev + 1, ad);
            if (re2 == null && tt2 != null && tt2.isValue("ВЛАДЕНИЕ", null)) 
                re2 = _TryParse(tt2.getNext(), true, lev + 1, ad);
            if (re2 != null) {
                com.pullenti.ner.Analyzer a = t.kit.processor.findAnalyzer("GEO");
                if (a != null && !MiscLocationHelper.isUserParamAddress(t)) {
                    com.pullenti.ner.ReferentToken rt = a.processReferent(tt2, null);
                    if (rt != null) 
                        return null;
                }
                for (com.pullenti.ner.Token tt = tt2; tt != null && tt.getEndChar() <= re2.getEndChar(); tt = tt.getNext()) {
                    com.pullenti.ner.address.internal.StreetItemToken sit = com.pullenti.ner.address.internal.StreetItemToken.tryParse(tt, null, false, null);
                    if (sit != null && sit.typ == com.pullenti.ner.address.internal.StreetItemType.NOUN && ((sit.isRoad() || sit.isRailway))) 
                        return null;
                }
                if (tt2.isValue("ВЛАДЕНИЕ", null)) 
                    re2.referent.addSlot("TYPE", "владение", false, 0);
                if (com.pullenti.ner.address.internal.AddressItemToken.M_PLOT.tryParse(t, com.pullenti.ner.core.TerminParseAttr.NO) != null) 
                    re2.referent.addSlot("TYPE", "участок", false, 0);
                re2.setBeginToken(t);
                if (br && com.pullenti.ner.core.BracketHelper.canBeEndOfSequence(re2.getEndToken().getNext(), false, null, false)) 
                    re2.setEndToken(re2.getEndToken().getNext());
                re2.hasTerrKeyword = true;
                return re2;
            }
            else if ((t instanceof com.pullenti.ner.TextToken) && ((((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term.startsWith("ТЕР") || ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term.startsWith("ПЛОЩ"))) && (tt2.getWhitespacesBeforeCount() < 3)) {
                NameToken nam1 = NameToken.tryParse(tt2, GeoTokenType.ORG, 0, true);
                if (nam1 != null && ((nam1.name != null || ((nam1.number != null && MiscLocationHelper.isUserParamAddress(tt2)))))) {
                    if (com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(tt2)) 
                        return null;
                    if (t.getNext() != nam1.getEndToken() && com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(nam1.getEndToken())) 
                        return null;
                    if (TerrItemToken.checkKeyword(tt2) != null) 
                        return null;
                    if (t.getNext() != nam1.getEndToken() && TerrItemToken.checkKeyword(nam1.getEndToken()) != null) 
                        return null;
                    com.pullenti.ner.core.IntOntologyToken ter = TerrItemToken.checkOntoItem(tt2);
                    if (ter != null) {
                        com.pullenti.ner.geo.GeoReferent _geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(ter.item.referent, com.pullenti.ner.geo.GeoReferent.class);
                        if (_geo.isCity() || _geo.isState()) 
                            return null;
                    }
                    if (CityItemToken.checkKeyword(tt2) != null) 
                        return null;
                    if (CityItemToken.checkOntoItem(tt2) != null) 
                        return null;
                    com.pullenti.ner.Token tt = nam1.getEndToken();
                    boolean ok = false;
                    if (tt.isNewlineAfter()) 
                        ok = true;
                    else if (tt.getNext() != null && ((tt.getNext().isComma() || tt.getNext().isChar(')')))) 
                        ok = true;
                    else if (com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(tt2, false, false)) 
                        ok = true;
                    else {
                        com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParsePureItem(nam1.getEndToken().getNext(), null, null);
                        if (ait != null && ait.getTyp() != com.pullenti.ner.address.internal.AddressItemType.NUMBER) 
                            ok = true;
                        else {
                            com.pullenti.ner.address.internal.AddressItemToken a2 = com.pullenti.ner.address.internal.AddressItemToken.tryParse(nam1.getEndToken().getNext(), false, null, ad);
                            if (a2 != null) {
                                com.pullenti.ner.address.internal.AddressItemToken a1 = com.pullenti.ner.address.internal.AddressItemToken.tryParse(tt2, false, null, ad);
                                if (a1 == null || (a1.getEndChar() < a2.getEndChar())) 
                                    ok = true;
                            }
                        }
                    }
                    if (ok) {
                        com.pullenti.ner.Referent org1 = t.kit.createReferent("ORGANIZATION");
                        if (nam1.name != null) 
                            org1.addSlot("NAME", nam1.name, false, 0);
                        if (nam1.number != null) 
                            org1.addSlot("NUMBER", nam1.number, false, 0);
                        if (tt2.getPrevious() != null && tt2.getPrevious().isValue("ВЛАДЕНИЕ", null)) 
                            org1.addSlot("TYPE", "владение", false, 0);
                        OrgItemToken res1 = new OrgItemToken(org1, t, nam1.getEndToken());
                        res1.data = t.kit.getAnalyzerDataByAnalyzerName("ORGANIZATION");
                        res1.hasTerrKeyword = true;
                        return res1;
                    }
                }
                com.pullenti.ner.ReferentToken rt = t.kit.processReferent("NAMEDENTITY", tt2, null);
                if (rt != null) {
                    OrgItemToken res1 = new OrgItemToken(rt.referent, t, rt.getEndToken());
                    res1.data = t.kit.getAnalyzerDataByAnalyzerName("NAMEDENTITY");
                    res1.hasTerrKeyword = true;
                    return res1;
                }
            }
            if (!t.isValue("САД", null)) 
                return null;
        }
        boolean typAfter = false;
        boolean doubt0 = false;
        OrgTypToken tokTyp = OrgTypToken.tryParse(t, afterTerr, ad);
        NameToken nam = null;
        boolean ignoreNum = false;
        if (tokTyp == null && t.isChar('(') && MiscLocationHelper.isUserParamAddress(t)) {
            NameToken nnn = NameToken.tryParse(t.getNext(), GeoTokenType.ORG, 0, false);
            if (nnn != null && nnn.getEndToken().getNext() != null && nnn.getEndToken().getNext().isComma()) {
                OrgTypToken ttt = OrgTypToken.tryParse(nnn.getEndToken().getNext().getNext(), afterTerr, ad);
                if (ttt != null && ttt.getEndToken().getNext() != null && ttt.getEndToken().getNext().isChar(')')) {
                    tokTyp = ttt;
                    tokTyp.setEndToken(tokTyp.getEndToken().getNext());
                    nam = nnn;
                    nam.setBeginToken(t);
                }
            }
            if (tokTyp == null) {
                OrgTypToken ttt = OrgTypToken.tryParse(t.getNext(), afterTerr, ad);
                if (ttt != null && ttt.getEndToken().getNext() != null) {
                    nnn = NameToken.tryParse((ttt.getEndToken().getNext().isComma() ? ttt.getEndToken().getNext().getNext() : ttt.getEndToken().getNext()), GeoTokenType.ORG, 0, false);
                    if (nnn != null) {
                        com.pullenti.ner.Token ttt2 = nnn.getEndToken().getNext();
                        if (ttt2 != null && ttt2.isChar('(')) {
                            com.pullenti.ner.core.BracketSequenceToken br = com.pullenti.ner.core.BracketHelper.tryParse(ttt2, com.pullenti.ner.core.BracketParseAttr.NO, 100);
                            if (br != null) 
                                nnn.setEndToken(br.getEndToken());
                        }
                        if (nnn.getEndToken().getNext() != null && nnn.getEndToken().getNext().isChar(')')) {
                            tokTyp = ttt;
                            tokTyp.setBeginToken(t);
                            nam = nnn;
                            nnn.setEndToken(nnn.getEndToken().getNext());
                        }
                    }
                }
            }
        }
        if (tokTyp == null) {
            NumToken num = NumToken.tryParse(t, GeoTokenType.ORG);
            if (num != null && num.hasSpecWord) {
                OrgItemToken _next = tryParse(num.getEndToken().getNext(), ad);
                if (_next != null && _next.referent.findSlot("NUMBER", null, true) == null) {
                    _next.setBeginToken(t);
                    _next.referent.addSlot("NUMBER", num.value, false, 0);
                    return _next;
                }
            }
            if (num != null && num.getEndToken().getNext() != null && afterTerr) {
                com.pullenti.ner.address.internal.StreetItemToken sss = com.pullenti.ner.address.internal.StreetItemToken.tryParse(num.getEndToken().getNext(), null, false, null);
                if (sss != null && sss.typ == com.pullenti.ner.address.internal.StreetItemType.NOUN && com.pullenti.unisharp.Utils.stringsEq(sss.termin.getCanonicText(), "КВАРТАЛ")) {
                    com.pullenti.ner.address.StreetReferent sr = com.pullenti.ner.address.StreetReferent._new1583(com.pullenti.ner.address.StreetKind.AREA);
                    sr.addTyp("квартал");
                    sr.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_NUMBER, num.value, false, 0);
                    OrgItemToken res3 = new OrgItemToken(sr, t, sss.getEndToken());
                    res3.notOrg = true;
                    res3.hasTerrKeyword = afterTerr;
                    res3.notGeo = true;
                    return res3;
                }
            }
            com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParsePureItem(t, null, null);
            if ((ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.HOUSE && ait.houseType == com.pullenti.ner.address.AddressHouseType.ESTATE) && ait.value != null) {
                boolean ok3 = false;
                if (afterTerr) 
                    ok3 = true;
                else if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(ait.getEndToken().getNext(), false)) 
                    ok3 = true;
                if (ok3) {
                    com.pullenti.ner.Referent org3 = t.kit.createReferent("ORGANIZATION");
                    org3.addSlot("TYPE", "владение", false, 0);
                    StringBuilder num3 = new StringBuilder();
                    StringBuilder nam3 = new StringBuilder();
                    for (char ch : ait.value.toCharArray()) {
                        if (Character.isDigit(ch)) 
                            num3.append(ch);
                        else if (Character.isLetter(ch)) 
                            nam3.append(ch);
                    }
                    if (num3.length() > 0) 
                        org3.addSlot("NUMBER", num3.toString(), false, 0);
                    if (nam3.length() > 0) 
                        org3.addSlot("NAME", nam3.toString(), false, 0);
                    OrgItemToken res3 = new OrgItemToken(org3, t, ait.getEndToken());
                    res3.data = t.kit.getAnalyzerDataByAnalyzerName("ORGANIZATION");
                    res3.notOrg = true;
                    res3.hasTerrKeyword = afterTerr;
                    res3.notGeo = true;
                    return res3;
                }
            }
            if ((afterTerr && ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.HOUSE) && ait.houseType == com.pullenti.ner.address.AddressHouseType.SPECIAL && ait.value != null) {
                com.pullenti.ner.Referent org3 = t.kit.createReferent("ORGANIZATION");
                String val = ait.value;
                int ii = val.indexOf('-');
                if (ii < 0) 
                    org3.addSlot("TYPE", val, false, 0);
                else {
                    org3.addSlot("TYPE", val.substring(0, 0 + ii), false, 0);
                    org3.addSlot("NUMBER", val.substring(ii + 1), false, 0);
                }
                OrgItemToken res3 = new OrgItemToken(org3, t, ait.getEndToken());
                res3.data = t.kit.getAnalyzerDataByAnalyzerName("ORGANIZATION");
                res3.notOrg = true;
                res3.hasTerrKeyword = afterTerr;
                res3.notGeo = true;
                return res3;
            }
            if ((afterTerr && ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.GENPLAN) && ait.value != null) {
                com.pullenti.ner.Referent org3 = t.kit.createReferent("ORGANIZATION");
                org3.addSlot("TYPE", "ГП", false, 0);
                org3.addSlot("NUMBER", ait.value, false, 0);
                OrgItemToken res3 = new OrgItemToken(org3, t, ait.getEndToken());
                res3.data = t.kit.getAnalyzerDataByAnalyzerName("ORGANIZATION");
                res3.notOrg = true;
                res3.hasTerrKeyword = afterTerr;
                res3.notGeo = true;
                return res3;
            }
            int ok = 0;
            if (com.pullenti.ner.core.BracketHelper.canBeStartOfSequence(t, true, false)) 
                ok = 2;
            else if (t.isValue("ИМ", null) || t.isValue("ИМЕНИ", null)) 
                ok = 2;
            else if (afterTerr) 
                ok = 1;
            else if ((t instanceof com.pullenti.ner.TextToken) && !t.chars.isAllLower() && t.getLengthChar() > 1) {
                if (t.getPrevious() != null && t.getPrevious().isHiphen() && !t.isWhitespaceBefore()) {
                }
                else 
                    ok = 1;
            }
            if (ok == 0) 
                return null;
            if (CityItemToken.checkKeyword(t) != null) 
                return null;
            if (CityItemToken.checkOntoItem(t) != null) 
                return null;
            if ((t.getLengthChar() > 5 && (t instanceof com.pullenti.ner.TextToken) && !t.chars.isAllUpper()) && !t.chars.isAllLower() && !t.chars.isCapitalUpper()) {
                String namm = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).getSourceText();
                if (Character.isUpperCase(namm.charAt(0)) && Character.isUpperCase(namm.charAt(1))) {
                    for (int i = 0; i < namm.length(); i++) {
                        if (Character.isLowerCase(namm.charAt(i)) && i > 2) {
                            String abbr = namm.substring(0, 0 + i - 1);
                            com.pullenti.ner.core.Termin te = com.pullenti.ner.core.Termin._new1197(abbr, abbr);
                            java.util.ArrayList<com.pullenti.ner.core.Termin> li = OrgTypToken.findTerminByAcronym(abbr);
                            if (li != null && li.size() > 0) {
                                nam = new NameToken(t, t);
                                nam.name = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term.substring(i - 1);
                                tokTyp = new OrgTypToken(t, t, null);
                                tokTyp.vals.add(li.get(0).getCanonicText().toLowerCase());
                                tokTyp.vals.add(abbr);
                                nam.tryAttachNumber();
                                break;
                            }
                        }
                    }
                }
            }
            if (nam == null) {
                if (afterTerr) 
                    ok = 2;
                if (ok < 2) {
                    int kk = 0;
                    for (com.pullenti.ner.Token tt = t.getNext(); tt != null && (kk < 5); tt = tt.getNext(),kk++) {
                        if (tt.isNewlineBefore()) 
                            break;
                        OrgTypToken ty22 = OrgTypToken.tryParse(tt, false, ad);
                        if (ty22 == null || ty22.isDoubt || ty22.canBeSingle) 
                            continue;
                        ok = 2;
                        break;
                    }
                }
                if (ok < 2) 
                    return null;
                typAfter = true;
                nam = NameToken.tryParse(t, GeoTokenType.ORG, 0, false);
                if (nam == null) 
                    return null;
                tokTyp = OrgTypToken.tryParse(nam.getEndToken().getNext(), false, null);
                if ((tokTyp != null && (tokTyp.getWhitespacesAfterCount() < 3) && !afterTerr) && nam.getBeginToken() == nam.getEndToken()) {
                    if (MiscLocationHelper.checkTerritory(tokTyp.getEndToken().getNext()) != null) {
                    }
                    else {
                        NameToken nam2 = NameToken.tryParse(tokTyp.getEndToken().getNext(), GeoTokenType.ORG, lev + 1, false);
                        if (nam2 != null && nam2.number != null) 
                            return null;
                    }
                }
                if (tokTyp == null && !afterTerr && MiscLocationHelper.isUserParamAddress(t)) {
                    tt2 = MiscLocationHelper.checkTerritory(nam.getEndToken().getNext());
                    if (tt2 != null && tt2.getNext() != null) {
                        tokTyp = OrgTypToken.tryParse(tt2.getNext(), true, ad);
                        if (tokTyp != null) {
                            NameToken nam2 = NameToken.tryParse(tokTyp.getEndToken().getNext(), GeoTokenType.ORG, 0, false);
                            if (nam2 != null && nam2.name != null) 
                                tokTyp = null;
                        }
                    }
                }
                if (tokTyp == null && nam.getBeginToken() != nam.getEndToken()) {
                    tokTyp = OrgTypToken.tryParse(nam.getEndToken(), false, null);
                    if (tokTyp != null) {
                        nam.setEndToken(nam.getEndToken().getPrevious());
                        nam.name = null;
                        for (com.pullenti.ner.Token ntt = nam.getBeginToken(); ntt.getEndChar() <= nam.getEndChar(); ntt = ntt.getNext()) {
                            if (!(ntt instanceof com.pullenti.ner.TextToken)) {
                                nam.name = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(nam, com.pullenti.ner.core.GetTextAttr.NO);
                                break;
                            }
                            String v = ntt.getNormalCaseText(com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphNumber.SINGULAR, tokTyp.getMorph().getGender(), false);
                            if (v == null) 
                                v = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(ntt, com.pullenti.ner.TextToken.class)).term;
                            if (nam.name == null) 
                                nam.name = v;
                            else 
                                nam.name = (nam.name + " " + v);
                        }
                    }
                }
                if (nam.name == null && nam.miscTyp == null) {
                    if (nam.number != null && tokTyp != null) {
                    }
                    else if (afterTerr) {
                    }
                    else 
                        return null;
                }
                if (tokTyp != null) {
                    if (nam.getBeginToken() == nam.getEndToken()) {
                        com.pullenti.morph.MorphClass mc = nam.getMorphClassInDictionary();
                        if (mc.isConjunction() || mc.isPreposition() || mc.isPronoun()) 
                            return null;
                    }
                    OrgItemToken rt2 = tryParse(tokTyp.getBeginToken(), null);
                    if (rt2 != null && rt2.isDoubt) 
                        rt2 = null;
                    if (rt2 != null) {
                        if (MiscLocationHelper.checkTerritory(tokTyp.getEndToken().getNext()) != null) {
                            OrgItemToken rt3 = tryParse(tokTyp.getEndToken().getNext(), ad);
                            if (rt3 != null) 
                                rt2 = null;
                        }
                    }
                    NameToken nam2 = NameToken.tryParse(tokTyp.getEndToken().getNext(), GeoTokenType.ORG, 0, false);
                    if (tokTyp.isNewlineAfter()) 
                        nam2 = null;
                    if (rt2 != null && rt2.getEndChar() > tokTyp.getEndChar()) {
                        if (nam2 == null || nam2.getEndToken() != rt2.getEndToken()) 
                            return null;
                        if (((nam.number == null && nam2.name == null && nam2.number != null)) || (((nam.name == null && nam.number != null && nam2.number == null) && nam2.name != null))) {
                            if (nam2.number != null) 
                                nam.number = nam2.number;
                            if (nam2.name != null) 
                                nam.name = nam2.name;
                            tokTyp = tokTyp.clone();
                            tokTyp.setEndToken(nam2.getEndToken());
                        }
                        else 
                            return null;
                    }
                    else if ((nam.number == null && nam2 != null && nam2.name == null) && nam2.number != null) {
                        nam.number = nam2.number;
                        tokTyp = tokTyp.clone();
                        tokTyp.setEndToken(nam2.getEndToken());
                    }
                    nam.setEndToken(tokTyp.getEndToken());
                    doubt0 = true;
                }
                else if (nam.name != null || nam.miscTyp != null) {
                    boolean busines = false;
                    if (nam.miscTyp != null) {
                    }
                    else if (nam.name.endsWith("ПЛАЗА") || nam.name.startsWith("БИЗНЕС")) 
                        busines = true;
                    else if (afterTerr && MiscLocationHelper.isUserParamAddress(nam)) {
                        if (com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(nam.getBeginToken())) 
                            return null;
                    }
                    else if (nam.getBeginToken() == nam.getEndToken()) 
                        return null;
                    else if (nam.name != null && nam.name.length() == 1 && nam.number == null) 
                        return null;
                    else if (com.pullenti.ner.core.BracketHelper.canBeStartOfSequence(nam.getBeginToken(), false, false) && MiscLocationHelper.isUserParamAddress(nam)) {
                    }
                    else if ((((tokTyp = OrgTypToken.tryParse(nam.getEndToken(), false, ad)))) == null) 
                        return null;
                    else if (nam.getMorph().getCase().isGenitive() && !nam.getMorph().getCase().isNominative()) {
                        nam.name = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(nam, com.pullenti.ner.core.GetTextAttr.FIRSTNOUNGROUPTONOMINATIVESINGLE).replace("-", " ");
                        if (tokTyp != null && tokTyp.vals.size() > 0) {
                            if (com.pullenti.unisharp.Utils.endsWithString(nam.name, tokTyp.vals.get(0), true)) 
                                nam.name = nam.name.substring(0, 0 + nam.name.length() - tokTyp.vals.get(0).length()).trim();
                        }
                    }
                    if (tokTyp == null) {
                        tokTyp = new OrgTypToken(t, t, null);
                        if (busines) {
                            tokTyp.vals.add("бизнес центр");
                            tokTyp.vals.add("БЦ");
                        }
                        else if (t.getPrevious() != null && t.getPrevious().isValue("САД", null)) 
                            tokTyp.vals.add("сад");
                        else if (nam.miscTyp != null) 
                            tokTyp.vals.add(nam.miscTyp);
                    }
                    nam.isDoubt = tokTyp.vals.size() == 0;
                    doubt0 = tokTyp.vals.size() == 0;
                }
                else 
                    return null;
            }
        }
        else {
            if (tokTyp.getWhitespacesAfterCount() > 3 && !tokTyp.isNewlineAfter()) 
                return null;
            com.pullenti.ner.Token tt3 = MiscLocationHelper.checkTerritory(tokTyp.getEndToken().getNext());
            if (tt3 != null) {
                tokTyp = tokTyp.clone();
                tokTyp.setEndToken(tt3);
                afterTerr = true;
                OrgTypToken tokTyp2 = OrgTypToken.tryParse(tokTyp.getEndToken().getNext(), true, ad);
                if (tokTyp2 != null && !tokTyp2.isDoubt) 
                    tokTyp.mergeWith(tokTyp2);
            }
            else {
                OrgTypToken tokTyp2 = OrgTypToken.tryParse(tokTyp.getEndToken().getNext(), true, ad);
                if (tokTyp2 != null && tokTyp2.getBeginToken() == tokTyp2.getEndToken()) {
                    com.pullenti.morph.MorphClass mc = tokTyp2.getBeginToken().getMorphClassInDictionary();
                    if (!mc.isUndefined()) 
                        tokTyp2 = null;
                }
                if (tokTyp2 != null && !tokTyp2.isDoubt) {
                    tokTyp = tokTyp.clone();
                    tokTyp.mergeWith(tokTyp2);
                }
            }
            if (com.pullenti.ner.core.BracketHelper.isBracket(tokTyp.getEndToken().getNext(), true)) {
                OrgTypToken tokTyp2 = OrgTypToken.tryParse(tokTyp.getEndToken().getNext().getNext(), afterTerr, ad);
                if (tokTyp2 != null && !tokTyp2.isDoubt) {
                    tokTyp = tokTyp.clone();
                    tokTyp.isDoubt = false;
                    nam = NameToken.tryParse(tokTyp2.getEndToken().getNext(), GeoTokenType.ORG, 0, false);
                    if (nam != null && com.pullenti.ner.core.BracketHelper.canBeEndOfSequence(nam.getEndToken().getNext(), false, null, false)) {
                        tokTyp.mergeWith(tokTyp2);
                        nam.setEndToken(nam.getEndToken().getNext());
                    }
                    else if (nam != null && com.pullenti.ner.core.BracketHelper.canBeEndOfSequence(nam.getEndToken(), false, null, false)) 
                        tokTyp.mergeWith(tokTyp2);
                    else 
                        nam = null;
                }
            }
        }
        com.pullenti.ner.Token tNext = tokTyp.getEndToken().getNext();
        if (tNext != null && tNext.isChar('.') && MiscLocationHelper.isUserParamAddress(tNext)) 
            tNext = tNext.getNext();
        if (m_Onto.tryParse(tNext, com.pullenti.ner.core.TerminParseAttr.NO) != null) {
        }
        else if (com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(tNext) && !tNext.chars.isCapitalUpper()) {
        }
        else if ((tNext != null && tNext.chars.isAllLower() && CityItemToken.checkKeyword(tNext) != null) && NumToken.tryParse(tNext, GeoTokenType.ORG) == null) {
        }
        else {
            if (nam == null && tNext != null && (tNext.getWhitespacesBeforeCount() < 3)) {
                if (tokTyp.canBeSingle && (tNext instanceof com.pullenti.ner.NumberToken)) {
                }
                else 
                    nam = NameToken.tryParse(tNext, GeoTokenType.ORG, 0, true);
            }
            if ((nam == null && tokTyp.chars.isAllUpper() && tNext != null) && tNext.isHiphen() && !tNext.isWhitespaceAfter()) {
                nam = NameToken.tryParse(tNext.getNext(), GeoTokenType.ORG, 0, true);
                if (nam != null) {
                    if (nam.chars.isAllLower() || (nam.getLengthChar() < 4)) 
                        nam = null;
                }
            }
            if ((nam != null && nam.getLengthChar() == 1 && nam.chars.isAllLower()) && ((nam.getBeginToken().isValue("С", null) || nam.isValue("Д", null) || nam.isValue("П", null)))) 
                nam = null;
            if (nam == null) {
                boolean ok = false;
                if (afterTerr && MiscLocationHelper.isUserParamAddress(tokTyp)) 
                    ok = true;
                else if (tokTyp.canBeSingle) 
                    ok = true;
                else if (tokTyp.getBeginToken() != tokTyp.getEndToken()) {
                    if (MiscLocationHelper.checkGeoObjectBefore(tokTyp.getBeginToken(), false)) 
                        ok = true;
                    else if (MiscLocationHelper.isUserParamAddress(tokTyp) && ((tokTyp.getEndToken().isNewlineAfter() || tokTyp.getEndToken().getNext().isComma()))) 
                        ok = true;
                    else if (com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(tokTyp.getEndToken().getNext(), false, false)) 
                        ok = true;
                }
                if (!ok) 
                    return null;
                if (tokTyp.vals.size() > 0 && tokTyp.vals.get(0).endsWith("район")) 
                    return null;
            }
        }
        if (tokTyp.isDoubt && ((nam == null || nam.isDoubt || nam.chars.isAllUpper()))) 
            return null;
        if (((tokTyp.getLengthChar() < 3) && nam != null && nam.name == null) && nam.pref == null) {
            if (afterTerr || MiscLocationHelper.isUserParamAddress(tokTyp)) {
            }
            else 
                return null;
        }
        if (((tokTyp.getBeginToken().isValue("СП", null) || tokTyp.getBeginToken().isValue("ГП", null))) && nam != null) {
            com.pullenti.ner.Token tt = nam.getEndToken().getNext();
            if (tt != null && tt.isComma()) 
                tt = tt.getNext();
            if (com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(tt, false, false)) {
            }
            else if (CityItemToken.checkKeyword(tt) != null) 
                return null;
        }
        com.pullenti.ner.Referent _org = t.kit.createReferent("ORGANIZATION");
        OrgItemToken res = new OrgItemToken(_org, t, (nam != null && nam.getEndChar() > tokTyp.getEndChar() ? nam.getEndToken() : tokTyp.getEndToken()));
        res.data = t.kit.getAnalyzerDataByAnalyzerName("ORGANIZATION");
        res.hasTerrKeyword = afterTerr;
        res.isDoubt = doubt0 || tokTyp.isDoubt || nam == null;
        res.keywordAfter = typAfter;
        res.notOrg = tokTyp.notOrg;
        res.notGeo = tokTyp.notGeo;
        if (!afterTerr) 
            res.isBuilding = tokTyp.isBuilding;
        if (tokTyp.canBeSingle) {
            _org.addSlot("NAME", tokTyp.vals.get(0).toUpperCase(), false, 0);
            res.isDoubt = false;
            res.isGsk = true;
            return res;
        }
        for (String ty : tokTyp.vals) {
            if (nam != null && com.pullenti.unisharp.Utils.stringsEq(ty, nam.miscTyp) && !(ty.indexOf("квартал") >= 0)) 
                continue;
            _org.addSlot("TYPE", ty, false, 0);
            if (com.pullenti.unisharp.Utils.stringsEq(ty, "поле")) 
                res.isDoubt = true;
        }
        boolean ignoreNext = false;
        if ((res.getWhitespacesAfterCount() < 3) && res.getEndToken().getNext() != null) {
            com.pullenti.ner.Token ttt = MiscLocationHelper.checkTerritory(res.getEndToken().getNext());
            if (ttt != null && _TryParse(ttt.getNext(), true, lev + 1, ad) == null) {
                res.setEndToken(ttt);
                ignoreNext = true;
            }
            else if (nam != null) {
                OrgTypToken tokTyp2 = OrgTypToken.tryParse(res.getEndToken().getNext(), false, null);
                if (tokTyp2 != null) {
                    OrgItemToken rrr2 = _TryParse(res.getEndToken().getNext(), false, lev + 1, ad);
                    if (rrr2 == null || rrr2.getEndChar() <= tokTyp2.getEndChar()) {
                        res.setEndToken(tokTyp2.getEndToken());
                        for (String ty : tokTyp2.vals) {
                            _org.addSlot("TYPE", ty, false, 0);
                        }
                    }
                }
            }
        }
        if (((res.getWhitespacesAfterCount() < 3) && nam != null && (res.getEndToken().getNext() instanceof com.pullenti.ner.TextToken)) && res.getEndToken().getNext().getLengthChar() == 1 && res.getEndToken().getNext().chars.isLetter()) {
            com.pullenti.ner.Token tt3 = res.getEndToken().getNext();
            if (((tt3.getNext() != null && tt3.getNext().isChar('.') && (tt3.getNext().getNext() instanceof com.pullenti.ner.TextToken)) && tt3.getNext().getNext().chars.isLetter() && tt3.getNext().getNext().getLengthChar() == 1) && tt3.getNext().getNext().getNext() != null && tt3.getNext().getNext().getNext().isChar('.')) 
                res.setEndToken(tt3.getNext().getNext().getNext());
        }
        if ((res.getWhitespacesAfterCount() < 3) && !tokTyp.notOrg) {
            com.pullenti.ner.Token tt = res.getEndToken().getNext();
            OrgItemToken _next = _TryParse(tt, false, lev + 1, ad);
            if (_next != null) {
                boolean merge = true;
                if (_next.isGsk) {
                    merge = false;
                    if ((nam != null && nam.name != null && nam.number == null) && _next.referent.findSlot("NAME", null, true) == null && _next.referent.findSlot("NUMBER", null, true) != null) {
                        for (String ty : _org.getStringValues("TYPE")) {
                            if (_next.referent.findSlot("TYPE", ty, true) != null) 
                                merge = true;
                        }
                    }
                }
                if (merge) {
                    res.setEndToken(_next.getEndToken());
                    for (com.pullenti.ner.Slot s : _next.referent.getSlots()) {
                        res.referent.addSlot(s.getTypeName(), s.getValue(), false, 0);
                    }
                }
                ignoreNext = true;
            }
            else {
                if (tt != null && tt.isValue("ПРИ", null)) 
                    tt = tt.getNext();
                com.pullenti.ner.ReferentToken rt = t.kit.processReferent("ORGANIZATION", tt, null);
                if (rt != null) {
                }
                if (rt != null) {
                    res.setEndToken(rt.getEndToken());
                    com.pullenti.ner.core.IntOntologyToken ter = TerrItemToken.checkOntoItem(res.getEndToken().getNext());
                    if (ter != null) 
                        res.setEndToken(ter.getEndToken());
                    ignoreNext = true;
                }
            }
        }
        String suffName = null;
        if (!ignoreNext && (res.getWhitespacesAfterCount() < 2) && !tokTyp.notOrg) {
            OrgTypToken tokTyp2 = OrgTypToken.tryParse(res.getEndToken().getNext(), true, ad);
            if (tokTyp2 != null) {
                res.setEndToken(tokTyp2.getEndToken());
                if (tokTyp2.isDoubt && nam != null && nam.name != null) 
                    suffName = tokTyp2.vals.get(0);
                else 
                    for (String ty : tokTyp2.vals) {
                        _org.addSlot("TYPE", ty, false, 0);
                    }
                if (nam != null && nam.number == null) {
                    NameToken nam2 = NameToken.tryParse(res.getEndToken().getNext(), GeoTokenType.ORG, 0, false);
                    if ((nam2 != null && nam2.number != null && nam2.name == null) && nam2.pref == null) {
                        nam.number = nam2.number;
                        res.setEndToken(nam2.getEndToken());
                    }
                }
            }
        }
        if (nam == null) {
            res.setGsk();
            if (res.getBeginToken() == res.getEndToken() && res.isDoubt) 
                return null;
            return res;
        }
        if (nam != null && nam.name != null) {
            if (nam.pref != null) {
                _org.addSlot("NAME", (nam.pref + " " + nam.name), false, 0);
                if (suffName != null) 
                    _org.addSlot("NAME", (nam.pref + " " + nam.name + " " + suffName), false, 0);
            }
            else {
                _org.addSlot("NAME", nam.name, false, 0);
                if (suffName != null) 
                    _org.addSlot("NAME", (nam.name + " " + suffName), false, 0);
            }
        }
        else if (nam.pref != null) 
            _org.addSlot("NAME", nam.pref, false, 0);
        else if (nam.number != null && (res.getWhitespacesAfterCount() < 2)) {
            NameToken nam2 = NameToken.tryParse(res.getEndToken().getNext(), GeoTokenType.ORG, 0, false);
            if (nam2 != null && nam2.name != null && nam2.number == null) {
                res.setEndToken(nam2.getEndToken());
                _org.addSlot("NAME", nam2.name, false, 0);
            }
        }
        if (nam.number != null) {
            if (nam.miscTyp != null) 
                _org.addSlot("MISC2", (nam.miscTyp + " " + nam.number), false, 0);
            else 
                _org.addSlot("NUMBER", nam.number, false, 0);
        }
        else if (res.getEndToken().getNext() != null && res.getEndToken().getNext().isHiphen() && (res.getEndToken().getNext().getNext() instanceof com.pullenti.ner.NumberToken)) {
            NameToken nam2 = NameToken.tryParse(res.getEndToken().getNext().getNext(), GeoTokenType.ORG, 0, false);
            if (nam2 != null && nam2.number != null && nam2.name == null) {
                if (nam2.miscTyp != null) 
                    _org.addSlot("MISC2", (nam2.miscTyp + " " + nam2.number), false, 0);
                else 
                    _org.addSlot("NUMBER", nam2.number, false, 0);
                res.setEndToken(nam2.getEndToken());
            }
        }
        boolean ok1 = false;
        int cou = 0;
        for (com.pullenti.ner.Token tt = res.getBeginToken(); tt != null && tt.getEndChar() <= res.getEndChar(); tt = tt.getNext()) {
            if ((tt instanceof com.pullenti.ner.TextToken) && tt.getLengthChar() > 1) {
                if (nam != null && tt.getBeginChar() >= nam.getBeginChar() && tt.getEndChar() <= nam.getEndChar()) {
                    if (tokTyp != null && tt.getBeginChar() >= tokTyp.getBeginChar() && tt.getEndChar() <= tokTyp.getEndChar()) {
                    }
                    else 
                        cou++;
                }
                if (!tt.chars.isAllLower()) 
                    ok1 = true;
            }
            else if (tt instanceof com.pullenti.ner.ReferentToken) 
                ok1 = true;
        }
        res.setGsk();
        if (!ok1) {
            if (!res.isGsk && !res.hasTerrKeyword && !MiscLocationHelper.isUserParamAddress(res)) 
                return null;
        }
        if (cou > 4) 
            return null;
        if (tokTyp != null && tokTyp.getBeginToken().isValue("СП", null)) {
            tt2 = res.getEndToken().getNext();
            if (tt2 != null && tt2.isComma()) 
                tt2 = tt2.getNext();
            java.util.ArrayList<CityItemToken> cits = CityItemToken.tryParseList(tt2, 3, null);
            if (cits != null && cits.size() == 2 && cits.get(0).typ == CityItemToken.ItemType.NOUN) 
                return null;
        }
        if (res.notOrg && (res.getWhitespacesAfterCount() < 2)) {
            com.pullenti.ner.Token tt = res.getEndToken().getNext();
            if ((tt instanceof com.pullenti.ner.TextToken) && tt.getLengthChar() == 1 && ((tt.isValue("П", null) || tt.isValue("Д", null)))) {
                if (!com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(tt, false, false)) {
                    res.setEndToken(res.getEndToken().getNext());
                    if (res.getEndToken().getNext() != null && res.getEndToken().getNext().isChar('.')) 
                        res.setEndToken(res.getEndToken().getNext());
                }
            }
        }
        if (tokTyp != null && tokTyp.vals.contains("лесничество") && MiscLocationHelper.isUserParamAddress(tokTyp)) {
            tt2 = tokTyp.getEndToken().getNext();
            if (tt2 != null && tt2.isComma()) 
                tt2 = tt2.getNext();
            com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParsePureItem(tt2, null, null);
            if (ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.FLAT && ait.value != null) {
                _org.addSlot("NUMBER", ait.value, false, 0);
                res.setEndToken(ait.getEndToken());
                for (tt2 = res.getEndToken().getNext(); tt2 != null; tt2 = tt2.getNext()) {
                    if (!tt2.isCommaAnd()) 
                        break;
                    ait = com.pullenti.ner.address.internal.AddressItemToken.tryParsePureItem(tt2.getNext(), null, null);
                    if (ait == null || ait.value == null) 
                        break;
                    if (ait.getTyp() != com.pullenti.ner.address.internal.AddressItemType.NUMBER && ait.getTyp() != com.pullenti.ner.address.internal.AddressItemType.FLAT) 
                        break;
                    _org.addSlot("NUMBER", ait.value, false, 0);
                    res.setEndToken((tt2 = ait.getEndToken()));
                }
            }
            else {
                NumToken nu = NumToken.tryParse(tt2, GeoTokenType.ORG);
                if (nu != null) {
                    if (nu.miscType != null) 
                        _org.addSlot("MISC2", (nu.miscType + " " + nu.value), false, 0);
                    else 
                        _org.addSlot("NUMBER", nu.value, false, 0);
                    res.setEndToken(nu.getEndToken());
                }
                else {
                    com.pullenti.ner.address.internal.StreetItemToken sit = com.pullenti.ner.address.internal.StreetItemToken.tryParse(tt2, null, false, null);
                    if (sit != null && sit.typ == com.pullenti.ner.address.internal.StreetItemType.NOUN && (sit.termin.getCanonicText().indexOf("КВАРТАЛ") >= 0)) {
                        for (tt2 = sit.getEndToken().getNext(); tt2 != null; tt2 = tt2.getNext()) {
                            NumToken num = NumToken.tryParse(tt2, GeoTokenType.ORG);
                            if (num == null) 
                                break;
                            _org.addSlot("NUMBER", num.value, false, 0);
                            res.setEndToken(num.getEndToken());
                            tt2 = num.getEndToken().getNext();
                            if (tt2 == null) 
                                break;
                            if (!tt2.isCommaAnd()) 
                                break;
                        }
                    }
                }
            }
        }
        if (!ignoreNext && (res.getWhitespacesAfterCount() < 2) && !tokTyp.notOrg) {
            com.pullenti.ner.Token ttt2 = res.getEndToken().getNext();
            if (ttt2 != null && ttt2.isComma()) 
                ttt2 = ttt2.getNext();
            NumToken nn = NumToken.tryParse(ttt2, GeoTokenType.ORG);
            if (nn != null && nn.hasSpecWord) {
                res.setEndToken(nn.getEndToken());
                if (nn.miscType != null) 
                    _org.addSlot("MISC2", (nn.miscType + " " + nn.value), false, 0);
                else {
                    String num = _org.getStringValue("NUMBER");
                    if (num == null) 
                        num = nn.value;
                    else 
                        num = (num + "+" + nn.value);
                    _org.addSlot("NUMBER", num, true, 0);
                }
            }
        }
        return res;
    }

    public static com.pullenti.ner.address.internal.StreetItemToken tryParseRailway(com.pullenti.ner.Token t) {
        if (!(t instanceof com.pullenti.ner.TextToken) || !t.chars.isLetter()) 
            return null;
        if (t.isValue("ДОРОГА", null) && (t.getWhitespacesAfterCount() < 3)) {
            com.pullenti.ner.address.internal.StreetItemToken _next = tryParseRailway(t.getNext());
            if (_next != null) {
                _next.setBeginToken(t);
                return _next;
            }
        }
        GeoAnalyzerData ad = com.pullenti.ner.geo.GeoAnalyzer.getData(t);
        if (ad == null) 
            return null;
        if (ad.oLevel > 0) 
            return null;
        ad.oLevel++;
        com.pullenti.ner.address.internal.StreetItemToken res = _tryParseRailway(t);
        ad.oLevel--;
        return res;
    }

    private static com.pullenti.ner.ReferentToken _tryParseRailwayOrg(com.pullenti.ner.Token t) {
        if (t == null) 
            return null;
        int cou = 0;
        boolean ok = false;
        for (com.pullenti.ner.Token tt = t; tt != null && (cou < 4); tt = tt.getNext(),cou++) {
            if (tt instanceof com.pullenti.ner.TextToken) {
                String val = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(tt, com.pullenti.ner.TextToken.class)).term;
                if (com.pullenti.unisharp.Utils.stringsEq(val, "Ж") || val.startsWith("ЖЕЛЕЗ")) {
                    ok = true;
                    break;
                }
                if (com.pullenti.morph.LanguageHelper.endsWith(val, "ЖД")) {
                    ok = true;
                    break;
                }
            }
        }
        if (!ok) 
            return null;
        com.pullenti.ner.ReferentToken rt = t.kit.processReferent("ORGANIZATION", t, null);
        if (rt == null) 
            return null;
        for (String ty : rt.referent.getStringValues("TYPE")) {
            if (ty.endsWith("дорога")) 
                return rt;
        }
        return null;
    }

    private static com.pullenti.ner.address.internal.StreetItemToken _tryParseRailway(com.pullenti.ner.Token t) {
        com.pullenti.ner.ReferentToken rt0 = _tryParseRailwayOrg(t);
        if (rt0 != null) {
            com.pullenti.ner.address.internal.StreetItemToken res = com.pullenti.ner.address.internal.StreetItemToken._new1585(t, rt0.getEndToken(), com.pullenti.ner.address.internal.StreetItemType.FIX, true);
            res.value = rt0.referent.getStringValue("NAME");
            t = res.getEndToken().getNext();
            if (t != null && t.isComma()) 
                t = t.getNext();
            com.pullenti.ner.address.internal.StreetItemToken _next = _tryParseRzdDir(t);
            if (_next != null) {
                res.setEndToken(_next.getEndToken());
                res.value = (res.value + " " + _next.value);
            }
            else if ((t instanceof com.pullenti.ner.TextToken) && t.getMorph()._getClass().isAdjective() && !t.chars.isAllLower()) {
                boolean ok = false;
                if (t.isNewlineAfter() || t.getNext() == null) 
                    ok = true;
                else if (t.getNext().isCharOf(".,")) 
                    ok = true;
                else if (com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(t.getNext(), false, false) || com.pullenti.ner.address.internal.AddressItemToken.checkKmAfter(t.getNext())) 
                    ok = true;
                if (ok) {
                    res.value = (res.value + " " + ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term + " НАПРАВЛЕНИЕ");
                    res.setEndToken(t);
                }
            }
            if (com.pullenti.unisharp.Utils.stringsEq(res.value, "РОССИЙСКИЕ ЖЕЛЕЗНЫЕ ДОРОГИ")) 
                res.nounIsDoubtCoef = 2;
            return res;
        }
        com.pullenti.ner.address.internal.StreetItemToken dir = _tryParseRzdDir(t);
        if (dir != null && dir.nounIsDoubtCoef == 0) 
            return dir;
        return null;
    }

    private static com.pullenti.ner.address.internal.StreetItemToken _tryParseRzdDir(com.pullenti.ner.Token t) {
        com.pullenti.ner.Token napr = null;
        com.pullenti.ner.Token tt0 = null;
        com.pullenti.ner.Token tt1 = null;
        String val = null;
        int cou = 0;
        for (com.pullenti.ner.Token tt = t; tt != null && (cou < 4); tt = tt.getNext(),cou++) {
            if (tt.isCharOf(",.")) 
                continue;
            if (tt.isNewlineBefore()) 
                break;
            if (tt.isValue("НАПРАВЛЕНИЕ", null)) {
                napr = tt;
                continue;
            }
            if (tt.isValue("НАПР", null)) {
                if (tt.getNext() != null && tt.getNext().isChar('.')) 
                    tt = tt.getNext();
                napr = tt;
                continue;
            }
            com.pullenti.ner.core.NounPhraseToken npt = MiscLocationHelper.tryParseNpt(tt);
            if (npt != null && npt.adjectives.size() > 0 && npt.noun.isValue("КОЛЬЦО", null)) {
                tt0 = tt;
                tt1 = npt.getEndToken();
                val = npt.getNormalCaseText(null, com.pullenti.morph.MorphNumber.SINGULAR, com.pullenti.morph.MorphGender.UNDEFINED, false);
                break;
            }
            if ((tt instanceof com.pullenti.ner.TextToken) && ((!tt.chars.isAllLower() || napr != null)) && ((short)((tt.getMorph().getGender().value()) & (com.pullenti.morph.MorphGender.NEUTER.value()))) != (com.pullenti.morph.MorphGender.UNDEFINED.value())) {
                tt0 = (tt1 = tt);
                continue;
            }
            if ((((tt instanceof com.pullenti.ner.TextToken) && ((!tt.chars.isAllLower() || napr != null)) && tt.getNext() != null) && tt.getNext().isHiphen() && (tt.getNext().getNext() instanceof com.pullenti.ner.TextToken)) && ((short)((tt.getNext().getNext().getMorph().getGender().value()) & (com.pullenti.morph.MorphGender.NEUTER.value()))) != (com.pullenti.morph.MorphGender.UNDEFINED.value())) {
                tt0 = tt;
                tt = tt.getNext().getNext();
                tt1 = tt;
                continue;
            }
            break;
        }
        if (tt0 == null) 
            return null;
        com.pullenti.ner.address.internal.StreetItemToken res = com.pullenti.ner.address.internal.StreetItemToken._new1586(tt0, tt1, com.pullenti.ner.address.internal.StreetItemType.FIX, true, 1);
        if (val != null) 
            res.value = val;
        else {
            res.value = tt1.getNormalCaseText(com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphNumber.SINGULAR, com.pullenti.morph.MorphGender.NEUTER, false);
            if (tt0 != tt1) 
                res.value = (((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(tt0, com.pullenti.ner.TextToken.class)).term + " " + res.value);
            res.value += " НАПРАВЛЕНИЕ";
        }
        if (napr != null && napr.getEndChar() > res.getEndChar()) 
            res.setEndToken(napr);
        t = res.getEndToken().getNext();
        if (t != null && t.isComma()) 
            t = t.getNext();
        if (t != null) {
            com.pullenti.ner.ReferentToken rt0 = _tryParseRailwayOrg(t);
            if (rt0 != null) {
                res.value = (rt0.referent.getStringValue("NAME") + " " + res.value);
                res.setEndToken(rt0.getEndToken());
                res.nounIsDoubtCoef = 0;
            }
        }
        return res;
    }

    private void _tryParseDetails() {
        if (getWhitespacesAfterCount() > 2) 
            return;
        com.pullenti.ner.Token t = getEndToken().getNext();
        if (t == null) 
            return;
        boolean isGaraz = false;
        for (com.pullenti.ner.Slot s : referent.getSlots()) {
            if (com.pullenti.unisharp.Utils.stringsEq(s.getTypeName(), "TYPE") && (s.getValue() instanceof String)) {
                String ty = (String)com.pullenti.unisharp.Utils.cast(s.getValue(), String.class);
                if ((ty.indexOf("гараж") >= 0) || (ty.indexOf("автомоб") >= 0)) {
                    isGaraz = true;
                    break;
                }
            }
        }
        com.pullenti.ner.Token t1 = null;
        com.pullenti.ner.core.TerminToken tok = m_Onto.tryParse(t, com.pullenti.ner.core.TerminParseAttr.NO);
        if (tok != null) 
            t1 = tok.getEndToken().getNext();
        else if (isGaraz && referent.findSlot("NAME", null, true) == null) 
            t1 = this.getEndToken().getNext();
        if (t1 != null) {
            t = t1;
            java.util.ArrayList<CityItemToken> cits = CityItemToken.tryParseList(t, 5, null);
            if (cits != null && cits.size() > 1) {
                com.pullenti.ner.ReferentToken rt = CityAttachHelper.tryDefine(cits, null, false);
                if (rt != null) {
                    setEndToken(rt.getEndToken());
                    t = this.getEndToken().getNext();
                    this._mergeWith(rt.referent);
                }
            }
            com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParse(t, false, null, null);
            if (ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.STREET && ait.referent != null) {
                setEndToken(ait.getEndToken());
                t = this.getEndToken().getNext();
                this._mergeWith(ait.referent);
                ait = com.pullenti.ner.address.internal.AddressItemToken.tryParse(t, false, null, null);
                if (ait != null && ((ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.HOUSE || ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.NUMBER)) && ait.value != null) {
                    referent.addSlot("NUMBER", ait.value, false, 0);
                    setEndToken(ait.getEndToken());
                    t = this.getEndToken().getNext();
                }
            }
            else if ((ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.HOUSE && ait.houseType != com.pullenti.ner.address.AddressHouseType.SPECIAL) && ait.value != null) {
                referent.addSlot("NUMBER", ait.value, false, 0);
                setEndToken(ait.getEndToken());
                t = this.getEndToken().getNext();
            }
            if (tok != null && t == tok.getEndToken().getNext()) {
                if (t == null || tok.isNewlineAfter()) {
                    setEndToken(tok.getEndToken());
                    return;
                }
                NameToken name = NameToken.tryParse(t, GeoTokenType.ORG, 0, false);
                if (name != null && name.name != null && referent.findSlot("NAME", null, true) == null) {
                    referent.addSlot("NAME", name.name, false, 0);
                    if (name.number != null) 
                        referent.addSlot("NUMBER", name.number, false, 0);
                    setEndToken(name.getEndToken());
                    t = this.getEndToken().getNext();
                }
            }
        }
        if (isGaraz) {
            com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParse(t, false, null, null);
            if (ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.STREET && ait.referent != null) {
            }
            else if (ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.HOUSE && ait.value != null) {
                referent.addSlot("NUMBER", ait.value, false, 0);
                setEndToken(ait.getEndToken());
                t = this.getEndToken().getNext();
            }
            else if (ait != null && ait.detailType == com.pullenti.ner.address.AddressDetailType.NEAR) {
                com.pullenti.ner.address.internal.AddressItemToken ait2 = com.pullenti.ner.address.internal.AddressItemToken.tryParse(ait.getEndToken().getNext(), false, null, null);
                if (ait2 != null && ait2.getTyp() == com.pullenti.ner.address.internal.AddressItemType.HOUSE && ait2.value != null) {
                    referent.addSlot("NUMBER", ait2.value, false, 0);
                    setEndToken(ait2.getEndToken());
                    t = this.getEndToken().getNext();
                }
            }
        }
    }

    private void _mergeWith(com.pullenti.ner.Referent r) {
        java.util.ArrayList<String> names = referent.getStringValues("NAME");
        for (String n : r.getStringValues("NAME")) {
            if (names.size() > 0) {
                for (String n0 : names) {
                    referent.addSlot("NAME", (n0 + " " + n), false, 0);
                }
            }
            else 
                referent.addSlot("NAME", n, false, 0);
        }
        for (String n : r.getStringValues("NUMBER")) {
            referent.addSlot("NUMBER", n, false, 0);
        }
        for (String n : r.getStringValues("MISC")) {
            referent.addSlot("MISC", n, false, 0);
        }
        for (String n : r.getStringValues("MISC2")) {
            referent.addSlot("MISC2", n, false, 0);
        }
    }

    public static com.pullenti.ner.core.TerminCollection m_Onto;

    public static void initialize() {
        m_Onto = new com.pullenti.ner.core.TerminCollection();
        com.pullenti.ner.core.Termin t;
        t = new com.pullenti.ner.core.Termin("В РАЙОНЕ", null, false);
        t.addAbridge("В Р-НЕ");
        m_Onto.add(t);
        t = new com.pullenti.ner.core.Termin("РАЙОН", null, false);
        t.addAbridge("Р-Н");
        t.addAbridge("Р-ОН");
        m_Onto.add(t);
        m_Onto.add(new com.pullenti.ner.core.Termin("ПО", null, false));
        m_Onto.add(new com.pullenti.ner.core.Termin("ОКОЛО", null, false));
        m_Onto.add(new com.pullenti.ner.core.Termin("ВО ДВОРЕ", null, false));
    }
    public OrgItemToken() {
        super();
    }
}
