Statement* multi_way_branch_statement_walker::dismantle_multi_way_branch_statement(MultiWayBranchStatement *the_case){
    StatementList *replacement = create_statement_list(the_case->get_suif_env());

    Expression *operand = the_case->get_decision_operand ();
    remove_suif_object(operand);

    DataType *type = operand->get_result_type();

    CodeLabelSymbol *default_lab =  the_case->get_default_target();
    the_case->set_default_target(0);
    Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator();
    while (iter.is_valid()) {
	MultiWayBranchStatement::case_pair pair = iter.current();
	IInteger value = pair.first;
	CodeLabelSymbol *lab = pair.second;
	IntConstant *exp = create_int_constant(the_case->get_suif_env(),type, value);
//	Expression *exp = create_load_constant_expression(get_env(),type,iconst);
	TypeBuilder *type_builder = (TypeBuilder *)
          the_case->get_suif_env()->get_object_factory(TypeBuilder::get_class_name());
	Expression *compare =  
	  create_binary_expression(the_case->get_suif_env(),type_builder->get_boolean_type(),
				   k_is_equal_to,
				   deep_suif_clone(operand),
				   exp);
	replacement->append_statement(create_branch_statement(the_case->get_suif_env(),compare,lab));
	iter.next();
	}
    delete operand;
    replacement->append_statement(create_jump_statement(the_case->get_suif_env(),default_lab));
    the_case->get_parent()->replace(the_case,replacement);
    return replacement;
}
Statement *while_statement_walker::dismantle_while_statement(WhileStatement *the_while){
    Statement *result = 0;

    Expression *condition = the_while->get_condition();

    // we are going to reuse the condition so we must remove it
    // from the if statement first to avoid ownership conflicts

    //    the_while->set_condition(SourceOp());
    //    remove_source_op(condition);
    remove_suif_object(condition);

    Statement *body = the_while->get_body();
    CodeLabelSymbol *break_label = the_while->get_break_label();
    CodeLabelSymbol *continue_label = the_while->get_continue_label();

    // likewise of these parts - remove from if.

    the_while->set_body(0);
    the_while->set_break_label(0);
    the_while->set_continue_label(0);

    if (body != 0) {
        StatementList *replacement = create_statement_list(body->get_suif_env());
        result = replacement;
        suif_assert(continue_label != 0);
        UnaryExpression* negated_condition = 
	    create_unary_expression(body->get_suif_env(),
				   condition->get_result_type(),
				   k_logical_not,
				   condition );
        replacement-> append_statement(create_label_location_statement(body->get_suif_env(), continue_label));
        replacement-> append_statement(create_branch_statement(body->get_suif_env(),
                                                 negated_condition, break_label));
        replacement->append_statement(body);

        suif_assert(break_label != 0);
        replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_label));
        replacement-> append_statement(create_label_location_statement(body->get_suif_env(), break_label));
        }

    the_while->get_parent()->replace(the_while,result);
    return result;
}
Walker::ApplyStatus multi_way_branch_statement_compactor::operator () (SuifObject *x)
    {
    MultiWayBranchStatement *the_case = to<MultiWayBranchStatement>(x);

    // is the table already compact?

    if (is_compact(the_case))
       return Walker::Continue;

    SymbolTable *scope = find_scope(x);
    if (!scope)
	return Walker::Continue;

    CodeLabelSymbol *default_lab =  the_case->get_default_target();

    // very special case - the case list is empty, so just jump to the default label

    if (the_case->get_case_count() == 0) {
	Statement *replacement = create_jump_statement(get_env(),default_lab);
	the_case->get_parent()->replace(the_case,replacement);
    	set_address(replacement);
    	return Walker::Replaced;
	}

    StatementList *replacement = create_statement_list(get_env());

    Expression *operand = the_case->get_decision_operand ();

    remove_suif_object(operand);

    DataType *type = operand->get_result_type();
    VariableSymbol *decision = create_variable_symbol(get_env(),get_type_builder(get_env())->get_qualified_type(type));
    scope->add_symbol(decision);

    replacement->append_statement(create_store_variable_statement(get_env(),decision,operand));

    the_case->set_default_target(0);
    MultiWayGroupList jump_list(get_env(),default_lab,decision);;
    
    Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator();
    while (iter.is_valid()) {
	MultiWayBranchStatement::case_pair pair = iter.current();
	jump_list.add_element(pair.first,pair.second);
	iter.next();
	}
    // we have built the new structure, now need to generate code for it

    jump_list.generate_code(replacement);
    
    the_case->get_parent()->replace(the_case,replacement);
    set_address(replacement);
    return Walker::Replaced;
    }
Walker::ApplyStatus dw2wtp_do_while_statement_walker::operator () (SuifObject *x) {
	SuifEnv *env = get_env();
	DoWhileStatement *do_while_stmt = to<DoWhileStatement>(x);

	Expression *do_while_condition = do_while_stmt->get_condition();
	do_while_stmt->set_condition(0);
	Statement *do_while_body = do_while_stmt->get_body();
	do_while_stmt->set_body(0);

	IfStatement *first_iteration = create_if_statement(env, 
						to<Expression>(deep_suif_clone(do_while_condition)), 
						to<Statement>(deep_suif_clone(do_while_body)));
	WhileStatement *remaining_iterations = create_while_statement(env, do_while_condition, do_while_body);

	StatementList *replacement = create_statement_list(env);
	replacement->append_statement(first_iteration);
	replacement->append_statement(remaining_iterations);

	do_while_stmt->get_parent()->replace(do_while_stmt, replacement);
	set_address(replacement);
    	return Walker::Replaced;
}
Statement* c_for_statement_walker::dismantle_c_for_statement(CForStatement *the_for){
    StatementList *replacement = create_statement_list(the_for->get_suif_env());
    StatementList *body  = create_statement_list(the_for->get_suif_env());
    Statement* original_body = the_for->get_body();
    the_for->set_body(0);
    body->append_statement(original_body);
    the_for->set_body(body);
    Statement* pre_pad = the_for->get_pre_pad();
    CodeLabelSymbol* break_lab = the_for->get_break_label();
    CodeLabelSymbol* continue_lab = the_for->get_continue_label();
    Statement* before = the_for->get_before();
    Expression* test = the_for->get_test();
    Statement* step = the_for->get_step();;

    if(before)remove_suif_object(before);
    if(test)remove_suif_object(test);
    if(step)remove_suif_object(step);
    if(body)remove_suif_object(body);
    if(pre_pad)remove_suif_object(pre_pad);
    the_for->set_break_label(0);
    the_for->set_continue_label(0);

    // I am guessing what pre-pad and post-pad do
    if (before)
	replacement->append_statement(before);
    
    // and loop if not out of range
    replacement->append_statement(
	create_label_location_statement(the_for->get_suif_env(), continue_lab));

    if(test) {
	    SuifEnv *env = the_for->get_suif_env();
	    DataType *bool_type = get_type_builder(env)->get_boolean_type();
	    test = create_unary_expression(env,bool_type,k_logical_not,test);
	    replacement->append_statement(create_branch_statement(env,test,break_lab));
	}

    if(pre_pad){
        replacement->append_statement(pre_pad);
    }

    append_flattened(replacement,body);
    append_flattened(replacement,step);
    replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_lab));
    replacement->append_statement(
        create_label_location_statement(body->get_suif_env(), break_lab));
    // end of loop

    the_for->get_parent()->replace(the_for, replacement);
    return replacement;
}
void ScalarReplacementPass2::AppendStores()
{
  assert(procDef != NULL) ;
  StatementList* innermost = InnermostList(procDef) ;
  assert(innermost != NULL) ;
  list<std::pair<Expression*, VariableSymbol*> >::iterator storeIter = 
    IdentifiedStores.begin() ;
  while (storeIter != IdentifiedStores.end())
  {
    (*storeIter).first->set_parent(NULL) ;
    LoadVariableExpression* loadTmp = 
      create_load_variable_expression(theEnv,
			   (*storeIter).second->get_type()->get_base_type(),
				      (*storeIter).second) ;
    StoreStatement* postStore = 
      create_store_statement(theEnv, 
			     loadTmp,
    			     (*storeIter).first) ;
    innermost->append_statement(postStore) ;
    ++storeIter ;
  }
}
Walker::ApplyStatus dste_call_statement_walker2::operator () (SuifObject *x) {
	SuifEnv *env = get_env();
	CallStatement *call_stmt = to<CallStatement>(x);

	SymbolAddressExpression *callee_address = to<SymbolAddressExpression>(call_stmt->get_callee_address());
	ProcedureSymbol *proc_symbol = to<ProcedureSymbol>(callee_address->get_addressed_symbol());
	String called_proc_name = proc_symbol->get_name();
	
	if(called_proc_name == String("ROCCC_lookup_in_state_table")){

 	   Expression *argument_expr = call_stmt->get_argument(0);
	   if(is_a<UnaryExpression>(argument_expr))
	      argument_expr = (to<UnaryExpression>(argument_expr))->get_source();
	   int st_id = (to<IntConstant>(argument_expr))->get_value().c_int();

	   suif_map<int, ST*>::iterator iter = state_table_defs->find(st_id);
	   if(iter == state_table_defs->end())
	      return Walker::Continue;
	
	   ST* state_table_def = (*iter).second;
	   int pattern_length = state_table_def->get_length();
	   int state_count = state_table_def->get_state_count();
	   int alphabet_count = state_table_def->get_alphabet_count();
	   int start_state = state_table_def->get_start_state();
	   int error_state = state_table_def->get_error_state();
	   int final_state = state_table_def->get_final_state();

	   VariableSymbol *char_set_array_sym = state_table_def->get_char_set_sym();
	   DataType *stream_data_type = get_array_element_type(char_set_array_sym);
	   QualifiedType *qualed_stream_data_type = retrieve_qualified_type(stream_data_type);

	   VariableSymbol *state_table_sym = state_table_def->get_state_table_sym();
	   DataType *dfa_state_data_type = get_array_element_type(state_table_sym);
	   QualifiedType *qualed_dfa_state_type = retrieve_qualified_type(dfa_state_data_type);

	   StatementList *replacement = create_statement_list(env);

 	   argument_expr = call_stmt->get_argument(1);
	   argument_expr->set_parent(0);
	   if(is_a<UnaryExpression>(argument_expr))
	      argument_expr = (to<UnaryExpression>(argument_expr))->get_source();

	   VariableSymbol* input_char_sym = new_anonymous_variable(env, proc_def_body, qualed_stream_data_type);
	   name_variable(input_char_sym, "ic");

	   StoreVariableStatement *store_var_stmt = create_store_variable_statement(env, input_char_sym, argument_expr);
	   replacement->append_statement(store_var_stmt);

           TypeBuilder *tb = get_type_builder(env);
           SymbolTable *external_symbol_table = get_external_symbol_table(get_procedure_definition(call_stmt));

           list<QualifiedType*> cam_proc_argument_types;
	   for(int j = 0; j < alphabet_count+1; j++)
	       cam_proc_argument_types.push_back(qualed_stream_data_type);
           DataType *cam_return_type;
           int cam_return_bit_size = get_unsigned_bit_size(alphabet_count);
	   cam_return_type = tb->get_integer_type(cam_return_bit_size, cam_return_bit_size, 0);
           cam_return_type->set_name(String("ROCCC_int") + String(cam_return_bit_size));
           CProcedureType *cam_proc_type = tb->get_c_procedure_type(cam_return_type, cam_proc_argument_types);
	   ProcedureSymbol *cam_proc_sym = create_procedure_symbol(env, cam_proc_type, String("ROCCC_cam") + String(alphabet_count));
           external_symbol_table->add_symbol(cam_proc_sym);

	   VariableSymbol* alphabet_index_sym = new_anonymous_variable(env, proc_def_body, retrieve_qualified_type(cam_return_type));
	   name_variable(alphabet_index_sym, "ais");

           SymbolAddressExpression *cam_proc_sym_expr = create_symbol_address_expression(env, tb->get_pointer_type(cam_proc_type), cam_proc_sym);
           CallStatement *cam_macro_stmt = create_call_statement(env, alphabet_index_sym, cam_proc_sym_expr);
	   for(int j = 0; j < alphabet_count; j++){

	       Expression *cam_argument_expr = create_symbol_address_expression(env, char_set_array_sym->get_type()->get_base_type(), char_set_array_sym);
	       cam_argument_expr = create_array_reference_expression(env, stream_data_type, cam_argument_expr, 
								create_int_constant(env, tb->get_integer_type(), IInteger(j)));
	       cam_argument_expr = create_load_expression(env, stream_data_type, cam_argument_expr);

               cam_macro_stmt->append_argument(cam_argument_expr);
	   }

           cam_macro_stmt->append_argument(create_load_variable_expression(env, stream_data_type, input_char_sym));
 	   replacement->append_statement(cam_macro_stmt);

	   suif_vector<VariableSymbol*>* state_column_vars = new suif_vector<VariableSymbol*>;
	   for(int i = 0; i < state_count; i++){

 	       VariableSymbol* state_column_sym = new_anonymous_variable(env, proc_def_body, qualed_dfa_state_type);
	       name_variable(state_column_sym, "st");
	       state_column_vars->push_back(state_column_sym);
	   }

           list<QualifiedType*> mux_proc_argument_types;
	   for(int j = 0; j < alphabet_count; j++)
	       mux_proc_argument_types.push_back(qualed_dfa_state_type);
	   mux_proc_argument_types.push_back(retrieve_qualified_type(cam_return_type));
           CProcedureType *mux_proc_type = tb->get_c_procedure_type(dfa_state_data_type, mux_proc_argument_types);
	   ProcedureSymbol *mux_proc_sym = create_procedure_symbol(env, mux_proc_type, String("ROCCC_mux") + String(alphabet_count));
           external_symbol_table->add_symbol(mux_proc_sym);

           ArrayType *state_table_array_type = to<ArrayType>(state_table_sym->get_type()->get_base_type());
	   for(int i = 0; i < state_count; i++){

	       if(i == error_state){
	          StoreVariableStatement *state_column_var_init_stmt = create_store_variable_statement(env, state_column_vars->at(i), 
									create_int_constant(env, tb->get_integer_type(), IInteger(i)));
	          replacement->append_statement(state_column_var_init_stmt);
		  continue;
	       }

               SymbolAddressExpression *mux_proc_sym_expr = create_symbol_address_expression(env, tb->get_pointer_type(mux_proc_type), mux_proc_sym);
               CallStatement *mux_macro_stmt = create_call_statement(env, state_column_vars->at(i), mux_proc_sym_expr);

	       for(int j = 0; j < alphabet_count; j++){
	           Expression *mux_argument_expr = create_symbol_address_expression(env, state_table_array_type, state_table_sym);
	           mux_argument_expr = create_array_reference_expression(env, state_table_array_type->get_element_type()->get_base_type(),
		  					mux_argument_expr, create_int_constant(env, tb->get_integer_type(), IInteger(i)));
	           mux_argument_expr = create_array_reference_expression(env, dfa_state_data_type, mux_argument_expr, 
							create_int_constant(env, tb->get_integer_type(), IInteger(j)));
	           mux_argument_expr = create_load_expression(env, dfa_state_data_type, mux_argument_expr);

                   mux_macro_stmt->append_argument(mux_argument_expr);
	       }
	   
               mux_macro_stmt->append_argument(create_load_variable_expression(env, cam_return_type, alphabet_index_sym));
	       replacement->append_statement(mux_macro_stmt);
	   }

	   suif_vector<VariableSymbol*>* current_state_vars = new suif_vector<VariableSymbol*>;
	   suif_vector<VariableSymbol*>* next_state_vars = new suif_vector<VariableSymbol*>;

	   StatementList *var_init_stmt_list = create_statement_list(env);
	   for(int i = 0; i < pattern_length; i++){

 	       VariableSymbol* current_state_sym = new_anonymous_variable(env, proc_def_body, qualed_dfa_state_type);
	       name_variable(current_state_sym, "cs");
               BrickAnnote *feedback_level_annote = create_brick_annote(env, "feedback_level");
               current_state_sym->append_annote(feedback_level_annote);
               feedback_level_annote->insert_brick(0, create_integer_brick(env, IInteger(0)));
	       current_state_vars->push_back(current_state_sym);

	       StoreVariableStatement *init_var_stmt = create_store_variable_statement(env, current_state_sym, 
							create_int_constant(env, dfa_state_data_type, IInteger(start_state)));
	       var_init_stmt_list->append_statement(init_var_stmt);

 	       VariableSymbol* next_state_sym = new_anonymous_variable(env, proc_def_body, qualed_dfa_state_type);
	       name_variable(next_state_sym, "ns");
	       next_state_vars->push_back(next_state_sym);
	   }
	   insert_statement_before(get_enclosing_c_for_stmt(call_stmt), var_init_stmt_list);

           mux_proc_argument_types.empty();
	   for(int j = 0; j < state_count+1; j++)
	       mux_proc_argument_types.push_back(qualed_dfa_state_type);
           mux_proc_type = tb->get_c_procedure_type(dfa_state_data_type, mux_proc_argument_types);
           mux_proc_sym = create_procedure_symbol(env, mux_proc_type, String("ROCCC_mux") + String(state_count));
           external_symbol_table->add_symbol(mux_proc_sym);

	   for(int i = 0; i < pattern_length; i++){

               SymbolAddressExpression *mux_proc_sym_expr = create_symbol_address_expression(env, tb->get_pointer_type(mux_proc_type), mux_proc_sym);
               CallStatement *mux_macro_stmt = create_call_statement(env, next_state_vars->at(i), mux_proc_sym_expr);

	       for(int k = 0; k < state_count; k++)
	           mux_macro_stmt->append_argument(create_load_variable_expression(env, dfa_state_data_type, state_column_vars->at(k)));

	       mux_macro_stmt->append_argument(create_load_variable_expression(env, dfa_state_data_type, current_state_vars->at(i)));
	       replacement->append_statement(mux_macro_stmt);
	   }

           Expression *equality_check_expr = create_binary_expression(env, tb->get_boolean_type(), String("is_equal_to"),
                                                create_load_variable_expression(env, dfa_state_data_type, next_state_vars->at(0)),
                                                create_int_constant(env, dfa_state_data_type, IInteger(final_state)));
           VariableSymbol *destination_sym = call_stmt->get_destination();
	   StoreVariableStatement *result_stmt = create_store_variable_statement(env, destination_sym, equality_check_expr); 
	   replacement->append_statement(result_stmt);
           for(int i = 1; i < pattern_length; i++){
               equality_check_expr = create_binary_expression(env, tb->get_boolean_type(), String("is_equal_to"),
                                                create_load_variable_expression(env, dfa_state_data_type, next_state_vars->at(i)),
                                                create_int_constant(env, dfa_state_data_type, IInteger(final_state)));
               Expression *result_expr = create_binary_expression(env, tb->get_boolean_type(), String("logical_or"),
                                                create_load_variable_expression(env, tb->get_boolean_type(), destination_sym),
                                                equality_check_expr);
	       result_stmt = create_store_variable_statement(env, destination_sym, result_expr); 
	       replacement->append_statement(result_stmt);
           }           
                    
           for(int i = 0; i < pattern_length-1; i++){
               
               StoreVariableStatement *store_var_stmt = create_store_variable_statement(env, current_state_vars->at(i+1),
                                        create_load_variable_expression(env, dfa_state_data_type, next_state_vars->at(i)));
               replacement->append_statement(store_var_stmt);
           }   

  	   call_stmt->get_parent()->replace(call_stmt, replacement);
	   return Walker::Truncate;
  	}

        return Walker::Continue;
}
Statement* if_statement_walker::dismantle_if_statement(IfStatement* the_if){
    Statement *result = 0;
    ProcedureDefinition* proc_def = get_procedure_definition(the_if);

    Expression *condition = the_if->get_condition();
    // we are going to reuse the condition so we must remove it
    // from the if statement first to avoid ownership conflicts

    remove_suif_object(condition);
    //    the_if->set_condition(SourceOp());
    //    remove_source_op(condition);

    Statement *then_part = the_if->get_then_part();
    Statement *else_part = the_if->get_else_part();

    // likewise of these parts - remove from if.

    the_if->set_then_part(0);
    the_if->set_else_part(0);
    remove_suif_object(then_part);
    remove_suif_object(else_part);

    if (then_part != 0) {
    StatementList *replacement = create_statement_list( the_if->get_suif_env() );
	result = replacement;
    UnaryExpression* negated_condition = 
    create_unary_expression( the_if->get_suif_env(),
			      condition->get_result_type(),
			      k_logical_not,
			      condition );
	if (else_part != 0) {
	    CodeLabelSymbol *else_label = new_anonymous_label(proc_def->get_symbol_table());
	    CodeLabelSymbol *done_label = new_anonymous_label(proc_def->get_symbol_table());
	    replacement->append_statement(create_branch_statement(the_if->get_suif_env(),
                                                 negated_condition, else_label));
	    replacement->append_statement(then_part);
	    replacement->append_statement(create_jump_statement(the_if->get_suif_env(),done_label));
	    replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), else_label));
	    replacement->append_statement(else_part);
	    replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), done_label));
	    }
	else {
            CodeLabelSymbol *done_label = create_new_label(get_procedure_definition(the_if));
            replacement-> append_statement(create_branch_statement(the_if->get_suif_env(),
                                                 negated_condition, done_label));
            replacement->append_statement(then_part);
            replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label));
	    }
	}
    else {
	if (else_part != 0)
	    {
	    StatementList *replacement = create_statement_list(the_if->get_suif_env());
	    result = replacement;
       	    CodeLabelSymbol *done_label = create_new_label(proc_def);
            replacement->append_statement(create_branch_statement(the_if->get_suif_env(), condition, done_label));
            replacement->append_statement(else_part);
            replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label));
	    }
	else
	    {
	    EvalStatement *replacement = create_eval_statement(the_if->get_suif_env());
	    result = replacement;
	    replacement->append_expression(condition);
	    }
	}

    the_if->get_parent()->replace(the_if, result);
    return result;
}
Statement *for_statement_walker::dismantle_for_statement(ForStatement *the_for){
    StatementList *replacement = create_statement_list(the_for->get_suif_env());
    VariableSymbol*  index = the_for->get_index();
    DataType *type = unqualify_data_type(index->get_type());
    Expression *lower = the_for->get_lower_bound();
    Expression *upper = the_for->get_upper_bound();
    Expression *step = the_for->get_step();
    LString compare_op = the_for->get_comparison_opcode();
    Statement* body =  the_for->get_body();
    Statement* pre_pad = the_for->get_pre_pad();
//    Statement* post_pad = the_for->get_post_pad();
    CodeLabelSymbol* break_lab = the_for->get_break_label();
    CodeLabelSymbol* continue_lab = the_for->get_continue_label();
    the_for->set_index(0);
    remove_suif_object(lower);
    remove_suif_object(upper);
    remove_suif_object(step);
    remove_suif_object(body);
    remove_suif_object(pre_pad);
//    the_for->set_post_pad(0);
//    remove_suif_object(post_pad);
    the_for->set_break_label(0);
    the_for->set_continue_label(0);

    // I am guessing what pre-pad and post-pad do

    if(pre_pad != 0)replacement->append_statement(pre_pad);

    // initialize the index. Is this right? should we ever initialize to upper, for -ve steps?
    // Is index guaranteed not to be changed? Should we be creating a temporary?

    replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,lower));

    replacement->append_statement(create_label_location_statement(body->get_suif_env(), continue_lab));

    if (body != 0)
	replacement->append_statement(body);

    // increment the counter

    Expression *index_expr = 
      create_load_variable_expression(body->get_suif_env(),
				      unqualify_data_type(index->get_type()),
				      index);
    Expression *increment = 
      create_binary_expression(body->get_suif_env(),type,k_add,
			       index_expr,step);

    replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,increment));

    // and loop if not out of range

    Expression *compare =  
      create_binary_expression(body->get_suif_env(),type,
			       compare_op,
			       deep_suif_clone<Expression>(index_expr),
			       deep_suif_clone<Expression>(step));
    replacement->append_statement(create_branch_statement(body->get_suif_env(),compare,continue_lab));

    // end of loop

    replacement->append_statement(create_label_location_statement(body->get_suif_env(),break_lab));
//    if(post_pad != 0)replacement->append_statement(post_pad);
    the_for->get_parent()->replace(the_for,replacement);
    return replacement;
}