public static double[] tileToMercBounds(int z, int x, int y) {
	    if (z == 0) {
	    	double[] result = {-MAX_X, -MAX_Y, MAX_X, MAX_Y}; 
	        return result;
	    }
	    
	    // x = 0 .. (2^z - 1)
	    // y = 0 .. (2^z - 1)
	    
	    int tilePastCentreAxis = (int)((Math.pow(2,z)) / 2);
	    
	    double bound_left;
	    double bound_right;
	    double bound_top;
	    double bound_bottom;
	    
	    boolean mirrored_x = false;
	    boolean mirrored_y = false;
	    
	    // flip all tiles left/above of the centre axis across to the right/bottom side for now
	    // in other words move everything to the bottom right quadrant
	    if (x < tilePastCentreAxis) {
	        mirrored_x = true;
	        x = ((int)Math.pow(2, z) - 1) - x;
	    }
	    
	    if (y < tilePastCentreAxis) {
	        mirrored_y = true;
	        y = ((int)Math.pow(2, z) - 1) - y;
	    }
	    
	    // 2^z / 2 <= x < 2^z
	    assert ((tilePastCentreAxis <= x) && (x < (Math.pow(2, z))));
	    assert ((tilePastCentreAxis <= y) && (y < (Math.pow(2, z))));
	    
	    // need to cast the numerator to double incase both would have been integers, but true answer should be a floating point number
	    // we also need to cast the tile number to double so that when we multiply it by MAX_X, we don't overfloat the int!
	    bound_left = ((double) (((double)x - tilePastCentreAxis) * (MAX_X)) / tilePastCentreAxis);
	    bound_right = ((double) (((double)(x + 1) - tilePastCentreAxis)  * (MAX_X)) / tilePastCentreAxis);
	    
	    bound_top = ((double) (((double)y - tilePastCentreAxis) * (MAX_Y)) / tilePastCentreAxis) * -1;
	    bound_bottom = ((double) (((double)(y + 1) - tilePastCentreAxis) * (MAX_Y)) / tilePastCentreAxis) * -1;
	    
	    // if we mirrored the tiles earlier, fix them up now that we have the merc bounds
	    if (mirrored_x) {
	        double br = bound_right;
	        double bl = bound_left;
	        
	        bound_left = -1 * br;
	        bound_right = -1 * bl;
	    }
	    
	    if (mirrored_y) {
	        double bb = bound_bottom;
	        double bt = bound_top;
	        
	        bound_bottom = -1 * bt;
	        bound_top = -1 * bb;
	    }
	    
	    double[] result = {bound_left, bound_bottom, bound_right, bound_top};
	    return result;
	}