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

public class AddressDefineHelper {

    public static com.pullenti.ner.Token tryDefine(java.util.ArrayList<AddressItemToken> li, com.pullenti.ner.Token t, com.pullenti.ner.core.AnalyzerData ad, boolean ignoreStreet) {
        if (li == null || li.size() == 0) 
            return null;
        boolean empty = true;
        boolean notEmpty = false;
        boolean badOrg = false;
        boolean hasGeo = false;
        boolean hasStreet = false;
        for (int ii = 0; ii < li.size(); ii++) {
            AddressItemToken v = li.get(ii);
            if (v.getTyp() == AddressItemType.SPACE && (li.size() < 3) && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(v)) 
                return null;
            if (v.getTyp() == AddressItemType.DETAIL) 
                continue;
            if ((v.getTyp() == AddressItemType.SPACE && ii == 0 && ((ii + 1) < li.size())) && ((li.get(ii + 1).getTyp() == AddressItemType.CITY || li.get(ii + 1).getTyp() == AddressItemType.COUNTRY))) 
                return null;
            if ((v.getTyp() == AddressItemType.STREET && v.refTokenIsGsk && li.size() == 2) && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(v)) {
                if ((v.toString().toUpperCase().indexOf("АЭРОПОРТ") >= 0)) {
                    if (ii == 0 && li.get(1).getTyp() == AddressItemType.CITY) 
                        return null;
                    if (ii == 1 && li.get(0).getTyp() == AddressItemType.CITY) 
                        return null;
                }
            }
            if (((v.getTyp() == AddressItemType.REGION && !v.isNewlineAfter() && ((ii + 2) < li.size())) && li.get(ii + 1).getTyp() == AddressItemType.STREET && !li.get(ii + 1).isNewlineAfter()) && li.get(ii + 2).getTyp() == AddressItemType.CITY) {
                AddressItemToken vv = li.get(ii + 1);
                com.pullenti.unisharp.Utils.putArrayValue(li, ii + 1, li.get(ii + 2));
                com.pullenti.unisharp.Utils.putArrayValue(li, ii + 2, vv);
            }
            else if ((v.getTyp() == AddressItemType.CITY && ((ii + 2) < li.size()) && li.get(ii + 1).getTyp() == AddressItemType.STREET) && li.get(ii + 2).getTyp() == AddressItemType.CITY) {
                if (com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(v.referent, com.pullenti.ner.geo.GeoReferent.class), (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(ii + 2).referent, com.pullenti.ner.geo.GeoReferent.class), null, null)) {
                    ((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(ii + 2).referent, com.pullenti.ner.geo.GeoReferent.class)).setHigher((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(v.referent, com.pullenti.ner.geo.GeoReferent.class));
                    AddressItemToken vv = li.get(ii + 1);
                    com.pullenti.unisharp.Utils.putArrayValue(li, ii + 1, li.get(ii + 2));
                    com.pullenti.unisharp.Utils.putArrayValue(li, ii + 2, vv);
                }
            }
            if (v.detailType == com.pullenti.ner.address.AddressDetailType.ORG && (li.size() < 4) && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(v)) 
                return null;
            if (v.getTyp() == AddressItemType.BUILDING && (ii < 2) && ((ii + 1) < li.size())) {
                if (li.get(ii).isDoubt || li.get(ii).getTyp() == AddressItemType.BUILDING) {
                    boolean ok = false;
                    if (ii > 0 && li.get(ii - 1).getTyp() == AddressItemType.CITY) 
                        ok = true;
                    for (int jj = ii + 1; jj < li.size(); jj++) {
                        if (li.get(jj).getTyp() != AddressItemType.STREET) 
                            ok = false;
                    }
                    if (!ok) 
                        return null;
                }
            }
            if ((v.buildingType == com.pullenti.ner.address.AddressBuildingType.LITER && v.getLengthChar() == 1 && ((ii + 1) < li.size())) && li.get(ii + 1).getTyp() == AddressItemType.STREET) {
                li.remove(ii);
                ii--;
                continue;
            }
            if (v.getTyp() == AddressItemType.NUMBER || v.getTyp() == AddressItemType.ZIP || v.getTyp() == AddressItemType.DETAIL) {
            }
            else if (v.getTyp() == AddressItemType.HOUSE && ((v.isDoubt || v.houseType == com.pullenti.ner.address.AddressHouseType.SPECIAL))) {
            }
            else if (v.getTyp() != AddressItemType.STREET) {
                empty = false;
                if (v.getTyp() != AddressItemType.CITY && v.getTyp() != AddressItemType.COUNTRY && v.getTyp() != AddressItemType.REGION) 
                    notEmpty = true;
                if (v.getTyp() == AddressItemType.CITY || v.getTyp() == AddressItemType.REGION) 
                    hasGeo = true;
            }
            else if ((v.referent instanceof com.pullenti.ner.address.StreetReferent) && com.pullenti.unisharp.Utils.stringsNe(v.referent.toString(), "улица")) {
                hasStreet = true;
                if (com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(v)) {
                    empty = false;
                    notEmpty = true;
                    continue;
                }
                com.pullenti.ner.address.StreetReferent s = (com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(v.referent, com.pullenti.ner.address.StreetReferent.class);
                if (s.getKind() == com.pullenti.ner.address.StreetKind.RAILWAY && s.getNumbers() == null) {
                }
                else if (s.getKind() == com.pullenti.ner.address.StreetKind.ORG || v.refToken != null) {
                    if (v.isDoubt && v.refToken != null && !v.refTokenIsGsk) 
                        badOrg = true;
                    if (badOrg) {
                        if (v == li.get(0)) 
                            return null;
                        else if (li.get(0).getTyp() == AddressItemType.PREFIX && v == li.get(1)) 
                            return null;
                    }
                }
                else if (s.getKind() == com.pullenti.ner.address.StreetKind.AREA) 
                    hasStreet = true;
                else {
                    if ((v.isDoubt && v == li.get(0) && !v.isStreetRoad()) && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(v)) {
                        boolean ok = false;
                        if (li.size() > 1 && li.get(1).getTyp() == AddressItemType.CITY) 
                            ok = true;
                        else if (v.referent != null && ad != null) {
                            for (com.pullenti.ner.Referent r : ad.getReferents()) {
                                if (v.referent.canBeEquals(r, com.pullenti.ner.core.ReferentsEqualType.WITHINONETEXT)) {
                                    ok = true;
                                    break;
                                }
                            }
                        }
                        if (!ok) 
                            return null;
                    }
                    hasStreet = true;
                    empty = false;
                    notEmpty = true;
                }
            }
        }
        if (ignoreStreet) {
        }
        else {
            if (empty) 
                return null;
            if (!notEmpty) {
                for (AddressItemToken v : li) {
                    if (v != li.get(0) && v.isNewlineBefore()) 
                        return null;
                }
                if (badOrg && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) 
                    return null;
                if (li.get(0).getTyp() == AddressItemType.STREET && ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(li.get(0).referent, com.pullenti.ner.address.StreetReferent.class)).getKind() == com.pullenti.ner.address.StreetKind.ORG) 
                    return null;
                if (li.size() == 1 && li.get(0).getTyp() != AddressItemType.STREET) {
                    if (li.get(0).detailType != com.pullenti.ner.address.AddressDetailType.UNDEFINED && com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
                    }
                    else if (li.get(0).detailMeters > 0) {
                    }
                    else 
                        return null;
                }
                if (li.size() == 2) {
                    if (li.get(0).getTyp() == AddressItemType.DETAIL && li.get(1).getTyp() != AddressItemType.CITY) 
                        return null;
                    if (li.get(1).getTyp() == AddressItemType.DETAIL && li.get(0).getTyp() != AddressItemType.CITY) 
                        return null;
                }
            }
            if (!hasGeo && !hasStreet) 
                return null;
        }
        if ((li.size() > 3 && li.get(0).getTyp() == AddressItemType.CITY && li.get(1).getTyp() == AddressItemType.STREET) && li.get(2).getTyp() == AddressItemType.CITY && li.get(3).getTyp() == AddressItemType.STREET) {
            if (((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(li.get(1).referent, com.pullenti.ner.address.StreetReferent.class)).getKind() == com.pullenti.ner.address.StreetKind.RAILWAY || ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(li.get(1).referent, com.pullenti.ner.address.StreetReferent.class)).getKind() == com.pullenti.ner.address.StreetKind.ROAD) {
                com.pullenti.ner.geo.GeoReferent geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(2).referent, com.pullenti.ner.geo.GeoReferent.class);
                if (geo != null && geo.getHigher() == null && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(0).referent, com.pullenti.ner.geo.GeoReferent.class), geo, null, null)) {
                    geo.setHigher((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(0).referent, com.pullenti.ner.geo.GeoReferent.class));
                    com.pullenti.unisharp.Utils.putArrayValue(li, 2, li.get(2).clone());
                    li.get(2).setBeginToken(li.get(0).getBeginToken());
                    for(int jjj = 0 + 2 - 1, mmm = 0; jjj >= mmm; jjj--) li.remove(jjj);
                }
            }
        }
        if (li.size() >= 2 && li.get(0).getTyp() == AddressItemType.BLOCK && li.get(1).getTyp() == AddressItemType.STREET) 
            return null;
        if (li.size() >= 2 && li.get(0).getTyp() == AddressItemType.CITY && li.get(1).getTyp() == AddressItemType.BUILDING) {
            if (li.get(1).getBeginToken().isValue("СТР", null) && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(1))) 
                return null;
        }
        if (li.get(0).getTyp() == AddressItemType.STREET && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
            if (li.get(0).refToken != null) {
                if (!li.get(0).refTokenIsGsk || ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(li.get(0).referent, com.pullenti.ner.address.StreetReferent.class)).getKind() == com.pullenti.ner.address.StreetKind.AREA) 
                    return null;
            }
        }
        if (li.get(0).getTyp() == AddressItemType.STREET && com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
            boolean ok = true;
            for (AddressItemToken it : li) {
                if ((it.getTyp() == AddressItemType.ZIP || it.getTyp() == AddressItemType.REGION || it.getTyp() == AddressItemType.CITY) || it.getTyp() == AddressItemType.COUNTRY) 
                    ok = false;
            }
            if (ok) {
                com.pullenti.ner.Token tt = li.get(li.size() - 1).getEndToken().getNext();
                while (tt != null) {
                    if (tt.isComma()) 
                        tt = tt.getNext();
                    else 
                        break;
                }
                com.pullenti.ner.geo.internal.TerrItemToken ter = com.pullenti.ner.geo.internal.TerrItemToken.tryParse(tt, null, null);
                if (ter != null && ter.terminItem == null && ter.ontoItem == null) {
                    com.pullenti.ner.Token tt2 = ter.getEndToken().getNext();
                    while (tt2 != null) {
                        if (tt2.isComma()) 
                            tt2 = tt2.getNext();
                        else 
                            break;
                    }
                    if (tt2 != null && (tt2.getReferent() instanceof com.pullenti.ner.geo.GeoReferent) && ((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(tt2.getReferent(), com.pullenti.ner.geo.GeoReferent.class)).isCity()) {
                        java.util.ArrayList<AddressItemToken> li2 = AddressItemToken.tryParseList(tt2, 20);
                        if (li2 != null) 
                            com.pullenti.unisharp.Utils.addToArrayList(li, li2);
                    }
                }
            }
        }
        if (li.size() >= 6) {
            for (int ii = 2; ii < (li.size() - 1); ii++) {
                if (li.get(ii).getBeginToken().getPrevious().isChar(';')) {
                    boolean hasCity = false;
                    boolean hasHouse = com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(ii));
                    for (int jj = 0; jj < ii; jj++) {
                        AddressItemToken v = li.get(jj);
                        if (v.getTyp() == AddressItemType.REGION || v.getTyp() == AddressItemType.CITY) 
                            hasCity = true;
                        else if ((v.getTyp() == AddressItemType.HOUSE || v.getTyp() == AddressItemType.STREET || v.getTyp() == AddressItemType.BUILDING) || v.getTyp() == AddressItemType.CORPUS) 
                            hasHouse = true;
                    }
                    if (!hasCity || !hasHouse) 
                        continue;
                    hasCity = false;
                    hasHouse = com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(ii));
                    for (int jj = ii; jj < li.size(); jj++) {
                        AddressItemToken v = li.get(jj);
                        if (v.getTyp() == AddressItemType.REGION || v.getTyp() == AddressItemType.CITY) 
                            hasCity = true;
                        else if ((v.getTyp() == AddressItemType.HOUSE || v.getTyp() == AddressItemType.STREET || v.getTyp() == AddressItemType.BUILDING) || v.getTyp() == AddressItemType.CORPUS) 
                            hasHouse = true;
                    }
                    if (!hasCity || !hasHouse) 
                        continue;
                    for(int jjj = ii + li.size() - ii - 1, mmm = ii; jjj >= mmm; jjj--) li.remove(jjj);
                    break;
                }
            }
        }
        com.pullenti.ner.address.AddressReferent addr = new com.pullenti.ner.address.AddressReferent();
        java.util.ArrayList<AddressItemToken> streets = new java.util.ArrayList<AddressItemToken>();
        int i;
        int j;
        AddressItemToken metro = null;
        java.util.ArrayList<AddressItemToken> details = new java.util.ArrayList<AddressItemToken>();
        AddressItemToken district = null;
        java.util.ArrayList<com.pullenti.ner.geo.GeoReferent> geos = null;
        boolean err = false;
        boolean cross = false;
        boolean hasGenplan = false;
        for (i = 0; i < li.size(); i++) {
            if ((li.get(i).getTyp() == AddressItemType.DETAIL && li.get(i).detailType == com.pullenti.ner.address.AddressDetailType.CROSS && ((i + 2) < li.size())) && li.get(i + 1).getTyp() == AddressItemType.STREET && li.get(i + 2).getTyp() == AddressItemType.STREET) {
                cross = true;
                streets.add(li.get(i + 1));
                streets.add(li.get(i + 2));
                li.get(i + 1).setEndToken(li.get(i + 2).getEndToken());
                li.get(i).tag = addr;
                li.get(i + 1).tag = addr;
                li.remove(i + 2);
                break;
            }
            else if (li.get(i).getTyp() == AddressItemType.STREET) {
                if (((li.get(i).refToken != null && !li.get(i).refTokenIsGsk)) && streets.size() == 0) {
                    if (i > 0 && li.get(i).isNewlineBefore()) {
                        err = true;
                        for(int jjj = i + li.size() - i - 1, mmm = i; jjj >= mmm; jjj--) li.remove(jjj);
                        break;
                    }
                    else if ((i + 1) == li.size()) 
                        err = details.size() == 0;
                    else if (((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.NUMBER) 
                        err = true;
                    if (err && geos != null) {
                        for (int ii = i - 1; ii >= 0; ii--) {
                            if (li.get(ii).getTyp() == AddressItemType.ZIP || li.get(ii).getTyp() == AddressItemType.PREFIX) 
                                err = false;
                        }
                    }
                    if (err && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(i))) 
                        break;
                }
                if (li.get(i).detailType != com.pullenti.ner.address.AddressDetailType.UNDEFINED) 
                    details.add(li.get(i));
                li.get(i).tag = addr;
                streets.add(li.get(i));
                if (li.get(i).referent2 != null) 
                    cross = true;
                if (((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.STREET) {
                }
                else if ((((i + 2) < li.size()) && li.get(i + 2).getTyp() == AddressItemType.STREET && li.get(i + 1).isHouse()) && (i + 3) == li.size() && !li.get(i + 2).refTokenIsGsk) 
                    i++;
                else if (((((i + 4) < li.size()) && ((li.get(i + 1).getTyp() == AddressItemType.HOUSE || li.get(i + 1).getTyp() == AddressItemType.NUMBER)) && li.get(i + 2).getTyp() == AddressItemType.DETAIL) && li.get(i + 2).detailType == com.pullenti.ner.address.AddressDetailType.CROSS && li.get(i + 3).getTyp() == AddressItemType.STREET) && ((li.get(i + 4).getTyp() == AddressItemType.HOUSE || li.get(i + 4).getTyp() == AddressItemType.NUMBER))) {
                    cross = true;
                    li.get(i + 2).tag = addr;
                    streets.add(li.get(i + 3));
                    li.get(i + 3).tag = addr;
                    com.pullenti.unisharp.Utils.putArrayValue(li, i + 4, li.get(i + 4).clone());
                    li.get(i + 4).value = (li.get(i + 1).value + "/" + li.get(i + 4).value);
                    li.remove(i + 1);
                    i--;
                    break;
                }
                else 
                    break;
            }
            else if (li.get(i).getTyp() == AddressItemType.CITY || li.get(i).getTyp() == AddressItemType.REGION || li.get(i).getTyp() == AddressItemType.COUNTRY) {
                if (geos == null) 
                    geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>();
                com.pullenti.ner.geo.GeoReferent geo = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class);
                if (li.get(i).detailType != com.pullenti.ner.address.AddressDetailType.UNDEFINED) {
                    details.add(li.get(i));
                    if (geos.size() == 0) {
                        if (geo.getHigher() != null) {
                            if (((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.STREET && (li.get(i + 1).referent instanceof com.pullenti.ner.address.StreetReferent)) {
                                com.pullenti.ner.address.StreetReferent sr = (com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(li.get(i + 1).referent, com.pullenti.ner.address.StreetReferent.class);
                                if (sr.getKind() == com.pullenti.ner.address.StreetKind.UNDEFINED) 
                                    geos.add(geo);
                                else 
                                    geos.add(geo.getHigher());
                            }
                            else 
                                geos.add(geo.getHigher());
                        }
                        else 
                            geos.add(geo);
                    }
                }
                else if ((geos.size() > 0 && geo.getHigher() == geos.get(geos.size() - 1) && li.get(i).getTyp() == AddressItemType.REGION) && li.get(i - 1).getTyp() == AddressItemType.CITY) 
                    district = li.get(i);
                else 
                    geos.add(0, geo);
                li.get(i).tag = addr;
            }
            else if (li.get(i).getTyp() == AddressItemType.DETAIL) {
                details.add(li.get(i));
                li.get(i).tag = addr;
            }
            else if (li.get(i).getTyp() == AddressItemType.GENPLAN) 
                hasGenplan = true;
        }
        if ((i >= li.size() && metro == null && details.size() == 0) && !cross && !ignoreStreet) {
            for (i = 0; i < li.size(); i++) {
                boolean cit = false;
                if (li.get(i).getTyp() == AddressItemType.CITY) 
                    cit = true;
                else if (li.get(i).getTyp() == AddressItemType.REGION) {
                    for (com.pullenti.ner.Slot s : li.get(i).referent.getSlots()) {
                        if (com.pullenti.unisharp.Utils.stringsEq(s.getTypeName(), com.pullenti.ner.geo.GeoReferent.ATTR_TYPE)) {
                            String ss = (String)com.pullenti.unisharp.Utils.cast(s.getValue(), String.class);
                            if ((ss.indexOf("посел") >= 0) || (ss.indexOf("сельск") >= 0) || (ss.indexOf("почтовое отделение") >= 0)) 
                                cit = true;
                        }
                    }
                }
                if (cit) {
                    if (((i + 1) < li.size()) && (((((((li.get(i + 1).getTyp() == AddressItemType.HOUSE || li.get(i + 1).getTyp() == AddressItemType.BLOCK || li.get(i + 1).getTyp() == AddressItemType.SPACE) || li.get(i + 1).getTyp() == AddressItemType.PLOT || li.get(i + 1).getTyp() == AddressItemType.FIELD) || li.get(i + 1).getTyp() == AddressItemType.BUILDING || li.get(i + 1).getTyp() == AddressItemType.CORPUS) || li.get(i + 1).getTyp() == AddressItemType.POSTOFFICEBOX || li.get(i + 1).getTyp() == AddressItemType.DELIVERYAREA) || li.get(i + 1).getTyp() == AddressItemType.PART || li.get(i + 1).getTyp() == AddressItemType.CSP) || li.get(i + 1).getTyp() == AddressItemType.GENPLAN))) 
                        break;
                    if (((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.NUMBER) {
                        if (li.get(i).getEndToken().getNext().isComma()) {
                            if ((li.get(i).referent instanceof com.pullenti.ner.geo.GeoReferent) && !((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class)).isBigCity() && ((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class)).isCity()) {
                                li.get(i + 1).setTyp(AddressItemType.HOUSE);
                                li.get(i + 1).isDoubt = true;
                                break;
                            }
                        }
                    }
                    if (li.get(0).getTyp() == AddressItemType.ZIP || li.get(0).getTyp() == AddressItemType.PREFIX) 
                        break;
                    if (com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) 
                        break;
                    continue;
                }
                if (li.get(i).getTyp() == AddressItemType.REGION) {
                    if ((li.get(i).referent instanceof com.pullenti.ner.geo.GeoReferent) && ((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class)).getHigher() != null && ((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class)).getHigher().isCity()) {
                        if (((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.HOUSE) 
                            break;
                    }
                }
            }
            if (i >= li.size()) 
                return null;
        }
        if (err && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) 
            return null;
        int i0 = i;
        if (i > 0 && li.get(i - 1).getTyp() == AddressItemType.HOUSE && li.get(i - 1).isDigit()) {
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_HOUSE, li.get(i - 1).value, false, 0).setTag(li.get(i - 1));
            if (li.get(i - 1).houseType != com.pullenti.ner.address.AddressHouseType.UNDEFINED) 
                addr.setHouseType(li.get(i - 1).houseType);
            li.get(i - 1).tag = addr;
        }
        else if ((i > 0 && li.get(i - 1).getTyp() == AddressItemType.KILOMETER && li.get(i - 1).isDigit()) && (i < li.size()) && li.get(i).isStreetRoad()) {
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_KILOMETER, li.get(i - 1).value, false, 0).setTag(li.get(i - 1));
            li.get(i - 1).tag = addr;
        }
        else {
            if (i >= li.size()) 
                i = -1;
            for (i = 0; i < li.size(); i++) {
                if (li.get(i).tag != null) 
                    continue;
                if (li.get(i).getTyp() == AddressItemType.CITY || li.get(i).getTyp() == AddressItemType.REGION || li.get(i).getTyp() == AddressItemType.COUNTRY) {
                    if (geos == null) 
                        geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>();
                    if (li.get(i).isNewlineBefore()) {
                        if (geos.size() > 0) {
                            if ((i > 0 && li.get(i - 1).getTyp() != AddressItemType.CITY && li.get(i - 1).getTyp() != AddressItemType.REGION) && li.get(i - 1).getTyp() != AddressItemType.ZIP && li.get(i - 1).getTyp() != AddressItemType.PREFIX) 
                                break;
                        }
                        if (((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.STREET && i > i0) 
                            break;
                    }
                    if (li.get(i).detailType != com.pullenti.ner.address.AddressDetailType.UNDEFINED) {
                        details.add(li.get(i));
                        li.get(i).tag = addr;
                        if (geos.size() > 0) 
                            continue;
                    }
                    if (geos.size() > 0) {
                        if (((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class)).getHigher() == geos.get(0)) 
                            geos.remove(0);
                    }
                    int ii;
                    for (ii = 0; ii < geos.size(); ii++) {
                        if (geos.get(ii).isCity()) 
                            break;
                    }
                    if (ii >= geos.size()) 
                        geos.add((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class));
                    else if (i > 0 && li.get(i).isNewlineBefore() && i > i0) {
                        int jj;
                        for (jj = 0; jj < i; jj++) {
                            if ((li.get(jj).getTyp() != AddressItemType.PREFIX && li.get(jj).getTyp() != AddressItemType.ZIP && li.get(jj).getTyp() != AddressItemType.REGION) && li.get(jj).getTyp() != AddressItemType.COUNTRY && li.get(jj).getTyp() != AddressItemType.CITY) 
                                break;
                        }
                        if (jj < i) 
                            break;
                    }
                    li.get(i).tag = addr;
                }
                else if (li.get(i).getTyp() == AddressItemType.STREET) {
                    if (streets.size() > 0) {
                        if (li.get(i).isNewlineBefore()) 
                            break;
                        if (com.pullenti.ner.core.MiscHelper.canBeStartOfSentence(li.get(i).getBeginToken()) && !li.get(i).getBeginToken().isChar('(')) 
                            break;
                    }
                    if (i == (li.size() - 1)) {
                    }
                    else if (li.get(i).refToken == null && i > 0 && li.get(i - 1).getTyp() != AddressItemType.STREET) {
                        if (li.get(i - 1).getTyp() == AddressItemType.HOUSE && li.get(i - 1).houseType == com.pullenti.ner.address.AddressHouseType.SPECIAL) {
                        }
                        else if (com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(i))) {
                        }
                        else 
                            break;
                    }
                    if (streets.size() > 0 && (li.get(i).referent instanceof com.pullenti.ner.address.StreetReferent)) {
                        com.pullenti.ner.address.StreetReferent ss = (com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.address.StreetReferent.class);
                        if (ss.getKind() == com.pullenti.ner.address.StreetKind.ORG && li.get(i).isStreetDetail()) {
                            details.add(li.get(i));
                            li.get(i).tag = addr;
                            continue;
                        }
                    }
                    if (streets.size() > 1) 
                        break;
                    streets.add(li.get(i));
                    li.get(i).tag = addr;
                }
                else if (li.get(i).getTyp() == AddressItemType.DETAIL) {
                    if ((i + 1) == li.size() && li.get(i).detailType == com.pullenti.ner.address.AddressDetailType.NEAR) 
                        break;
                    if (li.get(i).detailType == com.pullenti.ner.address.AddressDetailType.NEAR && ((i + 1) < li.size()) && li.get(i + 1).getTyp() == AddressItemType.CITY) {
                        details.add(li.get(i));
                        li.get(i).tag = addr;
                        i++;
                    }
                    if (li.get(i).getLengthChar() == 1 && li.get(i).detailType == com.pullenti.ner.address.AddressDetailType.CROSS && ((((i + 1) == li.size() || li.get(i + 1).getTyp() != AddressItemType.STREET || i == 0) || li.get(i - 1).getTyp() != AddressItemType.STREET))) {
                    }
                    else 
                        details.add(li.get(i));
                    li.get(i).tag = addr;
                }
                else {
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapi66 = new com.pullenti.unisharp.Outargwrapper<Integer>(i);
                    boolean inoutres67 = _addAddressAttrs(addr, li, wrapi66, i0, ignoreStreet, hasGenplan);
                    i = (wrapi66.value != null ? wrapi66.value : 0);
                    if (inoutres67) {
                        if (i >= li.size() || li.get(i).tag != null) 
                            continue;
                    }
                    else if (i > i0) {
                        if (((li.get(i).getTyp() == AddressItemType.REGION && li.get(i0).getTyp() == AddressItemType.STREET && ((i + 1) < li.size())) && li.get(i + 1).getTyp() != AddressItemType.STREET && li.get(i + 1).getTyp() != AddressItemType.REGION) && li.get(i + 1).getTyp() != AddressItemType.CITY) {
                        }
                        else 
                            break;
                    }
                }
            }
        }
        if (streets.size() == 1 && streets.get(0).ortoTerr != null) 
            streets.add(0, streets.get(0).ortoTerr);
        java.util.ArrayList<String> typs = new java.util.ArrayList<String>();
        for (com.pullenti.ner.Slot s : addr.getSlots()) {
            if (!typs.contains(s.getTypeName())) 
                typs.add(s.getTypeName());
        }
        if (streets.size() == 1 && !streets.get(0).isDoubt && streets.get(0).refToken == null) {
        }
        else if (li.size() > 2 && li.get(0).getTyp() == AddressItemType.ZIP && ((li.get(1).getTyp() == AddressItemType.COUNTRY || li.get(1).getTyp() == AddressItemType.REGION))) {
        }
        else if (ignoreStreet) {
        }
        else if ((typs.size() + streets.size()) < 2) {
            if (typs.size() > 0) {
                if ((((((com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_STREET) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_POSTOFFICEBOX) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_DELIVERYAREA)) && metro == null && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_HOUSE)) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_HOUSEORPLOT) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_CORPUS)) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_BUILDING) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_PLOT)) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_DETAIL) && com.pullenti.unisharp.Utils.stringsNe(typs.get(0), com.pullenti.ner.address.AddressReferent.ATTR_ZIP)) && details.size() == 0 && !cross) 
                    return null;
            }
            else if (streets.size() == 0 && details.size() == 0 && !cross) {
                if ((i > 0 && li.get(i - 1).getTyp() == AddressItemType.CITY && i > 2) && li.get(i - 2).getTyp() == AddressItemType.ZIP) {
                }
                else 
                    return null;
            }
            else if ((i == li.size() && streets.size() == 1 && (streets.get(0).referent instanceof com.pullenti.ner.address.StreetReferent)) && streets.get(0).referent.findSlot(com.pullenti.ner.address.StreetReferent.ATTR_TYPE, "квартал", true) != null && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) 
                return null;
            if (geos == null) {
                boolean hasGeo2 = false;
                for (com.pullenti.ner.Token tt = li.get(0).getBeginToken().getPrevious(); tt != null; tt = tt.getPrevious()) {
                    if (tt.getMorph()._getClass().isPreposition() || tt.isComma()) 
                        continue;
                    com.pullenti.ner.Referent r = tt.getReferent();
                    if (r == null) 
                        break;
                    if (com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "DATE") || com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "DATERANGE")) 
                        continue;
                    if (r instanceof com.pullenti.ner.geo.GeoReferent) {
                        if (!((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.geo.GeoReferent.class)).isState()) {
                            if (geos == null) 
                                geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>();
                            geos.add((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.geo.GeoReferent.class));
                            hasGeo2 = true;
                        }
                    }
                    break;
                }
                if (!hasGeo2 && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
                    if (streets.size() > 0 && streets.get(0).refTokenIsGsk && streets.get(0).refToken != null) {
                    }
                    else 
                        return null;
                }
            }
        }
        for (i = 0; i < li.size(); i++) {
            if (li.get(i).getTyp() == AddressItemType.PREFIX) 
                li.get(i).tag = addr;
            else if (li.get(i).tag == null) {
                if (li.get(i).isNewlineBefore() && i > i0) {
                    boolean stop = false;
                    for (j = i + 1; j < li.size(); j++) {
                        if (li.get(j).getTyp() == AddressItemType.STREET) {
                            stop = true;
                            break;
                        }
                    }
                    if (stop) 
                        break;
                }
                if (li.get(i).getTyp() == AddressItemType.COUNTRY || li.get(i).getTyp() == AddressItemType.REGION || li.get(i).getTyp() == AddressItemType.CITY) {
                    if (geos == null) 
                        geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>();
                    if (!geos.contains((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class))) 
                        geos.add((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(li.get(i).referent, com.pullenti.ner.geo.GeoReferent.class));
                    if (li.get(i).getTyp() != AddressItemType.COUNTRY) {
                        if (li.get(i).detailType != com.pullenti.ner.address.AddressDetailType.UNDEFINED && addr.getDetail() == com.pullenti.ner.address.AddressDetailType.UNDEFINED) {
                            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAIL, li.get(i).detailType.toString().toUpperCase(), false, 0).setTag(li.get(i));
                            if (li.get(i).detailMeters > 0) 
                                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAILPARAM, (((Integer)li.get(i).detailMeters).toString() + "м"), false, 0);
                        }
                    }
                    li.get(i).tag = addr;
                    continue;
                }
                com.pullenti.unisharp.Outargwrapper<Integer> wrapi68 = new com.pullenti.unisharp.Outargwrapper<Integer>(i);
                boolean inoutres69 = _addAddressAttrs(addr, li, wrapi68, i0, ignoreStreet, hasGenplan);
                i = (wrapi68.value != null ? wrapi68.value : 0);
                if (!inoutres69) 
                    break;
                if (i >= li.size() || li.get(i).tag != null) 
                    continue;
            }
        }
        com.pullenti.ner.Token t0 = null;
        com.pullenti.ner.Token t1 = null;
        for (i = 0; i < li.size(); i++) {
            if (li.get(i).tag != null) {
                t0 = li.get(i).getBeginToken();
                break;
            }
        }
        for (i = li.size() - 1; i >= 0; i--) {
            if (li.get(i).tag != null) {
                t1 = li.get(i).getEndToken();
                break;
            }
        }
        if (t0 == null || t1 == null) 
            return null;
        if (li.get(li.size() - 1).tag == null && com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
            boolean ok = true;
            for (i = li.size() - 1; i >= 0; i--) {
                if (li.get(i).tag != null) 
                    break;
                int ii;
                for (ii = 0; ii < i; ii++) {
                    if (com.pullenti.unisharp.Utils.stringsEq(li.get(ii).toString(), li.get(i).toString()) && li.get(ii).tag != null) 
                        break;
                }
                if (ii >= i) {
                    ok = false;
                    break;
                }
            }
            if (ok) 
                t1 = li.get(li.size() - 1).getEndToken();
        }
        if (geos != null && geos.size() > 1 && com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(t0)) {
            if (geos.get(0).getHigher() == null && geos.get(1).getHigher() != null) {
                com.pullenti.ner.geo.GeoReferent hi = geos.get(1).getHigher();
                geos.get(1).setHigher(null);
                if (com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(geos.get(0), geos.get(1), null, null) && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(hi, geos.get(0), null, null)) {
                    geos.get(0).setHigher(hi);
                    geos.get(1).setHigher(geos.get(0));
                    geos.remove(0);
                }
                else 
                    geos.get(1).setHigher(hi);
            }
        }
        if (addr.getSlots().size() == 0) {
            int pureStreets = 0;
            int gsks = 0;
            for (AddressItemToken s : streets) {
                if (s.refToken != null && s.refTokenIsGsk) 
                    gsks++;
                else if (s.refToken == null) 
                    pureStreets++;
            }
            if ((pureStreets + gsks) == 0 && streets.size() > 0) {
                if (((details.size() > 0 || cross)) && geos != null) {
                }
                else 
                    addr = null;
            }
            else if (streets.size() < 2) {
                if ((streets.size() == 1 && geos != null && geos.size() > 0) && ((streets.get(0).refToken == null || streets.get(0).refTokenIsGsk))) {
                }
                else if (details.size() > 0 && geos != null && streets.size() == 0) {
                }
                else 
                    addr = null;
            }
        }
        if (addr != null) {
            if (cross) {
                if (streets.size() > 1 || ((streets.size() == 1 && streets.get(0).referent2 != null))) 
                    addr.setDetail(com.pullenti.ner.address.AddressDetailType.CROSS);
            }
            else if (details.size() > 0) {
                com.pullenti.ner.address.AddressDetailType ty = com.pullenti.ner.address.AddressDetailType.UNDEFINED;
                String par = null;
                for (AddressItemToken v : details) {
                    if ((v.referent instanceof com.pullenti.ner.address.StreetReferent) && ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(v.referent, com.pullenti.ner.address.StreetReferent.class)).getKind() == com.pullenti.ner.address.StreetKind.ORG) {
                        com.pullenti.ner.Referent _org = (com.pullenti.ner.Referent)com.pullenti.unisharp.Utils.cast(v.referent.getSlotValue(com.pullenti.ner.address.StreetReferent.ATTR_REF), com.pullenti.ner.Referent.class);
                        if (_org != null && com.pullenti.unisharp.Utils.stringsEq(_org.getTypeName(), "ORGANIZATION")) {
                            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAILREF, _org, false, 0);
                            v.referent.moveExtReferent(addr, _org);
                        }
                    }
                    else if (v.referent != null) {
                        addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAILREF, v.referent, false, 0);
                        if (v.refToken != null) 
                            addr.addExtReferent(v.refToken);
                        com.pullenti.ner.geo.GeoReferent gg = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(v.referent, com.pullenti.ner.geo.GeoReferent.class);
                        if (gg != null && gg.getHigher() == null && geos != null) {
                            if (geos.size() > 0 && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(geos.get(0), gg, null, null)) 
                                gg.setHigher(geos.get(0));
                        }
                    }
                    else if (v.detailType == com.pullenti.ner.address.AddressDetailType.ORG && v.refToken != null) {
                        addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAILREF, v.refToken.referent, false, 0);
                        addr.addExtReferent(v.refToken);
                    }
                    if (v.detailType == com.pullenti.ner.address.AddressDetailType.CROSS && (streets.size() < 2)) 
                        continue;
                    if (ty == com.pullenti.ner.address.AddressDetailType.UNDEFINED || v.detailMeters > 0) {
                        if (v.detailMeters > 0) 
                            par = (((Integer)v.detailMeters).toString() + "м");
                        ty = v.detailType;
                    }
                    if (ty == com.pullenti.ner.address.AddressDetailType.UNDEFINED || v.detailType == com.pullenti.ner.address.AddressDetailType.RANGE) {
                        ty = v.detailType;
                        par = v.value;
                    }
                    if (v.detailParam != null) {
                        ty = v.detailType;
                        par = v.detailParam;
                    }
                }
                if (ty != com.pullenti.ner.address.AddressDetailType.UNDEFINED) 
                    addr.setDetail(ty);
                if (par != null) 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAILPARAM, par, false, 0);
                else 
                    for (AddressItemToken v : li) {
                        if (v.tag != null && v.detailMeters > 0) {
                            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DETAILPARAM, (((Integer)v.detailMeters).toString() + "м"), false, 0);
                            break;
                        }
                    }
            }
        }
        if (geos == null && streets.size() > 0 && !streets.get(0).isStreetRoad()) {
            int cou = 0;
            for (com.pullenti.ner.Token tt = t0.getPrevious(); tt != null && (cou < 200); tt = tt.getPrevious(),cou++) {
                if (tt.isNewlineAfter()) 
                    cou += 10;
                com.pullenti.ner.Referent r = tt.getReferent();
                if ((r instanceof com.pullenti.ner.geo.GeoReferent) && !((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.geo.GeoReferent.class)).isState()) {
                    geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>();
                    geos.add((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.geo.GeoReferent.class));
                    break;
                }
                if (r instanceof com.pullenti.ner.address.StreetReferent) {
                    java.util.ArrayList<com.pullenti.ner.geo.GeoReferent> ggg = ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.address.StreetReferent.class)).getGeos();
                    if (ggg.size() > 0) {
                        geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>(ggg);
                        break;
                    }
                }
                if (r instanceof com.pullenti.ner.address.AddressReferent) {
                    java.util.ArrayList<com.pullenti.ner.geo.GeoReferent> ggg = ((com.pullenti.ner.address.AddressReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.address.AddressReferent.class)).getGeos();
                    if (ggg.size() > 0) {
                        geos = new java.util.ArrayList<com.pullenti.ner.geo.GeoReferent>(ggg);
                        break;
                    }
                }
            }
        }
        com.pullenti.ner.ReferentToken rt;
        com.pullenti.ner.address.StreetReferent sr0 = null;
        for (int ii = 0; ii < streets.size(); ii++) {
            if ((district != null && geos != null && geos.size() == 1) && district.referent != null && district.refToken != null) {
                district.referent.addSlot(com.pullenti.ner.geo.GeoReferent.ATTR_TYPE, "район", false, 0);
                com.pullenti.ner.geo.GeoReferent distr = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(district.referent), com.pullenti.ner.geo.GeoReferent.class);
                geos.clear();
                geos.add(distr);
            }
            AddressItemToken s = streets.get(ii);
            com.pullenti.ner.address.StreetReferent sr = (com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(s.referent, com.pullenti.ner.address.StreetReferent.class);
            if (sr == null || sr.getSlots().size() == 0) 
                continue;
            String nam = sr.getStringValue(com.pullenti.ner.address.StreetReferent.ATTR_NAME);
            if (nam != null) {
                if (nam.startsWith("НЕ УКАЗАН") || nam.startsWith("НЕ ЗАДАН")) 
                    continue;
            }
            if ((s.areaTerr != null && geos != null && geos.size() == 1) && ((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(s.areaTerr.referent, com.pullenti.ner.geo.GeoReferent.class)).getHigher() == geos.get(0)) {
                geos.clear();
                geos.add((com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(s.areaTerr.referent, com.pullenti.ner.geo.GeoReferent.class));
            }
            if (geos != null && sr != null && sr.getGeos().size() == 0) {
                for (com.pullenti.ner.geo.GeoReferent gr : geos) {
                    if (gr.isCity() || ((gr.getHigher() != null && gr.getHigher().isCity())) || ((gr.isRegion() && sr.getKind() != com.pullenti.ner.address.StreetKind.UNDEFINED))) {
                        sr.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, gr, true, 0);
                        if (s.referent2 instanceof com.pullenti.ner.address.StreetReferent) 
                            s.referent2.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, gr, true, 0);
                        if (li.get(0).referent == gr) 
                            streets.get(0).setBeginToken(li.get(0).getBeginToken());
                        for (int jj = ii + 1; jj < streets.size(); jj++) {
                            if (streets.get(jj).referent instanceof com.pullenti.ner.address.StreetReferent) 
                                streets.get(jj).referent.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, gr, false, 0);
                        }
                        geos.remove(gr);
                        break;
                    }
                    else if (gr.isRegion()) {
                        boolean ok = false;
                        if ((sr.getKind() == com.pullenti.ner.address.StreetKind.RAILWAY || sr.getKind() == com.pullenti.ner.address.StreetKind.ROAD || sr.getKind() == com.pullenti.ner.address.StreetKind.AREA) || sr.getKind() == com.pullenti.ner.address.StreetKind.SPEC) 
                            ok = true;
                        else 
                            for (String v : gr.getTyps()) {
                                if (com.pullenti.unisharp.Utils.stringsEq(v, "муниципальный округ") || com.pullenti.unisharp.Utils.stringsEq(v, "городской округ")) 
                                    ok = true;
                            }
                        if (ok) {
                            if (li.get(0).referent == gr) 
                                streets.get(0).setBeginToken(li.get(0).getBeginToken());
                            sr.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, gr, true, 0);
                            geos.remove(gr);
                            break;
                        }
                    }
                }
            }
            boolean isReverce = false;
            if (sr != null && sr.getGeos().size() == 0) {
                if (sr0 != null) {
                    for (com.pullenti.ner.geo.GeoReferent g : sr0.getGeos()) {
                        sr.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, g, false, 0);
                    }
                }
                sr0 = sr;
            }
            if (s.referent != null && s.referent.findSlot(com.pullenti.ner.address.StreetReferent.ATTR_NAME, "НЕТ", true) != null) {
                for (com.pullenti.ner.Slot ss : s.referent.getSlots()) {
                    if (com.pullenti.unisharp.Utils.stringsEq(ss.getTypeName(), com.pullenti.ner.address.StreetReferent.ATTR_GEO)) {
                        if (addr != null) 
                            addr.addReferent((com.pullenti.ner.Referent)com.pullenti.unisharp.Utils.cast(ss.getValue(), com.pullenti.ner.Referent.class));
                    }
                }
            }
            else {
                if ((sr != null && ii > 0 && (streets.get(ii - 1).referent instanceof com.pullenti.ner.address.StreetReferent)) && !cross) {
                    com.pullenti.ner.address.StreetReferent sr00 = (com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(streets.get(ii - 1).referent, com.pullenti.ner.address.StreetReferent.class);
                    com.pullenti.ner.address.StreetKind ki = sr00.getKind();
                    boolean ok2 = false;
                    if (ki != sr.getKind() || ki == com.pullenti.ner.address.StreetKind.AREA || ki == com.pullenti.ner.address.StreetKind.ORG) {
                        if ((sr.getKind() == com.pullenti.ner.address.StreetKind.AREA || ki == com.pullenti.ner.address.StreetKind.AREA || ki == com.pullenti.ner.address.StreetKind.RAILWAY) || ki == com.pullenti.ner.address.StreetKind.ROAD || ((ki == com.pullenti.ner.address.StreetKind.ORG && sr.getKind() == com.pullenti.ner.address.StreetKind.UNDEFINED))) 
                            ok2 = true;
                    }
                    if (ki == com.pullenti.ner.address.StreetKind.ORG && streets.get(ii - 1).refTokenIsMassive) 
                        ok2 = true;
                    if (ki == com.pullenti.ner.address.StreetKind.UNDEFINED && ((sr.getKind() == com.pullenti.ner.address.StreetKind.ORG || sr.getKind() == com.pullenti.ner.address.StreetKind.AREA))) 
                        ok2 = true;
                    if ((sr.getKind() == com.pullenti.ner.address.StreetKind.ROAD && sr00.getNumbers() != null && sr00.getNumbers().endsWith("км")) && sr.getNumbers() == null) {
                        ok2 = true;
                        isReverce = true;
                    }
                    if (sr.findSlot(com.pullenti.ner.address.StreetReferent.ATTR_NAME, "ОЛИМПИЙСКАЯ ДЕРЕВНЯ", true) != null) {
                        ok2 = true;
                        isReverce = true;
                    }
                    if (((!ok2 && streets.size() == 2 && com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(streets.get(0))) && sr.getKind() == com.pullenti.ner.address.StreetKind.UNDEFINED && sr00.getKind() == com.pullenti.ner.address.StreetKind.UNDEFINED) && !sr.canBeEquals(sr00, com.pullenti.ner.core.ReferentsEqualType.WITHINONETEXT)) 
                        ok2 = true;
                    if (ok2) {
                        if (sr.getKind() == com.pullenti.ner.address.StreetKind.AREA || sr.getKind() == com.pullenti.ner.address.StreetKind.ORG) {
                            if (ki == com.pullenti.ner.address.StreetKind.UNDEFINED) 
                                isReverce = true;
                        }
                        if (isReverce) {
                            streets.get(ii - 1).setEndToken(streets.get(ii).getEndToken());
                            ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(streets.get(ii - 1).referent, com.pullenti.ner.address.StreetReferent.class)).setHigher(sr);
                            streets.get(ii - 1).referent.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, null, true, 0);
                        }
                        else {
                            sr.setHigher((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(streets.get(ii - 1).referent, com.pullenti.ner.address.StreetReferent.class));
                            sr.addSlot(com.pullenti.ner.address.StreetReferent.ATTR_GEO, null, true, 0);
                            if (addr != null) {
                                com.pullenti.ner.Slot slo = addr.findSlot(com.pullenti.ner.address.AddressReferent.ATTR_STREET, null, true);
                                if (slo != null) 
                                    addr.getSlots().remove(slo);
                            }
                            s.setBeginToken(t0);
                        }
                    }
                }
                if (addr != null) {
                    addr.moveExtReferent(s.referent, null);
                    if (s.referent2 != null) 
                        addr.moveExtReferent(s.referent2, null);
                }
                boolean hi = ii > 0 && (streets.get(ii - 1).referent instanceof com.pullenti.ner.address.StreetReferent) && ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(streets.get(ii - 1).referent, com.pullenti.ner.address.StreetReferent.class)).getHigher() == s.referent;
                s.referent = ad.registerReferent(s.referent);
                if (hi) 
                    ((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(streets.get(ii - 1).referent, com.pullenti.ner.address.StreetReferent.class)).setHigher((com.pullenti.ner.address.StreetReferent)com.pullenti.unisharp.Utils.cast(s.referent, com.pullenti.ner.address.StreetReferent.class));
                if (addr != null && !isReverce) 
                    addr.addReferent(s.referent);
                if (s.referent2 != null) {
                    s.referent2 = ad.registerReferent(s.referent2);
                    if (addr != null && !isReverce) 
                        addr.addReferent(s.referent2);
                }
                for (com.pullenti.ner.Token tt = s.getBeginToken().getPrevious(); tt != null && tt.getBeginChar() >= t0.getBeginChar(); tt = tt.getPrevious()) {
                    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 || sr == null) 
                        continue;
                    for (com.pullenti.ner.geo.GeoReferent gg : sr.getGeos()) {
                        if (gg.getTopHigher() == g.getTopHigher()) 
                            s.setBeginToken(tt);
                    }
                }
                t = (rt = new com.pullenti.ner.ReferentToken(s.referent, s.getBeginToken(), s.getEndToken(), null));
                t.kit.embedToken(rt);
                if (isReverce && (t.getPrevious() instanceof com.pullenti.ner.ReferentToken)) {
                    rt = new com.pullenti.ner.ReferentToken(t.getPrevious().getReferent(), t.getPrevious(), t, null);
                    t.kit.embedToken(rt);
                    t = rt;
                }
                if (s.getBeginChar() == t0.getBeginChar()) 
                    t0 = rt;
                if (s.getEndChar() == t1.getEndChar()) 
                    t1 = rt;
            }
        }
        if (addr != null) {
            boolean ok = false;
            for (com.pullenti.ner.Slot s : addr.getSlots()) {
                if (com.pullenti.unisharp.Utils.stringsNe(s.getTypeName(), com.pullenti.ner.address.AddressReferent.ATTR_DETAIL)) 
                    ok = true;
            }
            if ((streets.size() > 0 && streets.get(0).referent != null && streets.get(0).referent.getSlots().size() == 0) && geos != null && geos.size() > 0) 
                ok = true;
            if (!ok) 
                addr = null;
        }
        if (addr == null) 
            return t;
        if (geos != null && geos.size() > 0) {
            if ((geos.size() == 1 && geos.get(0).isRegion() && streets.size() == 1) && streets.get(0).refToken != null) {
            }
            if (streets.size() == 1 && streets.get(0).referent != null) {
                for (com.pullenti.ner.Slot s : streets.get(0).referent.getSlots()) {
                    if (com.pullenti.unisharp.Utils.stringsEq(s.getTypeName(), com.pullenti.ner.address.StreetReferent.ATTR_GEO) && (s.getValue() instanceof com.pullenti.ner.geo.GeoReferent)) {
                        int k = 0;
                        for (com.pullenti.ner.geo.GeoReferent gg = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(s.getValue(), com.pullenti.ner.geo.GeoReferent.class); gg != null && (k < 5); gg = (com.pullenti.ner.geo.GeoReferent)com.pullenti.unisharp.Utils.cast(gg.getParentReferent(), com.pullenti.ner.geo.GeoReferent.class),k++) {
                            for (int ii = geos.size() - 1; ii >= 0; ii--) {
                                if (geos.get(ii) == gg) {
                                    geos.remove(ii);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            while (geos.size() >= 2) {
                if (geos.get(1).getHigher() == null && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(geos.get(0), geos.get(1), null, null)) {
                    geos.get(1).setHigher(geos.get(0));
                    geos.remove(0);
                }
                else if (geos.get(0).getHigher() == null && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(geos.get(1), geos.get(0), null, null)) {
                    geos.get(0).setHigher(geos.get(1));
                    geos.remove(1);
                }
                else if (geos.get(1).getHigher() != null && geos.get(1).getHigher().getHigher() == null && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(geos.get(0), geos.get(1).getHigher(), null, null)) {
                    geos.get(1).getHigher().setHigher(geos.get(0));
                    geos.remove(0);
                }
                else if (geos.get(0).getHigher() != null && geos.get(0).getHigher().getHigher() == null && com.pullenti.ner.geo.internal.GeoOwnerHelper.canBeHigher(geos.get(1), geos.get(0).getHigher(), null, null)) {
                    geos.get(0).getHigher().setHigher(geos.get(1));
                    geos.remove(1);
                }
                else 
                    break;
            }
            for (com.pullenti.ner.geo.GeoReferent g : geos) {
                addr.addReferent(g);
            }
        }
        boolean ok1 = false;
        for (com.pullenti.ner.Slot s : addr.getSlots()) {
            if (com.pullenti.unisharp.Utils.stringsNe(s.getTypeName(), com.pullenti.ner.address.AddressReferent.ATTR_STREET)) {
                ok1 = true;
                break;
            }
        }
        if (!ok1) 
            return t;
        if (addr.getHouse() != null && addr.getCorpus() == null && addr.findSlot(com.pullenti.ner.address.AddressReferent.ATTR_STREET, null, true) == null) {
            if (geos != null && geos.size() > 0 && geos.get(0).findSlot(com.pullenti.ner.geo.GeoReferent.ATTR_NAME, "ЗЕЛЕНОГРАД", true) != null) {
                addr.setCorpus(addr.getHouse());
                addr.setHouse(null);
            }
        }
        for (int ii = addr.getSlots().size() - 1; ii >= 0; ii--) {
            if (addr.getSlots().get(ii).getValue() instanceof String) {
                if (com.pullenti.unisharp.Utils.stringsEq((String)com.pullenti.unisharp.Utils.cast(addr.getSlots().get(ii).getValue(), String.class), "НЕТ")) 
                    addr.getSlots().remove(ii);
            }
        }
        if (com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(t1)) {
            boolean hous = false;
            com.pullenti.unisharp.Outargwrapper<Boolean> wraphous70 = new com.pullenti.unisharp.Outargwrapper<Boolean>();
            t1 = AddressItemToken.gotoEndOfAddress(t1, wraphous70);
            hous = (wraphous70.value != null ? wraphous70.value : false);
            if ((hous && addr.getHouse() == null && addr.getBuilding() == null) && addr.getHouseOrPlot() == null && addr.getCorpus() == null) 
                addr.setHouse("0");
        }
        if (ad != null) 
            addr = (com.pullenti.ner.address.AddressReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(addr), com.pullenti.ner.address.AddressReferent.class);
        rt = new com.pullenti.ner.ReferentToken(addr, t0, t1, null);
        t.kit.embedToken(rt);
        t = rt;
        if ((t.getNext() != null && ((t.getNext().isComma() || t.getNext().isChar(';'))) && (t.getNext().getWhitespacesAfterCount() < 2)) && (t.getNext().getNext() instanceof com.pullenti.ner.NumberToken)) {
            AddressItemToken last = null;
            for (AddressItemToken ll : li) {
                if (ll.tag != null) 
                    last = ll;
            }
            String attrName = null;
            if (last == null) 
                return t;
            if (last.getTyp() == AddressItemType.HOUSE) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_HOUSE;
            else if (last.getTyp() == AddressItemType.CORPUS) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_CORPUS;
            else if (last.getTyp() == AddressItemType.BUILDING) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_BUILDING;
            else if (last.getTyp() == AddressItemType.FLAT) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_FLAT;
            else if (last.getTyp() == AddressItemType.PAVILION) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_PAVILION;
            else if (last.getTyp() == AddressItemType.PLOT) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_PLOT;
            else if (last.getTyp() == AddressItemType.FIELD) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_FIELD;
            else if (last.getTyp() == AddressItemType.GENPLAN) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_GENPLAN;
            else if (last.getTyp() == AddressItemType.BOX) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_BOX;
            else if (last.getTyp() == AddressItemType.WELL) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_WELL;
            else if (last.getTyp() == AddressItemType.CARPLACE) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_CARPLACE;
            else if (last.getTyp() == AddressItemType.PART) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_PART;
            else if (last.getTyp() == AddressItemType.SPACE) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_SPACE;
            else if (last.getTyp() == AddressItemType.POTCH) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_PORCH;
            else if (last.getTyp() == AddressItemType.BLOCK) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_BLOCK;
            else if (last.getTyp() == AddressItemType.OFFICE) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_OFFICE;
            else if (last.getTyp() == AddressItemType.ROOM) 
                attrName = com.pullenti.ner.address.AddressReferent.ATTR_ROOM;
            if (attrName != null) {
                for (t = t.getNext().getNext(); t != null; t = t.getNext()) {
                    if (!(t instanceof com.pullenti.ner.NumberToken)) 
                        break;
                    com.pullenti.ner.NumberToken nt = (com.pullenti.ner.NumberToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.NumberToken.class);
                    if (nt.getIntValue() == null || nt.getIntValue() > 1000) 
                        break;
                    com.pullenti.ner.address.AddressReferent addr1 = (com.pullenti.ner.address.AddressReferent)com.pullenti.unisharp.Utils.cast(addr.clone(), com.pullenti.ner.address.AddressReferent.class);
                    addr1.getOccurrence().clear();
                    addr1.addSlot(attrName, ((com.pullenti.ner.NumberToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.NumberToken.class)).getValue().toString(), true, 0);
                    if (ad != null) 
                        addr1 = (com.pullenti.ner.address.AddressReferent)com.pullenti.unisharp.Utils.cast(ad.registerReferent(addr1), com.pullenti.ner.address.AddressReferent.class);
                    rt = new com.pullenti.ner.ReferentToken(addr1, t, t, null);
                    t.kit.embedToken(rt);
                    t = rt;
                    if ((t.getNext() != null && ((t.getNext().isComma() || t.getNext().isChar(';'))) && (t.getNext().getWhitespacesAfterCount() < 2)) && (t.getNext().getNext() instanceof com.pullenti.ner.NumberToken)) {
                    }
                    else 
                        break;
                }
            }
        }
        return t;
    }

    private static boolean _addAddressAttrs(com.pullenti.ner.address.AddressReferent addr, java.util.ArrayList<AddressItemToken> li, com.pullenti.unisharp.Outargwrapper<Integer> i, int i0, boolean ignoreStreet, boolean hasGenplan) {
        if (li.get(i.value).getTyp() == AddressItemType.HOUSE) {
            if (addr.getHouse() != null) 
                return false;
            if (li.get(i.value).value != null || com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(i.value))) {
                if (li.get(i.value).value != null) {
                    String attr = com.pullenti.ner.address.AddressReferent.ATTR_HOUSE;
                    if (li.get(i.value).isDoubt) {
                        attr = com.pullenti.ner.address.AddressReferent.ATTR_HOUSEORPLOT;
                        if (((i.value + 1) < li.size()) && (((li.get(i.value + 1).getTyp() == AddressItemType.FLAT || li.get(i.value + 1).getTyp() == AddressItemType.POTCH || li.get(i.value + 1).getTyp() == AddressItemType.FLOOR) || li.get(i.value + 1).getTyp() == AddressItemType.NUMBER))) 
                            attr = com.pullenti.ner.address.AddressReferent.ATTR_HOUSE;
                    }
                    addr.addSlot(attr, (li.get(i.value).value != null ? li.get(i.value).value : "0"), false, 0).setTag(li.get(i.value));
                    if (li.get(i.value).houseType != com.pullenti.ner.address.AddressHouseType.UNDEFINED) 
                        addr.setHouseType(li.get(i.value).houseType);
                }
            }
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.KILOMETER && li.get(i.value).isDigit() && (((i0 < li.size()) && li.get(i0).isStreetRoad()))) {
            if (addr.getKilometer() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_KILOMETER, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.PLOT) {
            if (addr.getPlot() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_PLOT, (li.get(i.value).value != null ? li.get(i.value).value : "0"), false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.FIELD) {
            if (addr.getField() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FIELD, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.GENPLAN) {
            if (addr.getGenplan() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_GENPLAN, (li.get(i.value).value != null ? li.get(i.value).value : "0"), false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.BOX) {
            if (addr.getBox() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_BOX, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.WELL) {
            if (addr.getWell() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_WELL, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.CARPLACE) {
            if (addr.getCarplace() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CARPLACE, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.PART && li.get(i.value).isDigit()) {
            if (addr.getPart() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_PART, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.SPACE) {
            if (addr.getSpace() == null) {
                com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_SPACE, li.get(i.value).value, false, 0);
                if (s != null) 
                    s.setTag(li.get(i.value));
                li.get(i.value).tag = addr;
            }
            else if (li.get(i.value).detailParam == null || li.get(i.value).value != null) 
                return false;
            if (li.get(i.value).detailParam != null) {
                String dp = li.get(i.value).detailParam;
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_SPACETYPE, dp, false, 0);
                li.get(i.value).tag = addr;
            }
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.BLOCK && li.get(i.value).value != null) {
            if (addr.getBlock() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_BLOCK, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.CORPUS) {
            if (addr.getCorpus() != null) 
                return false;
            if (li.get(i.value).value != null) {
                com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0);
                if (s != null) 
                    s.setTag(li.get(i.value));
            }
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.BUILDING) {
            if (addr.getBuilding() != null) 
                return false;
            if (li.get(i.value).value != null) {
                com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_BUILDING, li.get(i.value).value, false, 0);
                if (s != null) 
                    s.setTag(li.get(i.value));
                if (li.get(i.value).buildingType != com.pullenti.ner.address.AddressBuildingType.UNDEFINED) 
                    addr.setBuildingType(li.get(i.value).buildingType);
            }
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.FLOOR && li.get(i.value).value != null) {
            if (addr.getFloor() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLOOR, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.POTCH) {
            if (addr.getPotch() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_PORCH, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.FLAT) {
            if (addr.getFlat() != null) 
                return false;
            if (li.get(i.value).value != null) 
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.PAVILION) {
            if (addr.getPavilion() != null) 
                return false;
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_PAVILION, (li.get(i.value).value != null ? li.get(i.value).value : "0"), false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.OFFICE) {
            if (addr.getOffice() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_OFFICE, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.ROOM) {
            if (addr.getRoom() != null) 
                return false;
            com.pullenti.ner.Slot s = addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_ROOM, li.get(i.value).value, false, 0);
            if (s != null) 
                s.setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.ZIP) {
            if (addr.getZip() != null) 
                return false;
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_ZIP, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.CORPUSORFLAT && ((li.get(i.value).isDigit() || li.get(i.value).value == null))) {
            int j;
            for (j = i.value + 1; j < li.size(); j++) {
                if (li.get(j).isDigit()) {
                    if ((((li.get(j).getTyp() == AddressItemType.FLAT || li.get(j).getTyp() == AddressItemType.CORPUSORFLAT || li.get(j).getTyp() == AddressItemType.OFFICE) || li.get(j).getTyp() == AddressItemType.FLOOR || li.get(j).getTyp() == AddressItemType.POTCH) || li.get(j).getTyp() == AddressItemType.DELIVERYAREA || li.get(j).getTyp() == AddressItemType.POSTOFFICEBOX) || li.get(j).getTyp() == AddressItemType.BUILDING || li.get(j).getTyp() == AddressItemType.PAVILION) 
                        break;
                }
            }
            if (li.get(i.value).value != null) {
                if ((j < li.size()) && addr.getCorpus() == null) 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                else if (addr.getCorpus() != null) 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                else if ((i.value + 2) == li.size() && li.get(i.value + 1).getTyp() == AddressItemType.NUMBER) {
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                    i.value++;
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                }
                else 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUSORFLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            }
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.NUMBER && li.get(i.value).isDigit() && ((((!li.get(i.value).isNewlineBefore() && i.value > 0 && li.get(i.value - 1).getTyp() == AddressItemType.STREET)) || ignoreStreet || li.get(i.value).isGenplan))) {
            int v = 0;
            com.pullenti.unisharp.Outargwrapper<Integer> wrapv80 = new com.pullenti.unisharp.Outargwrapper<Integer>();
            boolean inoutres81 = com.pullenti.unisharp.Utils.parseInteger(li.get(i.value).value, 0, null, wrapv80);
            v = (wrapv80.value != null ? wrapv80.value : 0);
            if (!inoutres81) {
                com.pullenti.unisharp.Outargwrapper<Integer> wrapv71 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                boolean inoutres72 = com.pullenti.unisharp.Utils.parseInteger(li.get(i.value).value.substring(0, 0 + li.get(i.value).value.length() - 1), 0, null, wrapv71);
                v = (wrapv71.value != null ? wrapv71.value : 0);
                if (!inoutres72) {
                    if (!(li.get(i.value).value.indexOf("/") >= 0)) 
                        return false;
                }
            }
            if (v > 500 && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0)) && !ignoreStreet) 
                return false;
            String attr = com.pullenti.ner.address.AddressReferent.ATTR_HOUSEORPLOT;
            int ii = i.value + 1;
            if ((ii < li.size()) && li.get(ii).getTyp() == AddressItemType.DETAIL) 
                ii++;
            if ((ii < li.size()) && (((((li.get(ii).getTyp() == AddressItemType.FLAT || li.get(ii).getTyp() == AddressItemType.CORPUSORFLAT || li.get(ii).getTyp() == AddressItemType.POTCH) || li.get(ii).getTyp() == AddressItemType.CORPUS || li.get(ii).getTyp() == AddressItemType.BUILDING) || li.get(ii).getTyp() == AddressItemType.FLOOR || li.get(ii).getTyp() == AddressItemType.NUMBER) || li.get(ii).getTyp() == AddressItemType.SPACE || ((li.get(ii).getTyp() == AddressItemType.STREET && li.get(ii).refTokenIsGsk))))) 
                attr = com.pullenti.ner.address.AddressReferent.ATTR_HOUSE;
            addr.addSlot(attr, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            if (li.get(i.value).isGenplan) {
                if (addr.getGenplan() == null) 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_GENPLAN, "0", false, 0);
            }
            li.get(i.value).tag = addr;
            if (((i.value + 1) < li.size()) && ((li.get(i.value + 1).getTyp() == AddressItemType.NUMBER || li.get(i.value + 1).getTyp() == AddressItemType.FLAT || li.get(i.value + 1).getTyp() == AddressItemType.CORPUSORFLAT)) && !li.get(i.value + 1).isNewlineBefore()) {
                com.pullenti.unisharp.Outargwrapper<Integer> wrapv78 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                boolean inoutres79 = com.pullenti.unisharp.Utils.parseInteger(li.get(i.value + 1).value, 0, null, wrapv78);
                v = (wrapv78.value != null ? wrapv78.value : 0);
                if (inoutres79) {
                    if (v > 500 && !com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
                        if (((i.value + 2) < li.size()) && li.get(i.value + 2).getTyp() == AddressItemType.CITY) {
                        }
                        else 
                            return false;
                    }
                }
                i.value++;
                if ((((li.get(i.value).getTyp() == AddressItemType.NUMBER || li.get(i.value).getTyp() == AddressItemType.CORPUSORFLAT)) && li.get(i.value).value != null && (i.value + 1) == (li.size() - 1)) && ((li.get(i.value + 1).getTyp() == AddressItemType.NUMBER || li.get(i.value + 1).getTyp() == AddressItemType.FLAT))) {
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                    li.get(i.value).tag = addr;
                    i.value++;
                    if (li.get(i.value).value != null) {
                        addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                        li.get(i.value).tag = addr;
                    }
                    return true;
                }
                if ((((i.value + 1) < li.size()) && li.get(i.value + 1).getTyp() == AddressItemType.BUILDING && !li.get(i.value + 1).isNewlineBefore()) && li.get(i.value + 1).buildingType == com.pullenti.ner.address.AddressBuildingType.LITER) {
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                    li.get(i.value).tag = addr;
                    return true;
                }
                if ((li.get(i.value).getTyp() == AddressItemType.NUMBER && li.get(i.value).getEndToken().getNext() != null && li.get(i.value).getEndToken().getNext().isComma()) && li.get(i.value).getBeginToken().getPrevious().isComma()) {
                    if (((i.value + 1) < li.size()) && ((li.get(i.value + 1).getTyp() == AddressItemType.CORPUS || li.get(i.value + 1).getTyp() == AddressItemType.CORPUSORFLAT))) {
                        addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_BUILDING, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                        li.get(i.value).tag = addr;
                        return true;
                    }
                    else {
                        if (li.get(i.value).getBeginToken().getPrevious().isComma() && li.get(i.value).getBeginToken().getPrevious().getPrevious() != null && li.get(i.value).getBeginToken().getPrevious().getPrevious().isComma()) 
                            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                        else {
                            int vv = 0;
                            com.pullenti.unisharp.Outargwrapper<Integer> wrapvv74 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                            boolean inoutres75 = com.pullenti.unisharp.Utils.parseInteger((li.get(i.value - 1).value != null ? li.get(i.value - 1).value : ""), 0, null, wrapvv74);
                            vv = (wrapvv74.value != null ? wrapvv74.value : 0);
                            if (!inoutres75) 
                                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUSORFLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                            else {
                                com.pullenti.unisharp.Outargwrapper<Integer> wrapvv73 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                                com.pullenti.unisharp.Utils.parseInteger((li.get(i.value).value != null ? li.get(i.value).value : ""), 0, null, wrapvv73);
                                vv = (wrapvv73.value != null ? wrapvv73.value : 0);
                                addr.addSlot((i.value == (li.size() - 1) && vv > 0 ? com.pullenti.ner.address.AddressReferent.ATTR_CORPUSORFLAT : com.pullenti.ner.address.AddressReferent.ATTR_CORPUS), li.get(i.value).value, false, 0).setTag(li.get(i.value));
                            }
                        }
                        li.get(i.value).tag = addr;
                        return true;
                    }
                }
                if ((((i.value + 1) < li.size()) && li.get(i.value + 1).getTyp() == AddressItemType.NUMBER && !li.get(i.value + 1).isNewlineBefore()) && (v < 5) && li.get(i.value).value != null) {
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapv76 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                    boolean inoutres77 = com.pullenti.unisharp.Utils.parseInteger(li.get(i.value + 1).value, 0, null, wrapv76);
                    v = (wrapv76.value != null ? wrapv76.value : 0);
                    if (inoutres77) {
                        if ((v < 500) || com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(0))) {
                            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                            li.get(i.value).tag = addr;
                            i.value++;
                        }
                    }
                }
                if ((li.get(i.value).getBeginToken().getPrevious().isHiphen() || addr.findSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, null, true) != null || li.get(i.value).value == null) || ((li.get(i.value).getBeginToken().getPrevious().isComma() && li.get(i.value).getBeginToken().getPrevious().getPrevious() != null && li.get(i.value).getBeginToken().getPrevious().getPrevious().isComma()))) 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, (li.get(i.value).value != null ? li.get(i.value).value : ""), false, 0).setTag(li.get(i.value));
                else 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUSORFLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                li.get(i.value).tag = addr;
            }
            return true;
        }
        if (((!li.get(i.value).isNewlineBefore() && li.get(i.value).getTyp() == AddressItemType.NUMBER && li.get(i.value).isDigit()) && li.get(i.value).value != null && i.value > 0) && (((li.get(i.value - 1).getTyp() == AddressItemType.NUMBER || li.get(i.value - 1).getTyp() == AddressItemType.HOUSE || li.get(i.value - 1).getTyp() == AddressItemType.BUILDING) || li.get(i.value - 1).getTyp() == AddressItemType.CORPUS))) {
            if (addr.getFlat() != null) 
                return false;
            if (addr.getHouse() == null && addr.getBuilding() == null && addr.getCorpus() == null) 
                return false;
            int v;
            com.pullenti.unisharp.Outargwrapper<Integer> wrapv82 = new com.pullenti.unisharp.Outargwrapper<Integer>();
            boolean inoutres83 = com.pullenti.unisharp.Utils.parseInteger(li.get(i.value).value, 0, null, wrapv82);
            v = (wrapv82.value != null ? wrapv82.value : 0);
            if (inoutres83) {
                if (v > 1000) 
                    return false;
            }
            if (((i.value + 1) < li.size()) && ((li.get(i.value + 1).getTyp() == AddressItemType.NUMBER || li.get(i.value + 1).getTyp() == AddressItemType.FLAT))) {
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CORPUS, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                li.get(i.value).tag = addr;
                i.value++;
                if (li.get(i.value).value != null) 
                    addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                li.get(i.value).tag = addr;
            }
            else {
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                li.get(i.value).tag = addr;
            }
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.POSTOFFICEBOX) {
            if (addr.getPostOfficeBox() != null) 
                return false;
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_POSTOFFICEBOX, (li.get(i.value).value != null ? li.get(i.value).value : ""), false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.DELIVERYAREA) {
            if (addr.getDeliveryArea() != null) 
                return false;
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_DELIVERYAREA, (li.get(i.value).value != null ? li.get(i.value).value : ""), false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (li.get(i.value).getTyp() == AddressItemType.CSP) {
            if (addr.getCSP() != null) 
                return false;
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_CSP, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if ((li.get(i.value).getTyp() == AddressItemType.NONUMBER && addr.getHouse() == null && addr.getPlot() == null) && addr.getHouseOrPlot() == null) {
            addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_HOUSEORPLOT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if (((li.get(i.value).getTyp() == AddressItemType.NUMBER && addr.getHouse() == null && addr.getCorpus() == null) && addr.getBuilding() == null && addr.getPlot() == null) && addr.getHouseOrPlot() == null && (((com.pullenti.ner.geo.internal.MiscLocationHelper.isUserParamAddress(li.get(i.value)) || hasGenplan || ((i.value > 0 && li.get(i.value - 1).getTyp() == AddressItemType.SPACE))) || i.value == (li.size() - 1)))) {
            if (addr.getSpace() != null && com.pullenti.unisharp.Utils.stringsNe(addr.getSpace(), "подвал")) 
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_HOUSE, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            else if ((i.value + 2) == li.size() && li.get(i.value + 1).getTyp() == AddressItemType.NUMBER) {
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_HOUSE, li.get(i.value).value, false, 0).setTag(li.get(i.value));
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_FLAT, li.get(i.value + 1).value, false, 0).setTag(li.get(i.value + 1));
                li.get(i.value + 1).tag = addr;
            }
            else 
                addr.addSlot(com.pullenti.ner.address.AddressReferent.ATTR_HOUSEORPLOT, li.get(i.value).value, false, 0).setTag(li.get(i.value));
            li.get(i.value).tag = addr;
            return true;
        }
        if ((li.get(i.value).getTyp() == AddressItemType.NUMBER && (((addr.getHouse() != null || addr.getBuilding() != null || addr.getCorpus() != null) || addr.getHouseOrPlot() != null)) && i.value > 0) && li.get(i.value - 1).getTyp() == AddressItemType.SPACE && !li.get(i.value - 1).isDigit()) {
            addr.setSpace(li.get(i.value).value);
            li.get(i.value).tag = addr;
            return true;
        }
        if ((li.get(i.value).getTyp() == AddressItemType.NUMBER && i.value > 0 && li.get(i.value - 1).getTyp() == AddressItemType.FLOOR) && addr.getFlat() == null) {
            addr.setFlat(li.get(i.value).value);
            li.get(i.value).tag = addr;
            return true;
        }
        return false;
    }
    public AddressDefineHelper() {
    }
}
