@Override
    public void nodeDispatch(String suffix, int divide, int start, int end) {
      MethodVisitor mv;
      mv = cw.visitMethod(ACC_PRIVATE, name() + suffix, signature(), null, null);
      mv.visitCode();
      Label startLabel = new Label();
      mv.visitLabel(startLabel);
      final int powerOfTwo = Integer.numberOfTrailingZeros(divide);

      int sStart = start >> powerOfTwo;
      int sEnd = end >> powerOfTwo;

      int left = end - (sEnd << powerOfTwo);
      if (left > 0) {
        sEnd++;
      }

      Label[] labels = newLabels(sEnd - sStart);
      Label defaultLabel = new Label();

      mv.visitVarInsn(ILOAD, argIndex());

      int sub = leafStart();
      if (sub != 0) {
        AsmUtils.addIndex(mv, sub);
        mv.visitInsn(ISUB);
      }

      AsmUtils.addIndex(mv, powerOfTwo);
      mv.visitInsn(ISHR);

      mv.visitVarInsn(ISTORE, maxArgIndex() + 1);
      mv.visitVarInsn(ILOAD, maxArgIndex() + 1);
      mv.visitTableSwitchInsn(sStart, sEnd - 1, defaultLabel, labels);

      for (int i = sStart; i < sEnd; i++) {

        int estart = i << powerOfTwo;
        int eend = Math.min(end, (i + 1) << powerOfTwo);

        mv.visitLabel(labels[i - sStart]);
        if (i == start) {
          mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
        } else {
          mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }

        loadArguments(mv);
        mv.visitMethodInsn(
            INVOKESPECIAL,
            classType,
            name() + (divide / maxMethodSize) + "n" + estart + "t" + eend,
            signature(),
            false);

        if (isVoid()) {
          if (i < (sEnd - 1)) {
            mv.visitJumpInsn(GOTO, defaultLabel);
          }
        } else {
          mv.visitInsn(ARETURN);
        }
      }

      mv.visitLabel(defaultLabel);
      mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);

      if (isVoid()) {
        mv.visitInsn(RETURN);
      } else {
        mv.visitInsn(ACONST_NULL);
        mv.visitInsn(ARETURN);
      }

      Label endLabel = new Label();
      mv.visitLabel(endLabel);
      appendDebugInfo(mv, startLabel, endLabel);
      mv.visitMaxs(6, 5);
      mv.visitEnd();
    }
  private static <T> void appendInit(
      DelayedCellSetterFactory<T, ?>[] delayedCellSetters,
      CellSetter<T>[] setters,
      ClassWriter cw,
      String targetType,
      String classType,
      int maxSize) {
    MethodVisitor mv; // constructor
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "<init>",
              "("
                  + AsmUtils.toDeclaredLType(Instantiator.class)
                  + AsmUtils.toDeclaredLType(DelayedCellSetter[].class)
                  + AsmUtils.toDeclaredLType(CellSetter[].class)
                  + AsmUtils.toDeclaredLType(CsvColumnKey[].class)
                  + AsmUtils.toDeclaredLType(ParsingContext.class)
                  + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class)
                  + ")V",
              "("
                  + "L"
                  + AsmUtils.toType(Instantiator.class)
                  + "<L"
                  + AsmUtils.toType(CsvMapperCellHandler.class)
                  + "<L"
                  + targetType
                  + ";>;L"
                  + targetType
                  + ";>;"
                  + "[L"
                  + DELAYED_CELL_SETTER_TYPE
                  + "<L"
                  + targetType
                  + ";*>;"
                  + "[L"
                  + CELL_SETTER_TYPE
                  + "<L"
                  + targetType
                  + ";>;"
                  + AsmUtils.toDeclaredLType(CsvColumnKey[].class)
                  + AsmUtils.toDeclaredLType(ParsingContext.class)
                  + "L"
                  + AsmUtils.toType(FieldMapperErrorHandler.class)
                  + "<L"
                  + AsmUtils.toType(CsvColumnKey.class)
                  + ";>;"
                  + ")V",
              null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 4);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitInsn(ARRAYLENGTH);
      mv.visitVarInsn(ALOAD, 3);
      mv.visitInsn(ARRAYLENGTH);
      mv.visitVarInsn(ALOAD, 5);
      mv.visitVarInsn(ALOAD, 6);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          CSV_CELL_MAPPER_TYPE,
          "<init>",
          "("
              + AsmUtils.toDeclaredLType(Instantiator.class)
              + AsmUtils.toDeclaredLType(CsvColumnKey[].class)
              + "I"
              + "I"
              + AsmUtils.toDeclaredLType(ParsingContext.class)
              + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class)
              + ")V",
          false);

      ShardingHelper.shard(
          delayedCellSetters.length,
          maxSize,
          new ShardingHelper.ShardCallBack() {
            @Override
            public void leafDispatch(String suffix, int start, int end) {}

            @Override
            public void nodeDispatch(String suffix, int divide, int start, int end) {}
          });
      for (int i = 0; i < delayedCellSetters.length; i++) {
        if (delayedCellSetters[i] != null) {
          mv.visitVarInsn(ALOAD, 0);
          mv.visitVarInsn(ALOAD, 2);
          AsmUtils.addIndex(mv, i);
          mv.visitInsn(AALOAD);
          mv.visitFieldInsn(
              PUTFIELD,
              classType,
              "delayedCellSetter" + i,
              AsmUtils.toDeclaredLType(DELAYED_CELL_SETTER_TYPE));
        }
      }

      for (int i = 0; i < setters.length; i++) {
        if (setters[i] != null) {
          mv.visitVarInsn(ALOAD, 0);
          mv.visitVarInsn(ALOAD, 3);
          AsmUtils.addIndex(mv, i);
          mv.visitInsn(AALOAD);
          mv.visitFieldInsn(
              PUTFIELD, classType, "setter" + i, AsmUtils.toDeclaredLType(CELL_SETTER_TYPE));
        }
      }

      mv.visitInsn(RETURN);
      mv.visitMaxs(7, 7);
      mv.visitEnd();
    }
  }