private static void processClassRec(
      ClassNode node,
      final HashMap<ClassWrapper, MethodWrapper> mapClassMeths,
      final HashSet<ClassWrapper> setFound) {

    final ClassWrapper wrapper = node.wrapper;

    // search code
    for (MethodWrapper meth : wrapper.getMethods()) {

      RootStatement root = meth.root;
      if (root != null) {

        DirectGraph graph = meth.getOrBuildGraph();

        graph.iterateExprents(
            new DirectGraph.ExprentIterator() {
              public int processExprent(Exprent exprent) {
                for (Entry<ClassWrapper, MethodWrapper> ent : mapClassMeths.entrySet()) {
                  if (replaceInvocations(exprent, ent.getKey(), ent.getValue())) {
                    setFound.add(ent.getKey());
                  }
                }
                return 0;
              }
            });
      }
    }

    // search initializers
    for (int j = 0; j < 2; j++) {
      VBStyleCollection<Exprent, String> initializers =
          j == 0 ? wrapper.getStaticFieldInitializers() : wrapper.getDynamicFieldInitializers();

      for (int i = 0; i < initializers.size(); i++) {
        for (Entry<ClassWrapper, MethodWrapper> ent : mapClassMeths.entrySet()) {
          Exprent exprent = initializers.get(i);
          if (replaceInvocations(exprent, ent.getKey(), ent.getValue())) {
            setFound.add(ent.getKey());
          }

          String cl = isClass14Invocation(exprent, ent.getKey(), ent.getValue());
          if (cl != null) {
            initializers.set(
                i, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/'), exprent.bytecode));
            setFound.add(ent.getKey());
          }
        }
      }
    }

    // iterate nested classes
    for (ClassNode nd : node.nested) {
      processClassRec(nd, mapClassMeths, setFound);
    }
  }
  private void mapClassMethods(ClassNode node, Map<ClassWrapper, MethodWrapper> map) {
    boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);

    ClassWrapper wrapper = node.wrapper;

    for (MethodWrapper method : wrapper.getMethods()) {
      StructMethod mt = method.methodStruct;

      if ((noSynthFlag || mt.isSynthetic())
          && mt.getDescriptor().equals("(Ljava/lang/String;)Ljava/lang/Class;")
          && mt.hasModifier(CodeConstants.ACC_STATIC)) {

        RootStatement root = method.root;
        if (root != null && root.getFirst().type == Statement.TYPE_TRYCATCH) {
          CatchStatement cst = (CatchStatement) root.getFirst();
          if (cst.getStats().size() == 2
              && cst.getFirst().type == Statement.TYPE_BASICBLOCK
              && cst.getStats().get(1).type == Statement.TYPE_BASICBLOCK
              && cst.getVars()
                  .get(0)
                  .getVarType()
                  .equals(
                      new VarType(
                          CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"))) {

            BasicBlockStatement body = (BasicBlockStatement) cst.getFirst();
            BasicBlockStatement handler = (BasicBlockStatement) cst.getStats().get(1);

            if (body.getExprents().size() == 1 && handler.getExprents().size() == 1) {
              if (bodyexprent.equals(body.getExprents().get(0))
                  && handlerexprent.equals(handler.getExprents().get(0))) {
                map.put(wrapper, method);
                break;
              }
            }
          }
        }
      }
    }

    // iterate nested classes
    for (ClassNode nd : node.nested) {
      mapClassMethods(nd, map);
    }
  }