void makeBMEAveragesTable( double[][] D, double[][] A )
	{
		edge e, f, exclude;
		node u,v;
	  	// first, let's deal with the averages involving the root of T
		e = root.leftEdge;
		f = depthFirstTraverse( null );
		while ( null != f ) 
		{
			if ( f.head.leaf() )
				A[e.head.index][f.head.index] = A[f.head.index][e.head.index]
				    = D[e.tail.index2][f.head.index2];
			else
			{
				u = f.head.leftEdge.head;
				v = f.head.rightEdge.head;
				A[e.head.index][f.head.index] = A[f.head.index][e.head.index]
				    = 0.5*(A[e.head.index][u.index] + A[e.head.index][v.index]);
			}
			f = depthFirstTraverse( f );
		}
		e = depthFirstTraverse( null );
		while ( root.leftEdge != e ) 
		{
			f = exclude = e;
			while ( root.leftEdge != f ) 
			{
				if ( f == exclude )
					exclude = exclude.tail.parentEdge;
				else if ( e.head.leaf() )
				{
					if ( f.head.leaf() )
						A[e.head.index][f.head.index] = 
							A[f.head.index][e.head.index]
							= D[e.head.index2][f.head.index2];
					else
					{
						//since f is chosen using a
					    // depth-first search, other values
					    // have been calculated
						u = f.head.leftEdge.head; 
						v = f.head.rightEdge.head;
						A[e.head.index][f.head.index] 
						    = A[f.head.index][e.head.index] 
						    = 0.5*(A[e.head.index][u.index] 
						    + A[e.head.index][v.index]);
					}
				}
				else
				{
					u = e.head.leftEdge.head;
					v = e.head.rightEdge.head;
					A[e.head.index][f.head.index] 
					    = A[f.head.index][e.head.index] 
					    = 0.5*(A[f.head.index][u.index] 
					    + A[f.head.index][v.index]);
				}
				f = depthFirstTraverse(f);
			}    
	    	e = depthFirstTraverse(e);
		}
		e = depthFirstTraverse( null );
		while ( root.leftEdge != e )
	    {
			// calculates averages for 
			// A[e.head.index][g.head.index] for
			// any edge g in path from e to root of tree
			calcUpAverages(D,A,e,e);  
			e = depthFirstTraverse(e);
	    }
	}