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);
    }
  }
  private static String isClass14Invocation(
      Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {

    if (exprent.type == Exprent.EXPRENT_FUNCTION) {
      FunctionExprent fexpr = (FunctionExprent) exprent;
      if (fexpr.getFuncType() == FunctionExprent.FUNCTION_IIF) {
        if (fexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FUNCTION) {
          FunctionExprent headexpr = (FunctionExprent) fexpr.getLstOperands().get(0);
          if (headexpr.getFuncType() == FunctionExprent.FUNCTION_EQ) {
            if (headexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD
                && headexpr.getLstOperands().get(1).type == Exprent.EXPRENT_CONST
                && ((ConstExprent) headexpr.getLstOperands().get(1))
                    .getConstType()
                    .equals(VarType.VARTYPE_NULL)) {

              FieldExprent field = (FieldExprent) headexpr.getLstOperands().get(0);
              ClassNode fieldnode =
                  DecompilerContext.getClassProcessor()
                      .getMapRootClasses()
                      .get(field.getClassname());

              if (fieldnode != null
                  && fieldnode.classStruct.qualifiedName.equals(
                      wrapper.getClassStruct().qualifiedName)) { // source class
                StructField fd =
                    wrapper
                        .getClassStruct()
                        .getField(
                            field.getName(),
                            field.getDescriptor().descriptorString); // FIXME: can be null! why??

                if (fd != null
                    && fd.hasModifier(CodeConstants.ACC_STATIC)
                    && (fd.isSynthetic()
                        || DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET))) {

                  if (fexpr.getLstOperands().get(1).type == Exprent.EXPRENT_ASSIGNMENT
                      && fexpr.getLstOperands().get(2).equals(field)) {
                    AssignmentExprent asexpr = (AssignmentExprent) fexpr.getLstOperands().get(1);

                    if (asexpr.getLeft().equals(field)
                        && asexpr.getRight().type == Exprent.EXPRENT_INVOCATION) {
                      InvocationExprent invexpr = (InvocationExprent) asexpr.getRight();

                      if (invexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName)
                          && invexpr.getName().equals(meth.methodStruct.getName())
                          && invexpr
                              .getStringDescriptor()
                              .equals(meth.methodStruct.getDescriptor())) {

                        if (invexpr.getLstParameters().get(0).type == Exprent.EXPRENT_CONST) {
                          wrapper
                              .getHiddenMembers()
                              .add(
                                  InterpreterUtil.makeUniqueKey(
                                      fd.getName(), fd.getDescriptor())); // hide synthetic field
                          return ((ConstExprent) invexpr.getLstParameters().get(0))
                              .getValue()
                              .toString();
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    return null;
  }