private RubyNode translateLocalAssignment(
      ISourcePosition sourcePosition, String name, org.jruby.ast.Node valueNode) {
    final SourceSection sourceSection = translate(sourcePosition);

    final RubyNode readNode;

    if (valueNode instanceof org.jruby.ast.NilImplicitNode) {
      // Multiple assignment

      if (useArray()) {
        readNode =
            ArrayIndexNodeFactory.create(context, sourceSection, index, loadArray(sourceSection));
      } else {
        readNode = readArgument(sourceSection, index);
      }
    } else {
      // Optional argument
      final RubyNode defaultValue = valueNode.accept(this);
      readNode =
          new ReadOptionalArgumentNode(
              context, sourceSection, index, index + argsNode.getPostCount() + 1, defaultValue);
    }

    final FrameSlot slot =
        methodBodyTranslator.getEnvironment().getFrameDescriptor().findFrameSlot(name);
    return WriteLocalVariableNodeFactory.create(context, sourceSection, slot, readNode);
  }
  @Override
  public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
    argsNode = node;

    final SourceSection sourceSection = translate(node.getPosition());

    final List<RubyNode> sequence = new ArrayList<>();

    int localIndex = 0;

    if (node.getPre() != null) {
      state = State.PRE;
      for (org.jruby.ast.Node arg : node.getPre().childNodes()) {
        sequence.add(arg.accept(this));
        index = ++localIndex;
      }
    }

    if (node.getOptArgs() != null) {
      // (BlockNode 0, (OptArgNode:a 0, (LocalAsgnNode:a 0, (FixnumNode 0))), ...)
      state = State.OPT;
      for (org.jruby.ast.Node arg : node.getOptArgs().childNodes()) {
        sequence.add(arg.accept(this));
        index = ++localIndex;
      }
    }

    if (node.getPost() != null) {
      state = State.POST;
      for (org.jruby.ast.Node arg : node.getPost().childNodes()) {
        sequence.add(arg.accept(this));
        index = ++localIndex;
      }
    }

    if (node.getRestArgNode() != null) {
      methodBodyTranslator.getEnvironment().hasRestParameter = true;
      sequence.add(node.getRestArgNode().accept(this));
    }

    if (node.getBlock() != null) {
      sequence.add(node.getBlock().accept(this));
    }

    return SequenceNode.sequence(context, sourceSection, sequence);
  }
 @Override
 protected RubyNode defaultVisit(org.jruby.ast.Node node) {
   // For normal expressions in the default value for optional arguments, use the normal body
   // translator
   return node.accept(methodBodyTranslator);
 }