Actual recursive lookup replacement.

@param base the string to resolve
@param seen strings already seen during this lookup, used to prevent unbound recursion
@return the resolved string
162592
private String lookupRecursively(String base, Set<String> seen)
      throws UnresolvablePropertyException {
    // check argument
    if (base == null) {
      throw new UnresolvablePropertyException("Can't resolve property with null value");
    }

    String resolved = base;
    // Lets find pattern match to ${key}.
    // TODO(hsaputra): Consider using Apache Commons StrSubstitutor.
    Matcher matcher = CONF_REGEX.matcher(base);
    while (matcher.find()) {
      String match = matcher.group(2).trim();
      if (!seen.add(match)) {
        throw new RuntimeException(ExceptionMessage.KEY_CIRCULAR_DEPENDENCY.getMessage(match));
      }
      if (!PropertyKey.isValid(match)) {
        throw new RuntimeException(ExceptionMessage.INVALID_CONFIGURATION_KEY.getMessage(match));
      }
      String value = lookupRecursively(mProperties.get(PropertyKey.fromString(match)), seen);
      seen.remove(match);
      if (value == null) {
        throw new UnresolvablePropertyException(ExceptionMessage
            .UNDEFINED_CONFIGURATION_KEY.getMessage(match));
      }
      LOG.debug("Replacing {} with {}", matcher.group(1), value);
      resolved = resolved.replaceFirst(REGEX_STRING, Matcher.quoteReplacement(value));
    }
    return resolved;
  }
191517
@Override
    public void sawOpcode(int seen) {
        // System.out.println(getPC() + " " + Const.getOpcodeName(seen) + " " + state);

        if (stack.getStackDepth() < stackDepth) {
            state = FormatState.NONE;
            stackDepth = 0;
            arguments = null;
        }
        if (seen == Const.ANEWARRAY && stack.getStackDepth() >= 2) {
            Object size = stack.getStackItem(0).getConstant();
            Object formatStr = stack.getStackItem(1).getConstant();
            if (size instanceof Integer && formatStr instanceof String) {
                arguments = new OpcodeStack.Item[(Integer) size];
                this.formatString = (String) formatStr;
                state = FormatState.READY_FOR_FORMAT;
                stackDepth = stack.getStackDepth();
            }
        } else if (state == FormatState.READY_FOR_FORMAT && seen == Const.DUP) {
            state = FormatState.EXPECTING_ASSIGNMENT;
        } else if (state == FormatState.EXPECTING_ASSIGNMENT && stack.getStackDepth() == stackDepth + 3 && seen == Const.AASTORE) {
            Object pos = stack.getStackItem(1).getConstant();
            OpcodeStack.Item value = stack.getStackItem(0);
            if (pos instanceof Integer) {
                int index = (Integer) pos;
                if (index >= 0 && index < arguments.length) {
                    arguments[index] = value;
                    state = FormatState.READY_FOR_FORMAT;
                } else {
                    state = FormatState.NONE;
                }
            } else {
                state = FormatState.NONE;
            }
        } else if (state == FormatState.READY_FOR_FORMAT
                && (seen == Const.INVOKESPECIAL || seen == Const.INVOKEVIRTUAL || seen == Const.INVOKESTATIC || seen == Const.INVOKEINTERFACE)
                && stack.getStackDepth() == stackDepth) {

            String cl = getClassConstantOperand();
            String nm = getNameConstantOperand();
            String sig = getSigConstantOperand();
            XMethod m = getXMethodOperand();
            if ((m == null || m.isVarArgs())
                    && sig.indexOf("Ljava/lang/String;[Ljava/lang/Object;)") >= 0
                    && ("java/util/Formatter".equals(cl) && "format".equals(nm) || "java/lang/String".equals(cl)
                            && "format".equals(nm) || "java/io/PrintStream".equals(cl) && "format".equals(nm)
                            || "java/io/PrintStream".equals(cl) && "printf".equals(nm) || cl.endsWith("Writer")
                            && "format".equals(nm) || cl.endsWith("Writer") && "printf".equals(nm)) || cl.endsWith("Logger")
                            && nm.endsWith("fmt")) {

                if (formatString.indexOf('\n') >= 0) {
                    bugReporter.reportBug(new BugInstance(this, "VA_FORMAT_STRING_USES_NEWLINE", NORMAL_PRIORITY)
                    .addClassAndMethod(this).addCalledMethod(this).addString(formatString)
                    .describe(StringAnnotation.FORMAT_STRING_ROLE).addSourceLine(this));
                }
            }

        }
    }
753132
@Override
    public void sawOpcode(int seen) {
        if (downwardBranchTarget == -1) {
            switch (state) {
                case SAW_NOTHING:
                    sawOpcodeAfterNothing(seen);
                break;

                case SAW_LOAD:
                    sawOpcodeAfterLoad(seen);
                break;

                case SAW_CHECKCAST:
                    sawOpcodeAfterCheckCast(seen);
                break;
            }

            int insTarget = -1;
            if (((seen >= Const.IFEQ) && (seen <= Const.IF_ACMPNE)) || (seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                insTarget = getBranchTarget();
                if (insTarget < getPC()) {
                    insTarget = -1;
                }
            } else if ((seen == Const.LOOKUPSWITCH) || (seen == Const.TABLESWITCH)) {
                insTarget = this.getDefaultSwitchOffset() + getPC();
            }

            if (insTarget > downwardBranchTarget) {
                downwardBranchTarget = insTarget;
            }
        } else {
            state = State.SAW_NOTHING;
            if (getPC() >= downwardBranchTarget) {
                downwardBranchTarget = -1;
            }
        }
    }
1306769
public Result getMatch(String lookup) {
        int strLen = lookup.length();
        char[] chars = new char[strLen + 1];
        lookup.getChars(0, strLen, chars, 0);
        chars[strLen] = '\uffff';
        
        TinyList resultList = new TinyList();
        fillMatchResults(chars, 1, resultList);

        return (Result)resultList.mElement;
    }
822911
public String relativePath(File base, File nested) throws IOException {
        String basePath = base.getCanonicalPath();
        String nestedPath = nested.getCanonicalPath();
        if (nestedPath.equals(basePath)) {
            return "";
        } else if (nestedPath.startsWith(basePath)) {
            return nestedPath.substring(basePath.length() + 1);
        } else {
            return nestedPath;
        }
    }
721762
public static int getStoreReg(DismantleBytecode dbc, int seen) {
        if ((seen == Const.ASTORE) || (seen == Const.ISTORE) || (seen == Const.LSTORE) || (seen == Const.FSTORE) || (seen == Const.DSTORE)) {
            return dbc.getRegisterOperand();
        }
        if (OpcodeUtils.isIStore(seen)) {
            return seen - Const.ISTORE_0;
        } else if (OpcodeUtils.isLStore(seen)) {
            return seen - Const.LSTORE_0;
        } else if (OpcodeUtils.isFStore(seen)) {
            return seen - Const.FSTORE_0;
        } else if (OpcodeUtils.isDStore(seen)) {
            return seen - Const.DSTORE_0;
        } else if (OpcodeUtils.isAStore(seen)) {
            return seen - Const.ASTORE_0;
        }
        return -1;
    }
434630
@Override
    public void sawOpcode(int seen) {
        Integer sawALOADReg = null;
        try {
            stack.precomputation(this);

            int pc = getPC();
            nullGuards.remove(Integer.valueOf(pc));
            clearEndOfLifeRegisters();

            switch (seen) {
                case Const.IFNULL: {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        int reg = itm.getRegisterNumber();
                        Integer target = Integer.valueOf(getBranchTarget());
                        if (reg >= 0) {
                            int eol = Integer.MAX_VALUE;
                            LocalVariableTable lvt = getMethod().getLocalVariableTable();
                            if (lvt != null) {
                                LocalVariable lv = lvt.getLocalVariable(reg, pc);
                                if (lv != null) {
                                    eol = pc + lv.getLength();
                                }
                            }

                            nullGuards.put(target, new NullGuard(reg, pc, eol, itm.getSignature()));
                        } else {
                            XField xf = itm.getXField();
                            Integer sourceFieldReg = (Integer) itm.getUserValue();
                            if ((xf != null) && (sourceFieldReg != null)) {
                                nullGuards.put(target, new NullGuard(xf, sourceFieldReg.intValue(), pc, itm.getSignature()));
                            }
                        }
                    }
                }
                break;

                case Const.ASTORE:
                case Const.ASTORE_0:
                case Const.ASTORE_1:
                case Const.ASTORE_2:
                case Const.ASTORE_3: {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        if (!itm.isNull()) {
                            NullGuard guard = findNullGuardWithRegister(RegisterUtils.getAStoreReg(this, seen));
                            if (guard != null) {
                                bugReporter.reportBug(new BugInstance(this, BugType.SNG_SUSPICIOUS_NULL_LOCAL_GUARD.name(), NORMAL_PRIORITY).addClass(this)
                                        .addMethod(this).addSourceLine(this));
                                removeNullGuard(guard);
                            }
                        }
                    }
                }
                break;

                case Const.ALOAD:
                case Const.ALOAD_0:
                case Const.ALOAD_1:
                case Const.ALOAD_2:
                case Const.ALOAD_3: {
                    NullGuard guard = findNullGuardWithRegister(RegisterUtils.getALoadReg(this, seen));
                    if (guard != null) {
                        removeNullGuard(guard);
                    }
                    sawALOADReg = Integer.valueOf(RegisterUtils.getALoadReg(this, seen));
                }
                break;

                case Const.PUTFIELD: {
                    if (stack.getStackDepth() <= 1) {
                        break;
                    }
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    if (itm.isNull()) {
                        break;
                    }
                    XField xf = getXFieldOperand();
                    itm = stack.getStackItem(1);
                    Integer fieldSourceReg = (Integer) itm.getUserValue();
                    if ((xf != null) && (fieldSourceReg != null)) {
                        NullGuard guard = findNullGuardWithField(xf, fieldSourceReg.intValue());
                        if (guard != null) {
                            bugReporter.reportBug(new BugInstance(this, BugType.SNG_SUSPICIOUS_NULL_FIELD_GUARD.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addSourceLine(this));
                            removeNullGuard(guard);
                        }
                    }
                }
                break;

                case Const.GETFIELD: {
                    if (stack.getStackDepth() > 0) {
                        XField xf = getXFieldOperand();
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        Integer fieldSourceReg = (Integer) itm.getUserValue();
                        if ((xf != null) && (fieldSourceReg != null)) {
                            NullGuard guard = findNullGuardWithField(xf, fieldSourceReg.intValue());
                            if (guard != null) {
                                removeNullGuard(guard);
                            } else {
                                sawALOADReg = (Integer) itm.getUserValue();
                            }
                        }
                    }
                }
                break;

                case Const.IFEQ:
                case Const.IFNE:
                case Const.IFLT:
                case Const.IFGE:
                case Const.IFGT:
                case Const.IFLE:
                case Const.IF_ICMPEQ:
                case Const.IF_ICMPNE:
                case Const.IF_ICMPLT:
                case Const.IF_ICMPGE:
                case Const.IF_ICMPGT:
                case Const.IF_ICMPLE:
                case Const.IF_ACMPEQ:
                case Const.IF_ACMPNE:
                case Const.GOTO:
                case Const.GOTO_W:
                case Const.IFNONNULL:
                    nullGuards.clear();
                break;
                default:
                break;
            }
        } finally {
            stack.sawOpcode(this, seen);
            if ((sawALOADReg != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(sawALOADReg);
            }
        }
    }
126765
@Override
    public void sawOpcode(int seen) {
        boolean reset = true;
        switch (state) { // TODO: Refactor this to use state pattern, not nested
                         // switches
            case SEEN_NOTHING:
                reset = sawOpcodeAfterNothing(seen);
            break;

            case SEEN_ALOAD:
                reset = sawOpcodeAfterLoad(seen);
            break;

            case SEEN_GETFIELD:
                reset = sawOpcodeAfterGetField(seen);
            break;

            case SEEN_DUAL_LOADS:
                reset = sawOpcodeAfterDualLoads(seen);
            break;

            case SEEN_INVOKEVIRTUAL:
                if (seen == Const.INVOKEVIRTUAL) {
                    checkForSGSU();
                }
            break;
        }

        if (reset) {
            beanReference1 = null;
            beanReference2 = null;
            propType = null;
            propName = null;
            sawField = false;
            state = State.SEEN_NOTHING;
        }
    }
997430
@Override
    public void sawOpcode(int seen) {
        stack.precomputation(this);

        switch (seen) {
            case Const.INVOKESTATIC: {
                String className = getClassConstantOperand();
                for (Backports backport : BACKPORTS) {
                    if (className.startsWith(backport.getPathPrefix())) {
                        if (clsVersion >= backport.getMinimumJDK()) {
                            reportBug(backport.getLibrary());
                            break;
                        }
                    }
                }
            }
            break;

            case Const.INVOKESPECIAL: {
                String className = getClassConstantOperand();
                String methodName = getNameConstantOperand();
                for (Backports backport : BACKPORTS) {
                    if (Values.CONSTRUCTOR.equals(methodName) && className.startsWith(backport.getPathPrefix()) && (clsVersion >= backport.getMinimumJDK())) {
                        reportBug(backport.getLibrary());
                        break;
                    }
                }
            }
            break;

            default:
            break;
        }
    }
311454
@Override
    public void sawOpcode(int seen) {
        if (isInitializer) {
            lookForCustomThreadFactoriesInConstructors(seen);
            return;
        }

        try {
            stack.precomputation(this);

            if ((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) {
                processInvoke();
            }
            // TODO Should not include private methods
            else if (seen == Const.ARETURN) {
                removeFieldsThatGetReturned();
            } else if (seen == Const.PUTFIELD) {
                XField f = getXFieldOperand();
                if (f != null) {
                    reportOverwrittenField(f);
                }
            } else if (seen == Const.IFNONNULL) {
                // indicates a null check, which means that we get an exemption
                // until the end of the branch
                OpcodeStack.Item nullCheckItem = stack.getStackItem(0);
                XField fieldWhichWasNullChecked = nullCheckItem.getXField();
                if (fieldWhichWasNullChecked != null) {
                    exemptExecutors.put(fieldWhichWasNullChecked, Integer.valueOf(getPC() + getBranchOffset()));
                }
            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
1152959
@Override
    public void sawOpcode(int seen) {

        try {
            stack.precomputation(this);

            if ((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) {
                FQMethod key = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand());

                Object posObject = characterMethods.get(key);
                if (posObject instanceof Integer) {
                    if (checkSingleParamMethod(((Integer) posObject).intValue()) && !isInlineAppend(key)) {
                        reportBug();
                    }
                } else if ((posObject instanceof IntPair) && checkDoubleParamMethod((IntPair) posObject)) {
                    reportBug();
                }

            } else if (seen == Const.DUP) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    String duppedSig = itm.getSignature();
                    if (Values.SIG_JAVA_UTIL_STRINGBUILDER.equals(duppedSig) || Values.SIG_JAVA_UTIL_STRINGBUFFER.equals(duppedSig)) {
                        itm.setUserValue(UCPMUserValue.INLINE);
                    }
                }
            } else if ((seen == Const.PUTFIELD) || (((seen == Const.PUTSTATIC) || OpcodeUtils.isAStore(seen)) && (stack.getStackDepth() > 0))) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(null);
            }
        } finally {
            UCPMUserValue uv = callHasInline(seen);

            stack.sawOpcode(this, seen);
            if ((uv == UCPMUserValue.INLINE) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(uv);
            }
        }
    }
715349
@Override
    public void sawOpcode(int seen) {
        switch (state) {
            case SEEN_NOTHING:
                if ((seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKEVIRTUAL)) {
                    String sig = getSigConstantOperand();
                    String returnSig = SignatureUtils.getReturnSignature(sig);
                    if (returnSig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX)) {
                        String clsName = getClassConstantOperand();
                        if (!Values.SLASHED_JAVA_LANG_OBJECT.equals(clsName) && !Values.SLASHED_JAVA_LANG_CLASS.equals(clsName)) {
                            returnType = SignatureUtils.trimSignature(returnSig);
                            invokePC = getPC();
                            state = State.SEEN_INVOKE;
                        }
                    }
                }
            break;

            case SEEN_INVOKE:
                if (seen == Const.POP) {
                    state = State.SEEN_POP;
                } else {
                    state = State.SEEN_NOTHING;
                    returnType = null;
                }
            break;

            case SEEN_POP:
                if (((seen >= Const.ACONST_NULL) && (seen <= Const.DCONST_1)) || (seen == Const.GETFIELD)) {
                    state = State.SEEN_POP;
                } else if ((seen == Const.INVOKESTATIC) || (seen == Const.GETSTATIC)) {
                    if (getClassConstantOperand().equals(returnType) && (lnTable.getSourceLine(invokePC) == lnTable.getSourceLine(getPC()))) {
                        bugReporter.reportBug(new BugInstance(this, BugType.NIR_NEEDLESS_INSTANCE_RETRIEVAL.name(), NORMAL_PRIORITY).addClass(this)
                                .addMethod(this).addSourceLine(this));
                    }
                    state = State.SEEN_NOTHING;
                    returnType = null;
                } else {
                    state = State.SEEN_NOTHING;
                    returnType = null;
                }
            break;

            default:
                state = State.SEEN_NOTHING;
                returnType = null;
            break;
        }
    }
547116
public static Map<String, Object> resolve(Map<String, Object> root)
	{
		Map<String, Object> newRoot = new HashMap<String, Object>();
		resolve(newRoot, root, "");
		return newRoot;
	}
245107
public static <T> T lookup(String name) {
        InitialContext initialContext = initialContext();
        try {
            @SuppressWarnings("unchecked")
            T object = (T) initialContext.lookup(name);
            if (object == null) {
                throw new NameNotFoundException(name + " was found but is null");
            }
            return object;
        } catch (NameNotFoundException e) {
            throw new IllegalArgumentException(name + " was not found in JNDI", e);
        } catch (NamingException e) {
            throw new IllegalArgumentException("JNDI lookup failed", e);
        } finally {
            closeContext(initialContext);
        }
    }
1010391
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            if ((seen == Const.CHECKCAST) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                if (item.getRegisterNumber() == 1) {
                    String thisCls = getClassName();
                    String equalsCls = getClassConstantOperand();
                    if (!thisCls.equals(equalsCls)) {
                        JavaClass thisJavaClass = getClassContext().getJavaClass();
                        JavaClass equalsJavaClass = Repository.lookupClass(equalsCls);
                        boolean inheritance = thisJavaClass.instanceOf(equalsJavaClass) || equalsJavaClass.instanceOf(thisJavaClass);

                        BugInstance bug = new BugInstance(this, BugType.NSE_NON_SYMMETRIC_EQUALS.name(), inheritance ? LOW_PRIORITY : NORMAL_PRIORITY)
                                .addClass(this).addMethod(this).addSourceLine(this).addString(equalsCls);
                        Map<String, BugInstance> bugs = possibleBugs.get(thisCls);
                        if (bugs == null) {
                            bugs = new HashMap<>();
                            possibleBugs.put(thisCls, bugs);
                        }
                        bugs.put(equalsCls, bug);
                    }
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
268364
@Override
    public void sawOpcode(final int seen) {
        if (stage == Stage.FIND_LOOP_STAGE) {
            sawOpcodeLoop(seen);
        } else {
            sawOpcodeBug(seen);
        }
    }
779371
public static Object lookup(String target) throws NamingException
    {
        if (theRootContext == null) {
            theRootContext = new InitialContext();
        }

        return theRootContext.lookup(localHomePrefixString + target);
    }