void updatePair( double[][] A, edge nearEdge, edge farEdge, node v,
			node root, double dcoeff, direction d )
	{
	  	edge sib;
	  	//the various cases refer to where the new vertex has
	    //been inserted, in relation to the edge nearEdge
	  	switch( d ) 
	    {
	    	case UP: 
	    		//this case is called when v has been inserted above 
	    		//or skew to farEdge
	    		//do recursive calls first!
	    		if ( null != farEdge.head.leftEdge )
	    			updatePair( A,nearEdge,farEdge.head.leftEdge,v,root,dcoeff, 
	    			    direction.UP );
	    		if ( null != farEdge.head.rightEdge )
	    			updatePair(A,nearEdge,farEdge.head.rightEdge,v,root,
	    			    dcoeff,direction.UP);
	    		A[farEdge.head.index][nearEdge.head.index] =
	    			A[nearEdge.head.index][farEdge.head.index]
	    	        = A[farEdge.head.index][nearEdge.head.index]
		            + dcoeff*A[farEdge.head.index][v.index]
		            - dcoeff*A[farEdge.head.index][root.index];
	    		break; 
	    case DOWN: //called when v has been inserted below farEdge
	    	if ( null != farEdge.tail.parentEdge )
	    		updatePair(A,nearEdge,farEdge.tail.parentEdge,v,root,
	    			dcoeff,direction.DOWN);
	    	sib = farEdge.siblingEdge();
	    	if (null != sib)
	    		updatePair(A,nearEdge,sib,v,root,dcoeff,direction.UP);
	    	A[farEdge.head.index][nearEdge.head.index] =
	    		A[nearEdge.head.index][farEdge.head.index]
		        = A[farEdge.head.index][nearEdge.head.index]
		        + dcoeff*A[v.index][farEdge.head.index]
		        - dcoeff*A[farEdge.head.index][root.index];	  
	    }
	}