com.ctrip.infosec.rule.util.Emitter.java Source code

Java tutorial

Introduction

Here is the source code for com.ctrip.infosec.rule.util.Emitter.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ctrip.infosec.rule.util;

import static com.ctrip.infosec.configs.utils.EventBodyUtils.valueAsInt;
import static com.ctrip.infosec.configs.utils.EventBodyUtils.valueAsString;
import static com.ctrip.infosec.configs.utils.EventBodyUtils.valueAsBoolean;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import com.ctrip.infosec.common.Constants;
import com.ctrip.infosec.common.model.RiskFact;
import com.ctrip.infosec.configs.rule.trace.logger.TraceLogger;
import com.ctrip.infosec.configs.rulemonitor.RuleMonitorHelper;
import com.ctrip.infosec.configs.utils.EventBodyUtils;
import com.ctrip.infosec.counter.model.CounterRuleExecuteResult;
import com.ctrip.infosec.counter.model.PolicyExecuteResult;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 *
 * @author zhengby
 */
public class Emitter {

    public static void emit(RiskFact fact, int riskLevel, String riskMessage) {
        String ruleNo = (String) fact.ext.get(Constants.key_ruleNo);
        emit(fact, ruleNo, riskLevel, riskMessage);
    }

    public static void emit(RiskFact fact, String riskLevelTxt, String riskMessage) {
        if (!StringUtils.isNumeric(riskLevelTxt)) {
            throw new IllegalArgumentException("\"riskLevel\"");
        }
        int riskLevel = NumberUtils.toInt(riskLevelTxt);
        emit(fact, riskLevel, riskMessage);
    }

    public static void emit(RiskFact fact, int riskLevel, String riskMessage, String... riskScene) {
        String ruleNo = (String) fact.ext.get(Constants.key_ruleNo);
        emit(fact, ruleNo, riskLevel, riskMessage, riskScene);
    }

    public static void emit(RiskFact fact, String riskLevelTxt, String riskMessage, String... riskScene) {
        if (!StringUtils.isNumeric(riskLevelTxt)) {
            throw new IllegalArgumentException("\"riskLevel\"");
        }
        int riskLevel = NumberUtils.toInt(riskLevelTxt, 0);
        emit(fact, riskLevel, riskMessage, riskScene);
    }

    public static void emit(RiskFact fact, String ruleNo, int riskLevel, String riskMessage) {
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (!Strings.isNullOrEmpty(ruleNo)) {
            Map<String, Object> result = Maps.newHashMap();
            result.put(Constants.riskLevel, riskLevel);
            result.put(Constants.riskMessage, riskMessage);
            result.put(Constants.async, _isAsync);
            if (!_isAsync) {
                result.put(Constants.ruleType, "N");
                fact.results.put(ruleNo, result);
            } else {
                result.put(Constants.ruleType, "NA");
                fact.results4Async.put(ruleNo, result);
            }

            //            RuleMonitorHelper.addRiskRuleNo(ruleNo);
            RuleMonitorHelper.addRiskRuleNo(ruleNo, riskLevel);
        }

    }

    public static void emit(RiskFact fact, String ruleNo, int riskLevel, String riskMessage, String... riskScene) {
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (!Strings.isNullOrEmpty(ruleNo)) {
            Map<String, Object> result = Maps.newHashMap();
            result.put(Constants.riskLevel, riskLevel);
            result.put(Constants.riskMessage, riskMessage);
            result.put(Constants.riskScene, Lists.newArrayList(riskScene));
            result.put(Constants.async, _isAsync);
            if (!_isAsync) {
                result.put(Constants.ruleType, "S");
                fact.resultsGroupByScene.put(ruleNo, result);
            } else {
                result.put(Constants.ruleType, "SA");
                fact.resultsGroupByScene4Async.put(ruleNo, result);
            }

            //            RuleMonitorHelper.addRiskRuleNo(ruleNo);
            RuleMonitorHelper.addRiskRuleNo(ruleNo, riskLevel);
        }
    }

    //
    //    ??subSceneType:
    //    
    //    resultsGroupByScene
    //    {
    //        "R1": {
    //            "riskLevel": 278,
    //            "riskMessage": "",
    //            "riskScene": [
    //                "PAYMENT-CONF-CC",
    //                "PAYMENT-CONF-DCARD"
    //            ],
    //            "subSceneType": {
    //                "PAYMENT-CONF-CC": {
    //                    "CC_ABC": {
    //                        "riskLevel": 295,
    //                        "riskMessage": ""
    //                    },
    //                    "CC_BOC": {
    //                        "riskLevel": 295,
    //                        "riskMessage": ""
    //                    }
    //                }
    //            }
    //        }
    //    }
    //    
    //    finalResultGroupByScene
    //    {
    //        "PAYMENT-CONF-CC": {
    //            "riskLevel": 278,
    //            "riskMessage": "",
    //            "subSceneType": {
    //                "CC_ABC": {
    //                    "riskLevel": 295,
    //                    "riskMessage": ""
    //                },
    //                "CC_BOC": {
    //                    "riskLevel": 295,
    //                    "riskMessage": ""
    //                }
    //            }
    //        },
    //        "PAYMENT-CONF-DCARD": {
    //            "riskLevel": 278,
    //            "riskMessage": ""
    //        }
    //    }
    public static void emit(RiskFact fact, int riskLevel, String riskMessage, String[] riskScene,
            Map<String, Map<String, Map<String, String>>> subSceneType) {
        String ruleNo = (String) fact.ext.get(Constants.key_ruleNo);
        emit(fact, ruleNo, riskLevel, riskMessage, riskScene, subSceneType);
    }

    public static void emit(RiskFact fact, String ruleNo, int riskLevel, String riskMessage, String[] riskScene,
            Map<String, Map<String, Map<String, String>>> subSceneType) {
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (!Strings.isNullOrEmpty(ruleNo)) {
            Map<String, Object> result = Maps.newHashMap();
            result.put(Constants.riskLevel, riskLevel);
            result.put(Constants.riskMessage, riskMessage);
            result.put(Constants.riskScene, Lists.newArrayList(riskScene));
            result.put(Constants.subSceneType, subSceneType);
            result.put(Constants.async, _isAsync);
            if (!_isAsync) {
                result.put(Constants.ruleType, "S");
                fact.resultsGroupByScene.put(ruleNo, result);
            } else {
                result.put(Constants.ruleType, "SA");
                fact.resultsGroupByScene4Async.put(ruleNo, result);
            }
        }
    }

    /**
     * ?Counter
     */
    public static void emit(RiskFact fact, PolicyExecuteResult counterPolicyExecuteResult) {
        if (counterPolicyExecuteResult.getRuleExecuteResults() == null
                || counterPolicyExecuteResult.getRuleExecuteResults().isEmpty()) {
            String resultCode = counterPolicyExecuteResult.getResultCode();
            String resultMessage = counterPolicyExecuteResult.getResultMessage();
            if (!"000".equals(resultCode)) {
                emit(fact, resultCode, resultMessage);
            }
        } else {
            boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
            for (CounterRuleExecuteResult ruleExecuteResult : counterPolicyExecuteResult.getRuleExecuteResults()) {
                if (StringUtils.isNotBlank(ruleExecuteResult.getRuleNo())
                        && StringUtils.isNumeric(ruleExecuteResult.getResultCode())) {

                    String ruleNo = ruleExecuteResult.getRuleNo();
                    int riskLevel = NumberUtils.toInt(ruleExecuteResult.getResultCode(), 0);
                    String riskMessage = ruleExecuteResult.getResultMessage();
                    String scenes = ruleExecuteResult.getScenes();
                    if (riskLevel > 0) {
                        Map<String, Object> result = Maps.newHashMap();
                        result.put(Constants.riskLevel, riskLevel);
                        result.put(Constants.riskMessage, riskMessage);
                        result.put(Constants.async, _isAsync);

                        if (StringUtils.isBlank(scenes)) {
                            if (!_isAsync) {
                                result.put(Constants.ruleType, "N");
                                fact.results.put(ruleNo, result);
                            } else {
                                result.put(Constants.ruleType, "NA");
                                fact.results4Async.put(ruleNo, result);
                            }
                        } else {
                            List<String> riskScenes = Splitter.on(",").omitEmptyStrings().trimResults()
                                    .splitToList(scenes);
                            result.put(Constants.riskScene, riskScenes);
                            if (!_isAsync) {
                                result.put(Constants.ruleType, "S");
                                fact.resultsGroupByScene.put(ruleNo, result);
                            } else {
                                result.put(Constants.ruleType, "SA");
                                fact.resultsGroupByScene4Async.put(ruleNo, result);
                            }
                        }

                        boolean withScene = Constants.eventPointsWithScene.contains(fact.eventPoint);
                        TraceLogger.traceLog("[trace] withScene = " + withScene + ", scenes = ["
                                + (scenes == null ? "" : scenes) + "]");
                        if (!withScene) {
                            if (StringUtils.isNotBlank(scenes)) {
                                TraceLogger.traceLog(">>>> [" + ruleNo
                                        + "] : [???] riskLevel = "
                                        + riskLevel + ", riskMessage = " + riskMessage + ", riskScene = [" + scenes
                                        + "]");
                            } else {
                                TraceLogger.traceLog(">>>> [" + ruleNo + "] : riskLevel = " + riskLevel
                                        + ", riskMessage = " + riskMessage);
                            }
                        } else if (withScene) {
                            if (StringUtils.isBlank(scenes)) {
                                TraceLogger.traceLog(">>>> [" + ruleNo
                                        + "] [?]: [?] riskLevel = "
                                        + riskLevel + ", riskMessage = " + riskMessage);
                            } else {
                                TraceLogger.traceLog(">>>> [" + ruleNo + "] [?]: riskLevel = "
                                        + riskLevel + ", riskMessage = " + riskMessage + ", riskScene = [" + scenes
                                        + "]");
                            }
                        }
                    }
                }
            }
        }
    }

    @Deprecated
    public static void emit(RiskFact fact, List<CounterRuleExecuteResult> counterExecuteResults) {
        mergeCounterResults(fact, counterExecuteResults);
    }

    @Deprecated
    public static void mergeCounterResults(RiskFact fact, List<CounterRuleExecuteResult> counterExecuteResults) {
        //        String _ruleNo = (String) fact.ext.get(Constants.key_ruleNo);
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (counterExecuteResults != null && !counterExecuteResults.isEmpty()) {

            for (CounterRuleExecuteResult ruleExecuteResult : counterExecuteResults) {
                if (StringUtils.isNotBlank(ruleExecuteResult.getRuleNo())
                        && StringUtils.isNumeric(ruleExecuteResult.getResultCode())) {

                    String ruleNo = ruleExecuteResult.getRuleNo();
                    int riskLevel = NumberUtils.toInt(ruleExecuteResult.getResultCode(), 0);
                    String riskMessage = ruleExecuteResult.getResultMessage();
                    String scenes = ruleExecuteResult.getScenes();
                    if (riskLevel > 0) {
                        Map<String, Object> result = Maps.newHashMap();
                        result.put(Constants.riskLevel, riskLevel);
                        result.put(Constants.riskMessage, riskMessage);
                        result.put(Constants.async, _isAsync);

                        if (StringUtils.isBlank(scenes)) {
                            if (!_isAsync) {
                                result.put(Constants.ruleType, "N");
                                fact.results.put(ruleNo, result);
                            } else {
                                result.put(Constants.ruleType, "NA");
                                fact.results4Async.put(ruleNo, result);
                            }
                        } else {
                            List<String> riskScenes = Splitter.on(",").omitEmptyStrings().trimResults()
                                    .splitToList(scenes);
                            result.put(Constants.riskScene, riskScenes);
                            if (!_isAsync) {
                                result.put(Constants.ruleType, "S");
                                fact.resultsGroupByScene.put(ruleNo, result);
                            } else {
                                result.put(Constants.ruleType, "SA");
                                fact.resultsGroupByScene4Async.put(ruleNo, result);
                            }
                        }

                        boolean withScene = Constants.eventPointsWithScene.contains(fact.eventPoint);
                        TraceLogger.traceLog("[trace] withScene = " + withScene + ", scenes = ["
                                + (scenes == null ? "" : scenes) + "]");
                        if (!withScene) {
                            if (StringUtils.isNotBlank(scenes)) {
                                TraceLogger.traceLog(">>>> [" + ruleNo
                                        + "] : [???] riskLevel = "
                                        + riskLevel + ", riskMessage = " + riskMessage + ", riskScene = [" + scenes
                                        + "]");
                            } else {
                                TraceLogger.traceLog(">>>> [" + ruleNo + "] : riskLevel = " + riskLevel
                                        + ", riskMessage = " + riskMessage);
                            }
                        } else if (withScene) {
                            if (StringUtils.isBlank(scenes)) {
                                TraceLogger.traceLog(">>>> [" + ruleNo
                                        + "] [?]: [?] riskLevel = "
                                        + riskLevel + ", riskMessage = " + riskMessage);
                            } else {
                                TraceLogger.traceLog(">>>> [" + ruleNo + "] [?]: riskLevel = "
                                        + riskLevel + ", riskMessage = " + riskMessage + ", riskScene = [" + scenes
                                        + "]");
                            }
                        }
                    }
                }
            }
        }
    }

    // ???
    static final String ACCOUNT = "ACCOUNT";
    static final String BW = "BW";

    /**
     * ????
     */
    public static void emitBWListResults(RiskFact fact, List<Map<String, String>> bwlistResults) {
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (_isAsync || bwlistResults == null || bwlistResults.isEmpty()) {
            return;
        }

        // ???(?BW)
        for (Map<String, String> resultMap : bwlistResults) {
            String ruleType = valueAsString(resultMap, "ruleType");
            //            String ruleNo = valueAsString(resultMap, "ruleName");
            String riskMessage = "???: " + valueAsString(resultMap, "ruleRemark"); // "???: [" + Joiner.on(", ").withKeyValueSeparator(":").useForNull("").join(resultMap) + "]";
            int riskLevel = valueAsInt(resultMap, "riskLevel");

            if (ruleType.equals(BW)) {
                if (riskLevel == 0) {
                    fact.finalWhitelistResult.put(Constants.riskLevel, 0);
                    fact.finalWhitelistResult.put(Constants.riskMessage, riskMessage);
                    emit(fact, riskLevel, riskMessage);
                    break;
                }
                if (riskLevel == 95) {
                    fact.finalWhitelistResult.put(Constants.riskLevel, 95);
                    fact.finalWhitelistResult.put(Constants.riskMessage, riskMessage);
                    emit(fact, riskLevel, riskMessage);
                    break;
                }
                // 97
                if (riskLevel >= 90 && riskLevel < 100) {
                    fact.finalWhitelistResult.put(Constants.riskLevel, 97);
                    fact.finalWhitelistResult.put(Constants.riskMessage, riskMessage);
                    emit(fact, riskLevel, riskMessage);
                }
            }
        }

        // ???
        if (fact.finalWhitelistResult.isEmpty() || (fact.finalWhitelistResult.containsKey(Constants.riskLevel)
                && valueAsInt(fact.finalWhitelistResult, Constants.riskLevel) == 97)) {
            emitBListResults(fact, bwlistResults);
        }

        // ??checkResultLogB????
        for (Map<String, String> resultMap : bwlistResults) {
            String ruleType = valueAsString(resultMap, "ruleType");
            String ruleName = valueAsString(resultMap, "ruleName");
            String riskMessage = valueAsString(resultMap, "ruleRemark");
            String ruleId = valueAsString(resultMap, "ruleID");
            int riskLevel = valueAsInt(resultMap, "riskLevel");

            if (ruleType.equals(BW) && riskLevel > 0) {
                Map<String, Object> result = Maps.newHashMap();
                result.put(Constants.riskLevel, riskLevel);
                result.put(Constants.riskMessage, riskMessage);
                result.put(Constants.ruleType, "B");
                result.put(Constants.ruleId, ruleId);
                result.put(Constants.ruleName, ruleName);
                fact.whitelistResults.put(ruleId, result);
            }
        }
    }

    /**
     * ????
     */
    static void emitBListResults(RiskFact fact, List<Map<String, String>> bwlistResults) {

        //result: [{"ruleType":"ACCOUNT","ruleID":0,"ruleName":"CREDIT-EXCHANGE","riskLevel":295,"ruleRemark":""},
        //         {"ruleType":"ACCOUNT","ruleID":0,"ruleName":"CREDIT-EXCHANGE1","riskLevel":80,"ruleRemark":""}]
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (_isAsync) {
            return;
        }

        String orderType = EventBodyUtils.valueAsString(fact.getEventBody(), "orderType");
        boolean isAdapterFact = Constants.eventPointsWithScene.contains(fact.eventPoint);
        boolean isScoreFact = orderType.equals("12"); //

        if (isAdapterFact) {
            //?
            for (Map<String, String> resultMap : bwlistResults) {

                String ruleType = valueAsString(resultMap, "ruleType");
                String ruleNo = valueAsString(resultMap, "ruleName");
                String riskMessage = "???: " + valueAsString(resultMap, "ruleRemark"); // "???: [" + Joiner.on(", ").withKeyValueSeparator(":").useForNull("").join(resultMap) + "]";
                int riskLevel = valueAsInt(resultMap, "riskLevel");

                if (ruleType.equals(ACCOUNT)) {
                    emit(fact, ruleNo, riskLevel, riskMessage, ruleNo);
                } else if (ruleType.equals(BW) && riskLevel > 100) {
                    emit(fact, "PAYMENT-CONF-LIPIN", 295, riskMessage, "PAYMENT-CONF-LIPIN");
                }

            }

        } else {

            //            String finalBRuleNo = null;
            int finalBRiskLevel = 0;
            String finalBRiskMessage = null;

            for (Map<String, String> resultMap : bwlistResults) {

                String ruleType = valueAsString(resultMap, "ruleType");
                String ruleNo = valueAsString(resultMap, "ruleName");
                String riskMessage = "???: " + valueAsString(resultMap, "ruleRemark");
                int riskLevel = valueAsInt(resultMap, "riskLevel");

                if (isScoreFact) {
                    //,?ruleType
                    if (riskLevel > finalBRiskLevel) {
                        //                        finalBRuleNo = ruleNo;
                        finalBRiskLevel = riskLevel;
                        finalBRiskMessage = riskMessage; // "???: [" + Joiner.on(", ").withKeyValueSeparator(":").useForNull("").join(resultMap) + "]";
                    }

                } else {
                    //??
                    //??ruleType = BW
                    if (ruleType.equals(BW)) {
                        if (riskLevel > finalBRiskLevel) {
                            //                            finalBRuleNo = ruleNo;
                            finalBRiskLevel = riskLevel;
                            finalBRiskMessage = riskMessage; // "???: [" + Joiner.on(", ").withKeyValueSeparator(":").useForNull("").join(resultMap) + "]";
                        }
                    }
                }
            }

            // 97??195????97
            boolean finalWhitelistResultSetted = fact.finalWhitelistResult.containsKey(Constants.riskLevel);
            int finalWhitelistRiskLevel = valueAsInt(fact.finalWhitelistResult, Constants.riskLevel);
            if (finalWhitelistRiskLevel == 97 && finalBRiskLevel < 195) {
                emit(fact, 97, finalBRiskMessage);
            } else {
                if (finalBRiskLevel < 200) {
                    emit(fact, finalBRiskLevel, finalBRiskMessage);
                } else if ((!finalWhitelistResultSetted || finalWhitelistRiskLevel != 0)
                        && finalBRiskLevel >= 200) {
                    emit(fact, finalBRiskLevel, finalBRiskMessage);
                }
            }
        }
    }

    /**
     * Counter???
     */
    public static void emitListRepoResult(RiskFact fact, int riskLevel, String riskMessage) {
        boolean _isAsync = valueAsBoolean(fact.ext, Constants.key_isAsync);
        if (!_isAsync) {
            boolean finalWhitelistResultSetted = fact.finalWhitelistResult.containsKey(Constants.riskLevel);
            int finalWhitelistRiskLevel = valueAsInt(fact.finalWhitelistResult, Constants.riskLevel);
            if (riskLevel == 0) {

                fact.finalWhitelistResult.put(Constants.riskLevel, riskLevel);
                fact.finalWhitelistResult.put(Constants.riskMessage, riskMessage);
                emit(fact, riskLevel, riskMessage);

            } else if ((!finalWhitelistResultSetted || finalWhitelistRiskLevel != 0) && riskLevel >= 200) {

                fact.finalWhitelistResult.put(Constants.riskLevel, riskLevel);
                fact.finalWhitelistResult.put(Constants.riskMessage, riskMessage);
                emit(fact, riskLevel, riskMessage);
            }
        }
    }

    /**
     * ????
     */
    public static void emitLeveldownResult(RiskFact fact, int riskLevel, String riskMessage) {
        String ruleNo = (String) fact.ext.get(Constants.key_ruleNo);
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, false);
        if (!_isAsync && !Strings.isNullOrEmpty(ruleNo)) {
            Map<String, Object> result = Maps.newHashMap();
            result.put(Constants.riskLevel, riskLevel);
            result.put(Constants.riskMessage, riskMessage);
            result.put(Constants.async, _isAsync);
            result.put(Constants.ruleType, "N");
            fact.leveldownResults.put(ruleNo, result);
            buidFinalResultAfterEmitLeveldownResult(fact, _isAsync);
            //            RuleMonitorHelper.addRiskRuleNo(ruleNo);
            RuleMonitorHelper.addRiskRuleNo(ruleNo, riskLevel);
        }
    }

    /**
     * emitLeveldownResult??finalResult
     */
    static void buidFinalResultAfterEmitLeveldownResult(RiskFact fact, boolean _isAsync) {
        if (!_isAsync && fact.leveldownResults.size() > 0) {
            // 
            int originalRiskLevel = valueAsInt(fact.finalResult, Constants.originalRiskLevel);
            //?
            Map<String, Object> finalResultAfterLeveldown = Constants.defaultResult;
            for (Map<String, Object> rs : fact.leveldownResults.values()) {
                finalResultAfterLeveldown = compareAndReturn(finalResultAfterLeveldown, rs);
            }
            int riskLevelAfterLeveldown = valueAsInt(finalResultAfterLeveldown, Constants.riskLevel);
            fact.finalResult.put(Constants.riskLevel, riskLevelAfterLeveldown);
            fact.finalResult.put(Constants.originalRiskLevel, originalRiskLevel);
        }
    }

    /**
     * 
     */
    public static void emitModelResult(RiskFact fact, int riskLevel, String riskMessage) {
        String ruleNo = (String) fact.ext.get(Constants.key_ruleNo);
        boolean _isAsync = MapUtils.getBoolean(fact.ext, Constants.key_isAsync, true);
        if (_isAsync && !Strings.isNullOrEmpty(ruleNo)) {
            Map<String, Object> result = Maps.newHashMap();
            result.put(Constants.riskLevel, riskLevel);
            result.put(Constants.riskMessage, riskMessage);
            result.put(Constants.ruleType, "M");
            fact.modelResults.put(ruleNo, result);
            //            RuleMonitorHelper.addRiskRuleNo(ruleNo);
            RuleMonitorHelper.addRiskRuleNo(ruleNo, riskLevel);
        }
    }

    /**
     * finalResult
     */
    static Map<String, Object> compareAndReturn(Map<String, Object> oldResult, Map<String, Object> newResult) {
        if (newResult == null) {
            return oldResult;
        }
        if (oldResult == null) {
            return newResult;
        }
        int newRriskLevel = MapUtils.getInteger(newResult, Constants.riskLevel, 0);
        int oldRriskLevel = MapUtils.getInteger(oldResult, Constants.riskLevel, 0);
        if (newRriskLevel > oldRriskLevel) {
            return newResult;
        }
        return oldResult;
    }
}