docs: function next_step(response, search){
  
  	ll('init start...');
  
  	// Prevent future actions (the register would be sticky).
  	search.unregister('search', 'next step');
  
  	// Take a look at the two facets that we'll be iterating over.
  	ll('Gathering functions for term data...');
  	var reqs_to_do = 0;
  	f1 = response.facet_field(global_facet1);
  	f2 = response.facet_field(global_facet2);
  	ll('f1: ' + f1);
  	ll('f2: ' + f2);
  
  	// Collect the initial node information for the two axes.
  	// Also collect the initial index by id for both axes.
  	var id_to_index = {};
  	us.each([f1, f2], function(set){
  	    us.each(set, function(set_pair, set_index){
  		var sid = set_pair[0];
  		nodes.push({id: sid, index: set_index});
  		id_to_index[sid] = set_index;
  	    });
  	});
  	ll('id_to_index #: ' + us.keys(id_to_index).length);
  
  	// Now collect the batch URLs along one facet in reference to
  	// the other (arbitrary)--we should be able to get what we
  	// want by just looking at once facet and checking the other
  	// as we vary it.
  	var collected_functions = [];
  	us.each(f1, function(f1_pair){
  	    reqs_to_do++;
  	    collected_functions.push(
  		function(){
  		    var f1_id = f1_pair[0];
  		    
  		    // Return the state.
  		    // We have to reset the rows as well since rows is
  		    // not sticky across a search action (think about
  		    // it).
  		    search.set('rows', 0); // we don't need any actual rows
  		    search.set_facet_limit(flimit);
  		    search.reset_query_filters();
  		    
  		    search.add_query_filter(global_facet1, f1_id);
  		    return search.search();
  		});
  	});
  
  	// Fetch the data and scrape out what we want.
  	var reqs_done = 0;
  	var accumulator_fun = function(resp){
  
  	    // Update progress bar.
  	    reqs_done++;
  	    var per = Math.round((reqs_done / reqs_to_do) * 100);
  	    //ll(reqs_done + ' of ' + reqs_to_do + ' = ' + per + '%');
  	    // jQuery(pwidget).progressbar('value', per);
  	    jQuery(pwidget_bs3_bar).css('width', per + '%');
  	    jQuery(pwidget_bs3_bar).attr('aria-valuenow', per);
  
  	    // Recover the facet that we're currently looking at: 1.
  	    var f1_name = '???';
      	    var fq_set = resp.parameter('fq');
  	    //ll('accumu: ' + dump(fq_set));
  	    us.each(fq_set, function(fq_item){
  		// Split up each line in the set.
  		var two_part = bbop.first_split(':', fq_item);
      		var fkey = two_part[0];
      		var fval = bbop.dequote(two_part[1]);
      		//ll('Looking at info for: ' + fval);
  		
  		// Check to see if it matches. If it does, that's the
  		// recovered value.
  		if( fkey === global_facet1 ){
  		    f1_name = fval;		     
  		}
  	    });
  	    ll('got: ' + f1_name);
  
  	    // Now grab out all of the second-facet information.
  	    //ll('accumu: ' + resp.raw());
  	    var incoming_facet = resp.facet_field(global_facet2);
  	    var in_hash = bbop.hashify(incoming_facet);	
  	    ll('in_hash: ' + bbop.dump(in_hash));
  	    us.each(f2, function(f2_line, f2_index){
  
  		// Figure out the value for this pair.
  		var f2_name = f2_line[0];
  		//var comb_val = f2_line[1];
  		var comb_val = 0;
  		var results_val = 0;
  		if( typeof(in_hash[f2_name]) !== 'undefined' ){
  		    results_val = in_hash[f2_name];
  		}
  		ll([f1_name, f2_name].join(', ') + ': ' + results_val);
  		
  		// Up the max.
  		if( results_val > max_val ){
  		    max_val = results_val;
  		}
  		
  		// While we're here, let's also create a lookup
  		// structure.
  		if( typeof(val_hash[f1_name]) === 'undefined' ){
  		    val_hash[f1_name] = {}; }
  		if( typeof(val_hash[f2_name]) === 'undefined' ){
  		    val_hash[f2_name] = {}; }
  		if( typeof(val_hash[f1_name][f2_name]) === 'undefined' ){
  		    val_hash[f1_name][f2_name] = results_val; }
  		if( typeof(val_hash[f2_name][f1_name]) === 'undefined' ){
  		    val_hash[f2_name][f1_name] = results_val; }
  	    });
  	};
  
  	///
  	/// Coloration functions using D3.
  	/// We have the max_val now, so we can compute color.
  	///
  
  	// A value from our values domain in to a color in our range.
  	// 0 always maps to a white-ish color.
  	var c = d3.scale.linear().domain([0,max_val]).rangeRound([127,255]);
  	function value_to_color_dark(val){
  	    //var retval = '#efefef';
  	    var retval = '#fafafa';
  	    if( val !== 0 ){
  		var cval = c(val);
  		var cinv = 255 - cval;
  		var chex = cinv.toString(16);
  		if( cval ){
  		    if( chex.length === 1 ){ chex = '0' + chex; }
  		    retval = '#' + chex + chex + chex + '';
  		}
  	    }
  	    return retval;
  	}
  	function value_to_color_step(val){
  	    //var retval = '#efefef';
  	    var retval = '#fafafa';
  	    if( val !== 0 ){
  		// 1-3 = pale green
  		// 4-10 = yellow
  		// 11-100 = orange
  		// 101+ = red 
  		if( val <= 3 ){
  		    retval = '#79f853'; // green
  		}else if( val <= 10 ){
  		    //retval = '#f5ff2b'; // yellow
  		    retval = '#e8f129'; // yellow
  		}else if( val <= 100 ){
  		    retval = '#fd953b'; // orange		
  		}else{
  		    retval = '#ff4e53';
  		}
  	    }
  	    return retval;
  	}	
  	// Decide our coloration live at this point.
  	//var value_to_color = value_to_color_dark; // default
  	value_to_color = value_to_color_step; // default
  	// var curr_color_selection =
  	// 	jQuery("input:radio[name=color]:checked").val();
  	
  	// The final function is the data renderer.
  	var final_fun = function(){
  	    ll('Entering final_fun...');
  
  	    // We are done!
  	    jQuery(pwidget_bs3_container).hide();
  
  	    //render(matrix, nodes, max_val);
  	    render();
  	};
  
  	// The final function is the data renderer.
  	var error_fun = function(err){
  	    alert('Encountered error while running: ' + err.toString());
  	};
  
  	search.run_promise_functions(collected_functions,
  				     accumulator_fun, final_fun, error_fun);
      }