public InternalNode(int d, Node p0, int k1, Node p1, Node n, Node p) {

    super(d, n, p);
    ptrs[0] = p0;
    keys[1] = k1;
    ptrs[1] = p1;
    lastindex = 1;

    if (p0 != null) p0.setParent(new Reference(this, 0, false));
    if (p1 != null) p1.setParent(new Reference(this, 1, false));
  }
  public void insert(int val, Node ptr) {
    // find correct position to insert
    int p = this.findKeyIndex(val);

    // if node is not full
    if (!full()) {
      // if val is larger than last key, increment p
      if (val > this.getKey(this.getLast())) {
        p++;
      }
      // insertion for simple case
      this.insertSimple(val, ptr, p);
    } else {
      // create a neighbor node with val and ptr
      Node split = new InternalNode(degree, null, val, ptr, this.getNext(), this);
      // set split to be next node of current node
      this.setNext(split);
      // get val to be inserted into parent
      int parentVal = this.redistribute();

      // if current node has a parent, insert value into parent
      if (this.getParent() != null) {
        this.getParent().getNode().insert(parentVal, split);
        // if no parent for current node, create a new root
      } else {
        Node newRoot = new InternalNode(degree, this, parentVal, split, null, null);
        // set parent references
        this.setParent(new Reference(newRoot, 0, false));
        split.setParent(new Reference(newRoot, 1, false));
      }
    }
  }