InternalNode* InternalNode::insert(int value)
{
  // students must write this
  updateMinimums();
  sort();
  //updateMinimums();
  //cout << "Starting InternalNode insert: " << value << endl;
  
  //search keys for position to insert, count - 1 because elements start at 0
  int searchKey = count-1;
  for(int i = count-1; keys[searchKey] > value && i > 0; i--){
    //cout << keys[searchKey] << " > " << value << endl;
    searchKey--;
  }
  BTreeNode* leafSplit = children[searchKey]->insert(value);
  updateMinimums();
  sort();
  //updateMinimums();
  //for(int i = 6; i >= 0; i--)
  //  cout << "Keys[" << i << "]: " << keys[i] << endl;
  if(!leafSplit){
    //cout << "no leaf split" << endl;
    return NULL;  
  }
  
  if(leafSplit && count < internalSize){
    //add here
    //cout << "InternalNode Insert Here" << endl;
    //cout << "InternalNode leafSplit has min: " << leafSplit->getMinimum() << endl;
    keys[count] = leafSplit->getMinimum();
    children[count] = leafSplit;
    count++;
    updateMinimums();
    sort();
    //updateMinimums();
    return NULL;
  }

  else if(leftSibling && leftSibling->getCount() < internalSize){
    //addToLeft(internalSplit)
    //cout << "NEED TO SHARE TO LEFT" << endl;
    //  cout << "Adding to left internal" << endl;
    ((InternalNode*)leftSibling)->insert(children[0]);
    ((InternalNode*)leftSibling)->updateMinimums();
    ((InternalNode*)leftSibling)->sort();
    //((InternalNode*)leftSibling)->updateMinimums();
    count--;
    for(int i = 0; i < count; i++)
    {
      children[i] = children[i + 1];
      keys[i] = keys[i + 1];
    }
      
      children[count] = leafSplit; 
      keys[count] = leafSplit->getMinimum();
      count++;
      updateMinimums();
      sort();
      //updateMinimums();
      //cout << "leafSplit min: " << leafSplit->getMinimum() << endl; 
      leafSplit->setParent(this);
      if(parent)
        parent->findMin(this);
      return NULL;
  }
  else if(rightSibling && rightSibling->getCount() < internalSize){
    //addtoRight
    if(keys[count-1] > leafSplit->getMinimum()){
      //cout << "Internal Passing to right: " << keys[count-1] << endl; 
      ((InternalNode*) rightSibling)->insert(children[count-1]);
      ((InternalNode*) rightSibling)->updateMinimums();
      ((InternalNode*) rightSibling)->sort();
      children[count-1] = leafSplit;
      updateMinimums();
      sort();
      if(((InternalNode*) rightSibling)->parent){
        (((InternalNode*) rightSibling)->parent)->updateMinimums();
        (((InternalNode*) rightSibling)->parent)->sort();

      }
    } 
    
    
    return NULL;
  }

  else if(leafSplit){
    //cout << "Internal Split" << endl;
    InternalNode* newRight = new InternalNode(internalSize, leafSize, parent, this, rightSibling);
    BTreeNode* oldRight = getRightSibling();
    if(rightSibling){
      oldRight->setLeftSibling(newRight);
      newRight->setRightSibling(oldRight);
      newRight->setLeftSibling(this);
    }
    
    rightSibling = newRight;
    int rightCount;
    for(int i = (internalSize+1) / 2; i < internalSize; i++){
      //cout << "i: " << i << endl;
      //cout << "rightCount: " << newRight->getCount() << endl;
      //cout << "passing " << keys[i] << endl;
      //cout << "value: " << value << endl;
      
      rightCount = newRight->getCount();
      newRight->children[rightCount] = children[i];
      newRight->keys[rightCount] = keys[i];
      newRight->count++;
      children[i]->setParent(newRight);
      
      count--;
    }
    //pass the leafSplit
    if(leafSplit->getMinimum() > keys[((internalSize+1)/2)-1]){
      //cout << leafSplit->getMinimum() << " > " << keys[(((internalSize+1)/2)-1)] << endl;
      //cout << "Passing: " << leafSplit->getMinimum() << endl;
      newRight->children[newRight->count] = leafSplit;
      newRight->count++;
      leafSplit->setParent(newRight);
    }
    //pass the value directly left of keys internalsize+1/2-1...
    else{
      //cout << "Passing: " << keys[(((internalSize+1)/2)-1)] << endl;
      newRight->children[newRight->count] = children[(((internalSize+1)/2)-1)];
      newRight->keys[newRight->count] = keys[(((internalSize+1)/2)-1)];
      count--;
      newRight->count++;
      children[(((internalSize+1)/2)-1)] = leafSplit;
      keys[(((internalSize+1)/2)-1)] = leafSplit->getMinimum();
      count++;


    }

    

    updateMinimums();
    sort();
    //sort();
    //updateMinimums();

    //newRight->sort();
    //newRight->updateMinimums();
    //cout << "newRight ->count : " << newRight->count << endl; 
    //cout << "newRight keys 0 and 1: " << newRight->keys[0] << " " << newRight->keys[1] << endl;
    newRight->updateMinimums();
    newRight->sort();
    //cout << "newRight keys 0 and 1: " << newRight->keys[0] << " " << newRight->keys[1] << endl;
    //newRight->updateMinimums();
    return newRight;
        


    //split
    return NULL; //need to split here
  } 

  return NULL; // to avoid warnings for now.
} // InternalNode::insert()