/** visit end method for intrumentation */
  @Override
  public void visitEnd() {
    for (Object o : methods) {
      MethodNode mn = (MethodNode) o;

      // filtering the methods
      if (!(validateMapReduceClinitMethod(mn.name, MAP_METHOD, REDUCE_METHOD, CLINIT_METHOD)
          || checkMethodNameAndArgumentLength(mn)
          || (mn.access & Opcodes.ACC_SYNTHETIC) == Opcodes.ACC_SYNTHETIC)) {

        InsnList insnList = mn.instructions;
        AbstractInsnNode[] insnArr = insnList.toArray();

        // adding entry logging
        logger.info(
            MessageFormat.format(
                InstrumentationMessageLoader.getMessage(MessageConstants.LOG_METHOD_ENTRY),
                getClassName() + "##" + mn.name + "##" + mn.desc));

        String logMsg = InstrumentationMessageLoader.getMessage(MessageConstants.ENTERED_METHOD);

        String cSymbol = env.getClassSymbol(getClassName());
        String mSymbol = env.getMethodSymbol(getClassName(), cSymbol, mn.name);

        InsnList il = InstrumentUtil.addLogMessage(cSymbol, mSymbol, logMsg);
        insnList.insertBefore(insnList.getFirst(), il);

        for (AbstractInsnNode abstractInsnNode : insnArr) {
          if (Opcodes.RETURN >= abstractInsnNode.getOpcode()
              && Opcodes.IRETURN <= abstractInsnNode.getOpcode()) {
            // adding exit logging
            logger.info(
                MessageFormat.format(
                    InstrumentationMessageLoader.getMessage(MessageConstants.LOG_METHOD_EXIT),
                    getClassName() + "##" + mn.name));

            logMsg = InstrumentationMessageLoader.getMessage(MessageConstants.EXITING_METHOD);
            cSymbol = env.getClassSymbol(getClassName());
            mSymbol = env.getMethodSymbol(getClassName(), cSymbol, mn.name);
            il = InstrumentUtil.addLogMessage(cSymbol, mSymbol, logMsg);

            // inserting the list at the associated label node
            AbstractInsnNode prevNode = abstractInsnNode.getPrevious();
            while (!(prevNode instanceof LabelNode)) {
              prevNode = prevNode.getPrevious();
            }
            insnList.insert(prevNode, il);
          }
        }
      }
      mn.visitMaxs(0, 0);
    }
    accept(cv);
  }
  /**
   * This method is called when a class being visited
   *
   * @param name In the format "util/a/b/c"
   * @see org.jumbune.debugger.instrumentation.adapter.BaseAdapter#visit(int, int, java.lang.String,
   *     java.lang.String, java.lang.String, java.lang.String[])
   */
  public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    Config config = getConfig();
    setClassName(name);
    super.visit(version, access, name, signature, superName, interfaces);
    JobConfig jobConfig = (JobConfig) config;
    String keyValidationClass = jobConfig.getMapReduceKeyValidator(getClassName());
    String valueValidationClass = jobConfig.getMapReduceValueValidator(getClassName());
    boolean instrumentMapreduceUserdefinedValidation =
        jobConfig.isInstrumentEnabled("instrumentUserDefValidate");

    LOG.info(
        MessageFormat.format(
            InstrumentationMessageLoader.getMessage(MessageConstants.CLASS_BEING_INSTRUMENTED),
            getClassName()));

    if (instrumentMapreduceUserdefinedValidation
        && (name.equals(keyValidationClass) || name.equals(valueValidationClass))) {

      isValidValidation = false;
      for (int i = 0; i < interfaces.length; i++) {
        if (interfaces[i].equals(InstrumentConstants.CLASSNAME_PATTERNVALIDATOR)) {
          isValidValidation = true;
          break;
        }
      }
      if (!isValidValidation) {
        LOG.info(
            MessageFormat.format(
                InstrumentationMessageLoader.getMessage(
                    MessageConstants.NOT_IMPLEMENTING_PATTERNVALIDATOR),
                getClassName()));
      }
    }
    accept(cv);
  }