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

public class PersonNormalHelper {

    public static void analyze(com.pullenti.ner.person.PersonNormalData res, String txt, java.util.HashMap<String, java.util.HashMap<String, String>> corr) throws Exception {
        java.util.HashMap<String, String> co = null;
        if (corr != null && corr.containsKey("")) 
            co = corr.get("");
        StringBuilder ttt = new StringBuilder(txt);
        for (int i = 1; i < (ttt.length() - 2); i++) {
            if (ttt.charAt(i) == '-' && Character.isLowerCase(ttt.charAt(i + 1))) 
                ttt.setCharAt(i + 1, Character.toUpperCase(ttt.charAt(i + 1)));
            else if (ttt.charAt(i) == '-' && ttt.charAt(i + 1) == ' ' && Character.isLetter(ttt.charAt(i + 2))) {
                ttt.setCharAt(i + 2, Character.toUpperCase(ttt.charAt(i + 2)));
                ttt.delete(i + 1, i + 1 + 1);
            }
        }
        for (int i = ttt.length() - 2; i >= 0; i--) {
            if (ttt.charAt(i) == ' ' && ttt.charAt(i + 1) == ' ') 
                ttt.delete(i + 1, i + 1 + 1);
            else if (com.pullenti.morph.LanguageHelper.isHiphen(ttt.charAt(i)) && com.pullenti.morph.LanguageHelper.isHiphen(ttt.charAt(i + 1))) 
                ttt.delete(i + 1, i + 1 + 1);
            else if (ttt.charAt(i) == '\t') 
                ttt.setCharAt(i, '\n');
        }
        txt = ttt.toString();
        res.resTyp = com.pullenti.ner.person.PersonNormalResult.NOTPERSON;
        res.errorMessage = "Похоже на просто текст";
        if (txt.length() > 200) 
            return;
        com.pullenti.ner.AnalysisResult ar = null;
        String altSurname = null;
        java.util.HashMap<String, String> addcorr = null;
        for (int kk = 0; kk < 20; kk++) {
            ar = com.pullenti.ner.ProcessorService.getEmptyProcessor().process(com.pullenti.ner.SourceOfAnalysis._new3442(txt, co, false, false), null, null);
            if (ar == null || ar.firstToken == null) 
                return;
            boolean ch = false;
            for (com.pullenti.ner.Token t = ar.firstToken; t != null; t = t.getNext()) {
                if (((((t instanceof com.pullenti.ner.TextToken) && !t.chars.isLetter() && !t.isWhitespaceBefore()) && (t.getPrevious() instanceof com.pullenti.ner.TextToken) && t.getPrevious().chars.isCyrillicLetter()) && !t.isWhitespaceAfter() && (t.getNext() instanceof com.pullenti.ner.TextToken)) && t.getNext().chars.isCyrillicLetter()) {
                    String str = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getPrevious(), com.pullenti.ner.TextToken.class)).term + ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term;
                    com.pullenti.morph.MorphWordForm mb = com.pullenti.morph.MorphologyService.getWordBaseInfo(str, com.pullenti.morph.MorphLang.RU, true, true);
                    if (mb._getClass().isProperSurname() || mb._getClass().isProperName() || mb._getClass().isProperSecname()) {
                        boolean ok = true;
                        if (t.isHiphen() && !t.getNext().chars.isAllLower()) {
                            ok = false;
                            if (m_MaleNames.contains(str) || m_MaleSecnames.contains(str) || m_FemaleSecnames.contains(str)) 
                                ok = true;
                        }
                        if (ok) {
                            txt = (txt.substring(0, 0 + t.getBeginChar()) + txt.substring(t.getEndChar() + 1));
                            ch = true;
                            break;
                        }
                    }
                }
                if ((((t instanceof com.pullenti.ner.TextToken) && ((t.chars.isCapitalUpper() || t.chars.isAllUpper())) && t.getWhitespacesAfterCount() == 1) && (t.getNext() instanceof com.pullenti.ner.TextToken) && ((t.getNext().chars.isAllLower() || t.getLengthChar() == 1))) && t.chars.isLetter() && t.getNext().chars.isLetter()) {
                    if (t.getLengthChar() == 1 && (t.getNext().getLengthChar() < 4)) 
                        continue;
                    if ((t.getLengthChar() < 4) && t.getNext().getLengthChar() == 1) 
                        continue;
                    String str = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term + ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term;
                    com.pullenti.morph.MorphWordForm mb = com.pullenti.morph.MorphologyService.getWordBaseInfo(str, com.pullenti.morph.MorphLang.RU, true, true);
                    if (mb._getClass().isProperSurname() || mb._getClass().isProperName() || mb._getClass().isProperSecname()) {
                        txt = txt.substring(0, 0 + t.getEndChar() + 1) + txt.substring(t.getNext().getBeginChar());
                        ch = true;
                        break;
                    }
                }
                else if (((t instanceof com.pullenti.ner.NumberToken) && !t.isWhitespaceAfter() && (t.getNext() instanceof com.pullenti.ner.TextToken)) && t.getNext().chars.isLetter()) {
                    String n = ((com.pullenti.ner.NumberToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.NumberToken.class)).getValue();
                    String str = null;
                    if (com.pullenti.unisharp.Utils.stringsEq(n, "0")) 
                        str = "О" + ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term;
                    else if (com.pullenti.unisharp.Utils.stringsEq(n, "3")) 
                        str = "З" + ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term;
                    if (str != null) {
                        com.pullenti.morph.MorphWordForm mb = com.pullenti.morph.MorphologyService.getWordBaseInfo(str, com.pullenti.morph.MorphLang.RU, true, true);
                        if ((mb._getClass().isProperSurname() || mb._getClass().isProperName() || mb._getClass().isProperSecname()) || t.getLengthChar() == 1) {
                            txt = (txt.substring(0, 0 + t.getEndChar()) + str.charAt(0) + txt.substring(t.getNext().getBeginChar()));
                            ch = true;
                            break;
                        }
                    }
                    if (!t.isWhitespaceBefore() && (t.getPrevious() instanceof com.pullenti.ner.TextToken) && t.getPrevious().chars.isCyrillicLetter()) {
                        com.pullenti.morph.MorphWordForm mb = com.pullenti.morph.MorphologyService.getWordBaseInfo(((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getPrevious(), com.pullenti.ner.TextToken.class)).term + ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t.getNext(), com.pullenti.ner.TextToken.class)).term, com.pullenti.morph.MorphLang.RU, true, true);
                        if (mb._getClass().isProperSurname() || mb._getClass().isProperName() || mb._getClass().isProperSecname()) {
                            txt = (txt.substring(0, 0 + t.getBeginChar()) + txt.substring(t.getEndChar() + 1));
                            ch = true;
                            break;
                        }
                    }
                }
                else if (t.isValue("РАНЕЕ", null) && (t.getNext() instanceof com.pullenti.ner.TextToken) && t.getPrevious() != null) {
                    if (t.getNext().getEndChar() < (txt.length() - 1)) 
                        txt = txt.substring(0, 0 + t.getPrevious().getEndChar() + 1) + " " + txt.substring(t.getNext().getEndChar() + 1);
                    else 
                        txt = txt.substring(0, 0 + t.getPrevious().getEndChar() + 1);
                    ch = true;
                    break;
                }
                else if ((t.isValue("ДО", null) && (t.getNext() instanceof com.pullenti.ner.TextToken) && t.getPrevious() != null) && t.getNext() != null) {
                    com.pullenti.ner.Token tt = t.getNext();
                    if (tt.isHiphen() || tt.isCharOf("\\/")) {
                        if (tt.getNext() != null) 
                            tt = tt.getNext();
                    }
                    if (((((tt.isValue("БРАК", null) || tt.isValue("ЗАМУЖЕСТВО", null) || tt.isValue("ПЕРЕМЕНА", null)) || tt.isValue("ПЕРЕМ", null) || tt.isValue("ПЕР", null)) || tt.isValue("СМЕНА", null) || tt.isValue("БР", null)) || tt.isValue("РАСТ", null) || tt.isValue("РАСТОРЖЕНИЕ", null)) || tt.isValue("РАСТОРЖ", null)) {
                        for (tt = tt.getNext(); tt != null; tt = tt.getNext()) {
                            if (((tt.isChar('.') || tt.isValue("ФАМИЛИЯ", null) || tt.isValue("ФАМ", null)) || tt.isValue("ФАМИЛ", null) || tt.isValue("БР", null)) || tt.isValue("БРАК", null)) {
                            }
                            else 
                                break;
                        }
                        if (tt instanceof com.pullenti.ner.TextToken) {
                            PersonItemToken ppp = PersonItemToken.tryAttach(tt, PersonItemToken.ParseAttr.CANBELOWER, null);
                            if (ppp != null) {
                                if (ppp.lastname != null) {
                                    altSurname = ppp.value;
                                    tt = ppp.getEndToken().getNext();
                                }
                            }
                        }
                        if (t.getPrevious() != null && t.getPrevious().getPrevious() != null && ((t.getPrevious().isHiphen() || t.getPrevious().isCharOf("\\/")))) 
                            t = t.getPrevious();
                        if (tt != null) 
                            txt = txt.substring(0, 0 + t.getPrevious().getEndChar() + 1) + " " + txt.substring(tt.getBeginChar());
                        else 
                            txt = txt.substring(0, 0 + t.getPrevious().getEndChar() + 1);
                        ch = true;
                        break;
                    }
                }
                else if (t.getNext() == null && (t instanceof com.pullenti.ner.TextToken) && t.getBeginChar() > 10) {
                    com.pullenti.morph.MorphClass mc = t.getMorphClassInDictionary();
                    if ((mc.isProperSecname() || mc.isProperName() || t.getPrevious() == null) || t.getPrevious().getPrevious() == null) {
                    }
                    else {
                        com.pullenti.ner.person.PersonNormalData rr = new com.pullenti.ner.person.PersonNormalData(null);
                        rr.middlename = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term;
                        _corrCoef(t, rr, corr);
                        if (rr.corrWords.containsKey(((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term)) {
                            addcorr = rr.corrWords;
                            txt = txt.substring(0, 0 + t.getBeginChar()) + rr.corrWords.get(((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term);
                            ch = true;
                            break;
                        }
                    }
                }
                if ((t instanceof com.pullenti.ner.TextToken) && t.getLengthChar() > 10 && t.chars.isCyrillicLetter()) {
                    if ((!t.chars.isAllLower() && !t.chars.isCapitalUpper() && !t.chars.isAllUpper()) && !t.chars.isLastLower()) {
                        String str = t.getSourceText();
                        if (Character.isUpperCase(str.charAt(0)) && Character.isLowerCase(str.charAt(1))) {
                            for (int ii = 2; ii < (str.length() - 4); ii++) {
                                if (Character.isUpperCase(str.charAt(ii)) && Character.isLowerCase(str.charAt(ii + 1)) && Character.isLetter(str.charAt(ii + 1))) {
                                    String s1 = str.substring(0, 0 + ii).toUpperCase();
                                    String s2 = str.substring(ii).toUpperCase();
                                    com.pullenti.morph.MorphWordForm b1 = com.pullenti.morph.MorphologyService.getWordBaseInfo(s1, com.pullenti.morph.MorphLang.RU, true, true);
                                    com.pullenti.morph.MorphWordForm b2 = com.pullenti.morph.MorphologyService.getWordBaseInfo(s2, com.pullenti.morph.MorphLang.RU, true, true);
                                    if (b1._getClass().isProper() && b2._getClass().isProper()) {
                                        txt = txt.substring(0, 0 + t.getBeginChar() + ii) + " " + txt.substring(t.getBeginChar() + ii);
                                        ch = true;
                                    }
                                    break;
                                }
                            }
                        }
                        if (ch) 
                            break;
                    }
                }
                if (t.isHiphen()) {
                    boolean okk = false;
                    if (t.isWhitespaceBefore() || t.isWhitespaceAfter()) 
                        okk = true;
                    else if ((t.getPrevious() != null && t.getPrevious().getMorph()._getClass().isProperSurname() && t.getNext() != null) && t.getNext().getMorphClassInDictionary().isProperName()) 
                        okk = true;
                    if (okk) {
                        txt = txt.substring(0, 0 + t.getBeginChar()) + " " + txt.substring(t.getEndChar() + 1);
                        ch = true;
                        break;
                    }
                }
            }
            if (!ch) 
                break;
        }
        int maxChar = 0;
        for (com.pullenti.ner.Token t = ar.firstToken; t != null; t = t.getNext()) {
            if (t.isValue("ДО", null) && t.getNext() != null && t.getNext().isValue("БРАК", null)) {
                maxChar = t.getPrevious().getEndChar();
                break;
            }
            else if (t.isValue("БЕЗ", null) && t.getNext() != null && t.getNext().isValue("ОТЧЕСТВА", null)) {
                maxChar = t.getPrevious().getEndChar();
                break;
            }
            else if (t.isValue("БЕЗ", null) && t.getNext() != null && t.getNext().isValue("СОГЛАСИЕ", null)) 
                return;
            else if (t.isValue("ПО", null) && t.getNext() != null && t.getNext().isValue("ДАННЫЙ", null)) {
                maxChar = t.getPrevious().getEndChar();
                break;
            }
            else if ((t instanceof com.pullenti.ner.TextToken) && t.getNext() == null) {
                String term = ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(t, com.pullenti.ner.TextToken.class)).term;
                if (((com.pullenti.unisharp.Utils.stringsEq(term, "НЕТ") || com.pullenti.unisharp.Utils.stringsEq(term, "РФ") || com.pullenti.unisharp.Utils.stringsEq(term, "РОССИЯ")) || com.pullenti.unisharp.Utils.stringsEq(term, "МУЖ") || com.pullenti.unisharp.Utils.stringsEq(term, "ЖЕН")) || com.pullenti.unisharp.Utils.stringsEq(term, "ЖЕНА")) {
                    maxChar = t.getPrevious().getEndChar();
                    break;
                }
            }
        }
        int cou = 0;
        int dict = 0;
        int prdict = 0;
        int props = 0;
        int __org = 0;
        for (com.pullenti.ner.Token tt = ar.firstToken; tt != null; tt = tt.getNext()) {
            if (maxChar > 0 && tt.getBeginChar() > maxChar) 
                break;
            cou++;
            com.pullenti.ner.address.internal.AddressItemToken ait = com.pullenti.ner.address.internal.AddressItemToken.tryParsePureItem(tt, null, null);
            if (ait != null) {
                if (ait.getTyp() == com.pullenti.ner.address.internal.AddressItemType.NUMBER || ait.value == null) 
                    continue;
                res.resTyp = com.pullenti.ner.person.PersonNormalResult.NOTPERSON;
                res.errorMessage = "Похоже на просто текст";
                return;
            }
            com.pullenti.morph.MorphClass mc = tt.getMorphClassInDictionary();
            if (mc.isProperName() || mc.isProperSecname() || mc.isProperSurname()) {
                prdict = 0;
                dict--;
                props++;
                continue;
            }
            com.pullenti.ner.ReferentToken oty = tt.kit.processReferent("ORGANIZATION", tt, "TYPE");
            if (oty != null && oty.getEndToken().isValue("ОЛИМПИАДА", null)) 
                oty = null;
            if (oty != null) {
                __org++;
                if (oty.getBeginToken() != oty.getEndToken() || tt == ar.firstToken) {
                    boolean ok = false;
                    if (oty.getEndToken().getNext() != null) {
                        com.pullenti.morph.MorphClass mc1 = oty.getEndToken().getNext().getMorphClassInDictionary();
                        if (mc1.isProperName() || mc1.isProperSecname()) 
                            ok = true;
                    }
                    if (!ok) {
                        res.errorMessage = "Похоже на организацию";
                        return;
                    }
                }
            }
            if (com.pullenti.ner.core.BracketHelper.isBracket(tt, true)) {
                if (__org > 0) {
                    res.errorMessage = "Похоже на организацию";
                    return;
                }
            }
            if (tt.getLengthChar() >= 2 && ((tt.chars.isAllLower() || !mc.isUndefined()))) {
                if (!tt.chars.isAllLower() && (tt.getLengthChar() < 5)) {
                }
                else if (mc.isAdjective()) {
                    prdict++;
                    dict += prdict;
                }
            }
            else 
                prdict = 0;
        }
        if (dict > (cou - 2) || ((dict == 2 && (cou < 5))) || dict >= 3) {
            if (props < 2) 
                return;
        }
        if (__org > 1 || ((__org > 0 && (props < 1)))) {
            res.errorMessage = "Похоже на организацию";
            return;
        }
        com.pullenti.ner.Token t0 = ar.firstToken;
        for (com.pullenti.ner.Token tt = t0; tt != null; tt = tt.getNext()) {
            if (maxChar > 0 && tt.getBeginChar() > maxChar) 
                break;
            if (tt.getLengthChar() == 1 && !tt.chars.isLetter()) {
                t0 = tt.getNext();
                continue;
            }
            if (!tt.chars.isAllLower()) 
                break;
            com.pullenti.morph.MorphClass mc = tt.getMorphClassInDictionary();
            if (mc.isProper()) 
                break;
            if (mc.isUndefined()) {
                if (tt.getNext() != null && tt.getNext().isCharOf(",.")) {
                }
                else 
                    break;
            }
            break;
        }
        int attrs = ((PersonItemToken.ParseAttr.CANBELOWER.value()) | (PersonItemToken.ParseAttr.MUSTBEITEMALWAYS.value()) | (PersonItemToken.ParseAttr.NOMINATIVECASE.value())) | (PersonItemToken.ParseAttr.SURNAMEPREFIXNOTMERGE.value());
        java.util.ArrayList<PersonItemToken> pits = PersonItemToken.tryAttachList(t0, PersonItemToken.ParseAttr.of(attrs), 10);
        com.pullenti.ner.Token tt0 = ar.firstToken;
        if (pits != null && pits.size() > 0) {
            PersonItemToken pit = pits.get(pits.size() - 1);
            tt0 = pit.getEndToken().getNext();
            if (tt0 != null && pit.chars.isAllLower() && pits.size() > 1) {
                tt0 = pit.getBeginToken();
                pits.remove(pits.size() - 1);
            }
        }
        else 
            pits = new java.util.ArrayList<PersonItemToken>();
        double coefMult = 1.0;
        for (; tt0 != null; tt0 = tt0.getNext()) {
            if (maxChar > 0 && tt0.getBeginChar() > maxChar) 
                break;
            coefMult *= 0.9;
            java.util.ArrayList<PersonItemToken> pits1 = PersonItemToken.tryAttachList(tt0, PersonItemToken.ParseAttr.of((PersonItemToken.ParseAttr.NOMINATIVECASE.value()) | (PersonItemToken.ParseAttr.SURNAMEPREFIXNOTMERGE.value())), 10);
            if (pits1 != null && pits.size() > 0) {
                com.pullenti.unisharp.Utils.addToArrayList(pits, pits1);
                tt0 = pits1.get(pits1.size() - 1).getEndToken();
            }
        }
        if (pits.size() > 15) 
            return;
        if (pits != null && pits.size() > 3) {
            for (int i = 0; i < (pits.size() - 3); i++) {
                if (com.pullenti.unisharp.Utils.stringsEq(pits.get(i).value, pits.get(i + 2).value) && com.pullenti.unisharp.Utils.stringsEq(pits.get(i + 1).value, pits.get(i + 3).value)) {
                    pits.get(i + 1).setEndToken(pits.get(i + 3).getEndToken());
                    pits.remove(i + 3);
                    pits.remove(i + 2);
                    i--;
                }
            }
            for (int i = 0; i < (pits.size() - 2); i++) {
                if (com.pullenti.unisharp.Utils.stringsEq(pits.get(i).value, (pits.get(i + 1).value + "-" + pits.get(i + 2).value))) {
                    pits.get(i + 1).setBeginToken(pits.get(i).getBeginToken());
                    pits.remove(i);
                    i--;
                }
            }
            for (int i = 0; i < (pits.size() - 2); i++) {
                if (com.pullenti.unisharp.Utils.stringsEq(pits.get(i + 2).value, (pits.get(i).value + "-" + pits.get(i + 1).value))) {
                    pits.get(i + 1).setEndToken(pits.get(i + 2).getEndToken());
                    pits.remove(i + 2);
                    i--;
                }
            }
            for (int i = 0; i < (pits.size() - 1); i++) {
                if (com.pullenti.unisharp.Utils.stringsEq(pits.get(i).value, pits.get(i + 1).value)) {
                    pits.get(i).setEndToken(pits.get(i + 1).getEndToken());
                    pits.remove(i + 1);
                    i--;
                }
            }
        }
        if (pits != null) {
            double coef = m_Fio.process(pits);
            double ciof = m_Iof.process(pits);
            ciof *= 0.9;
            PersonNormalNode pn = m_Fio;
            if (coef < ciof) {
                pn = m_Iof;
                coef = ciof;
            }
            if (coef > 0.3) {
                pn.createResult(res);
                res.coef = (int)((coef * (100.0) * coefMult));
                res.lastnameAlt = altSurname;
                _corrCoef(ar.firstToken, res, corr);
                res.resTyp = com.pullenti.ner.person.PersonNormalResult.OK;
                if (res.coef < 60) 
                    res.resTyp = com.pullenti.ner.person.PersonNormalResult.MANUAL;
                if (addcorr != null) {
                    for (java.util.Map.Entry<String, String> kp : addcorr.entrySet()) {
                        if (!res.corrWords.containsKey(kp.getKey())) 
                            res.corrWords.put(kp.getKey(), kp.getValue());
                    }
                }
                return;
            }
        }
        ar = com.pullenti.ner.ProcessorService.getStandardProcessor().process(com.pullenti.ner.SourceOfAnalysis._new3443(txt, co, false), null, null);
        if (ar != null) {
            for (com.pullenti.ner.Token tt = ar.firstToken; tt != null; tt = tt.getNext()) {
                com.pullenti.ner.Referent r = tt.getReferent();
                if (r != null && ((com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "GEO") || com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "STREET") || com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "ADDRESS")))) {
                    res.errorMessage = "Похоже на адрес";
                    return;
                }
                if (r != null && com.pullenti.unisharp.Utils.stringsEq(r.getTypeName(), "ORGANIZATION")) {
                    res.errorMessage = "Похоже на организацию";
                    return;
                }
                if (r instanceof com.pullenti.ner.person.PersonReferent) {
                    com.pullenti.ner.person.PersonReferent pr = (com.pullenti.ner.person.PersonReferent)com.pullenti.unisharp.Utils.cast(r, com.pullenti.ner.person.PersonReferent.class);
                    res.coef = 100;
                    res.resTyp = com.pullenti.ner.person.PersonNormalResult.OK;
                    if ((((res.firstname = pr.getStringValue(com.pullenti.ner.person.PersonReferent.ATTR_FIRSTNAME)))) == null) 
                        res.coef = (int)((0.8 * ((double)res.coef)));
                    res.middlename = pr.getStringValue(com.pullenti.ner.person.PersonReferent.ATTR_MIDDLENAME);
                    if ((((res.lastname = pr.getStringValue(com.pullenti.ner.person.PersonReferent.ATTR_LASTNAME)))) == null) 
                        res.coef = (int)((0.5 * ((double)res.coef)));
                    for (com.pullenti.ner.Token tt2 = tt.getNext(); tt2 != null; tt2 = tt2.getNext()) {
                        if ((tt2 instanceof com.pullenti.ner.TextToken) && !tt2.chars.isLetter()) {
                        }
                        else 
                            res.coef = (int)((0.5 * ((double)res.coef)));
                    }
                    for (com.pullenti.ner.Token tt2 = tt.getPrevious(); tt2 != null; tt2 = tt2.getPrevious()) {
                        if ((tt2 instanceof com.pullenti.ner.TextToken) && !tt2.chars.isLetter()) {
                        }
                        else 
                            res.coef = (int)((0.5 * ((double)res.coef)));
                    }
                    _corrCoef(ar.firstToken, res, corr);
                    if (res.coef < 90) 
                        res.resTyp = com.pullenti.ner.person.PersonNormalResult.MANUAL;
                    return;
                }
            }
        }
    }

    private static java.util.HashMap<String, String> corrMiddnameTails;

    private static void _loadCorrMiddlaTails(String txt) {
        corrMiddnameTails = new java.util.HashMap<String, String>();
        for (String s : com.pullenti.unisharp.Utils.split(txt, String.valueOf('\n'), false)) {
            String line = s.trim().toUpperCase();
            int i = line.indexOf(":");
            if (i < 0) 
                i = line.indexOf(';');
            if (i < 0) 
                continue;
            String err = line.substring(0, 0 + i);
            if (err.endsWith("$")) 
                err = err.substring(0, 0 + err.length() - 1);
            String ok = line.substring(i + 1);
            if (!corrMiddnameTails.containsKey(err)) 
                corrMiddnameTails.put(err, ok);
        }
    }

    private static void _corrCoef(com.pullenti.ner.Token t, com.pullenti.ner.person.PersonNormalData r, java.util.HashMap<String, java.util.HashMap<String, String>> corr) throws Exception {
        if (t.kit.correctedTokens != null) {
            for (java.util.Map.Entry<com.pullenti.ner.Token, String> kp : t.kit.correctedTokens.entrySet()) {
                if (kp.getKey() instanceof com.pullenti.ner.TextToken) {
                    if (!r.corrWords.containsKey(kp.getValue())) 
                        r.corrWords.put(kp.getValue(), ((com.pullenti.ner.TextToken)com.pullenti.unisharp.Utils.cast(kp.getKey(), com.pullenti.ner.TextToken.class)).term);
                }
            }
        }
        if (corr != null) {
            java.util.HashMap<String, String> dic;
            com.pullenti.unisharp.Outargwrapper<java.util.HashMap<String, String>> wrapdic3448 = new com.pullenti.unisharp.Outargwrapper<java.util.HashMap<String, String>>();
            boolean inoutres3449 = com.pullenti.unisharp.Utils.tryGetValue(corr, "name", wrapdic3448);
            dic = wrapdic3448.value;
            if (r.firstname != null && inoutres3449) {
                if (dic.containsKey(r.firstname)) {
                    if (!r.corrWords.containsKey(r.firstname)) 
                        r.corrWords.put(r.firstname, dic.get(r.firstname));
                    r.firstname = dic.get(r.firstname);
                    r.coef = (int)((((double)r.coef) * 0.95));
                }
            }
            com.pullenti.unisharp.Outargwrapper<java.util.HashMap<String, String>> wrapdic3446 = new com.pullenti.unisharp.Outargwrapper<java.util.HashMap<String, String>>();
            boolean inoutres3447 = com.pullenti.unisharp.Utils.tryGetValue(corr, "midname", wrapdic3446);
            dic = wrapdic3446.value;
            if (r.middlename != null && inoutres3447) {
                if (dic.containsKey(r.middlename)) {
                    if (!r.corrWords.containsKey(r.middlename)) 
                        r.corrWords.put(r.middlename, dic.get(r.middlename));
                    r.middlename = dic.get(r.middlename);
                    r.coef = (int)((((double)r.coef) * 0.95));
                }
            }
            com.pullenti.unisharp.Outargwrapper<java.util.HashMap<String, String>> wrapdic3444 = new com.pullenti.unisharp.Outargwrapper<java.util.HashMap<String, String>>();
            boolean inoutres3445 = com.pullenti.unisharp.Utils.tryGetValue(corr, "lastname", wrapdic3444);
            dic = wrapdic3444.value;
            if (r.lastname != null && inoutres3445) {
                if (dic.containsKey(r.lastname)) {
                    if (!r.corrWords.containsKey(r.lastname)) 
                        r.corrWords.put(r.lastname, dic.get(r.lastname));
                    r.lastname = dic.get(r.lastname);
                    r.coef = (int)((((double)r.coef) * 0.95));
                }
            }
        }
        if (r.middlename != null) {
            for (java.util.Map.Entry<String, String> kp : corrMiddnameTails.entrySet()) {
                if (r.middlename.endsWith(kp.getKey())) {
                    String mmm = r.middlename;
                    r.middlename = r.middlename.substring(0, 0 + r.middlename.length() - kp.getKey().length());
                    r.middlename += kp.getValue();
                    r.coef = (int)((((double)r.coef) * 0.95));
                    if (!r.corrWords.containsKey(mmm)) 
                        r.corrWords.put(mmm, r.middlename);
                    break;
                }
            }
        }
        if (r.firstnameAlt != null) {
            if (ShortNameHelper.getNamesForShortname(r.firstnameAlt) == null) {
                if (com.pullenti.unisharp.Utils.stringsNe(r.firstnameAlt, "СВЕТА")) {
                    if (m_MaleNames.contains(r.firstname)) {
                        if (!r.corrWords.containsKey(r.firstnameAlt)) 
                            r.corrWords.put(r.firstnameAlt, r.firstname);
                    }
                    else 
                        r.firstname = r.firstnameAlt;
                    r.firstnameAlt = null;
                }
            }
        }
        if (r.firstname != null) {
            String cc = _corrDublsChars(r.firstname, 1, r.gender);
            if (cc != null) {
                if (!r.corrWords.containsKey(r.firstname)) 
                    r.corrWords.put(r.firstname, cc);
                r.firstname = cc;
                r.coef = (int)((((double)r.coef) * 0.95));
            }
        }
        if (r.middlename != null) {
            String cc = _corrDublsChars(r.middlename, 2, r.gender);
            if (cc != null) {
                if (!r.corrWords.containsKey(r.middlename)) 
                    r.corrWords.put(r.middlename, cc);
                r.middlename = cc;
                r.coef = (int)((((double)r.coef) * 0.95));
            }
            com.pullenti.morph.MorphWordForm bb = com.pullenti.morph.MorphologyService.getWordBaseInfo(r.middlename, com.pullenti.morph.MorphLang.RU, true, true);
            if (!bb._getClass().isProperSecname() && (r.middlename.indexOf('-') < 0)) {
                cc = com.pullenti.morph.MorphologyService.correctWord(r.middlename, null);
                if (cc != null) {
                    if (((r.gender == 1 && m_MaleSecnames.contains(cc))) || ((r.gender == 2 && m_FemaleSecnames.contains(cc)))) {
                        if (!r.corrWords.containsKey(r.middlename)) 
                            r.corrWords.put(r.middlename, cc);
                        r.middlename = cc;
                        r.coef = (int)((((double)r.coef) * 0.95));
                    }
                }
            }
        }
        if (r.lastname != null) {
            int glas = 0;
            for (char ch : r.lastname.toCharArray()) {
                if (com.pullenti.morph.LanguageHelper.isCyrillicVowel(ch)) 
                    glas++;
            }
            if (glas == 0) 
                r.coef = (int)((((double)r.coef) * 0.8));
            else if (glas > 2 && glas == r.lastname.length()) 
                r.coef = (int)((((double)r.coef) * 0.6));
            String cc = _corrDublsChars(r.lastname, 3, r.gender);
            if (cc != null) {
                if (!r.corrWords.containsKey(r.lastname)) 
                    r.corrWords.put(r.lastname, cc);
                r.lastname = cc;
                r.coef = (int)((((double)r.coef) * 0.95));
            }
        }
    }

    private static String _corrDublsChars(String str, int typ, int gender) throws Exception {
        if (str.length() < 4) 
            return null;
        int cou = 0;
        for (int i = str.length() - 2; i > 0; i--) {
            if (str.charAt(i) != str.charAt(str.length() - 1)) {
                if (cou >= 2) {
                    String res = str.substring(0, 0 + i + 2);
                    com.pullenti.morph.MorphWordForm bb = com.pullenti.morph.MorphologyService.getWordBaseInfo(res, com.pullenti.morph.MorphLang.RU, true, true);
                    if (bb._getClass().isProper()) 
                        return res;
                    String res0 = res.substring(0, 0 + res.length() - 1);
                    bb = com.pullenti.morph.MorphologyService.getWordBaseInfo(res0, com.pullenti.morph.MorphLang.RU, true, true);
                    if (bb._getClass().isProper()) 
                        return res0;
                    return res;
                }
                break;
            }
            else 
                cou++;
        }
        if (typ == 3) 
            return null;
        if (typ == 2) {
            if (gender == 1 && !str.endsWith("ИЧ")) {
                String str1 = str.substring(0, 0 + str.length() - 1);
                if (str1.endsWith("ИЧ")) 
                    return str1;
            }
        }
        com.pullenti.morph.MorphWordForm bb0 = com.pullenti.morph.MorphologyService.getWordBaseInfo(str, com.pullenti.morph.MorphLang.RU, true, true);
        if (typ == 1 && com.pullenti.morph.LanguageHelper.isCyrillicVowel(str.charAt(str.length() - 1))) {
            String str1 = str + "Й";
            if (m_MaleNames.contains(str1)) 
                return str1;
        }
        if (bb0._getClass().isProper()) 
            return null;
        String str0 = str.substring(0, 0 + str.length() - 1);
        bb0 = com.pullenti.morph.MorphologyService.getWordBaseInfo(str0, com.pullenti.morph.MorphLang.RU, true, true);
        if (bb0._getClass().isProperName() && typ == 1 && bb0.getNumber() == com.pullenti.morph.MorphNumber.SINGULAR) {
            if (str0.charAt(str0.length() - 1) == str.charAt(str.length() - 1)) 
                return str0;
        }
        if (bb0._getClass().isProperSecname() && typ == 2 && bb0.getNumber() == com.pullenti.morph.MorphNumber.SINGULAR) 
            return str0;
        return null;
    }

    private static java.util.ArrayList<String> m_MaleNames;

    private static java.util.ArrayList<String> m_MaleSecnames;

    private static java.util.ArrayList<String> m_FemaleSecnames;

    private static PersonNormalNode m_Fio;

    private static PersonNormalNode m_Iof;

    public static void initialize() {
        _loadCorrMiddlaTails("слаовна$:славовна\nславона$:славовна\nславоич$:славович\nслаович$:славович\nвнана$:вна\nевана$:евна\nевнва$:евна\nевнаа$:евна\nевнна$:евна\nована$:овна\nовнва$:овна\nовнаа$:овна\nовнна$:овна\nевена$:евна\nевсна$:евна\nевона$:евна\nовена$:овна\nовсна$:овна\nовона$:овна\nовоич$:ович\nевича$:евич\nевичч$:евич\nевивч$:евич\nевиич$:евич\nеваич$:евич\nевнич$:евич\nовича$:ович\nовичч$:ович\nовивч$:ович\nовиич$:ович\nоваич$:ович\nовнич$:ович\nеана$:евна\nенва$:евна\nевнв$:евна\nевне$:евна\nевну$:евна\nевны$:евна\nевеа$:евна\nеван$:евна\nоана$:овна\nонва$:овна\nовнв$:овна\nовне$:овна\nовну$:овна\nовны$:овна\nовеа$:овна\nован$:овна\nевга$:евна\nовга$:овна\nвеич$:евич\nвоич$:ович\nивоч$:ович\nовоч$:ович\nевия$:евич\nевмч$:евич\nеивч$:евич\nеаич$:евич\nивеч$:евич\nевоч$:евич\nовия$:ович\nовмч$:ович\nоивч$:ович\nеаич$:ович\nевн$:евна\nена$:евна\nовн$:овна\nона$:овна\nеич$:евич\nови$:ович\nоич$:ович\nевч$:евич\nеви$:евич\nовч$:ович\nови$:ович\nишна$:ична\nофич$:ович\nефич$:евич\nева$:евна\nова$:овна");
    }

    public PersonNormalHelper() {
    }
    
    static {
        m_MaleNames = new java.util.ArrayList<String>(java.util.Arrays.asList(new String[] {"АНДРЕЙ", "АЛЕКСЕЙ", "АЛЕКСАНДР", "АНАТОЛИЙ", "АРКАДИЙ", "АРТЕМ", "БОРИС", "ВАЛЕНТИН", "ВАЛЕРИЙ", "ВАСИЛИЙ", "ВИКТОР", "ВИТАЛИЙ", "ВЛАДИМИР", "ВЛАДИСЛАВ", "ВСЕВОЛОД", "ГЕННАДИЙ", "ГЕНАДИЙ", "ГЕОРГИЙ", "ГРИГОРИЙ", "ДЕНИС", "ДМИТРИЙ", "ЕВГЕНИЙ", "ЕГОР", "ИВАН", "ИГОРЬ", "КИРИЛЛ", "КОНСТАНТИН", "ЛЕОНИД", "ЛЕВ", "МАКСИМ", "МИХАИЛ", "НИКОЛАЙ", "НИКИТА", "ОЛЕГ", "ПАВЕЛ", "ПЕТР", "РОМАН", "СЕМЕН", "СЕРГЕЙ", "СТАНИСЛАВ", "СТЕПАН", "ФЕДОР", "ЭДУАРД", "ЮРИЙ", "ЯКОВ", "ЯРОСЛАВ"}));
        m_MaleSecnames = new java.util.ArrayList<String>(java.util.Arrays.asList(new String[] {"АЛЕКСЕЕВИЧ", "АЛЕКСАНДРОВИЧ", "АНАТОЛЬЕВИЧ", "АЛЬБЕРТОВИЧ", "АНДРЕЕВИЧ", "АРКАДЬЕВИЧ", "АРТЕМОВИЧ", "БОРИСОВИЧ", "ВАЛЕНТИНОВИЧ", "ВАЛЕРЬЕВИЧ", "ВАСИЛЬЕВИЧ", "ВИКТОРОВИЧ", "ВИТАЛЬЕВИЧ", "ВЛАДИМИРОВИЧ", "ВЛАДИСЛАВОВИЧ", "ВСЕВОЛОДОВИЧ", "ГЕННАДИЕВИЧ", "ГЕНАДИЕВИЧ", "ГЕОРГИЕВИЧ", "ГРИГОРЬЕВИЧ", "ДЕНИСОВИЧ", "ДМИТРИЕВИЧ", "ЕВГЕНЬЕВИЧ", "ЕГОРОВИЧ", "ИВАНОВИЧ", "ИГОРЕВИЧ", "ИЛЬИЧ", "КИРИЛЛОВИЧ", "КОНСТАНТИНОВИЧ", "ЛЕОНИДОВИЧ", "ЛЬВОВИЧ", "МАКСИМОВИЧ", "МИХАЙЛОВИЧ", "НИКОЛАЕВИЧ", "НИКИТИЧ", "ОЛЕГОВИЧ", "ПАВЛОВИЧ", "ПЕТРОВИЧ", "РОМАНОВИЧ", "СЕМЕНОВИЧ", "СЕРГЕЕВИЧ", "СТАНИСЛАВОВИЧ", "СТЕПАНОВИЧ", "ФЕДОРОВИЧ", "ЭДУАРДОВИЧ", "ЮРЬЕВИЧ", "ЯКОВЛЕВИЧ", "ЯРОСЛАВОВИЧ"}));
        m_FemaleSecnames = new java.util.ArrayList<String>(java.util.Arrays.asList(new String[] {"АЛЕКСЕЕВНА", "АЛЕКСАНДРОВНА", "АНАТОЛЬЕВНА", "АЛЬБЕРТОВНА", "АНДРЕЕВНА", "АРКАДЬЕВНА", "АРТЕМОВНА", "БОРИСОВНА", "ВАЛЕНТИНОВНА", "ВАЛЕРЬЕВНА", "ВАСИЛЬЕВНА", "ВИКТОРОВНА", "ВИТАЛЬЕВНА", "ВЛАДИМИРОВНА", "ВЛАДИСЛАВОВНА", "ВСЕВОЛОДОВНА", "ГЕННАДИЕВНА", "ГЕНАДИЕВНА", "ГЕОРГИЕВНА", "ГРИГОРЬЕВНА", "ДЕНИСОВНА", "ДМИТРИЕВНА", "ЕВГЕНЬЕВНА", "ЕГОРОВНА", "ИВАНОВНА", "ИГОРЕВНА", "ИЛЬИНИЧНА", "КИРИЛЛОВНА", "КОНСТАНТИНОВНА", "ЛЕОНИДОВНА", "ЛЬВОВНА", "МАКСИМОВНА", "МИХАЙЛОВНА", "НИКОЛАЕВНА", "НИКИТИЧНА", "ОЛЕГОВНА", "ПАВЛОВНА", "ПЕТРОВНА", "РОМАНОВНА", "СЕМЕНОВНА", "СЕРГЕЕВНА", "СТАНИСЛАВОВНА", "СТЕПАНОВНА", "ФЕДОРОВНА", "ЭДУАРДОВНА", "ЮРЬЕВНА", "ЯКОВЛЕВНА", "ЯРОСЛАВОВНА"}));
        m_Fio = new PersonNormalNode(false);
        m_Iof = new PersonNormalNode(true);
    }
}
