/*
 * 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 TerrDefineHelper {

    private static com.pullenti.ner.ReferentToken _tryAttachMoscowAO(java.util.ArrayList<TerrItemToken> li, com.pullenti.ner.core.AnalyzerData ad) {
        if (li.get(0).terminItem == null || !li.get(0).terminItem.isMoscowRegion) 
            return null;
        if (li.get(0).isDoubt) {
            boolean ok = false;
            if (CityAttachHelper.checkCityAfter(li.get(0).getEndToken().getNext())) 
                ok = true;
            else {
                java.util.ArrayList<com.pullenti.ner.address.internal.AddressItemToken> ali = com.pullenti.ner.address.internal.AddressItemToken.tryParseList(li.get(0).getEndToken().getNext(), 2);
                if (ali != null && ali.size() > 0 && ali.get(0).getTyp() == com.pullenti.ner.address.internal.AddressItemType.STREET) 
                    ok = true;
            }
            if (!ok) 
                return null;
        }
        com.pullenti.ner.geo.GeoReferent reg = new com.pullenti.ner.geo.GeoReferent();
        String typ = "АДМИНИСТРАТИВНЫЙ ОКРУГ";
        reg.addTyp(typ);
        String name = li.get(0).terminItem.getCanonicText();
        if (com.pullenti.morph.LanguageHelper.endsWith(name, typ)) 
            name = name.substring(0, 0 + name.length() - typ.length() - 1).trim();
        reg.addName(name);
        return new com.pullenti.ner.ReferentToken(reg, li.get(0).getBeginToken(), li.get(0).getEndToken(), null);
    }

    public static com.pullenti.ner.ReferentToken tryDefine(java.util.ArrayList<TerrItemToken> li, com.pullenti.ner.core.AnalyzerData ad, boolean attachAlways, java.util.ArrayList<CityItemToken> cits, java.util.ArrayList<com.pullenti.ner.geo.GeoReferent> exists) {
        if (li == null || li.size() == 0) 
            return null;
        TerrItemToken exObj = null;
        TerrItemToken newName = null;
        java.util.ArrayList<TerrItemToken> adjList = new java.util.ArrayList<TerrItemToken>();
        TerrItemToken noun = null;
        TerrItemToken addNoun = null;
        com.pullenti.ner.address.internal.AddressItemToken number = null;
        com.pullenti.ner.ReferentToken rt = _tryAttachMoscowAO(li, ad);
        if (rt != null) 
            return rt;
        boolean canBeCityBefore = false;
        boolean adjTerrBefore = false;
        if (cits != null) {
            if (cits.get(0).typ == CityItemToken.ItemType.CITY) 
                canBeCityBefore = true;
            else if (cits.get(0).typ == CityItemToken.ItemType.NOUN && cits.size() > 1) 
                canBeCityBefore = true;
        }
        int k;
        for (k = 0; k < li.size(); k++) {
            if (li.get(k).ontoItem != null) {
                if (exObj != null || newName != null) 
                    break;
                if (noun != null) {
                    if (k == 1) {
                        if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "РАЙОН") || com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "ОБЛАСТЬ") || com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "СОЮЗ")) {
                            if (li.get(k).ontoItem.referent instanceof com.pullenti.ner.geo.GeoReferent) {
                                if (((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(k).ontoItem.referent, com.pullenti.ner.geo.GeoReferent.class)).isState()) 
                                    break;
                            }
                            boolean ok = false;
                            com.pullenti.ner.Token tt = li.get(k).getEndToken().getNext();
                            if (tt == null) 
                                ok = true;
                            else if (tt.isCharOf(",.")) 
                                ok = true;
                            if ((!ok && li.size() >= 4 && li.get(2).terminItem != null) && li.get(3).terminItem == null) 
                                ok = true;
                            if (!ok) 
                                ok = MiscLocationHelper.checkGeoObjectBefore(li.get(0).getBeginToken(), false);
                            if (!ok) 
                                ok = MiscLocationHelper.checkGeoObjectAfter(li.get(1).getEndToken(), false, false);
                            if (!ok) {
                                com.pullenti.ner.address.internal.AddressItemToken adr = com.pullenti.ner.address.internal.AddressItemToken.tryParse(tt, false, null, null);
                                if (adr != null) {
                                    if (adr.getTyp() == com.pullenti.ner.address.internal.AddressItemType.STREET) 
                                        ok = true;
                                }
                            }
                            if (!ok && MiscLocationHelper.isUserParamAddress(tt) && (tt instanceof com.pullenti.ner.NumberToken)) 
                                ok = true;
                            if (!ok) 
                                break;
                        }
                        if (li.get(k).ontoItem != null) {
                            if (noun.getBeginToken().isValue("МО", null) || noun.getBeginToken().isValue("ЛО", null)) 
                                return null;
                        }
                    }
                }
                exObj = li.get(k);
            }
            else if (li.get(k).terminItem != null) {
                if (noun != null) 
                    break;
                if (li.get(k).terminItem.isAlwaysPrefix && k > 0) 
                    break;
                if (k > 0 && li.get(k).isDoubt) {
                    if (li.get(k).getBeginToken() == li.get(k).getEndToken() && li.get(k).getBeginToken().isValue("ЗАО", null)) 
                        break;
                }
                if (li.get(k).terminItem.isAdjective || li.get(k).isGeoInDictionary) 
                    adjList.add(li.get(k));
                else {
                    if (exObj != null) {
                        com.pullenti.ner.geo.GeoReferent _geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(exObj.ontoItem.referent, com.pullenti.ner.geo.GeoReferent.class);
                        if (_geo == null) 
                            break;
                        if (exObj.isAdjective && ((com.pullenti.unisharp.Utils.stringsEq(li.get(k).terminItem.getCanonicText(), "СОЮЗ") || com.pullenti.unisharp.Utils.stringsEq(li.get(k).terminItem.getCanonicText(), "ФЕДЕРАЦИЯ")))) {
                            String str = exObj.ontoItem.toString();
                            if (!(str.indexOf(li.get(k).terminItem.getCanonicText()) >= 0)) 
                                break;
                        }
                        if (com.pullenti.unisharp.Utils.stringsEq(li.get(k).terminItem.getCanonicText(), "РАЙОН") || com.pullenti.unisharp.Utils.stringsEq(li.get(k).terminItem.getCanonicText(), "ОКРУГ") || com.pullenti.unisharp.Utils.stringsEq(li.get(k).terminItem.getCanonicText(), "КРАЙ")) {
                            StringBuilder tmp = new StringBuilder();
                            for (com.pullenti.ner.Slot s : _geo.getSlots()) {
                                if (com.pullenti.unisharp.Utils.stringsEq(s.getTypeName(), com.pullenti.ner.geo.GeoReferent.ATTR_TYPE)) 
                                    tmp.append(s.getValue()).append(";");
                            }
                            if (!(tmp.toString().toUpperCase().indexOf(li.get(k).terminItem.getCanonicText()) >= 0)) {
                                if (k != 1 || newName != null) 
                                    break;
                                newName = li.get(0);
                                newName.isAdjective = true;
                                newName.ontoItem = null;
                                exObj = null;
                            }
                        }
                    }
                    noun = li.get(k);
                    if (k == 0 && !li.get(k).isNewlineBefore()) {
                        TerrItemToken tt = TerrItemToken.tryParse(li.get(k).getBeginToken().getPrevious(), null, null);
                        if (tt != null && tt.getMorph()._getClass().isAdjective()) 
                            adjTerrBefore = true;
                    }
                }
            }
            else {
                if (exObj != null) 
                    break;
                if (newName != null) {
                    if ((k == 2 && li.size() == 3 && li.get(0) == newName) && li.get(1).terminItem != null) {
                        if (CityItemToken.checkKeyword(li.get(2).getEndToken().getNext()) != null) 
                            break;
                        if (li.get(0).getBeginToken().getPrevious() != null) {
                            CityItemToken cit = CityItemToken.tryParse(li.get(0).getBeginToken().getPrevious(), null, false, null);
                            if (cit == null) 
                                cit = CityItemToken.tryParse(li.get(0).getBeginToken().getPrevious().getPrevious(), null, false, null);
                            if (cit != null && cit.typ == CityItemToken.ItemType.NOUN) 
                                return null;
                        }
                    }
                    if ((k == 1 && li.size() == 3 && li.get(2).terminItem != null) && li.get(1).getBeginToken().isChar('(')) 
                        continue;
                    if ((k == 2 && newName == li.get(1) && li.size() == 3) && noun != null) {
                        CityItemToken cit = CityItemToken.tryParse(newName.getBeginToken(), null, false, null);
                        if (cit != null && cit.typ == CityItemToken.ItemType.NOUN && cit.getEndToken().getNext() == li.get(k).getBeginToken()) {
                            if ((noun.terminItem.getCanonicText().indexOf("МУНИЦИПАЛ") >= 0)) {
                                CityItemToken nam = CityItemToken.tryParse(cit.getEndToken().getNext(), null, false, null);
                                if (nam != null && ((nam.typ == CityItemToken.ItemType.PROPERNAME || nam.typ == CityItemToken.ItemType.CITY))) {
                                    if (nam.getEndToken().getNext() != null && nam.getEndToken().getNext().isAnd()) {
                                        java.util.ArrayList<TerrItemToken> li2 = TerrItemToken.tryParseList(nam.getEndToken().getNext().getNext(), 4, null);
                                        if (li2 != null && li2.size() >= 2 && ((li2.get(0).terminItem != null || li2.get(1).terminItem != null))) {
                                            com.pullenti.ner.geo.GeoReferent geo1 = new com.pullenti.ner.geo.GeoReferent();
                                            com.pullenti.ner.ReferentToken rt1 = new com.pullenti.ner.ReferentToken(geo1, li.get(0).getBeginToken(), li2.get(1).getEndToken(), null);
                                            geo1.addTyp(noun.terminItem.getCanonicText());
                                            geo1.addSlot(com.pullenti.ner.geo.GeoReferent.ATTR_NAME, com.pullenti.ner.core.MiscHelper.getTextValue(li.get(1).getBeginToken(), rt1.getEndToken(), com.pullenti.ner.core.GetTextAttr.NO), false, 0);
                                            return rt1;
                                        }
                                    }
                                }
                            }
                        }
                        else 
                            break;
                    }
                    else 
                        break;
                }
                newName = li.get(k);
            }
        }
        String name = null;
        String altName = null;
        String fullName = null;
        com.pullenti.ner.MorphCollection _morph = null;
        String typVar = null;
        com.pullenti.ner.Token endTok = null;
        if (exObj != null && noun != null) {
            com.pullenti.ner.geo.GeoReferent _geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(exObj.ontoItem.referent, com.pullenti.ner.geo.GeoReferent.class);
            if (_geo != null && !_geo.isCity() && ((_geo.isState() || (noun.terminItem.getCanonicText().length() < 3) || _geo.containsType(noun.terminItem.getCanonicText())))) {
            }
            else {
                newName = exObj;
                exObj = null;
            }
        }
        if (exObj != null) {
            if (exObj.isAdjective && !exObj.getMorph().getLanguage().isEn() && noun == null) {
                if (attachAlways && exObj.getEndToken().getNext() != null) {
                    com.pullenti.ner.core.NounPhraseToken npt = MiscLocationHelper.tryParseNpt(exObj.getBeginToken());
                    if (exObj.getEndToken().getNext().isCommaAnd()) {
                    }
                    else if (npt == null) {
                    }
                    else {
                        com.pullenti.ner.address.internal.StreetItemToken str = com.pullenti.ner.address.internal.StreetItemToken.tryParse(exObj.getEndToken().getNext(), null, false, null);
                        if (str != null) {
                            if (str.typ == com.pullenti.ner.address.internal.StreetItemType.NOUN && str.getEndToken() == npt.getEndToken()) 
                                return null;
                        }
                    }
                }
                else if (exObj.getBeginToken().isValue("ПОДНЕБЕСНЫЙ", null)) {
                }
                else if (MiscLocationHelper.isUserParamAddress(exObj) && exObj.isNewlineBefore() && !com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(exObj.getEndToken().getNext())) {
                    com.pullenti.ner.address.internal.StreetItemToken sit = com.pullenti.ner.address.internal.StreetItemToken.tryParse(exObj.getEndToken().getNext(), null, false, null);
                    if (sit != null) {
                        if (sit.typ == com.pullenti.ner.address.internal.StreetItemType.NUMBER || sit.typ == com.pullenti.ner.address.internal.StreetItemType.STDADJECTIVE) 
                            return null;
                    }
                }
                else {
                    com.pullenti.ner.core.NounPhraseToken npt = com.pullenti.ner.core.NounPhraseHelper.tryParse(exObj.getBeginToken(), com.pullenti.ner.core.NounPhraseParseAttr.CANNOTHASCOMMAAND, 0, null);
                    if (npt != null && npt.getEndToken() != npt.getBeginToken()) 
                        return null;
                    com.pullenti.ner.Token ttt = exObj.getEndToken().getNext();
                    if (ttt != null && ttt.isComma() && li.size() == 1) 
                        ttt = ttt.getNext();
                    else if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(exObj.getBeginToken(), false)) 
                        return null;
                    else if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(exObj.getBeginToken().getPrevious(), false)) 
                        return null;
                    java.util.ArrayList<CityItemToken> cit = CityItemToken.tryParseList(ttt, 5, null);
                    if (cit != null && ((cit.get(0).typ == CityItemToken.ItemType.NOUN || cit.get(0).typ == CityItemToken.ItemType.CITY))) {
                        if (npt != null && npt.getEndToken() == cit.get(0).getEndToken()) {
                        }
                        else if (!MiscLocationHelper.isUserParamAddress(exObj)) 
                            return null;
                        else if (cit.get(0).typ == CityItemToken.ItemType.NOUN && ((cit.size() == 2 || cit.size() == 4)) && ((cit.get(1).typ == CityItemToken.ItemType.CITY || cit.get(1).typ == CityItemToken.ItemType.PROPERNAME))) {
                            if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(cit.get(1).getBeginToken(), false)) 
                                return null;
                        }
                        else if (cit.get(0).typ == CityItemToken.ItemType.CITY) {
                        }
                        else 
                            return null;
                    }
                    else if ((cit != null && cit.get(0).typ == CityItemToken.ItemType.PROPERNAME && cit.size() == 2) && cit.get(1).typ == CityItemToken.ItemType.NOUN && exObj.getEndToken().getNext().isComma()) {
                    }
                    else if (ttt == null || ttt.getWhitespacesBeforeCount() > 4) 
                        return null;
                    else if (MiscLocationHelper.checkGeoObjectAfter(ttt.getPrevious(), false, false)) {
                    }
                    else if (!MiscLocationHelper.isUserParamAddress(exObj)) 
                        return null;
                    else if (com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(exObj.getEndToken().getNext(), true, false)) 
                        return null;
                    else if (ttt.isHiphen()) 
                        return null;
                    com.pullenti.ner.MetaToken cnou = CityItemToken.checkKeywordBefore(exObj.getBeginToken().getPrevious());
                    if (cnou != null) 
                        return null;
                }
            }
            if (noun == null && ((exObj.canBeCity || exObj.canBeSurname))) {
                CityItemToken cit0 = CityItemToken.tryParseBack(exObj.getBeginToken().getPrevious(), false);
                if (cit0 != null && cit0.typ != CityItemToken.ItemType.PROPERNAME) 
                    return null;
            }
            if (exObj.isDoubt && noun == null) {
                boolean ok2 = false;
                if (_canBeGeoAfter(exObj.getEndToken().getNext())) 
                    ok2 = true;
                else if (!exObj.canBeSurname && !exObj.canBeCity) {
                    if ((exObj.getEndToken().getNext() != null && exObj.getEndToken().getNext().isChar(')') && exObj.getBeginToken().getPrevious() != null) && exObj.getBeginToken().getPrevious().isChar('(')) 
                        ok2 = true;
                    else if (exObj.chars.isLatinLetter() && exObj.getBeginToken().getPrevious() != null) {
                        if (exObj.getBeginToken().getPrevious().isValue("IN", null)) 
                            ok2 = true;
                        else if (exObj.getBeginToken().getPrevious().isValue("THE", null) && exObj.getBeginToken().getPrevious().getPrevious() != null && exObj.getBeginToken().getPrevious().getPrevious().isValue("IN", null)) 
                            ok2 = true;
                    }
                }
                if (!ok2) {
                    CityItemToken cit0 = CityItemToken.tryParseBack(exObj.getBeginToken().getPrevious(), false);
                    if (cit0 != null && cit0.typ != CityItemToken.ItemType.PROPERNAME) {
                    }
                    else {
                        if (MiscLocationHelper.checkGeoObjectBefore(exObj.getBeginToken().getPrevious(), false)) {
                        }
                        if (exObj.isNewlineBefore() && MiscLocationHelper.isUserParamAddress(exObj)) {
                        }
                        else 
                            return null;
                    }
                }
            }
            name = exObj.ontoItem.getCanonicText();
            _morph = exObj.getMorph();
        }
        else if (newName != null && noun == null) {
            if (!MiscLocationHelper.isUserParamAddress(newName)) 
                return null;
            if (!li.get(0).getMorph()._getClass().isAdjective()) 
                return null;
            if (com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(li.get(0).getBeginToken())) 
                return null;
            boolean afterOrg = false;
            com.pullenti.ner.Token ttt = li.get(0).getBeginToken().getPrevious();
            if ((ttt != null && ttt.isComma() && li.get(0).getEndToken().getNext() != null) && li.get(0).getEndToken().getNext().isComma()) {
                int cou = 10;
                for (com.pullenti.ner.Token tt0 = ttt.getPrevious(); tt0 != null && cou > 0; tt0 = tt0.getPrevious(),cou--) {
                    OrgItemToken _org = OrgItemToken.tryParse(tt0, null);
                    if (_org == null) 
                        continue;
                    if (_org.getEndToken().getNext() == ttt) {
                        afterOrg = true;
                        break;
                    }
                }
                if (afterOrg) {
                    afterOrg = false;
                    ttt = li.get(0).getEndToken().getNext();
                    while (ttt != null) {
                        if (ttt.isComma()) 
                            ttt = ttt.getNext();
                        else 
                            break;
                    }
                    java.util.ArrayList<TerrItemToken> ters = TerrItemToken.tryParseList(ttt, 4, null);
                    if (ters != null) {
                        if (((ters.size() == 1 || ters.size() == 2)) && ters.get(0).ontoItem != null) 
                            afterOrg = true;
                        else if (ters.size() == 2 && ters.get(0).terminItem != null) 
                            afterOrg = true;
                    }
                }
            }
            if (!afterOrg) {
                if ((li.size() == 3 && li.get(1).ontoItem == null && li.get(2).ontoItem == null) && li.get(1).terminItem == null && li.get(2).terminItem == null) {
                    if (MiscLocationHelper.isUserParamAddress(li.get(0))) {
                        if (com.pullenti.ner.address.internal.AddressItemToken.checkHouseAfter(li.get(2).getEndToken().getNext(), false, false)) {
                            com.pullenti.ner.address.internal.AddressItemToken aa = com.pullenti.ner.address.internal.AddressItemToken.tryParse(li.get(0).getBeginToken(), false, null, null);
                            if ((aa != null && aa.getEndChar() > li.get(0).getEndChar() && aa.getTyp() == com.pullenti.ner.address.internal.AddressItemType.STREET) && !aa.isDoubt) {
                            }
                            else {
                                com.pullenti.ner.geo.GeoReferent rr = new com.pullenti.ner.geo.GeoReferent();
                                rr.setProbable(true);
                                rr.addTyp("район");
                                rr.addSlot(com.pullenti.ner.geo.GeoReferent.ATTR_NAME, com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(li.get(0), com.pullenti.ner.core.GetTextAttr.NO), false, 0);
                                return com.pullenti.ner.ReferentToken._new958(rr, li.get(0).getBeginToken(), li.get(0).getEndToken(), li.get(0).getMorph());
                            }
                        }
                    }
                }
                if (li.size() != 1) 
                    return null;
                if (!MiscLocationHelper.checkGeoObjectBefore(li.get(0).getBeginToken(), false)) {
                    if (li.get(0).getBeginToken().getPrevious() == null && li.get(0).getEndToken().getNext() != null && li.get(0).getEndToken().getNext().isComma()) {
                    }
                    else 
                        return null;
                }
                String str = li.get(0).getSourceText();
                if (com.pullenti.unisharp.Utils.endsWithString(str, "О", true)) 
                    return null;
                if (com.pullenti.unisharp.Utils.endsWithString(str, "ОЕ", true)) 
                    return null;
                if (com.pullenti.unisharp.Utils.endsWithString(str, "АЯ", true)) 
                    return null;
                com.pullenti.ner.Token tt0 = li.get(0).getBeginToken().getPrevious();
                while (tt0 != null && tt0.isComma()) {
                    tt0 = tt0.getPrevious();
                }
                if (tt0 == null) {
                }
                else {
                    if (!(tt0 instanceof com.pullenti.ner.ReferentToken)) 
                        return null;
                    com.pullenti.ner.geo.GeoReferent geo0 = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(tt0.getReferent(), com.pullenti.ner.geo.GeoReferent.class);
                    if (geo0 == null) 
                        return null;
                    if (geo0 != null && geo0.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_TYPE, "район", true) != null) 
                        return null;
                }
                java.util.ArrayList<CityItemToken> cit = CityItemToken.tryParseList(li.get(0).getBeginToken(), 5, null);
                if (cit != null && cit.size() > 0) {
                    if ((cit.get(0).typ == CityItemToken.ItemType.CITY || cit.get(0).typ == CityItemToken.ItemType.NOUN)) 
                        return null;
                    if (cit.size() == 2 && cit.get(1).typ == CityItemToken.ItemType.NOUN) 
                        return null;
                    if (cit.size() > 1 && cit.get(1).typ == CityItemToken.ItemType.NOUN) {
                        if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(cit.get(1).getEndToken().getNext(), false)) 
                            return null;
                    }
                }
                java.util.ArrayList<com.pullenti.ner.address.internal.StreetItemToken> sits = com.pullenti.ner.address.internal.StreetItemToken.tryParseList(li.get(0).getBeginToken(), 3, null);
                if (sits != null && sits.size() == 2 && sits.get(1).typ == com.pullenti.ner.address.internal.StreetItemType.NOUN) 
                    return null;
            }
            name = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(li.get(0), com.pullenti.ner.core.GetTextAttr.NO);
            _morph = li.get(0).getMorph();
            typVar = "район";
        }
        else if (newName != null) {
            for (int j = 1; j < k; j++) {
                if (li.get(j).isNewlineBefore() && ((!li.get(0).isNewlineBefore() || !li.get(j).isNewlineAfter()))) {
                    if (com.pullenti.ner.core.BracketHelper.canBeStartOfSequence(li.get(j).getBeginToken(), false, false)) {
                    }
                    else {
                        if (j < (k - 1)) 
                            return null;
                        if (li.size() == 2 && k == 2) {
                        }
                        else {
                            java.util.ArrayList<TerrItemToken> li2 = new java.util.ArrayList<TerrItemToken>(li);
                            for(int jjj = 0 + k - 1, mmm = 0; jjj >= mmm; jjj--) li2.remove(jjj);
                            com.pullenti.ner.ReferentToken rt2 = tryDefine(li2, ad, false, null, null);
                            if (rt2 != null && rt2.getEndToken() == li2.get(li2.size() - 1).getEndToken()) {
                            }
                            else 
                                return null;
                        }
                    }
                }
            }
            _morph = noun.getMorph();
            if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "МУНИЦИПАЛЬНЫЙ РАЙОН")) {
                if (com.pullenti.ner.address.internal.StreetItemToken.checkKeyword(noun.getBeginToken())) {
                    boolean ok = false;
                    for (com.pullenti.ner.Token tt = li.get(0).getBeginToken().getPrevious(); tt != null; tt = tt.getPrevious()) {
                        if (tt.getLengthChar() == 1) 
                            continue;
                        com.pullenti.ner.geo.GeoReferent _geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(tt.getReferent(), com.pullenti.ner.geo.GeoReferent.class);
                        if (_geo != null) {
                            if (_geo.isRegion() || _geo.isState()) 
                                ok = true;
                        }
                        break;
                    }
                    if (!ok) 
                        return null;
                }
            }
            if (newName.isAdjective) {
                if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.acronym, "АО")) {
                    if (noun.getBeginToken() != noun.getEndToken()) 
                        return null;
                    if (newName.getMorph().getGender() != com.pullenti.morph.MorphGender.FEMINIE) 
                        return null;
                }
                com.pullenti.ner.geo.GeoReferent geoBefore = null;
                com.pullenti.ner.Token tt0 = li.get(0).getBeginToken().getPrevious();
                if (tt0 != null && tt0.isCommaAnd()) 
                    tt0 = tt0.getPrevious();
                if (!li.get(0).isNewlineBefore() && tt0 != null) 
                    geoBefore = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(tt0.getReferent(), com.pullenti.ner.geo.GeoReferent.class);
                if (li.indexOf(noun) < li.indexOf(newName)) {
                    if (noun.terminItem.isState) 
                        return null;
                    if (newName.canBeSurname && geoBefore == null) {
                        if (((com.pullenti.morph.MorphCase.ooBitand(noun.getMorph().getCase(), newName.getMorph().getCase()))).isUndefined()) {
                            if (!MiscLocationHelper.isUserParamAddress(newName)) 
                                return null;
                        }
                    }
                    boolean dontCheck = false;
                    if (com.pullenti.ner.core.MiscHelper.isExistsInDictionary(newName.getBeginToken(), newName.getEndToken(), com.pullenti.morph.MorphClass.ooBitor(com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphClass.ooBitor(com.pullenti.morph.MorphClass.PRONOUN, com.pullenti.morph.MorphClass.VERB)))) {
                        if (noun.getBeginToken() != newName.getBeginToken()) {
                            if (geoBefore == null) {
                                if (li.size() == 2 && _canBeGeoAfter(li.get(1).getEndToken().getNext())) {
                                }
                                else if (li.size() == 3 && li.get(2).terminItem != null && ((_canBeGeoAfter(li.get(2).getEndToken().getNext()) || (noun.terminItem.getCanonicText().indexOf("МУНИЦИП") >= 0) || (noun.terminItem.getCanonicText().indexOf("ГОРОДСК") >= 0)))) 
                                    addNoun = li.get(2);
                                else if (li.size() == 4 && li.get(2).terminItem != null && li.get(3).terminItem == null) {
                                }
                                else if (newName.isGeoInDictionary) {
                                }
                                else if (newName.getEndToken().isNewlineAfter()) {
                                }
                                else if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(newName.getEndToken().getNext(), false)) {
                                }
                                else if (newName.getEndToken().getNext() != null && newName.getEndToken().getNext().isValue("КИЛОМЕТР", null)) {
                                }
                                else if (OrgItemToken.tryParse(newName.getEndToken().getNext(), null) != null) {
                                }
                                else if (MiscLocationHelper.isUserParamAddress(newName)) {
                                }
                                else 
                                    return null;
                                dontCheck = true;
                            }
                        }
                    }
                    if (!dontCheck) {
                        com.pullenti.ner.core.NounPhraseToken npt = com.pullenti.ner.core.NounPhraseHelper.tryParse(newName.getEndToken(), com.pullenti.ner.core.NounPhraseParseAttr.of((com.pullenti.ner.core.NounPhraseParseAttr.PARSEPRONOUNS.value()) | (com.pullenti.ner.core.NounPhraseParseAttr.CANNOTHASCOMMAAND.value())), 0, null);
                        if (npt != null && npt.getEndToken() != newName.getEndToken()) {
                            if (li.size() == 3 && li.get(2).terminItem != null && npt.getEndToken() == li.get(2).getEndToken()) 
                                addNoun = li.get(2);
                            else if (li.size() == 4 && li.get(2).terminItem != null && npt.getEndToken() == li.get(2).getEndToken()) {
                            }
                            else if (com.pullenti.ner.address.internal.AddressItemToken.checkStreetAfter(npt.getEndToken(), false)) {
                            }
                            else if (MiscLocationHelper.checkGeoObjectAfter(newName.getEndToken(), false, false)) {
                            }
                            else if (npt.getEndToken().isValue("КИЛОМЕТР", null)) {
                            }
                            else if (OrgItemToken.tryParse(newName.getEndToken().getNext(), null) != null) {
                            }
                            else if (li.size() == 2 && newName == li.get(1)) {
                                java.util.ArrayList<CityItemToken> cits0 = CityItemToken.tryParseList(li.get(1).getEndToken().getNext(), 2, null);
                                if (cits0 != null && cits0.size() == 1 && cits0.get(0).typ == CityItemToken.ItemType.NOUN) 
                                    endTok = cits0.get(0).getEndToken();
                                else 
                                    return null;
                            }
                            else 
                                return null;
                        }
                    }
                    com.pullenti.ner.ReferentToken rtp = newName.kit.processReferent("PERSON", newName.getBeginToken(), null);
                    if (rtp != null) 
                        return null;
                    if (newName.realName != null) 
                        name = com.pullenti.ner.core.ProperNameHelper.getNameEx(newName.realName.getBeginToken(), newName.realName.getEndToken(), com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphCase.UNDEFINED, noun.terminItem.getGender(), false, false);
                    else 
                        name = com.pullenti.ner.core.ProperNameHelper.getNameEx(newName.getBeginToken(), newName.getEndToken(), com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphCase.UNDEFINED, noun.terminItem.getGender(), false, false);
                    String vvv = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(newName, com.pullenti.ner.core.GetTextAttr.NO);
                    if (vvv.endsWith("ВО")) 
                        name = vvv;
                }
                else {
                    boolean ok = false;
                    if (((k + 1) < li.size()) && li.get(k).terminItem == null && li.get(k + 1).terminItem != null) 
                        ok = true;
                    else if ((k < li.size()) && li.get(k).ontoItem != null) 
                        ok = true;
                    else if (k == li.size() && !newName.isAdjInDictionary) {
                        ok = true;
                        if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "ТЕРРИТОРИЯ")) {
                            CityItemToken cit1 = CityItemToken.tryParseBack(li.get(0).getBeginToken().getPrevious(), false);
                            if (cit1 != null && cit1.typ == CityItemToken.ItemType.NOUN) 
                                return null;
                        }
                        if (noun.getBeginToken().getLengthChar() == 1 && newName.getBeginToken() == newName.getEndToken()) {
                            if (NameToken.checkInitialAndSurname(((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(noun.getBeginToken(), com.pullenti.ner.TextToken.class)).term, newName.getBeginToken())) 
                                return null;
                        }
                    }
                    else if (MiscLocationHelper.checkGeoObjectBefore(li.get(0).getBeginToken(), false) || canBeCityBefore) 
                        ok = true;
                    else if (MiscLocationHelper.checkGeoObjectAfter(li.get(k - 1).getEndToken(), false, false)) 
                        ok = true;
                    else if (li.size() == 3 && k == 2) {
                        CityItemToken cit = CityItemToken.tryParse(li.get(2).getBeginToken(), null, false, null);
                        if (cit != null) {
                            if (cit.typ == CityItemToken.ItemType.CITY || cit.typ == CityItemToken.ItemType.NOUN) 
                                ok = true;
                        }
                    }
                    else if (li.size() == 2) 
                        ok = _canBeGeoAfter(li.get(li.size() - 1).getEndToken().getNext());
                    if (!ok && !li.get(0).isNewlineBefore() && !li.get(0).chars.isAllLower()) {
                        com.pullenti.ner.ReferentToken rt00 = li.get(0).kit.processReferent("PERSONPROPERTY", li.get(0).getBeginToken().getPrevious(), null);
                        if (rt00 != null) 
                            ok = true;
                    }
                    if (noun.terminItem != null && noun.terminItem.isStrong && newName.isAdjective) 
                        ok = true;
                    if (noun.isDoubt && adjList.size() == 0 && geoBefore == null) 
                        return null;
                    if (newName.realName != null) 
                        name = com.pullenti.ner.core.ProperNameHelper.getNameEx(newName.realName.getBeginToken(), newName.realName.getEndToken(), com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphCase.UNDEFINED, noun.terminItem.getGender(), false, false);
                    else 
                        name = com.pullenti.ner.core.ProperNameHelper.getNameEx(newName.getBeginToken(), newName.getEndToken(), com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphCase.UNDEFINED, noun.terminItem.getGender(), false, false);
                    String vvv = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(newName, com.pullenti.ner.core.GetTextAttr.NO);
                    if (vvv.endsWith("ВО")) 
                        name = vvv;
                    if (!ok && !attachAlways && !MiscLocationHelper.isUserParamAddress(newName)) {
                        if (com.pullenti.ner.core.MiscHelper.isExistsInDictionary(newName.getBeginToken(), newName.getEndToken(), com.pullenti.morph.MorphClass.ooBitor(com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphClass.ooBitor(com.pullenti.morph.MorphClass.PRONOUN, com.pullenti.morph.MorphClass.VERB)))) {
                            if (exists != null) {
                                for (com.pullenti.ner.geo.GeoReferent e : exists) {
                                    if (e.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_NAME, name, true) != null) {
                                        ok = true;
                                        break;
                                    }
                                }
                            }
                            if (!ok) 
                                return null;
                        }
                    }
                    fullName = (com.pullenti.ner.core.ProperNameHelper.getNameEx(li.get(0).getBeginToken(), noun.getBeginToken().getPrevious(), com.pullenti.morph.MorphClass.ADJECTIVE, com.pullenti.morph.MorphCase.UNDEFINED, noun.terminItem.getGender(), false, false) + " " + noun.terminItem.getCanonicText());
                }
            }
            else {
                if (!attachAlways || ((noun.terminItem != null && com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "ФЕДЕРАЦИЯ")))) {
                    boolean isLatin = noun.chars.isLatinLetter() && newName.chars.isLatinLetter();
                    if (li.indexOf(noun) > li.indexOf(newName)) {
                        if (!isLatin && newName.namedBy == null) {
                            if (noun.getEndToken().getNext() != null && noun.getEndToken().getNext().isComma()) {
                            }
                            else 
                                return null;
                        }
                    }
                    if (!newName.isDistrictName && newName.namedBy == null && !com.pullenti.ner.core.BracketHelper.canBeStartOfSequence(newName.getBeginToken(), false, false)) {
                        if (adjList.size() == 0 && com.pullenti.ner.core.MiscHelper.isExistsInDictionary(newName.getBeginToken(), newName.getEndToken(), com.pullenti.morph.MorphClass.ooBitor(com.pullenti.morph.MorphClass.NOUN, com.pullenti.morph.MorphClass.PRONOUN))) {
                            if (li.size() == 2 && noun.isCityRegion() && (noun.getWhitespacesAfterCount() < 2)) {
                            }
                            else if (MiscLocationHelper.checkGeoObjectAfter(newName.getEndToken(), false, false)) {
                            }
                            else if (li.size() < 3) {
                                if (MiscLocationHelper.isUserParamAddress(li.get(0))) {
                                }
                                else 
                                    return null;
                            }
                            else {
                                int ii = li.indexOf(newName);
                                java.util.ArrayList<TerrItemToken> li2 = new java.util.ArrayList<TerrItemToken>(li);
                                for(int jjj = 0 + ii + 1 - 1, mmm = 0; jjj >= mmm; jjj--) li2.remove(jjj);
                                com.pullenti.ner.ReferentToken rt2 = tryDefine(li2, ad, false, null, null);
                                if (rt2 == null) 
                                    return null;
                            }
                        }
                        if (!isLatin) {
                            if ((noun.terminItem.isRegion && !attachAlways && ((!adjTerrBefore || newName.isDoubt))) && !noun.isCityRegion() && !noun.terminItem.isSpecificPrefix) {
                                if (!MiscLocationHelper.checkGeoObjectBefore(noun.getBeginToken(), false)) {
                                    if (!noun.isDoubt && noun.getBeginToken() != noun.getEndToken()) {
                                    }
                                    else if ((noun.terminItem.isAlwaysPrefix && li.size() == 2 && li.get(0) == noun) && li.get(1) == newName) {
                                    }
                                    else if (MiscLocationHelper.isUserParamAddress(li.get(0))) {
                                    }
                                    else 
                                        return null;
                                }
                            }
                            if (noun.isDoubt && adjList.size() == 0) {
                                if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.acronym, "МО") || com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.acronym, "ЛО")) {
                                    if (k == (li.size() - 1) && li.get(k).terminItem != null) {
                                        addNoun = li.get(k);
                                        k++;
                                    }
                                    else if (li.size() == 2 && noun == li.get(0) && newName.toString().endsWith("совет")) {
                                    }
                                    else 
                                        return null;
                                }
                                else 
                                    return null;
                            }
                            if (newName.getBeginToken().isValue("КОРОЛЕВ", null)) {
                            }
                            else {
                                com.pullenti.ner.ReferentToken pers = newName.kit.processReferent("PERSON", newName.getBeginToken(), null);
                                if (pers != null) 
                                    return null;
                            }
                        }
                    }
                }
                if (newName.realName != null) 
                    name = com.pullenti.ner.core.MiscHelper.getTextValue(newName.realName.getBeginToken(), newName.realName.getEndToken(), com.pullenti.ner.core.GetTextAttr.NO);
                else 
                    name = com.pullenti.ner.core.MiscHelper.getTextValue(newName.getBeginToken(), newName.getEndToken(), com.pullenti.ner.core.GetTextAttr.NO);
                if (newName.namedBy != null) 
                    name = com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(newName.namedBy, com.pullenti.ner.core.GetTextAttr.NO);
                if (newName.getBeginToken() != newName.getEndToken()) {
                    for (com.pullenti.ner.Token ttt = newName.getBeginToken().getNext(); ttt != null && ttt.getEndChar() <= newName.getEndChar(); ttt = ttt.getNext()) {
                        if (ttt.chars.isLetter()) {
                            TerrItemToken ty = TerrItemToken.tryParse(ttt, null, null);
                            if ((ty != null && ty.terminItem != null && noun != null) && (((ty.terminItem.getCanonicText().indexOf(noun.terminItem.getCanonicText()) >= 0) || (noun.terminItem.getCanonicText().indexOf(ty.terminItem.getCanonicText()) >= 0)))) {
                                name = com.pullenti.ner.core.MiscHelper.getTextValue(newName.getBeginToken(), ttt.getPrevious(), com.pullenti.ner.core.GetTextAttr.NO);
                                break;
                            }
                            CityItemToken cit = CityItemToken.tryParse(ttt, null, false, null);
                            if (cit != null && cit.typ == CityItemToken.ItemType.NOUN) {
                                typVar = cit.value.toLowerCase();
                                name = com.pullenti.ner.core.MiscHelper.getTextValue(newName.getBeginToken(), ttt.getPrevious(), com.pullenti.ner.core.GetTextAttr.NO);
                                if (ttt.getPrevious() == newName.getBeginToken() && com.pullenti.ner.core.BracketHelper.isBracket(ttt.getPrevious(), false) && (cit.getEndChar() < newName.getEndChar())) 
                                    name = com.pullenti.ner.core.MiscHelper.getTextValue(cit.getEndToken().getNext(), newName.getEndToken(), com.pullenti.ner.core.GetTextAttr.NO);
                                break;
                            }
                        }
                    }
                }
                if (newName.getBeginToken() != newName.getEndToken()) {
                    com.pullenti.ner.Token tt2 = newName.getBeginToken();
                    if (com.pullenti.ner.core.BracketHelper.isBracket(tt2, false)) 
                        tt2 = tt2.getNext();
                    if (tt2.isValue("ГОРОД", null)) {
                        java.util.ArrayList<CityItemToken> cits2 = CityItemToken.tryParseList(tt2, 3, null);
                        if (cits2 != null && cits2.size() == 2 && ((cits2.get(1).typ == CityItemToken.ItemType.CITY || cits2.get(1).typ == CityItemToken.ItemType.PROPERNAME))) {
                            com.pullenti.ner.ReferentToken rt2 = CityAttachHelper.tryDefine(cits2, null, false);
                            if (rt2 != null) {
                                if (newName.getEndChar() > rt2.getEndChar()) 
                                    rt2.setEndToken(newName.getEndToken());
                                if (noun != null && (noun.terminItem.getCanonicText().indexOf("ГОРОД") >= 0)) {
                                    if (noun.getBeginChar() < rt2.getBeginChar()) 
                                        rt2.setBeginToken(noun.getBeginToken());
                                    if (noun.getEndChar() > rt2.getEndChar()) 
                                        rt2.setEndToken(noun.getEndToken());
                                }
                                return rt2;
                            }
                        }
                    }
                }
                if (adjList.size() > 0) {
                    com.pullenti.ner.core.NounPhraseToken npt = MiscLocationHelper.tryParseNpt(adjList.get(0).getBeginToken());
                    if (npt != null && npt.getEndToken() == noun.getEndToken()) 
                        altName = (npt.getNormalCaseText(null, com.pullenti.morph.MorphNumber.UNDEFINED, com.pullenti.morph.MorphGender.UNDEFINED, false) + " " + name);
                }
            }
        }
        else {
            if ((li.size() == 1 && noun != null && noun.getEndToken().getNext() != null) && (noun.getEndToken().getNext().getReferent() instanceof com.pullenti.ner.geo.GeoReferent)) {
                com.pullenti.ner.geo.GeoReferent g = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(noun.getEndToken().getNext().getReferent(), com.pullenti.ner.geo.GeoReferent.class);
                if (noun.terminItem != null) {
                    String tyy = noun.terminItem.getCanonicText().toLowerCase();
                    boolean ooo = false;
                    if (g.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_TYPE, tyy, true) != null) 
                        ooo = true;
                    else if (tyy.endsWith("район") && g.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_TYPE, "район", true) != null) 
                        ooo = true;
                    if (ooo) 
                        return com.pullenti.ner.ReferentToken._new958(g, noun.getBeginToken(), noun.getEndToken().getNext(), noun.getBeginToken().getMorph());
                }
            }
            if ((li.size() == 1 && noun == li.get(0) && li.get(0).terminItem != null) && TerrItemToken.tryParse(li.get(0).getEndToken().getNext(), null, null) == null && TerrItemToken.tryParse(li.get(0).getBeginToken().getPrevious(), null, null) == null) {
                if (li.get(0).getMorph().getNumber() == com.pullenti.morph.MorphNumber.PLURAL) 
                    return null;
                int cou = 0;
                String str = li.get(0).terminItem.getCanonicText().toLowerCase();
                for (com.pullenti.ner.Token tt = li.get(0).getBeginToken().getPrevious(); tt != null; tt = tt.getPrevious()) {
                    if (tt.isNewlineAfter()) 
                        cou += 10;
                    else 
                        cou++;
                    if (cou > 500) 
                        break;
                    com.pullenti.ner.geo.GeoReferent g = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(tt.getReferent(), com.pullenti.ner.geo.GeoReferent.class);
                    if (g == null) 
                        continue;
                    boolean ok = true;
                    cou = 0;
                    for (tt = li.get(0).getEndToken().getNext(); tt != null; tt = tt.getNext()) {
                        if (tt.isNewlineBefore()) 
                            cou += 10;
                        else 
                            cou++;
                        if (cou > 500) 
                            break;
                        TerrItemToken tee = TerrItemToken.tryParse(tt, null, null);
                        if (tee == null) 
                            continue;
                        ok = false;
                        break;
                    }
                    if (ok) {
                        for (int ii = 0; g != null && (ii < 3); g = g.getHigher(),ii++) {
                            if (g.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_TYPE, str, true) != null) 
                                return com.pullenti.ner.ReferentToken._new958(g, li.get(0).getBeginToken(), li.get(0).getEndToken(), noun.getBeginToken().getMorph());
                        }
                    }
                    break;
                }
            }
            if (li.size() == 1 && li.get(0).terminItem != null && com.pullenti.unisharp.Utils.stringsEq(li.get(0).terminItem.getCanonicText(), "МУНИЦИПАЛЬНЫЙ ОКРУГ")) {
                com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParsePureItem(li.get(0).getEndToken().getNext(), null, null);
                if (ait != null && ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.NUMBER) {
                    number = ait;
                    name = number.value;
                }
            }
            if (name == null) 
                return null;
        }
        com.pullenti.ner.geo.GeoReferent ter = null;
        if (exObj != null && (exObj.tag instanceof com.pullenti.ner.geo.GeoReferent)) 
            ter = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(exObj.tag, com.pullenti.ner.geo.GeoReferent.class);
        else {
            ter = new com.pullenti.ner.geo.GeoReferent();
            if (exObj != null) {
                com.pullenti.ner.geo.GeoReferent _geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(exObj.ontoItem.referent, com.pullenti.ner.geo.GeoReferent.class);
                if (_geo != null && !_geo.isCity() && (((_geo.isState() || noun == null || (noun.terminItem.getCanonicText().length() < 3)) || _geo.containsType(noun.terminItem.getCanonicText())))) {
                    boolean psevdo = false;
                    if (noun == null && exObj.getBeginToken() == exObj.getEndToken()) {
                        if (exObj.getBeginToken().isValue("ПРИМОРСКИЙ", null)) {
                            int cou = 0;
                            for (com.pullenti.ner.Token ttt = exObj.getEndToken().getNext(); ttt != null && (cou < 5); ttt = ttt.getNext(),cou++) {
                                if (ttt.isValue("АРХАНГЕЛЬСКИЙ", null)) {
                                    psevdo = true;
                                    break;
                                }
                            }
                        }
                    }
                    if (psevdo) {
                        ter.addName(com.pullenti.ner.core.MiscHelper.getTextValueOfMetaToken(exObj, com.pullenti.ner.core.GetTextAttr.NO));
                        ter.addTyp("район");
                    }
                    else 
                        ter.mergeSlots2(_geo, li.get(0).kit.baseLanguage);
                }
                else 
                    ter.addName(name);
                if (noun == null && exObj.canBeCity) 
                    ter.addTypCity(li.get(0).kit.baseLanguage, true);
                else {
                }
            }
            else if (name != null) {
                ter.addName(name);
                if (altName != null) 
                    ter.addName(altName);
            }
            if (typVar != null) {
                if (noun == null) 
                    ter.setProbable(true);
                ter.addTyp(typVar);
            }
            if (noun != null) {
                if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "АО")) 
                    ter.addTyp((li.get(0).kit.baseLanguage.isUa() ? "АВТОНОМНИЙ ОКРУГ" : "АВТОНОМНЫЙ ОКРУГ"));
                else if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "МУНИЦИПАЛЬНОЕ СОБРАНИЕ") || com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "МУНІЦИПАЛЬНЕ ЗБОРИ")) 
                    ter.addTyp((li.get(0).kit.baseLanguage.isUa() ? "МУНІЦИПАЛЬНЕ УТВОРЕННЯ" : "МУНИЦИПАЛЬНОЕ ОБРАЗОВАНИЕ"));
                else if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.acronym, "МО") && addNoun != null) 
                    ter.addTyp(addNoun.terminItem.getCanonicText());
                else {
                    if (com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "СОЮЗ") && exObj != null && exObj.getEndChar() > noun.getEndChar()) 
                        return com.pullenti.ner.ReferentToken._new958(ter, exObj.getBeginToken(), exObj.getEndToken(), exObj.getMorph());
                    ter.addTyp(noun.terminItem.getCanonicText());
                    if (noun.terminItem.isRegion && ter.isState()) 
                        ter.addTypReg(li.get(0).kit.baseLanguage);
                }
                if (noun.terminItem2 != null) 
                    ter.addTyp(noun.terminItem2.getCanonicText());
            }
            if (ter.isState() && ter.isRegion()) {
                for (TerrItemToken a : adjList) {
                    if (a.terminItem.isRegion) {
                        ter.addTypReg(li.get(0).kit.baseLanguage);
                        break;
                    }
                }
            }
            if (ter.isState()) {
                if (fullName != null) 
                    ter.addName(fullName);
                if (ter.getAlpha2() == null && ter.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_NAME, "АБХАЗИЯ", true) != null) {
                    com.pullenti.ner.Slot s = ter.findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_TYPE, "государство", true);
                    if (s != null) {
                        ter.getSlots().remove(s);
                        ter.addTyp("регион");
                    }
                }
            }
        }
        if (noun == null) {
            while (k > 1 && adjList.contains(li.get(k - 1))) {
                k--;
            }
        }
        com.pullenti.ner.ReferentToken res = new com.pullenti.ner.ReferentToken(ter, li.get(0).getBeginToken(), (endTok != null ? endTok : li.get(k - 1).getEndToken()), null);
        if ((k == 2 && li.size() == 3 && noun == li.get(0)) && li.get(2).terminItem != null) {
            if (li.get(2).terminItem == noun.terminItem || ((com.pullenti.unisharp.Utils.stringsEq(li.get(2).terminItem.getCanonicText(), "АВТОНОМНЫЙ ОКРУГ") && com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "АО")))) {
                res.setEndToken(li.get(2).getEndToken());
                k = 3;
            }
        }
        if (noun != null && noun.getMorph()._getClass().isNoun()) 
            res.setMorph(noun.getMorph());
        else {
            res.setMorph(new com.pullenti.ner.MorphCollection(null));
            for (int ii = 0; ii < k; ii++) {
                for (com.pullenti.morph.MorphBaseInfo v : li.get(ii).getMorph().getItems()) {
                    com.pullenti.morph.MorphBaseInfo bi = new com.pullenti.morph.MorphBaseInfo();
                    bi.copyFrom(v);
                    if (noun != null) {
                        if (bi._getClass().isAdjective()) 
                            bi._setClass(com.pullenti.morph.MorphClass.NOUN);
                    }
                    res.getMorph().addItem(bi);
                }
            }
        }
        if (li.get(0).terminItem != null && li.get(0).terminItem.isSpecificPrefix) 
            res.setBeginToken(li.get(0).getEndToken().getNext());
        if (addNoun != null && addNoun.getEndChar() > res.getEndChar()) 
            res.setEndToken(addNoun.getEndToken());
        if (number != null && number.getEndChar() > res.getEndChar()) 
            res.setEndToken(number.getEndToken());
        if ((res.getBeginToken().getPrevious() instanceof com.pullenti.ner.TextToken) && (res.getWhitespacesBeforeCount() < 2)) {
            com.pullenti.ner.TextToken tt = (com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(res.getBeginToken().getPrevious(), com.pullenti.ner.TextToken.class);
            if (com.pullenti.unisharp.Utils.stringsEq(tt.term, "АР")) {
                for (String ty : ter.getTyps()) {
                    if ((ty.indexOf("республика") >= 0) || (ty.indexOf("республіка") >= 0)) {
                        res.setBeginToken(tt);
                        break;
                    }
                }
            }
        }
        if (li.size() == 3 && li.get(1) == noun) {
            if (li.get(2).terminItem == noun.terminItem) 
                res.setEndToken(li.get(2).getEndToken());
        }
        if (noun != null && (noun.terminItem.getCanonicText().indexOf("МЕЖСЕЛЕН") >= 0)) {
            com.pullenti.ner.Token tt = res.getEndToken().getNext();
            if (tt != null && tt.isComma()) 
                tt = tt.getNext();
            if ((tt != null && tt.isValue("НАХОДИТЬСЯ", null) && tt.getNext() != null) && tt.getNext().isValue("ВНЕ", null)) {
                for (tt = tt.getNext().getNext(); tt != null; tt = tt.getNext()) {
                    com.pullenti.morph.MorphClass mc = tt.getMorphClassInDictionary();
                    if (!mc.isNoun()) 
                        continue;
                    if (tt.isValue("ГРАНИЦА", null) || tt.isValue("ПРЕДЕЛ", null) || tt.isValue("ПОСЕЛЕНИЕ", null)) 
                        res.setEndToken(tt);
                    else if (!mc.isAdjective()) 
                        break;
                }
            }
        }
        if (noun != null && com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "СЕЛЬСКИЙ ОКРУГ")) {
            com.pullenti.ner.Token t0 = res.getBeginToken().getPrevious();
            if (t0 != null && ((t0.isValue("ПОСЕЛОК", null) || t0.isValue("ПОСЕЛЕНИЕ", null)))) {
                if (t0.getPrevious() != null && t0.getPrevious().isValue("СЕЛЬСКИЙ", null)) 
                    res.setBeginToken(t0.getPrevious());
            }
        }
        if (noun != null && com.pullenti.unisharp.Utils.stringsEq(noun.terminItem.getCanonicText(), "АВТОНОМНЫЙ ОКРУГ")) {
            com.pullenti.ner.Token t0 = res.getBeginToken().getPrevious();
            if (t0 != null && t0.isCharOf(".-")) 
                t0 = t0.getPrevious();
            if (t0 != null && t0.isValue("АО", null)) 
                res.setBeginToken(t0);
        }
        if (noun != null && noun.terminItem.getCanonicText().endsWith(" ОКРУГ") && newName != null) {
            com.pullenti.ner.Token t0 = res.getBeginToken().getPrevious();
            if (t0 != null && t0.isComma()) 
                t0 = t0.getPrevious();
            if (t0 != null && t0.getPrevious() != null) {
                boolean ok = false;
                if (t0.getPrevious().isComma()) 
                    ok = true;
                if (ok) {
                    TerrItemToken nnn = TerrItemToken.tryParse(t0, null, null);
                    if (nnn != null && com.pullenti.unisharp.Utils.stringsEq(nnn.toString(), newName.toString())) {
                        res.setBeginToken(t0);
                        ter.addTyp("город");
                    }
                }
            }
        }
        if (res.getEndToken().getNext() != null && res.getEndToken().getNext().isHiphen() && res.getEndToken().getNext().getNext() != null) {
            com.pullenti.ner.Token tt = res.getEndToken().getNext().getNext();
            if (com.pullenti.unisharp.Utils.stringsEq(ter.toString(), "область Кемеровская")) {
                if (tt.isValue("КУЗБАСС", null)) 
                    res.setEndToken(tt);
            }
            else {
                TerrItemToken next = TerrItemToken.tryParse(tt, null, null);
                if ((next != null && next.ontoItem != null && exObj != null) && next.ontoItem == exObj.ontoItem) 
                    res.setEndToken(tt);
            }
            java.util.ArrayList<TerrItemToken> nexts = TerrItemToken.tryParseList(tt.getNext(), 3, null);
            if (nexts != null && nexts.size() == 1 && nexts.get(0).terminItem != null) 
                res.setEndToken(nexts.get(0).getEndToken());
        }
        if (res.getWhitespacesAfterCount() < 3) {
            com.pullenti.ner.Token tt = res.getEndToken().getNext();
            if (tt != null && tt.isValue("МУНИЦИПАЛЬНЫЙ", null)) {
                if (com.pullenti.ner.core.NounPhraseHelper.tryParse(tt, com.pullenti.ner.core.NounPhraseParseAttr.NO, 0, null) == null) 
                    res.setEndToken(tt);
            }
            if ((tt instanceof com.pullenti.ner.TextToken) && com.pullenti.unisharp.Utils.stringsEq(((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(tt, com.pullenti.ner.TextToken.class)).term, "МО")) {
                if (com.pullenti.unisharp.Utils.stringsEq(ter.toString(), "область Московская")) 
                    res.setEndToken(tt);
            }
            if (((tt instanceof com.pullenti.ner.NumberToken) && MiscLocationHelper.isUserParamAddress(tt) && tt.getNext() != null) && tt.getNext().isComma()) 
                res.setEndToken(tt);
            tt = res.getEndToken().getNext();
            if (tt != null && tt.isChar('(')) {
                com.pullenti.ner.core.BracketSequenceToken br = com.pullenti.ner.core.BracketHelper.tryParse(tt, com.pullenti.ner.core.BracketParseAttr.NO, 100);
                if (br != null && (br.getLengthChar() < 100)) {
                    for (com.pullenti.ner.Token ttt = tt; ttt != null && (ttt.getEndChar() < br.getEndChar()); ttt = ttt.getNext()) {
                        if (ttt.isValue("СОСТАВ", null)) {
                            res.setEndToken(br.getEndToken());
                            break;
                        }
                        else if (ttt.getReferent() != null && com.pullenti.unisharp.Utils.stringsEq(ttt.getReferent().getTypeName(), "DATERANGE")) {
                            res.setEndToken(br.getEndToken());
                            break;
                        }
                    }
                }
            }
        }
        return res;
    }

    private static boolean _canBeGeoAfter(com.pullenti.ner.Token tt) {
        while (tt != null && ((tt.isComma() || com.pullenti.ner.core.BracketHelper.isBracket(tt, true)))) {
            tt = tt.getNext();
        }
        if (tt == null) 
            return false;
        if (tt.getReferent() instanceof com.pullenti.ner.geo.GeoReferent) 
            return true;
        java.util.ArrayList<TerrItemToken> tli = TerrItemToken.tryParseList(tt, 2, null);
        if (tli != null && tli.size() > 1) {
            if (tli.get(0).terminItem == null && tli.get(1).terminItem != null) 
                return true;
            else if (tli.get(0).terminItem != null && tli.get(1).terminItem == null) 
                return true;
        }
        if (CityAttachHelper.checkCityAfter(tt)) 
            return true;
        if (tryAttachStateUSATerritory(tt) != null) 
            return true;
        return false;
    }

    public static com.pullenti.ner.ReferentToken tryAttachStateUSATerritory(com.pullenti.ner.Token t) {
        if (t == null || !t.chars.isLatinLetter()) 
            return null;
        com.pullenti.ner.core.TerminToken tok = TerrItemToken.m_GeoAbbrs.tryParse(t, com.pullenti.ner.core.TerminParseAttr.NO);
        if (tok == null) 
            return null;
        com.pullenti.ner.geo.GeoReferent g = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(tok.termin.tag, com.pullenti.ner.geo.GeoReferent.class);
        if (g == null) 
            return null;
        if (tok.getEndToken().getNext() != null && tok.getEndToken().getNext().isChar('.')) 
            tok.setEndToken(tok.getEndToken().getNext());
        com.pullenti.ner.Referent gg = g.clone();
        gg.getOccurrence().clear();
        return new com.pullenti.ner.ReferentToken(gg, tok.getBeginToken(), tok.getEndToken(), null);
    }
    public TerrDefineHelper() {
    }
}
