THRIFT-4532: Do not update previously generated output files if the contents have not changed
diff --git a/compiler/cpp/src/thrift/generate/t_as3_generator.cc b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
index 87089b4..41724fe 100644
--- a/compiler/cpp/src/thrift/generate/t_as3_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -83,13 +83,13 @@
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(ofstream& out,
+  std::string render_const_value(ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -100,19 +100,19 @@
 
   void generate_as3_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_as3_struct_definition(std::ofstream& out,
+  void generate_as3_struct_definition(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_xception = false,
                                       bool in_class = false,
                                       bool is_result = false);
   // removed -- equality,compare_to
-  void generate_as3_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_struct_tostring(std::ofstream& out, t_struct* tstruct, bool bindable);
-  void generate_as3_meta_data_map(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_as3_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_as3_validator(std::ostream& out, t_struct* tstruct);
+  void generate_as3_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_as3_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_as3_struct_tostring(std::ostream& out, t_struct* tstruct, bool bindable);
+  void generate_as3_meta_data_map(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_as3_type_string(t_type* type);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
@@ -122,15 +122,15 @@
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_bean_boilerplate(std::ofstream& out, t_struct* tstruct, bool bindable);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_as3_bean_boilerplate(std::ostream& out, t_struct* tstruct, bool bindable);
 
   void generate_function_helpers(t_function* tfunction);
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
   // removed std::string isset_field_id(t_field* field);
 
   void generate_service_interface(t_service* tservice);
@@ -143,38 +143,38 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_as3_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_as3_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_as3_doc(std::ofstream& out, t_function* tdoc);
+  void generate_as3_doc(std::ostream& out, t_function* tdoc);
 
   /**
    * Helper rendering functions
@@ -208,7 +208,7 @@
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 
   bool bindable_;
@@ -353,8 +353,8 @@
 void t_as3_generator::generate_enum(t_enum* tenum) {
   // Make output file
   string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".as";
-  ofstream f_enum;
-  f_enum.open(f_enum_name.c_str());
+  ofstream_with_content_based_conditional_update f_enum;
+  f_enum.open(f_enum_name);
 
   // Comment and package it
   f_enum << autogen_comment() << as3_package() << endl;
@@ -416,8 +416,8 @@
   }
 
   string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.as";
-  ofstream f_consts;
-  f_consts.open(f_consts_name.c_str());
+  ofstream_with_content_based_conditional_update f_consts;
+  f_consts.open(f_consts_name);
 
   // Print header
   f_consts << autogen_comment() << as3_package();
@@ -443,7 +443,7 @@
   f_consts.close();
 }
 
-void t_as3_generator::print_const_value(std::ofstream& out,
+void t_as3_generator::print_const_value(std::ostream& out,
                                         string name,
                                         t_type* type,
                                         t_const_value* value,
@@ -567,7 +567,7 @@
   }
 }
 
-string t_as3_generator::render_const_value(ofstream& out,
+string t_as3_generator::render_const_value(ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value) {
@@ -644,7 +644,7 @@
 void t_as3_generator::generate_as3_struct(t_struct* tstruct, bool is_exception) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".as";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << as3_package();
@@ -678,7 +678,7 @@
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_as3_generator::generate_as3_struct_definition(ofstream& out,
+void t_as3_generator::generate_as3_struct_definition(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception,
                                                      bool in_class,
@@ -782,7 +782,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_struct_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public function read(iprot:TProtocol):void {" << endl;
   indent_up();
 
@@ -862,7 +862,7 @@
 
 // generates as3 method to perform various checks
 // (e.g. check that all required fields are set)
-void t_as3_generator::generate_as3_validator(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public function validate():void {" << endl;
   indent_up();
 
@@ -912,7 +912,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol):void {" << endl;
   indent_up();
 
@@ -971,7 +971,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol):void {" << endl;
   indent_up();
 
@@ -1044,7 +1044,7 @@
   indent_down();
 }
 
-void t_as3_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_as3_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                              t_struct* tstruct) {
 
   std::ostringstream getter_stream;
@@ -1100,7 +1100,7 @@
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_as3_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1134,7 +1134,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_bean_boilerplate(ofstream& out,
+void t_as3_generator::generate_as3_bean_boilerplate(ostream& out,
                                                     t_struct* tstruct,
                                                     bool bindable) {
   const vector<t_field*>& fields = tstruct->get_members();
@@ -1216,7 +1216,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_tostring(ofstream& out,
+void t_as3_generator::generate_as3_struct_tostring(ostream& out,
                                                    t_struct* tstruct,
                                                    bool bindable) {
   // If it's bindable, it extends EventDispatcher so toString is an override.
@@ -1293,7 +1293,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_meta_data_map(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_meta_data_map(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1381,7 +1381,7 @@
   }
 }
 
-void t_as3_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_as3_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -1960,7 +1960,7 @@
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_as3_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_as3_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
@@ -2025,7 +2025,7 @@
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_as3_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_as3_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
       << prefix << ".read(iprot);" << endl;
 }
@@ -2033,7 +2033,7 @@
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_as3_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_as3_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string obj;
@@ -2093,7 +2093,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_as3_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_as3_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2111,7 +2111,7 @@
 /**
  * Deserializes a set element
  */
-void t_as3_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_as3_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2125,7 +2125,7 @@
 /**
  * Deserializes a list element
  */
-void t_as3_generator::generate_deserialize_list_element(ofstream& out,
+void t_as3_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   string elem = tmp("_elem");
@@ -2144,7 +2144,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_as3_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_as3_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2213,7 +2213,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_as3_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_as3_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".write(oprot);" << endl;
 }
@@ -2224,7 +2224,7 @@
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_as3_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_as3_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2282,7 +2282,7 @@
 /**
  * Serializes the members of a map.
  */
-void t_as3_generator::generate_serialize_map_element(ofstream& out,
+void t_as3_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string iter,
                                                      string map) {
@@ -2295,7 +2295,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_as3_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_as3_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2303,7 +2303,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_as3_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_as3_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2390,7 +2390,7 @@
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2539,7 +2539,7 @@
 /**
  * Emits a As3Doc comment if the provided object has a doc in Thrift
  */
-void t_as3_generator::generate_as3_doc(ofstream& out, t_doc* tdoc) {
+void t_as3_generator::generate_as3_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
   }
@@ -2548,7 +2548,7 @@
 /**
  * Emits a As3Doc comment if the provided function object has a doc in Thrift
  */
-void t_as3_generator::generate_as3_doc(ofstream& out, t_function* tfunction) {
+void t_as3_generator::generate_as3_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -2573,7 +2573,7 @@
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_as3_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_as3_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
   }
diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
index 3ae7854..b27fc60 100644
--- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
@@ -33,7 +33,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -116,10 +116,10 @@
 
 private:
   /* file streams */
-  ofstream f_types_;
-  ofstream f_types_impl_;
-  ofstream f_header_;
-  ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_types_impl_;
+  ofstream_with_content_based_conditional_update f_header_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   /* namespace variables */
   string nspace;
@@ -145,8 +145,8 @@
                        bool pointer = false,
                        bool constant = false,
                        bool reference = false);
-  void declare_local_variable(ofstream& out, t_type* ttype, string& base_name, bool for_hash_table);
-  void declore_local_variable_for_write(ofstream& out, t_type* ttype, string& base_name);
+  void declare_local_variable(ostream& out, t_type* ttype, string& base_name, bool for_hash_table);
+  void declore_local_variable_for_write(ostream& out, t_type* ttype, string& base_name);
 
   /* generation functions */
   void generate_const_initializer(string name,
@@ -159,51 +159,51 @@
   void generate_service_processor(t_service* tservice);
   void generate_service_server(t_service* tservice);
   void generate_object(t_struct* tstruct);
-  void generate_struct_writer(ofstream& out,
+  void generate_struct_writer(ostream& out,
                               t_struct* tstruct,
                               string this_name,
                               string this_get = "",
                               bool is_function = true);
-  void generate_struct_reader(ofstream& out,
+  void generate_struct_reader(ostream& out,
                               t_struct* tstruct,
                               string this_name,
                               string this_get = "",
                               bool is_function = true);
 
-  void generate_serialize_field(ofstream& out,
+  void generate_serialize_field(ostream& out,
                                 t_field* tfield,
                                 string prefix,
                                 string suffix,
                                 int error_ret);
-  void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix, int error_ret);
-  void generate_serialize_container(ofstream& out, t_type* ttype, string prefix, int error_ret);
-  void generate_serialize_map_element(ofstream& out,
+  void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix, int error_ret);
+  void generate_serialize_container(ostream& out, t_type* ttype, string prefix, int error_ret);
+  void generate_serialize_map_element(ostream& out,
                                       t_map* tmap,
                                       string key,
                                       string value,
                                       int error_ret);
-  void generate_serialize_set_element(ofstream& out, t_set* tset, string element, int error_ret);
-  void generate_serialize_list_element(ofstream& out,
+  void generate_serialize_set_element(ostream& out, t_set* tset, string element, int error_ret);
+  void generate_serialize_list_element(ostream& out,
                                        t_list* tlist,
                                        string list,
                                        string index,
                                        int error_ret);
 
-  void generate_deserialize_field(ofstream& out,
+  void generate_deserialize_field(ostream& out,
                                   t_field* tfield,
                                   string prefix,
                                   string suffix,
                                   int error_ret,
                                   bool allocate = true);
-  void generate_deserialize_struct(ofstream& out,
+  void generate_deserialize_struct(ostream& out,
                                    t_struct* tstruct,
                                    string prefix,
                                    int error_ret,
                                    bool allocate = true);
-  void generate_deserialize_container(ofstream& out, t_type* ttype, string prefix, int error_ret);
-  void generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix, int error_ret);
-  void generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix, int error_ret);
-  void generate_deserialize_list_element(ofstream& out,
+  void generate_deserialize_container(ostream& out, t_type* ttype, string prefix, int error_ret);
+  void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix, int error_ret);
+  void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix, int error_ret);
+  void generate_deserialize_list_element(ostream& out,
                                          t_list* tlist,
                                          string prefix,
                                          string index,
@@ -3480,7 +3480,7 @@
 /**
  * Generates functions to write Thrift structures to a stream.
  */
-void t_c_glib_generator::generate_struct_writer(ofstream& out,
+void t_c_glib_generator::generate_struct_writer(ostream& out,
                                                 t_struct* tstruct,
                                                 string this_name,
                                                 string this_get,
@@ -3553,7 +3553,7 @@
 /**
  * Generates code to read Thrift structures from a stream.
  */
-void t_c_glib_generator::generate_struct_reader(ofstream& out,
+void t_c_glib_generator::generate_struct_reader(ostream& out,
                                                 t_struct* tstruct,
                                                 string this_name,
                                                 string this_get,
@@ -3690,7 +3690,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_c_glib_generator::generate_serialize_field(ofstream& out,
+void t_c_glib_generator::generate_serialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   string suffix,
@@ -3756,7 +3756,7 @@
   }
 }
 
-void t_c_glib_generator::generate_serialize_struct(ofstream& out,
+void t_c_glib_generator::generate_serialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix,
                                                    int error_ret) {
@@ -3766,7 +3766,7 @@
       << indent() << "xfer += ret;" << endl << endl;
 }
 
-void t_c_glib_generator::generate_serialize_container(ofstream& out,
+void t_c_glib_generator::generate_serialize_container(ostream& out,
                                                       t_type* ttype,
                                                       string prefix,
                                                       int error_ret) {
@@ -3923,7 +3923,7 @@
   scope_down(out);
 }
 
-void t_c_glib_generator::generate_serialize_map_element(ofstream& out,
+void t_c_glib_generator::generate_serialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string key,
                                                         string value,
@@ -3935,7 +3935,7 @@
   generate_serialize_field(out, &vfield, "", "", error_ret);
 }
 
-void t_c_glib_generator::generate_serialize_set_element(ofstream& out,
+void t_c_glib_generator::generate_serialize_set_element(ostream& out,
                                                         t_set* tset,
                                                         string element,
                                                         int error_ret) {
@@ -3943,7 +3943,7 @@
   generate_serialize_field(out, &efield, "", "", error_ret);
 }
 
-void t_c_glib_generator::generate_serialize_list_element(ofstream& out,
+void t_c_glib_generator::generate_serialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string list,
                                                          string index,
@@ -3975,7 +3975,7 @@
 }
 
 /* deserializes a field of any type. */
-void t_c_glib_generator::generate_deserialize_field(ofstream& out,
+void t_c_glib_generator::generate_deserialize_field(ostream& out,
                                                     t_field* tfield,
                                                     string prefix,
                                                     string suffix,
@@ -4068,7 +4068,7 @@
   }
 }
 
-void t_c_glib_generator::generate_deserialize_struct(ofstream& out,
+void t_c_glib_generator::generate_deserialize_struct(ostream& out,
                                                      t_struct* tstruct,
                                                      string prefix,
                                                      int error_ret,
@@ -4101,7 +4101,7 @@
   out << indent() << "}" << endl << indent() << "xfer += ret;" << endl;
 }
 
-void t_c_glib_generator::generate_deserialize_container(ofstream& out,
+void t_c_glib_generator::generate_deserialize_container(ostream& out,
                                                         t_type* ttype,
                                                         string prefix,
                                                         int error_ret) {
@@ -4202,7 +4202,7 @@
   scope_down(out);
 }
 
-void t_c_glib_generator::declare_local_variable(ofstream& out, t_type* ttype, string& name, bool for_hash_table) {
+void t_c_glib_generator::declare_local_variable(ostream& out, t_type* ttype, string& name, bool for_hash_table) {
   string tname = type_name(ttype);
 
   /* If the given type is a typedef, find its underlying type so we
@@ -4226,7 +4226,7 @@
   }
 }
 
-void t_c_glib_generator::declore_local_variable_for_write(ofstream& out,
+void t_c_glib_generator::declore_local_variable_for_write(ostream& out,
                                                           t_type* ttype,
                                                           string& name) {
   string tname = type_name(ttype);
@@ -4236,7 +4236,7 @@
   out << indent() << tname << ptr << name << init_val << ";" << endl;
 }
 
-void t_c_glib_generator::generate_deserialize_map_element(ofstream& out,
+void t_c_glib_generator::generate_deserialize_map_element(ostream& out,
                                                           t_map* tmap,
                                                           string prefix,
                                                           int error_ret) {
@@ -4270,7 +4270,7 @@
   indent_down();
 }
 
-void t_c_glib_generator::generate_deserialize_set_element(ofstream& out,
+void t_c_glib_generator::generate_deserialize_set_element(ostream& out,
                                                           t_set* tset,
                                                           string prefix,
                                                           int error_ret) {
@@ -4290,7 +4290,7 @@
   indent_down();
 }
 
-void t_c_glib_generator::generate_deserialize_list_element(ofstream& out,
+void t_c_glib_generator::generate_deserialize_list_element(ostream& out,
                                                            t_list* tlist,
                                                            string prefix,
                                                            string index,
diff --git a/compiler/cpp/src/thrift/generate/t_cl_generator.cc b/compiler/cpp/src/thrift/generate/t_cl_generator.cc
index d9266d1..628d0d8 100644
--- a/compiler/cpp/src/thrift/generate/t_cl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cl_generator.cc
@@ -79,15 +79,15 @@
   void generate_struct      (t_struct*   tstruct);
   void generate_xception    (t_struct*   txception);
   void generate_service     (t_service*  tservice);
-  void generate_cl_struct (std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_cl_struct_internal (std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_exception_sig(std::ofstream& out, t_function* f);
+  void generate_cl_struct (std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_cl_struct_internal (std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_exception_sig(std::ostream& out, t_function* f);
   std::string render_const_value(t_type* type, t_const_value* value);
 
   std::string cl_autogen_comment();
-  void asdf_def(std::ofstream &out);
-  void package_def(std::ofstream &out);
-  void package_in(std::ofstream &out);
+  void asdf_def(std::ostream &out);
+  void package_def(std::ostream &out);
+  void package_in(std::ostream &out);
   std::string generated_package();
   std::string prefix(std::string name);
   std::string package_of(t_program* program);
@@ -107,9 +107,9 @@
   /**
    * Isolate the variable definitions, as they can require structure definitions
    */
-  std::ofstream f_asd_;
-  std::ofstream f_types_;
-  std::ofstream f_vars_;
+  ofstream_with_content_based_conditional_update f_asd_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_vars_;
 
   std::string copy_options_;
 
@@ -195,7 +195,7 @@
   return program_->get_namespace("cpp");
 }
 
-void t_cl_generator::asdf_def(std::ofstream &out) {
+void t_cl_generator::asdf_def(std::ostream &out) {
   out << "(asdf:defsystem #:" << system_prefix << program_name_ << endl;
   indent_up();
   out << indent() << render_includes()
@@ -209,7 +209,7 @@
 /***
  * Generate a package definition. Add use references equivalent to the idl file's include statements.
  */
-void t_cl_generator::package_def(std::ofstream &out) {
+void t_cl_generator::package_def(std::ostream &out) {
   const vector<t_program*>& includes = program_->get_includes();
 
   out << "(thrift:def-package :" << package();
@@ -223,7 +223,7 @@
   out << ")" << endl << endl;
 }
 
-void t_cl_generator::package_in(std::ofstream &out) {
+void t_cl_generator::package_in(std::ostream &out) {
   out << "(cl:in-package :" << package() << ")" << endl << endl;
 }
 
@@ -381,7 +381,7 @@
   generate_cl_struct(f_types_, txception, true);
 }
 
-void t_cl_generator::generate_cl_struct_internal(std::ofstream& out, t_struct* tstruct, bool is_exception) {
+void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* tstruct, bool is_exception) {
   (void)is_exception;
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
@@ -417,7 +417,7 @@
   out << ")";
 }
 
-void t_cl_generator::generate_cl_struct(std::ofstream& out, t_struct* tstruct, bool is_exception = false) {
+void t_cl_generator::generate_cl_struct(std::ostream& out, t_struct* tstruct, bool is_exception = false) {
   std::string name = type_name(tstruct);
   out << (is_exception ? "(thrift:def-exception " : "(thrift:def-struct ") <<
       prefix(name) << endl;
@@ -432,7 +432,7 @@
   out << ")" << endl << endl;
 }
 
-void t_cl_generator::generate_exception_sig(std::ofstream& out, t_function* f) {
+void t_cl_generator::generate_exception_sig(std::ostream& out, t_function* f) {
   generate_cl_struct_internal(out, f->get_xceptions(), true);
 }
 
diff --git a/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc b/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
index 0c0e1e0..5bed2d7 100644
--- a/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
@@ -109,35 +109,35 @@
                                  bool box_it = false);
 
   void generate_cocoa_struct(t_struct* tstruct, bool is_exception);
-  void generate_cocoa_struct_interface(std::ofstream& out,
+  void generate_cocoa_struct_interface(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false);
-  void generate_cocoa_struct_implementation(std::ofstream& out,
+  void generate_cocoa_struct_implementation(std::ostream& out,
                                             t_struct* tstruct,
                                             bool is_xception = false,
                                             bool is_result = false);
-  void generate_cocoa_struct_initializer_signature(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_init_with_coder_method(ofstream& out,
+  void generate_cocoa_struct_initializer_signature(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_init_with_coder_method(ostream& out,
                                                     t_struct* tstruct,
                                                     bool is_exception);
-  void generate_cocoa_struct_encode_with_coder_method(ofstream& out,
+  void generate_cocoa_struct_encode_with_coder_method(ostream& out,
                                                       t_struct* tstruct,
                                                       bool is_exception);
-  void generate_cocoa_struct_copy_method(ofstream& out,
+  void generate_cocoa_struct_copy_method(ostream& out,
                                          t_struct* tstruct,
                                          bool is_exception);
-  void generate_cocoa_struct_hash_method(ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_is_equal_method(ofstream& out,
+  void generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_is_equal_method(ostream& out,
                                              t_struct* tstruct,
                                              bool is_exception);
-  void generate_cocoa_struct_field_accessor_implementations(std::ofstream& out,
+  void generate_cocoa_struct_field_accessor_implementations(std::ostream& out,
                                                             t_struct* tstruct,
                                                             bool is_exception);
-  void generate_cocoa_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_description(std::ofstream& out, t_struct* tstruct);
+  void generate_cocoa_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_validator(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_description(std::ostream& out, t_struct* tstruct);
 
   std::string function_result_helper_struct_type(t_service *tservice, t_function* tfunction);
   std::string function_args_helper_struct_type(t_service* tservice, t_function* tfunction);
@@ -147,29 +147,29 @@
    * Service-level generation functions
    */
 
-  void generate_cocoa_service_protocol(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_async_protocol(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_protocol(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_async_protocol(std::ostream& out, t_service* tservice);
 
-  void generate_cocoa_service_client_interface(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_client_async_interface(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_client_interface(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_client_async_interface(std::ostream& out, t_service* tservice);
 
-  void generate_cocoa_service_client_send_function_implementation(ofstream& out,
+  void generate_cocoa_service_client_send_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_cocoa_service_client_send_function_invocation(ofstream& out, t_function* tfunction);
-  void generate_cocoa_service_client_send_async_function_invocation(ofstream& out,
+  void generate_cocoa_service_client_send_function_invocation(ostream& out, t_function* tfunction);
+  void generate_cocoa_service_client_send_async_function_invocation(ostream& out,
                                                                     t_function* tfunction,
                                                                     string failureBlockName);
-  void generate_cocoa_service_client_recv_function_implementation(ofstream& out,
+  void generate_cocoa_service_client_recv_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_cocoa_service_client_implementation(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_client_async_implementation(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_client_implementation(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_client_async_implementation(std::ostream& out, t_service* tservice);
 
-  void generate_cocoa_service_server_interface(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_server_implementation(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_server_interface(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_server_implementation(std::ostream& out, t_service* tservice);
   void generate_cocoa_service_helpers(t_service* tservice);
   void generate_service_client(t_service* tservice);
   void generate_service_server(t_service* tservice);
@@ -179,34 +179,34 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string fieldName);
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string fieldName);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string fieldName = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string fieldName = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out,
+  void generate_serialize_list_element(std::ostream& out,
                                        t_list* tlist,
                                        std::string index,
                                        std::string listName);
@@ -254,8 +254,8 @@
    * File streams
    */
 
-  std::ofstream f_header_;
-  std::ofstream f_impl_;
+  ofstream_with_content_based_conditional_update f_header_;
+  ofstream_with_content_based_conditional_update f_impl_;
 
   bool log_unexpected_;
   bool validate_required_;
@@ -568,7 +568,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_interface(ostream& out,
                                                         t_struct* tstruct,
                                                         bool is_exception) {
 
@@ -618,7 +618,7 @@
  * Generate signature for initializer of struct with a parameter for
  * each field.
  */
-void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ostream& out,
                                                                     t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
@@ -641,7 +641,7 @@
  * Generate the initWithCoder method for this struct so it's compatible with
  * the NSCoding protocol
  */
-void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ostream& out,
                                                                      t_struct* tstruct,
                                                                      bool is_exception) {
 
@@ -713,7 +713,7 @@
  * Generate the encodeWithCoder method for this struct so it's compatible with
  * the NSCoding protocol
  */
-void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ostream& out,
                                                                        t_struct* tstruct,
                                                                        bool is_exception) {
 
@@ -780,7 +780,7 @@
 /**
  * Generate the copy method for this struct
  */
-void t_cocoa_generator::generate_cocoa_struct_copy_method(ofstream& out, t_struct* tstruct, bool is_exception) {
+void t_cocoa_generator::generate_cocoa_struct_copy_method(ostream& out, t_struct* tstruct, bool is_exception) {
   out << indent() << "- (instancetype) copyWithZone:(NSZone *)zone" << endl;
   scope_up(out);
 
@@ -815,7 +815,7 @@
 /**
  * Generate the hash method for this struct
  */
-void t_cocoa_generator::generate_cocoa_struct_hash_method(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct) {
   indent(out) << "- (NSUInteger) hash" << endl;
   scope_up(out);
   out << indent() << "NSUInteger hash = 17;" << endl;
@@ -846,7 +846,7 @@
 /**
  * Generate the isEqual method for this struct
  */
-void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ofstream& out, t_struct* tstruct, bool is_exception) {
+void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ostream& out, t_struct* tstruct, bool is_exception) {
   indent(out) << "- (BOOL) isEqual: (id) anObject" << endl;
   scope_up(out);
 
@@ -913,7 +913,7 @@
  * @param is_exception Is this an exception?
  * @param is_result    If this is a result it needs a different writer
  */
-void t_cocoa_generator::generate_cocoa_struct_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_implementation(ostream& out,
                                                              t_struct* tstruct,
                                                              bool is_exception,
                                                              bool is_result) {
@@ -1017,7 +1017,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_reader(ostream& out, t_struct* tstruct) {
   out << "- (BOOL) read: (id <TProtocol>) inProtocol error: (NSError *__autoreleasing *)__thriftError" << endl;
   scope_up(out);
 
@@ -1111,7 +1111,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
   indent_up();
 
@@ -1162,7 +1162,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
   indent_up();
 
@@ -1225,7 +1225,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_validator(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_validator(ostream& out, t_struct* tstruct) {
   out << indent() << "- (BOOL) validate: (NSError *__autoreleasing *)__thriftError {" << endl;
   indent_up();
 
@@ -1259,7 +1259,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ostream& out,
                                                                              t_struct* tstruct,
                                                                              bool is_exception) {
   (void)is_exception;
@@ -1298,7 +1298,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_description(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_description(ostream& out, t_struct* tstruct) {
 
   // Allow use of debugDescription so the app can add description via a cateogory/extension
   if (debug_descriptions_) {
@@ -1428,7 +1428,7 @@
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out, t_service* tservice) {
+void t_cocoa_generator::generate_cocoa_service_protocol(ostream& out, t_service* tservice) {
   out << "@protocol " << cocoa_prefix_ << tservice->get_name() << " <NSObject>" << endl;
 
   vector<t_function*> functions = tservice->get_functions();
@@ -1452,7 +1452,7 @@
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_cocoa_generator::generate_cocoa_service_async_protocol(ofstream& out, t_service* tservice) {
+void t_cocoa_generator::generate_cocoa_service_async_protocol(ostream& out, t_service* tservice) {
   out << "@protocol " << cocoa_prefix_ << tservice->get_name() << "Async"
       << " <NSObject>" << endl;
 
@@ -1472,7 +1472,7 @@
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_interface(ostream& out,
                                                                 t_service* tservice) {
   out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : TBaseClient <"
       << cocoa_prefix_ << tservice->get_name() << "> " << endl;
@@ -1488,7 +1488,7 @@
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_cocoa_generator::generate_cocoa_service_client_async_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_async_interface(ostream& out,
                                                                       t_service* tservice) {
   out << "@interface " << cocoa_prefix_ << tservice->get_name() << "ClientAsync : TBaseClient <"
       << cocoa_prefix_ << tservice->get_name() << "Async> " << endl
@@ -1506,7 +1506,7 @@
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_server_interface(ostream& out,
                                                                 t_service* tservice) {
   out << "@interface " << cocoa_prefix_ << tservice->get_name()
       << "Processor : NSObject <TProcessor> " << endl;
@@ -1519,7 +1519,7 @@
 }
 
 void t_cocoa_generator::generate_cocoa_service_client_send_function_implementation(
-    ofstream& out,
+    ostream& out,
     t_service *tservice,
     t_function* tfunction,
     bool needs_protocol) {
@@ -1577,7 +1577,7 @@
 }
 
 void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementation(
-    ofstream& out,
+    ostream& out,
     t_service* tservice,
     t_function* tfunction,
     bool needs_protocol) {
@@ -1666,7 +1666,7 @@
  * @param tfunction The service to generate an implementation for
  */
 void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(
-                                                                               ofstream& out,
+                                                                               ostream& out,
                                                                                t_function* tfunction) {
 
   t_struct* arg_struct = tfunction->get_arglist();
@@ -1696,7 +1696,7 @@
  * @param tfunction The service to generate an implementation for
  */
 void t_cocoa_generator::generate_cocoa_service_client_send_async_function_invocation(
-                                                                                     ofstream& out,
+                                                                                     ostream& out,
                                                                                      t_function* tfunction,
                                                                                      string failureBlockName) {
 
@@ -1730,7 +1730,7 @@
  *
  * @param tservice The service to generate an implementation for
  */
-void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = cocoa_prefix_ + tservice->get_name() + "Client";
@@ -1814,7 +1814,7 @@
  *
  * @param tservice The service to generate an implementation for
  */
-void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ostream& out,
                                                                            t_service* tservice) {
 
   string name = cocoa_prefix_ + tservice->get_name() + "ClientAsync";
@@ -1974,7 +1974,7 @@
  *
  * @param tservice The service to generate an implementation for
  */
-void t_cocoa_generator::generate_cocoa_service_server_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_server_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = cocoa_prefix_ + tservice->get_name() + "Processor";
@@ -2150,7 +2150,7 @@
  * @param tfield The field
  * @param fieldName The variable name for this field
  */
-void t_cocoa_generator::generate_deserialize_field(ofstream& out,
+void t_cocoa_generator::generate_deserialize_field(ostream& out,
                                                    t_field* tfield,
                                                    string fieldName) {
   t_type* type = get_true_type(tfield->get_type());
@@ -2216,7 +2216,7 @@
 /**
  * Generates an unserializer for a struct, allocates the struct and invokes read:
  */
-void t_cocoa_generator::generate_deserialize_struct(ofstream& out,
+void t_cocoa_generator::generate_deserialize_struct(ostream& out,
                                                     t_struct* tstruct,
                                                     string fieldName) {
   indent(out) << type_name(tstruct) << fieldName << " = [[" << type_name(tstruct, true)
@@ -2227,7 +2227,7 @@
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_cocoa_generator::generate_deserialize_container(ofstream& out,
+void t_cocoa_generator::generate_deserialize_container(ostream& out,
                                                        t_type* ttype,
                                                        string fieldName) {
   string size = tmp("_size");
@@ -2348,7 +2348,7 @@
 /**
  * Generates code to deserialize a map element
  */
-void t_cocoa_generator::generate_deserialize_map_element(ofstream& out,
+void t_cocoa_generator::generate_deserialize_map_element(ostream& out,
                                                          t_map* tmap,
                                                          string fieldName) {
   string key = tmp("_key");
@@ -2368,7 +2368,7 @@
 /**
  * Deserializes a set element
  */
-void t_cocoa_generator::generate_deserialize_set_element(ofstream& out,
+void t_cocoa_generator::generate_deserialize_set_element(ostream& out,
                                                          t_set* tset,
                                                          string fieldName) {
   string elem = tmp("_elem");
@@ -2383,7 +2383,7 @@
 /**
  * Deserializes a list element
  */
-void t_cocoa_generator::generate_deserialize_list_element(ofstream& out,
+void t_cocoa_generator::generate_deserialize_list_element(ostream& out,
                                                           t_list* tlist,
                                                           string fieldName) {
   string elem = tmp("_elem");
@@ -2401,7 +2401,7 @@
  * @param tfield The field to serialize
  * @param fieldName Name to of the variable holding the field
  */
-void t_cocoa_generator::generate_serialize_field(ofstream& out, t_field* tfield, string fieldName) {
+void t_cocoa_generator::generate_serialize_field(ostream& out, t_field* tfield, string fieldName) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2468,7 +2468,7 @@
  * @param tstruct The struct to serialize
  * @param fieldName Name of variable holding struct
  */
-void t_cocoa_generator::generate_serialize_struct(ofstream& out,
+void t_cocoa_generator::generate_serialize_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   string fieldName) {
   (void)tstruct;
@@ -2481,7 +2481,7 @@
  * @param ttype  The type of container
  * @param fieldName Name of variable holding container
  */
-void t_cocoa_generator::generate_serialize_container(ofstream& out,
+void t_cocoa_generator::generate_serialize_container(ostream& out,
                                                      t_type* ttype,
                                                      string fieldName) {
   scope_up(out);
@@ -2547,7 +2547,7 @@
 /**
  * Serializes the members of a map.
  */
-void t_cocoa_generator::generate_serialize_map_element(ofstream& out,
+void t_cocoa_generator::generate_serialize_map_element(ostream& out,
                                                        t_map* tmap,
                                                        string key,
                                                        string mapName) {
@@ -2560,7 +2560,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_cocoa_generator::generate_serialize_set_element(ofstream& out,
+void t_cocoa_generator::generate_serialize_set_element(ostream& out,
                                                        t_set* tset,
                                                        string elementName) {
   t_field efield(tset->get_elem_type(), elementName);
@@ -2570,7 +2570,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_cocoa_generator::generate_serialize_list_element(ofstream& out,
+void t_cocoa_generator::generate_serialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string index,
                                                         string listName) {
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index c78b806..3e8f728 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -112,8 +112,8 @@
 
   void generate_typedef(t_typedef* ttypedef);
   void generate_enum(t_enum* tenum);
-  void generate_enum_ostream_operator_decl(std::ofstream& out, t_enum* tenum);
-  void generate_enum_ostream_operator(std::ofstream& out, t_enum* tenum);
+  void generate_enum_ostream_operator_decl(std::ostream& out, t_enum* tenum);
+  void generate_enum_ostream_operator(std::ostream& out, t_enum* tenum);
   void generate_forward_declaration(t_struct* tstruct);
   void generate_struct(t_struct* tstruct) { generate_cpp_struct(tstruct, false); }
   void generate_xception(t_struct* txception) { generate_cpp_struct(txception, true); }
@@ -121,13 +121,13 @@
 
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value);
-  std::string render_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out, std::string name, t_type* type, t_const_value* value);
+  std::string render_const_value(std::ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
 
-  void generate_struct_declaration(std::ofstream& out,
+  void generate_struct_declaration(std::ostream& out,
                                    t_struct* tstruct,
                                    bool is_exception = false,
                                    bool pointers = false,
@@ -135,26 +135,26 @@
                                    bool write = true,
                                    bool swap = false,
                                    bool is_user_struct = false);
-  void generate_struct_definition(std::ofstream& out,
-                                  std::ofstream& force_cpp_out,
+  void generate_struct_definition(std::ostream& out,
+                                  std::ostream& force_cpp_out,
                                   t_struct* tstruct,
                                   bool setters = true,
                                   bool is_user_struct = false);
-  void generate_copy_constructor(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_move_constructor(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_constructor_helper(std::ofstream& out,
+  void generate_copy_constructor(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_move_constructor(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_constructor_helper(std::ostream& out,
                                    t_struct* tstruct,
                                    bool is_excpetion,
                                    bool is_move);
-  void generate_assignment_operator(std::ofstream& out, t_struct* tstruct);
-  void generate_move_assignment_operator(std::ofstream& out, t_struct* tstruct);
-  void generate_assignment_helper(std::ofstream& out, t_struct* tstruct, bool is_move);
-  void generate_struct_reader(std::ofstream& out, t_struct* tstruct, bool pointers = false);
-  void generate_struct_writer(std::ofstream& out, t_struct* tstruct, bool pointers = false);
-  void generate_struct_result_writer(std::ofstream& out, t_struct* tstruct, bool pointers = false);
-  void generate_struct_swap(std::ofstream& out, t_struct* tstruct);
-  void generate_struct_print_method(std::ofstream& out, t_struct* tstruct);
-  void generate_exception_what_method(std::ofstream& out, t_struct* tstruct);
+  void generate_assignment_operator(std::ostream& out, t_struct* tstruct);
+  void generate_move_assignment_operator(std::ostream& out, t_struct* tstruct);
+  void generate_assignment_helper(std::ostream& out, t_struct* tstruct, bool is_move);
+  void generate_struct_reader(std::ostream& out, t_struct* tstruct, bool pointers = false);
+  void generate_struct_writer(std::ostream& out, t_struct* tstruct, bool pointers = false);
+  void generate_struct_result_writer(std::ostream& out, t_struct* tstruct, bool pointers = false);
+  void generate_struct_swap(std::ostream& out, t_struct* tstruct);
+  void generate_struct_print_method(std::ostream& out, t_struct* tstruct);
+  void generate_exception_what_method(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -179,45 +179,45 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   std::string suffix = "");
 
-  void generate_deserialize_struct(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out,
                                    t_struct* tstruct,
                                    std::string prefix = "",
                                    bool pointer = false);
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix,
                                          bool push_back,
                                          std::string index);
 
-  void generate_serialize_field(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 std::string suffix = "");
 
-  void generate_serialize_struct(std::ofstream& out,
+  void generate_serialize_struct(std::ostream& out,
                                  t_struct* tstruct,
                                  std::string prefix = "",
                                  bool pointer = false);
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out, t_map* tmap, std::string iter);
+  void generate_serialize_map_element(std::ostream& out, t_map* tmap, std::string iter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   void generate_function_call(ostream& out,
                               t_function* tfunction,
@@ -248,16 +248,16 @@
   std::string argument_list(t_struct* tstruct, bool name_params = true, bool start_comma = false);
   std::string type_to_enum(t_type* ttype);
 
-  void generate_enum_constant_list(std::ofstream& f,
+  void generate_enum_constant_list(std::ostream& f,
                                    const vector<t_enum_value*>& constants,
                                    const char* prefix,
                                    const char* suffix,
                                    bool include_values);
 
-  void generate_struct_ostream_operator_decl(std::ofstream& f, t_struct* tstruct);
-  void generate_struct_ostream_operator(std::ofstream& f, t_struct* tstruct);
-  void generate_struct_print_method_decl(std::ofstream& f, t_struct* tstruct);
-  void generate_exception_what_method_decl(std::ofstream& f,
+  void generate_struct_ostream_operator_decl(std::ostream& f, t_struct* tstruct);
+  void generate_struct_ostream_operator(std::ostream& f, t_struct* tstruct);
+  void generate_struct_print_method_decl(std::ostream& f, t_struct* tstruct);
+  void generate_exception_what_method_decl(std::ostream& f,
                                            t_struct* tstruct,
                                            bool external = false);
 
@@ -360,12 +360,12 @@
    * function.
    */
 
-  std::ofstream f_types_;
-  std::ofstream f_types_impl_;
-  std::ofstream f_types_tcc_;
-  std::ofstream f_header_;
-  std::ofstream f_service_;
-  std::ofstream f_service_tcc_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_types_impl_;
+  ofstream_with_content_based_conditional_update f_types_tcc_;
+  ofstream_with_content_based_conditional_update f_header_;
+  ofstream_with_content_based_conditional_update f_service_;
+  ofstream_with_content_based_conditional_update f_service_tcc_;
 
   // The ProcessorGenerator is used to generate parts of the code,
   // so it needs access to many of our protected members and methods.
@@ -386,7 +386,7 @@
 
   // Make output file
   string f_types_name = get_out_dir() + program_name_ + "_types.h";
-  f_types_.open(f_types_name.c_str());
+  f_types_.open(f_types_name);
 
   string f_types_impl_name = get_out_dir() + program_name_ + "_types.cpp";
   f_types_impl_.open(f_types_impl_name.c_str());
@@ -505,7 +505,7 @@
            << ttypedef->get_symbolic() << ";" << endl << endl;
 }
 
-void t_cpp_generator::generate_enum_constant_list(std::ofstream& f,
+void t_cpp_generator::generate_enum_constant_list(std::ostream& f,
                                                   const vector<t_enum_value*>& constants,
                                                   const char* prefix,
                                                   const char* suffix,
@@ -585,7 +585,7 @@
   generate_enum_ostream_operator(f_types_impl_, tenum);
 }
 
-void t_cpp_generator::generate_enum_ostream_operator_decl(std::ofstream& out, t_enum* tenum) {
+void t_cpp_generator::generate_enum_ostream_operator_decl(std::ostream& out, t_enum* tenum) {
 
   out << "std::ostream& operator<<(std::ostream& out, const ";
   if (gen_pure_enums_) {
@@ -597,7 +597,7 @@
   out << endl;
 }
 
-void t_cpp_generator::generate_enum_ostream_operator(std::ofstream& out, t_enum* tenum) {
+void t_cpp_generator::generate_enum_ostream_operator(std::ostream& out, t_enum* tenum) {
 
   // If we've been told the consuming application will provide an ostream
   // operator definition then we only make a declaration:
@@ -635,12 +635,12 @@
  */
 void t_cpp_generator::generate_consts(std::vector<t_const*> consts) {
   string f_consts_name = get_out_dir() + program_name_ + "_constants.h";
-  ofstream f_consts;
-  f_consts.open(f_consts_name.c_str());
+  ofstream_with_content_based_conditional_update f_consts;
+  f_consts.open(f_consts_name);
 
   string f_consts_impl_name = get_out_dir() + program_name_ + "_constants.cpp";
-  ofstream f_consts_impl;
-  f_consts_impl.open(f_consts_impl_name.c_str());
+  ofstream_with_content_based_conditional_update f_consts_impl;
+  f_consts_impl.open(f_consts_impl_name);
 
   // Print header
   f_consts << autogen_comment();
@@ -684,6 +684,7 @@
   f_consts.close();
 
   f_consts_impl << endl << ns_close_ << endl << endl;
+  f_consts_impl.close();
 }
 
 /**
@@ -691,7 +692,7 @@
  * is NOT performed in this function as it is always run beforehand using the
  * validate_types method in main.cc
  */
-void t_cpp_generator::print_const_value(ofstream& out,
+void t_cpp_generator::print_const_value(ostream& out,
                                         string name,
                                         t_type* type,
                                         t_const_value* value) {
@@ -764,7 +765,7 @@
 /**
  *
  */
-string t_cpp_generator::render_const_value(ofstream& out,
+string t_cpp_generator::render_const_value(ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value) {
@@ -826,7 +827,7 @@
   generate_struct_declaration(f_types_, tstruct, is_exception, false, true, true, true, true);
   generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true);
 
-  std::ofstream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_);
+  std::ostream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_);
   generate_struct_reader(out, tstruct);
   generate_struct_writer(out, tstruct);
   generate_struct_swap(f_types_impl_, tstruct);
@@ -848,13 +849,13 @@
   }
 }
 
-void t_cpp_generator::generate_copy_constructor(ofstream& out,
+void t_cpp_generator::generate_copy_constructor(ostream& out,
                                                 t_struct* tstruct,
                                                 bool is_exception) {
   generate_constructor_helper(out, tstruct, is_exception, /*is_move=*/false);
 }
 
-void t_cpp_generator::generate_move_constructor(ofstream& out,
+void t_cpp_generator::generate_move_constructor(ostream& out,
                                                 t_struct* tstruct,
                                                 bool is_exception) {
   generate_constructor_helper(out, tstruct, is_exception, /*is_move=*/true);
@@ -870,7 +871,7 @@
 }
 }
 
-void t_cpp_generator::generate_constructor_helper(ofstream& out,
+void t_cpp_generator::generate_constructor_helper(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_exception,
                                                   bool is_move) {
@@ -913,15 +914,15 @@
   indent(out) << "}" << endl;
 }
 
-void t_cpp_generator::generate_assignment_operator(ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_assignment_operator(ostream& out, t_struct* tstruct) {
   generate_assignment_helper(out, tstruct, /*is_move=*/false);
 }
 
-void t_cpp_generator::generate_move_assignment_operator(ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_move_assignment_operator(ostream& out, t_struct* tstruct) {
   generate_assignment_helper(out, tstruct, /*is_move=*/true);
 }
 
-void t_cpp_generator::generate_assignment_helper(ofstream& out, t_struct* tstruct, bool is_move) {
+void t_cpp_generator::generate_assignment_helper(ostream& out, t_struct* tstruct, bool is_move) {
   std::string tmp_name = tmp("other");
 
   indent(out) << tstruct->get_name() << "& " << tstruct->get_name() << "::operator=(";
@@ -964,7 +965,7 @@
  * @param out Output stream
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_declaration(ofstream& out,
+void t_cpp_generator::generate_struct_declaration(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_exception,
                                                   bool pointers,
@@ -1213,8 +1214,8 @@
   }
 }
 
-void t_cpp_generator::generate_struct_definition(ofstream& out,
-                                                 ofstream& force_cpp_out,
+void t_cpp_generator::generate_struct_definition(ostream& out,
+                                                 ostream& force_cpp_out,
                                                  t_struct* tstruct,
                                                  bool setters,
                                                  bool is_user_struct) {
@@ -1271,7 +1272,7 @@
  * @param out Stream to write to
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, bool pointers) {
+void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bool pointers) {
   if (gen_templates_) {
     out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
         << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl;
@@ -1394,7 +1395,7 @@
  * @param out Stream to write to
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, bool pointers) {
+void t_cpp_generator::generate_struct_writer(ostream& out, t_struct* tstruct, bool pointers) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1460,7 +1461,7 @@
  * @param out Output stream
  * @param tstruct The result struct
  */
-void t_cpp_generator::generate_struct_result_writer(ofstream& out,
+void t_cpp_generator::generate_struct_result_writer(ostream& out,
                                                     t_struct* tstruct,
                                                     bool pointers) {
   string name = tstruct->get_name();
@@ -1524,7 +1525,7 @@
  * @param out Stream to write to
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_swap(ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) {
   out << indent() << "void swap(" << tstruct->get_name() << " &a, " << tstruct->get_name()
       << " &b) {" << endl;
   indent_up();
@@ -1561,14 +1562,14 @@
   out << endl;
 }
 
-void t_cpp_generator::generate_struct_ostream_operator_decl(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_ostream_operator_decl(std::ostream& out, t_struct* tstruct) {
   out << "std::ostream& operator<<(std::ostream& out, const "
       << tstruct->get_name()
       << "& obj);" << endl;
   out << endl;
 }
 
-void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_ostream_operator(std::ostream& out, t_struct* tstruct) {
   if (!has_custom_ostream(tstruct)) {
     // thrift defines this behavior
     out << "std::ostream& operator<<(std::ostream& out, const "
@@ -1582,7 +1583,7 @@
   }
 }
 
-void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_print_method_decl(std::ostream& out, t_struct* tstruct) {
   out << "void ";
   if (tstruct) {
     out << tstruct->get_name() << "::";
@@ -1590,7 +1591,7 @@
   out << "printTo(std::ostream& out) const";
 }
 
-void t_cpp_generator::generate_exception_what_method_decl(std::ofstream& out,
+void t_cpp_generator::generate_exception_what_method_decl(std::ostream& out,
                                                           t_struct* tstruct,
                                                           bool external) {
   out << "const char* ";
@@ -1601,33 +1602,33 @@
 }
 
 namespace struct_ostream_operator_generator {
-void generate_required_field_value(std::ofstream& out, const t_field* field) {
+void generate_required_field_value(std::ostream& out, const t_field* field) {
   out << " << to_string(" << field->get_name() << ")";
 }
 
-void generate_optional_field_value(std::ofstream& out, const t_field* field) {
+void generate_optional_field_value(std::ostream& out, const t_field* field) {
   out << "; (__isset." << field->get_name() << " ? (out";
   generate_required_field_value(out, field);
   out << ") : (out << \"<null>\"))";
 }
 
-void generate_field_value(std::ofstream& out, const t_field* field) {
+void generate_field_value(std::ostream& out, const t_field* field) {
   if (field->get_req() == t_field::T_OPTIONAL)
     generate_optional_field_value(out, field);
   else
     generate_required_field_value(out, field);
 }
 
-void generate_field_name(std::ofstream& out, const t_field* field) {
+void generate_field_name(std::ostream& out, const t_field* field) {
   out << "\"" << field->get_name() << "=\"";
 }
 
-void generate_field(std::ofstream& out, const t_field* field) {
+void generate_field(std::ostream& out, const t_field* field) {
   generate_field_name(out, field);
   generate_field_value(out, field);
 }
 
-void generate_fields(std::ofstream& out,
+void generate_fields(std::ostream& out,
                      const vector<t_field*>& fields,
                      const std::string& indent) {
   const vector<t_field*>::const_iterator beg = fields.begin();
@@ -1649,7 +1650,7 @@
 /**
  * Generates operator<<
  */
-void t_cpp_generator::generate_struct_print_method(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_print_method(std::ostream& out, t_struct* tstruct) {
   out << indent();
   generate_struct_print_method_decl(out, tstruct);
   out << " {" << endl;
@@ -1668,7 +1669,7 @@
 /**
  * Generates what() method for exceptions
  */
-void t_cpp_generator::generate_exception_what_method(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_exception_what_method(std::ostream& out, t_struct* tstruct) {
   out << indent();
   generate_exception_what_method_decl(out, tstruct, true);
   out << " {" << endl;
@@ -1835,7 +1836,7 @@
 void t_cpp_generator::generate_service_helpers(t_service* tservice) {
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
 
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     t_struct* ts = (*f_iter)->get_arglist();
@@ -2071,7 +2072,7 @@
 
   string ns = namespace_prefix(tservice->get_program()->get_namespace("cpp"));
 
-  ofstream f_skeleton;
+  ofstream_with_content_based_conditional_update f_skeleton;
   f_skeleton.open(f_skeleton_name.c_str());
   f_skeleton << "// This autogenerated skeleton file illustrates one way to adapt a synchronous"
              << endl << "// interface into an asynchronous interface. You should copy it to another"
@@ -2239,7 +2240,7 @@
     ifstyle = "CobCl";
   }
 
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
   string template_header, template_suffix, short_suffix, protocol_type, _this;
   string const prot_factory_type = "::apache::thrift::protocol::TProtocolFactory";
   if (gen_templates_) {
@@ -2830,8 +2831,8 @@
 
   t_cpp_generator* generator_;
   t_service* service_;
-  std::ofstream& f_header_;
-  std::ofstream& f_out_;
+  std::ostream& f_header_;
+  std::ostream& f_out_;
   string service_name_;
   string style_;
   string pstyle_;
@@ -3205,7 +3206,7 @@
     return;
   }
 
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
 
   t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result");
   t_field success(tfunction->get_returntype(), "success", 0);
@@ -3252,7 +3253,7 @@
   vector<t_field*>::const_iterator x_iter;
   string service_func_name = "\"" + tservice->get_name() + "." + tfunction->get_name() + "\"";
 
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
 
   string prot_type = (specialized ? "Protocol_" : "::apache::thrift::protocol::TProtocol");
   string class_suffix;
@@ -3664,7 +3665,7 @@
 
   string ns = namespace_prefix(tservice->get_program()->get_namespace("cpp"));
 
-  ofstream f_skeleton;
+  ofstream_with_content_based_conditional_update f_skeleton;
   f_skeleton.open(f_skeleton_name.c_str());
   f_skeleton << "// This autogenerated skeleton file illustrates how to build a server." << endl
              << "// You should copy it to another filename to avoid overwriting it." << endl << endl
@@ -3726,7 +3727,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_cpp_generator::generate_deserialize_field(ofstream& out,
+void t_cpp_generator::generate_deserialize_field(ostream& out,
                                                  t_field* tfield,
                                                  string prefix,
                                                  string suffix) {
@@ -3795,7 +3796,7 @@
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_cpp_generator::generate_deserialize_struct(ofstream& out,
+void t_cpp_generator::generate_deserialize_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   string prefix,
                                                   bool pointer) {
@@ -3819,7 +3820,7 @@
   }
 }
 
-void t_cpp_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_cpp_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string size = tmp("_size");
@@ -3880,7 +3881,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_cpp_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_cpp_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -3895,7 +3896,7 @@
   generate_deserialize_field(out, &fval);
 }
 
-void t_cpp_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_cpp_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -3906,7 +3907,7 @@
   indent(out) << prefix << ".insert(" << elem << ");" << endl;
 }
 
-void t_cpp_generator::generate_deserialize_list_element(ofstream& out,
+void t_cpp_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix,
                                                         bool use_push,
@@ -3929,7 +3930,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_cpp_generator::generate_serialize_field(ofstream& out,
+void t_cpp_generator::generate_serialize_field(ostream& out,
                                                t_field* tfield,
                                                string prefix,
                                                string suffix) {
@@ -4002,7 +4003,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_cpp_generator::generate_serialize_struct(ofstream& out,
+void t_cpp_generator::generate_serialize_struct(ostream& out,
                                                 t_struct* tstruct,
                                                 string prefix,
                                                 bool pointer) {
@@ -4019,7 +4020,7 @@
   }
 }
 
-void t_cpp_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_cpp_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -4065,7 +4066,7 @@
  * Serializes the members of a map.
  *
  */
-void t_cpp_generator::generate_serialize_map_element(ofstream& out, t_map* tmap, string iter) {
+void t_cpp_generator::generate_serialize_map_element(ostream& out, t_map* tmap, string iter) {
   t_field kfield(tmap->get_key_type(), iter + "->first");
   generate_serialize_field(out, &kfield, "");
 
@@ -4076,7 +4077,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_cpp_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_cpp_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), "(*" + iter + ")");
   generate_serialize_field(out, &efield, "");
 }
@@ -4084,7 +4085,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_cpp_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_cpp_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), "(*" + iter + ")");
   generate_serialize_field(out, &efield, "");
 }
diff --git a/compiler/cpp/src/thrift/generate/t_csharp_generator.cc b/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
index cc2567b..73ee030 100644
--- a/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
@@ -37,7 +37,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -100,46 +100,46 @@
   void generate_union(t_struct* tunion);
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
-  void generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset);
-  void generate_csharp_property(ofstream& out,
+  void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
+  void generate_csharp_property(ostream& out,
                                 t_field* tfield,
                                 bool isPublic,
                                 bool includeIsset = true,
                                 std::string fieldPrefix = "");
-  bool print_const_value(std::ofstream& out,
+  bool print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false,
                          bool needtype = false);
-  std::string render_const_value(std::ofstream& out,
+  std::string render_const_value(std::ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
-  void print_const_constructor(std::ofstream& out, std::vector<t_const*> consts);
-  void print_const_def_value(std::ofstream& out,
+  void print_const_constructor(std::ostream& out, std::vector<t_const*> consts);
+  void print_const_def_value(std::ostream& out,
                              std::string name,
                              t_type* type,
                              t_const_value* value);
 
   void generate_csharp_struct(t_struct* tstruct, bool is_exception);
   void generate_csharp_union(t_struct* tunion);
-  void generate_csharp_struct_definition(std::ofstream& out,
+  void generate_csharp_struct_definition(std::ostream& out,
                                          t_struct* tstruct,
                                          bool is_xception = false,
                                          bool in_class = false,
                                          bool is_result = false);
-  void generate_csharp_union_definition(std::ofstream& out, t_struct* tunion);
-  void generate_csharp_union_class(std::ofstream& out, t_struct* tunion, t_field* tfield);
-  void generate_csharp_wcffault(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_equals(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_hashcode(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_union_reader(std::ofstream& out, t_struct* tunion);
+  void generate_csharp_union_definition(std::ostream& out, t_struct* tunion);
+  void generate_csharp_union_class(std::ostream& out, t_struct* tunion, t_field* tfield);
+  void generate_csharp_wcffault(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_equals(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_hashcode(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_union_reader(std::ostream& out, t_struct* tunion);
 
   void generate_function_helpers(t_function* tfunction);
   void generate_service_interface(t_service* tservice);
@@ -156,36 +156,36 @@
   void generate_process_function(t_service* tservice, t_function* function);
   void generate_process_function_async(t_service* tservice, t_function* function);
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool is_propertyless = false);
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
-  void generate_deserialize_list_element(std::ofstream& out, t_list* list, std::string prefix = "");
-  void generate_serialize_field(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_list_element(std::ostream& out, t_list* list, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 bool is_element = false,
                                 bool is_propertyless = false);
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_csharp_doc(std::ofstream& out, t_field* field);
-  void generate_csharp_doc(std::ofstream& out, t_doc* tdoc);
-  void generate_csharp_doc(std::ofstream& out, t_function* tdoc);
-  void generate_csharp_docstring_comment(std::ofstream& out, string contents);
+  void generate_csharp_doc(std::ostream& out, t_field* field);
+  void generate_csharp_doc(std::ostream& out, t_doc* tdoc);
+  void generate_csharp_doc(std::ostream& out, t_function* tdoc);
+  void generate_csharp_docstring_comment(std::ostream& out, string contents);
 
-  void start_csharp_namespace(std::ofstream& out);
-  void end_csharp_namespace(std::ofstream& out);
+  void start_csharp_namespace(std::ostream& out);
+  void end_csharp_namespace(std::ostream& out);
 
   std::string csharp_type_usings();
   std::string csharp_thrift_usings();
@@ -224,7 +224,7 @@
 
 private:
   std::string namespace_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string namespace_dir_;
   bool async_;
   bool nullable_;
@@ -403,14 +403,14 @@
   csharp_keywords["yield"] = 1;
 }
 
-void t_csharp_generator::start_csharp_namespace(ofstream& out) {
+void t_csharp_generator::start_csharp_namespace(ostream& out) {
   if (!namespace_name_.empty()) {
     out << "namespace " << namespace_name_ << "\n";
     scope_up(out);
   }
 }
 
-void t_csharp_generator::end_csharp_namespace(ofstream& out) {
+void t_csharp_generator::end_csharp_namespace(ostream& out) {
   if (!namespace_name_.empty()) {
     scope_down(out);
   }
@@ -438,7 +438,7 @@
 
 void t_csharp_generator::generate_enum(t_enum* tenum) {
   string f_enum_name = namespace_dir_ + "/" + (tenum->get_name()) + ".cs";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   f_enum << autogen_comment() << endl;
@@ -471,7 +471,7 @@
     return;
   }
   string f_consts_name = namespace_dir_ + '/' + program_name_ + ".Constants.cs";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   f_consts << autogen_comment() << csharp_type_usings() << endl;
@@ -504,7 +504,7 @@
   f_consts.close();
 }
 
-void t_csharp_generator::print_const_def_value(std::ofstream& out,
+void t_csharp_generator::print_const_def_value(std::ostream& out,
                                                string name,
                                                t_type* type,
                                                t_const_value* value) {
@@ -557,7 +557,7 @@
   }
 }
 
-void t_csharp_generator::print_const_constructor(std::ofstream& out, std::vector<t_const*> consts) {
+void t_csharp_generator::print_const_constructor(std::ostream& out, std::vector<t_const*> consts) {
   indent(out) << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()"
               << endl;
   scope_up(out);
@@ -574,7 +574,7 @@
 
 // it seems like all that methods that call this are using in_static to be the opposite of what it
 // would imply
-bool t_csharp_generator::print_const_value(std::ofstream& out,
+bool t_csharp_generator::print_const_value(std::ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value,
@@ -614,7 +614,7 @@
   return need_static_construction;
 }
 
-std::string t_csharp_generator::render_const_value(ofstream& out,
+std::string t_csharp_generator::render_const_value(ostream& out,
                                                    string name,
                                                    t_type* type,
                                                    t_const_value* value) {
@@ -671,7 +671,7 @@
 
 void t_csharp_generator::generate_csharp_struct(t_struct* tstruct, bool is_exception) {
   string f_struct_name = namespace_dir_ + "/" + (tstruct->get_name()) + ".cs";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
 
   f_struct.open(f_struct_name.c_str());
 
@@ -682,7 +682,7 @@
   f_struct.close();
 }
 
-void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
+void t_csharp_generator::generate_csharp_struct_definition(ostream& out,
                                                            t_struct* tstruct,
                                                            bool is_exception,
                                                            bool in_class,
@@ -885,7 +885,7 @@
   }
 }
 
-void t_csharp_generator::generate_csharp_wcffault(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_wcffault(ostream& out, t_struct* tstruct) {
   out << endl;
   indent(out) << "#if !SILVERLIGHT" << endl;
   indent(out) << "[Serializable]" << endl;
@@ -915,7 +915,7 @@
   out << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "public void Read (TProtocol iprot)" << endl;
   scope_up(out);
 
@@ -1005,7 +1005,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public void Write(TProtocol oprot) {" << endl;
   indent_up();
 
@@ -1084,7 +1084,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_result_writer(ostream& out, t_struct* tstruct) {
   indent(out) << "public void Write(TProtocol oprot) {" << endl;
   indent_up();
 
@@ -1156,7 +1156,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_tostring(ostream& out, t_struct* tstruct) {
   indent(out) << "public override string ToString() {" << endl;
   indent_up();
 
@@ -1230,7 +1230,7 @@
 
 void t_csharp_generator::generate_csharp_union(t_struct* tunion) {
   string f_union_name = namespace_dir_ + "/" + (tunion->get_name()) + ".cs";
-  ofstream f_union;
+  ofstream_with_content_based_conditional_update f_union;
 
   f_union.open(f_union_name.c_str());
 
@@ -1241,7 +1241,7 @@
   f_union.close();
 }
 
-void t_csharp_generator::generate_csharp_union_definition(std::ofstream& out, t_struct* tunion) {
+void t_csharp_generator::generate_csharp_union_definition(std::ostream& out, t_struct* tunion) {
   // Let's define the class first
   start_csharp_namespace(out);
 
@@ -1292,7 +1292,7 @@
   end_csharp_namespace(out);
 }
 
-void t_csharp_generator::generate_csharp_union_class(std::ofstream& out,
+void t_csharp_generator::generate_csharp_union_class(std::ostream& out,
                                                      t_struct* tunion,
                                                      t_field* tfield) {
   indent(out) << "public class " << tfield->get_name() << " : " << tunion->get_name() << " {"
@@ -1341,7 +1341,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_equals(ostream& out, t_struct* tstruct) {
   indent(out) << "public override bool Equals(object that) {" << endl;
   indent_up();
 
@@ -1390,7 +1390,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_hashcode(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_hashcode(ostream& out, t_struct* tstruct) {
   indent(out) << "public override int GetHashCode() {" << endl;
   indent_up();
 
@@ -2378,7 +2378,7 @@
   f_service_ << endl;
 }
 
-void t_csharp_generator::generate_csharp_union_reader(std::ofstream& out, t_struct* tunion) {
+void t_csharp_generator::generate_csharp_union_reader(std::ostream& out, t_struct* tunion) {
   // Thanks to THRIFT-1768, we don't need to check for required fields in the union
   const vector<t_field*>& fields = tunion->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -2452,7 +2452,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_deserialize_field(ofstream& out,
+void t_csharp_generator::generate_deserialize_field(ostream& out,
                                                     t_field* tfield,
                                                     string prefix,
                                                     bool is_propertyless) {
@@ -2525,7 +2525,7 @@
   }
 }
 
-void t_csharp_generator::generate_deserialize_struct(ofstream& out,
+void t_csharp_generator::generate_deserialize_struct(ostream& out,
                                                      t_struct* tstruct,
                                                      string prefix) {
   if (union_ && tstruct->is_union()) {
@@ -2536,7 +2536,7 @@
   }
 }
 
-void t_csharp_generator::generate_deserialize_container(ofstream& out,
+void t_csharp_generator::generate_deserialize_container(ostream& out,
                                                         t_type* ttype,
                                                         string prefix) {
   scope_up(out);
@@ -2587,7 +2587,7 @@
   scope_down(out);
 }
 
-void t_csharp_generator::generate_deserialize_map_element(ofstream& out,
+void t_csharp_generator::generate_deserialize_map_element(ostream& out,
                                                           t_map* tmap,
                                                           string prefix) {
   string key = tmp("_key");
@@ -2605,7 +2605,7 @@
   indent(out) << prefix << "[" << key << "] = " << val << ";" << endl;
 }
 
-void t_csharp_generator::generate_deserialize_set_element(ofstream& out,
+void t_csharp_generator::generate_deserialize_set_element(ostream& out,
                                                           t_set* tset,
                                                           string prefix) {
   string elem = tmp("_elem");
@@ -2618,7 +2618,7 @@
   indent(out) << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_csharp_generator::generate_deserialize_list_element(ofstream& out,
+void t_csharp_generator::generate_deserialize_list_element(ostream& out,
                                                            t_list* tlist,
                                                            string prefix) {
   string elem = tmp("_elem");
@@ -2631,7 +2631,7 @@
   indent(out) << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_csharp_generator::generate_serialize_field(ofstream& out,
+void t_csharp_generator::generate_serialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool is_element,
@@ -2704,14 +2704,14 @@
   }
 }
 
-void t_csharp_generator::generate_serialize_struct(ofstream& out,
+void t_csharp_generator::generate_serialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".Write(oprot);" << endl;
 }
 
-void t_csharp_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_csharp_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2763,7 +2763,7 @@
   scope_down(out);
 }
 
-void t_csharp_generator::generate_serialize_map_element(ofstream& out,
+void t_csharp_generator::generate_serialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string iter,
                                                         string map) {
@@ -2773,25 +2773,25 @@
   generate_serialize_field(out, &vfield, "", true);
 }
 
-void t_csharp_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_csharp_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "", true);
 }
 
-void t_csharp_generator::generate_serialize_list_element(ofstream& out,
+void t_csharp_generator::generate_serialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "", true);
 }
 
-void t_csharp_generator::generate_property(ofstream& out,
+void t_csharp_generator::generate_property(ostream& out,
                                            t_field* tfield,
                                            bool isPublic,
                                            bool generateIsset) {
   generate_csharp_property(out, tfield, isPublic, generateIsset, "_");
 }
-void t_csharp_generator::generate_csharp_property(ofstream& out,
+void t_csharp_generator::generate_csharp_property(ostream& out,
                                                   t_field* tfield,
                                                   bool isPublic,
                                                   bool generateIsset,
@@ -3040,7 +3040,7 @@
       ttype = ((t_typedef*)ttype)->get_type();
     }
     if (ttype->is_base_type() && field_has_default(tfield)) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -3158,11 +3158,11 @@
   throw "INVALID TYPE IN type_to_enum: " + type->get_name();
 }
 
-void t_csharp_generator::generate_csharp_docstring_comment(ofstream& out, string contents) {
+void t_csharp_generator::generate_csharp_docstring_comment(ostream& out, string contents) {
   generate_docstring_comment(out, "/// <summary>\n", "/// ", contents, "/// </summary>\n");
 }
 
-void t_csharp_generator::generate_csharp_doc(ofstream& out, t_field* field) {
+void t_csharp_generator::generate_csharp_doc(ostream& out, t_field* field) {
   if (field->get_type()->is_enum()) {
     string combined_message = field->get_doc() + "\n<seealso cref=\""
                               + get_enum_class_name(field->get_type()) + "\"/>";
@@ -3172,13 +3172,13 @@
   }
 }
 
-void t_csharp_generator::generate_csharp_doc(ofstream& out, t_doc* tdoc) {
+void t_csharp_generator::generate_csharp_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_csharp_docstring_comment(out, tdoc->get_doc());
   }
 }
 
-void t_csharp_generator::generate_csharp_doc(ofstream& out, t_function* tfunction) {
+void t_csharp_generator::generate_csharp_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ps;
     const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc
index bbef639..df56cfc 100644
--- a/compiler/cpp/src/thrift/generate/t_d_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc
@@ -118,7 +118,7 @@
   virtual void generate_consts(std::vector<t_const*> consts) {
     if (!consts.empty()) {
       string f_consts_name = package_dir_ + program_name_ + "_constants.d";
-      ofstream f_consts;
+      ofstream_with_content_based_conditional_update f_consts;
       f_consts.open(f_consts_name.c_str());
 
       f_consts << autogen_comment() << "module " << render_package(*program_) << program_name_
@@ -201,7 +201,7 @@
 
     // Service implementation file includes
     string f_servicename = package_dir_ + svc_name + ".d";
-    std::ofstream f_service;
+    ofstream_with_content_based_conditional_update f_service;
     f_service.open(f_servicename.c_str());
     f_service << autogen_comment() << "module " << render_package(*program_) << svc_name << ";"
               << endl << endl;
@@ -339,13 +339,13 @@
 
     // Server skeleton generation.
     string f_skeletonname = package_dir_ + svc_name + "_server.skeleton.d";
-    std::ofstream f_skeleton;
+    ofstream_with_content_based_conditional_update f_skeleton;
     f_skeleton.open(f_skeletonname.c_str());
     print_server_skeleton(f_skeleton, tservice);
     f_skeleton.close();
   }
 
-  void emit_doc(t_doc *doc, std::ofstream& out) {
+  void emit_doc(t_doc *doc, std::ostream& out) {
     if (!doc->has_doc()) {
       return;
     }
@@ -733,8 +733,8 @@
    * File streams, stored here to avoid passing them as parameters to every
    * function.
    */
-  ofstream f_types_;
-  ofstream f_header_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_header_;
 
   string package_dir_;
 };
diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
index c2d07e9..d190e16 100644
--- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -141,13 +141,13 @@
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(ofstream& out,
+  std::string render_const_value(ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -158,21 +158,21 @@
 
   void generate_dart_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_dart_struct_definition(std::ofstream& out,
+  void generate_dart_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool is_result = false,
                                        string export_file_name = "");
-  void generate_dart_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_struct_tostring(std::ofstream& out, t_struct* tstruct);
+  void generate_dart_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_dart_validator(std::ostream& out, t_struct* tstruct);
+  void generate_dart_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_dart_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_dart_struct_tostring(std::ostream& out, t_struct* tstruct);
   std::string get_dart_type_string(t_type* type);
-  void generate_generic_field_getters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_field_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_field_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_dart_bean_boilerplate(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string init_value(t_field* tfield);
@@ -184,7 +184,7 @@
   std::string get_constants_class_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
 
   void generate_service_interface(t_service* tservice);
   void generate_service_helpers(t_service* tservice);
@@ -196,38 +196,38 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_dart_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_dart_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_dart_doc(std::ofstream& out, t_function* tdoc);
+  void generate_dart_doc(std::ostream& out, t_function* tdoc);
 
   /**
    * Helper rendering functions
@@ -265,7 +265,7 @@
   std::string constant_name(std::string name);
 
 private:
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   std::string library_name_;
   std::string library_prefix_;
@@ -391,7 +391,7 @@
     f_library_name = get_out_dir() + "/" + library_name_ + ".dart";
   }
 
-  ofstream f_library;
+  ofstream_with_content_based_conditional_update f_library;
   f_library.open(f_library_name.c_str());
 
   f_library << autogen_comment() << endl;
@@ -413,7 +413,7 @@
 
 void t_dart_generator::generate_dart_pubspec() {
   string f_pubspec_name = base_dir_ + "/pubspec.yaml";
-  ofstream f_pubspec;
+  ofstream_with_content_based_conditional_update f_pubspec;
   f_pubspec.open(f_pubspec_name.c_str());
 
   indent(f_pubspec) << "name: " << library_name_ << endl;
@@ -478,7 +478,7 @@
   string file_name = get_file_name(tenum->get_name());
 
   string f_enum_name = src_dir_ + "/" + file_name + ".dart";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and add library
@@ -540,7 +540,7 @@
   string file_name = get_file_name(class_name);
 
   string f_consts_name = src_dir_ + "/" + file_name + ".dart";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -566,7 +566,7 @@
   f_consts.close();
 }
 
-void t_dart_generator::print_const_value(std::ofstream& out,
+void t_dart_generator::print_const_value(std::ostream& out,
                                         string name,
                                         t_type* type,
                                         t_const_value* value,
@@ -668,7 +668,7 @@
   }
 }
 
-string t_dart_generator::render_const_value(ofstream& out,
+string t_dart_generator::render_const_value(ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value) {
@@ -740,7 +740,7 @@
 void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception) {
   string file_name = get_file_name(tstruct->get_name());
   string f_struct_name = src_dir_ + "/" + file_name + ".dart";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << dart_library(file_name) << endl;
@@ -764,7 +764,7 @@
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_dart_generator::generate_dart_struct_definition(ofstream& out,
+void t_dart_generator::generate_dart_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
                                                        bool is_result,
@@ -861,7 +861,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "read(TProtocol iprot)";
   scope_up(out);
 
@@ -949,7 +949,7 @@
 
 // generates dart method to perform various checks
 // (e.g. check that all required fields are set)
-void t_dart_generator::generate_dart_validator(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "validate()";
   scope_up(out);
 
@@ -1000,7 +1000,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "write(TProtocol oprot)";
   scope_up(out);
 
@@ -1056,7 +1056,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct* tstruct) {
   indent(out) << "write(TProtocol oprot)";
   scope_up(out);
 
@@ -1097,7 +1097,7 @@
   scope_down(out, endl2);
 }
 
-void t_dart_generator::generate_generic_field_getters(std::ofstream& out,
+void t_dart_generator::generate_generic_field_getters(std::ostream& out,
                                                       t_struct* tstruct) {
   // create the getter
   indent(out) << "getFieldValue(int fieldID)";
@@ -1127,7 +1127,7 @@
   scope_down(out, endl2);  // method
 }
 
-void t_dart_generator::generate_generic_field_setters(std::ofstream& out,
+void t_dart_generator::generate_generic_field_setters(std::ostream& out,
                                                       t_struct* tstruct) {
 
   // create the setter
@@ -1172,7 +1172,7 @@
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_dart_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1208,7 +1208,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_bean_boilerplate(ofstream& out,
+void t_dart_generator::generate_dart_bean_boilerplate(ostream& out,
                                                     t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1257,7 +1257,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_tostring(ofstream& out,
+void t_dart_generator::generate_dart_struct_tostring(ostream& out,
                                                    t_struct* tstruct) {
   indent(out) << "String toString()";
   scope_up(out);
@@ -1784,7 +1784,7 @@
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_dart_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
   string field_name = get_member_name(tfield->get_name());
 
@@ -1850,7 +1850,7 @@
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_dart_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_dart_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl;
   indent(out) << prefix << ".read(iprot);" << endl;
 }
@@ -1858,7 +1858,7 @@
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_dart_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   indent(out);
   scope_up(out, "");
 
@@ -1915,7 +1915,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_dart_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_dart_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -1933,7 +1933,7 @@
 /**
  * Deserializes a set element
  */
-void t_dart_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_dart_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -1947,7 +1947,7 @@
 /**
  * Deserializes a list element
  */
-void t_dart_generator::generate_deserialize_list_element(ofstream& out,
+void t_dart_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   string elem = tmp("_elem");
@@ -1966,7 +1966,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_dart_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
   string field_name = get_member_name(tfield->get_name());
 
@@ -2036,7 +2036,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_dart_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_dart_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ".write(oprot);" << endl;
 }
@@ -2047,7 +2047,7 @@
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_dart_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   indent(out);
   scope_up(out, "");
 
@@ -2098,7 +2098,7 @@
 /**
  * Serializes the members of a map.
  */
-void t_dart_generator::generate_serialize_map_element(ofstream& out,
+void t_dart_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string iter,
                                                      string map) {
@@ -2111,7 +2111,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_dart_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_dart_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2119,7 +2119,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_dart_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_dart_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2194,7 +2194,7 @@
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std:: ofstream dummy;
       result += " = " + render_const_value(dummy, field_name, ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2452,7 +2452,7 @@
 /**
  * Emits a doc comment if the provided object has a doc in Thrift
  */
-void t_dart_generator::generate_dart_doc(ofstream& out, t_doc* tdoc) {
+void t_dart_generator::generate_dart_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "", "/// ", tdoc->get_doc(), "");
   }
@@ -2461,7 +2461,7 @@
 /**
  * Emits a doc comment if the provided function object has a doc in Thrift
  */
-void t_dart_generator::generate_dart_doc(ofstream& out, t_function* tfunction) {
+void t_dart_generator::generate_dart_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -2488,7 +2488,7 @@
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_dart_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_dart_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     string field_name = get_member_name(field->get_name());
     indent(out) << "this.__isset_" << field_name << " = true;" << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index c7f2f41..db06827 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -786,7 +786,7 @@
   unitname = normalize_name(unitname);
   
   std::string f_name = get_out_dir() + "/" + unitname + ".pas";
-  std::ofstream f_all;
+  ofstream_with_content_based_conditional_update f_all;
 
   f_all.open(f_name.c_str());
 
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index 768db13..587133f 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -220,15 +220,15 @@
   std::ostringstream f_info_;
   std::ostringstream f_info_ext_;
 
-  std::ofstream f_types_file_;
-  std::ofstream f_types_hrl_file_;
+  ofstream_with_content_based_conditional_update f_types_file_;
+  ofstream_with_content_based_conditional_update f_types_hrl_file_;
 
-  std::ofstream f_consts_file_;
-  std::ofstream f_consts_hrl_file_;
+  ofstream_with_content_based_conditional_update f_consts_file_;
+  ofstream_with_content_based_conditional_update f_consts_hrl_file_;
 
   std::ostringstream f_service_;
-  std::ofstream f_service_file_;
-  std::ofstream f_service_hrl_;
+  ofstream_with_content_based_conditional_update f_service_file_;
+  ofstream_with_content_based_conditional_update f_service_hrl_;
 
   /**
    * Metadata containers
diff --git a/compiler/cpp/src/thrift/generate/t_generator.h b/compiler/cpp/src/thrift/generate/t_generator.h
index cbbfcb9..abe31fe 100644
--- a/compiler/cpp/src/thrift/generate/t_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_generator.h
@@ -21,6 +21,7 @@
 #define T_GENERATOR_H
 #define MSC_2015_VER 1900
 
+#include <cstring>
 #include <string>
 #include <iomanip>
 #include <iostream>
@@ -28,6 +29,7 @@
 #include <limits>
 #include <sstream>
 #include "thrift/common.h"
+#include "thrift/logging.h"
 #include "thrift/version.h"
 #include "thrift/generate/t_generator_registry.h"
 #include "thrift/parse/t_program.h"
@@ -186,7 +188,6 @@
     }
   }
 
-
   /**
    * Indentation print function
    */
@@ -227,6 +228,7 @@
     }
     return in;
   }
+
   /**
    * Transforms a camel case string to an equivalent one separated by underscores
    * e.g. aMultiWord -> a_multi_word
@@ -245,6 +247,7 @@
     }
     return in;
   }
+
   /**
     * Transforms a string with words separated by underscores to a camel case equivalent
     * e.g. a_multi_word -> aMultiWord
@@ -346,4 +349,77 @@
   int tmp_;
 };
 
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+class template_ofstream_with_content_based_conditional_update : public std::ostringstream {
+public:
+  template_ofstream_with_content_based_conditional_update(): contents_written(false) {}
+
+  template_ofstream_with_content_based_conditional_update(std::string const& output_file_path_)
+  : output_file_path(output_file_path_), contents_written(false) {}
+
+  ~template_ofstream_with_content_based_conditional_update() {
+    if (!contents_written) {
+      close();
+    }
+  }
+
+  void open(std::string const& output_file_path_) {
+    output_file_path = output_file_path_;
+    clear_buf();
+    contents_written = false;
+  }
+
+  void close() {
+    if (contents_written || output_file_path == "")
+      return;
+
+    if (!is_readable(output_file_path)) {
+      dump();
+      return;
+    }
+
+    std::ifstream old_file;
+    old_file.exceptions(old_file.exceptions() | std::ifstream::badbit | std::ifstream::failbit);
+    old_file.open(output_file_path.c_str(), std::ios::in);
+
+    if (old_file) {
+      std::string const old_file_contents(static_cast<std::ostringstream const&>(std::ostringstream() << old_file.rdbuf()).str());
+      old_file.close();
+
+      if (old_file_contents != str()) {
+        dump();
+      }
+    }
+  }
+
+protected:
+  void dump() {
+    std::ofstream out_file;
+    out_file.exceptions(out_file.exceptions() | std::ofstream::badbit | std::ofstream::failbit);
+    try {
+      out_file.open(output_file_path.c_str(), std::ios::out);
+    }
+    catch (const std::ios_base::failure& e) {
+      ::failure("failed to write the output to the file '%s', details: '%s'", output_file_path.c_str(), e.what());
+    }
+    out_file << str();
+    out_file.close();
+    clear_buf();
+    contents_written = true;
+  }
+
+  void clear_buf() {
+    str(std::string());
+  }
+
+  static bool is_readable(std::string const& file_name) {
+    return static_cast<bool>(std::ifstream(file_name.c_str()));
+  }
+
+private:
+  std::string output_file_path;
+  bool contents_written;
+};
+typedef template_ofstream_with_content_based_conditional_update<char> ofstream_with_content_based_conditional_update;
+
 #endif
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc
index c1be332..5b65d2c 100644
--- a/compiler/cpp/src/thrift/generate/t_go_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc
@@ -42,7 +42,7 @@
 #include "thrift/generate/t_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -126,27 +126,27 @@
    */
 
   void generate_go_struct(t_struct* tstruct, bool is_exception);
-  void generate_go_struct_definition(std::ofstream& out,
+  void generate_go_struct_definition(std::ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false,
                                      bool is_result = false,
                                      bool is_args = false);
-  void generate_go_struct_initializer(std::ofstream& out,
+  void generate_go_struct_initializer(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_args_or_result = false);
-  void generate_isset_helpers(std::ofstream& out,
+  void generate_isset_helpers(std::ostream& out,
                               t_struct* tstruct,
                               const string& tstruct_name,
                               bool is_result = false);
-  void generate_countsetfields_helper(std::ofstream& out,
+  void generate_countsetfields_helper(std::ostream& out,
                                       t_struct* tstruct,
                                       const string& tstruct_name,
                                       bool is_result = false);
-  void generate_go_struct_reader(std::ofstream& out,
+  void generate_go_struct_reader(std::ostream& out,
                                  t_struct* tstruct,
                                  const string& tstruct_name,
                                  bool is_result = false);
-  void generate_go_struct_writer(std::ofstream& out,
+  void generate_go_struct_writer(std::ostream& out,
                                  t_struct* tstruct,
                                  const string& tstruct_name,
                                  bool is_result = false,
@@ -171,7 +171,7 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   bool declare,
                                   std::string prefix = "",
@@ -180,64 +180,64 @@
                                   bool inkey = false,
                                   bool in_container = false);
 
-  void generate_deserialize_struct(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out,
                                    t_struct* tstruct,
                                    bool is_pointer_field,
                                    bool declare,
                                    std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out,
+  void generate_deserialize_container(std::ostream& out,
                                       t_type* ttype,
                                       bool pointer_field,
                                       bool declare,
                                       std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out,
+  void generate_deserialize_set_element(std::ostream& out,
                                         t_set* tset,
                                         bool declare,
                                         std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out,
+  void generate_deserialize_map_element(std::ostream& out,
                                         t_map* tmap,
                                         bool declare,
                                         std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          bool declare,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 bool inkey = false);
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out,
+  void generate_serialize_container(std::ostream& out,
                                     t_type* ttype,
                                     bool pointer_field,
                                     std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_go_docstring(std::ofstream& out, t_struct* tstruct);
+  void generate_go_docstring(std::ostream& out, t_struct* tstruct);
 
-  void generate_go_docstring(std::ofstream& out, t_function* tfunction);
+  void generate_go_docstring(std::ostream& out, t_function* tfunction);
 
-  void generate_go_docstring(std::ofstream& out,
+  void generate_go_docstring(std::ostream& out,
                              t_doc* tdoc,
                              t_struct* tstruct,
                              const char* subheader);
 
-  void generate_go_docstring(std::ofstream& out, t_doc* tdoc);
+  void generate_go_docstring(std::ostream& out, t_doc* tdoc);
 
   /**
    * Helper rendering functions
@@ -290,9 +290,9 @@
    * File streams
    */
 
-  std::ofstream f_types_;
+  ofstream_with_content_based_conditional_update f_types_;
   std::string f_types_name_;
-  std::ofstream f_consts_;
+  ofstream_with_content_based_conditional_update f_consts_;
   std::string f_consts_name_;
   std::stringstream f_const_values_;
 
@@ -757,7 +757,7 @@
 
   // Create file for the GoUnusedProtection__ variable
   string f_unused_prot_name_ = package_dir_ + "/" + "GoUnusedProtection__.go";
-  ofstream f_unused_prot_;
+  ofstream_with_content_based_conditional_update f_unused_prot_;
   f_unused_prot_.open(f_unused_prot_name_.c_str());
   f_unused_prot_ << go_autogen_comment() << go_package() << render_import_protection();
   f_unused_prot_.close();
@@ -1250,7 +1250,7 @@
   *OUT_def_value = tfield->get_value();
 }
 
-void t_go_generator::generate_go_struct_initializer(ofstream& out,
+void t_go_generator::generate_go_struct_initializer(ostream& out,
                                                     t_struct* tstruct,
                                                     bool is_args_or_result) {
   out << publicize(type_name(tstruct), is_args_or_result) << "{";
@@ -1276,7 +1276,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_go_generator::generate_go_struct_definition(ofstream& out,
+void t_go_generator::generate_go_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception,
                                                    bool is_result,
@@ -1433,7 +1433,7 @@
 /**
  * Generates the IsSet helper methods for a struct
  */
-void t_go_generator::generate_isset_helpers(ofstream& out,
+void t_go_generator::generate_isset_helpers(ostream& out,
                                             t_struct* tstruct,
                                             const string& tstruct_name,
                                             bool is_result) {
@@ -1472,7 +1472,7 @@
 /**
  * Generates the CountSetFields helper method for a struct
  */
-void t_go_generator::generate_countsetfields_helper(ofstream& out,
+void t_go_generator::generate_countsetfields_helper(ostream& out,
                                                     t_struct* tstruct,
                                                     const string& tstruct_name,
                                                     bool is_result) {
@@ -1511,7 +1511,7 @@
 /**
  * Generates the read method for a struct
  */
-void t_go_generator::generate_go_struct_reader(ofstream& out,
+void t_go_generator::generate_go_struct_reader(ostream& out,
                                                t_struct* tstruct,
                                                const string& tstruct_name,
                                                bool is_result) {
@@ -1664,7 +1664,7 @@
   }
 }
 
-void t_go_generator::generate_go_struct_writer(ofstream& out,
+void t_go_generator::generate_go_struct_writer(ostream& out,
                                                t_struct* tstruct,
                                                const string& tstruct_name,
                                                bool is_result,
@@ -2097,7 +2097,7 @@
   vector<t_function*>::iterator f_iter;
   string f_remote_name = f_remote_dir + "/"
                          + underscore(service_name_) + "-remote.go";
-  ofstream f_remote;
+  ofstream_with_content_based_conditional_update f_remote;
   f_remote.open(f_remote_name.c_str());
   string service_module = get_real_go_module(program_);
   string::size_type loc;
@@ -2826,7 +2826,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_go_generator::generate_deserialize_field(ofstream& out,
+void t_go_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 bool declare,
                                                 string prefix,
@@ -2942,7 +2942,7 @@
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_go_generator::generate_deserialize_struct(ofstream& out,
+void t_go_generator::generate_deserialize_struct(ostream& out,
                                                  t_struct* tstruct,
                                                  bool pointer_field,
                                                  bool declare,
@@ -2961,7 +2961,7 @@
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_go_generator::generate_deserialize_container(ofstream& out,
+void t_go_generator::generate_deserialize_container(ostream& out,
                                                     t_type* orig_type,
                                                     bool pointer_field,
                                                     bool declare,
@@ -3037,7 +3037,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_go_generator::generate_deserialize_map_element(ofstream& out,
+void t_go_generator::generate_deserialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       bool declare,
                                                       string prefix) {
@@ -3056,7 +3056,7 @@
 /**
  * Write a set element
  */
-void t_go_generator::generate_deserialize_set_element(ofstream& out,
+void t_go_generator::generate_deserialize_set_element(ostream& out,
                                                       t_set* tset,
                                                       bool declare,
                                                       string prefix) {
@@ -3071,7 +3071,7 @@
 /**
  * Write a list element
  */
-void t_go_generator::generate_deserialize_list_element(ofstream& out,
+void t_go_generator::generate_deserialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        bool declare,
                                                        string prefix) {
@@ -3089,7 +3089,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_go_generator::generate_serialize_field(ofstream& out,
+void t_go_generator::generate_serialize_field(ostream& out,
                                               t_field* tfield,
                                               string prefix,
                                               bool inkey) {
@@ -3176,7 +3176,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_go_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_go_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << "if err := " << prefix << "." << write_method_name_ << "(oprot); err != nil {" << endl;
   out << indent() << "  return thrift.PrependError(fmt.Sprintf(\"%T error writing struct: \", "
@@ -3184,7 +3184,7 @@
   out << indent() << "}" << endl;
 }
 
-void t_go_generator::generate_serialize_container(ofstream& out,
+void t_go_generator::generate_serialize_container(ostream& out,
                                                   t_type* ttype,
                                                   bool pointer_field,
                                                   string prefix) {
@@ -3265,7 +3265,7 @@
  * Serializes the members of a map.
  *
  */
-void t_go_generator::generate_serialize_map_element(ofstream& out,
+void t_go_generator::generate_serialize_map_element(ostream& out,
                                                     t_map* tmap,
                                                     string kiter,
                                                     string viter) {
@@ -3280,7 +3280,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_go_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_go_generator::generate_serialize_set_element(ostream& out, t_set* tset, string prefix) {
   t_field efield(tset->get_elem_type(), "");
   efield.set_req(t_field::T_OPT_IN_REQ_OUT);
   generate_serialize_field(out, &efield, prefix);
@@ -3289,7 +3289,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_go_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string prefix) {
+void t_go_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string prefix) {
   t_field efield(tlist->get_elem_type(), "");
   efield.set_req(t_field::T_OPT_IN_REQ_OUT);
   generate_serialize_field(out, &efield, prefix);
@@ -3298,21 +3298,21 @@
 /**
  * Generates the docstring for a given struct.
  */
-void t_go_generator::generate_go_docstring(ofstream& out, t_struct* tstruct) {
+void t_go_generator::generate_go_docstring(ostream& out, t_struct* tstruct) {
   generate_go_docstring(out, tstruct, tstruct, "Attributes");
 }
 
 /**
  * Generates the docstring for a given function.
  */
-void t_go_generator::generate_go_docstring(ofstream& out, t_function* tfunction) {
+void t_go_generator::generate_go_docstring(ostream& out, t_function* tfunction) {
   generate_go_docstring(out, tfunction, tfunction->get_arglist(), "Parameters");
 }
 
 /**
  * Generates the docstring for a struct or function.
  */
-void t_go_generator::generate_go_docstring(ofstream& out,
+void t_go_generator::generate_go_docstring(ostream& out,
                                            t_doc* tdoc,
                                            t_struct* tstruct,
                                            const char* subheader) {
@@ -3355,7 +3355,7 @@
 /**
  * Generates the docstring for a generic object.
  */
-void t_go_generator::generate_go_docstring(ofstream& out, t_doc* tdoc) {
+void t_go_generator::generate_go_docstring(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "", "//", tdoc->get_doc(), "");
   }
diff --git a/compiler/cpp/src/thrift/generate/t_gv_generator.cc b/compiler/cpp/src/thrift/generate/t_gv_generator.cc
index c2f8b5a..7f8301a 100644
--- a/compiler/cpp/src/thrift/generate/t_gv_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_gv_generator.cc
@@ -87,7 +87,7 @@
   void print_const_value(t_type* type, t_const_value* tvalue);
 
 private:
-  std::ofstream f_out_;
+  ofstream_with_content_based_conditional_update f_out_;
   std::list<string> edges;
   bool exception_arrows;
 };
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index ce3816d..3b88c4d 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -89,13 +89,13 @@
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(ofstream& out,
+  std::string render_const_value(ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -106,18 +106,18 @@
 
   void generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result = false);
 
-  void generate_haxe_struct_definition(std::ofstream& out,
+  void generate_haxe_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool is_result = false);
   // removed -- equality,compare_to
-  void generate_haxe_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_meta_data_map(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_haxe_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_validator(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_meta_data_map(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_haxe_type_string(t_type* type);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
@@ -127,15 +127,15 @@
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_property_getters_setters(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_property_getters_setters(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
   // removed std::string isset_field_id(t_field* field);
 
   void generate_service_interface(t_service* tservice);
@@ -149,30 +149,30 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_haxe_doc(std::ofstream& out, t_doc* tdoc);
-  void generate_haxe_doc(std::ofstream& out, t_function* tdoc);
+  void generate_haxe_doc(std::ostream& out, t_doc* tdoc);
+  void generate_haxe_doc(std::ostream& out, t_function* tdoc);
 
-  void generate_rtti_decoration(std::ofstream& out);
-  void generate_macro_decoration(std::ofstream& out);
+  void generate_rtti_decoration(std::ostream& out);
+  void generate_macro_decoration(std::ostream& out);
 
   /**
    * Helper rendering functions
@@ -229,7 +229,7 @@
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 };
 
@@ -386,7 +386,7 @@
 void t_haxe_generator::generate_enum(t_enum* tenum) {
   // Make output file
   string f_enum_name = package_dir_ + "/" + get_cap_name(tenum->get_name()) + ".hx";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
@@ -448,7 +448,7 @@
   }
 
   string f_consts_name = package_dir_ + "/" + get_cap_name(program_name_) + "Constants.hx";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -475,7 +475,7 @@
   f_consts.close();
 }
 
-void t_haxe_generator::print_const_value(std::ofstream& out,
+void t_haxe_generator::print_const_value(std::ostream& out,
                                          string name,
                                          t_type* type,
                                          t_const_value* value,
@@ -599,7 +599,7 @@
   }
 }
 
-string t_haxe_generator::render_const_value(ofstream& out,
+string t_haxe_generator::render_const_value(ostream& out,
                                             string name,
                                             t_type* type,
                                             t_const_value* value) {
@@ -676,7 +676,7 @@
 void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + get_cap_name(tstruct->get_name()) + ".hx";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << haxe_package() << ";" << endl;
@@ -703,7 +703,7 @@
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_haxe_generator::generate_haxe_struct_definition(ofstream& out,
+void t_haxe_generator::generate_haxe_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
                                                        bool is_result) {
@@ -817,7 +817,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public function read( iprot : TProtocol) : Void {" << endl;
   indent_up();
 
@@ -910,7 +910,7 @@
 
 // generates haxe method to perform various checks
 // (e.g. check that all required fields are set)
-void t_haxe_generator::generate_haxe_validator(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public function validate() : Void {" << endl;
   indent_up();
 
@@ -961,7 +961,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol) : Void {" << endl;
   indent_up();
 
@@ -1031,7 +1031,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol) : Void {" << endl;
   indent_up();
 
@@ -1116,7 +1116,7 @@
   indent_down();
 }
 
-void t_haxe_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_haxe_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                               t_struct* tstruct) {
 
   std::ostringstream getter_stream;
@@ -1174,7 +1174,7 @@
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_haxe_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1210,7 +1210,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_property_getters_setters(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_property_getters_setters(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@@ -1272,7 +1272,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct) {
   out << indent() << "public "
       << "function toString() : String {" << endl;
   indent_up();
@@ -1346,7 +1346,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_meta_data_map(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1434,7 +1434,7 @@
   }
 }
 
-void t_haxe_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_haxe_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -2176,7 +2176,7 @@
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_haxe_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
@@ -2241,7 +2241,7 @@
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_haxe_generator::generate_deserialize_struct(ofstream& out,
+void t_haxe_generator::generate_deserialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << endl
@@ -2251,7 +2251,7 @@
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_haxe_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string obj;
@@ -2309,7 +2309,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_haxe_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_haxe_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2327,7 +2327,7 @@
 /**
  * Deserializes a set element
  */
-void t_haxe_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_haxe_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2341,7 +2341,7 @@
 /**
  * Deserializes a list element
  */
-void t_haxe_generator::generate_deserialize_list_element(ofstream& out,
+void t_haxe_generator::generate_deserialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string prefix) {
   string elem = tmp("_elem");
@@ -2360,7 +2360,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_haxe_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2429,7 +2429,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_haxe_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_haxe_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".write(oprot);" << endl;
 }
@@ -2440,7 +2440,7 @@
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_haxe_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2498,7 +2498,7 @@
 /**
  * Serializes the members of a map.
  */
-void t_haxe_generator::generate_serialize_map_element(ofstream& out,
+void t_haxe_generator::generate_serialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       string iter,
                                                       string map) {
@@ -2511,7 +2511,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_haxe_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_haxe_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2519,7 +2519,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_haxe_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_haxe_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2661,7 +2661,7 @@
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2904,7 +2904,7 @@
 /**
  * Enables RTTI for a class or interface
  */
-void t_haxe_generator::generate_rtti_decoration(ofstream& out) {
+void t_haxe_generator::generate_rtti_decoration(ostream& out) {
   if (rtti_) {
     out << "@:rtti" << endl;
   }
@@ -2913,7 +2913,7 @@
 /**
  * Adds build macros to a class or interface
  */
-void t_haxe_generator::generate_macro_decoration(ofstream& out) {
+void t_haxe_generator::generate_macro_decoration(ostream& out) {
   if (!buildmacro_.empty()) {
     out << "#if ! macro" << endl;
     out << "@:build( " << buildmacro_ << ")" << endl;     // current class/interface
@@ -2925,7 +2925,7 @@
 /**
  * Emits a haxeDoc comment if the provided object has a doc in Thrift
  */
-void t_haxe_generator::generate_haxe_doc(ofstream& out, t_doc* tdoc) {
+void t_haxe_generator::generate_haxe_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
   }
@@ -2934,7 +2934,7 @@
 /**
  * Emits a haxeDoc comment if the provided function object has a doc in Thrift
  */
-void t_haxe_generator::generate_haxe_doc(ofstream& out, t_function* tfunction) {
+void t_haxe_generator::generate_haxe_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -2959,7 +2959,7 @@
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_haxe_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_haxe_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
   }
diff --git a/compiler/cpp/src/thrift/generate/t_hs_generator.cc b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
index 6c8cb7f..ce7cd0c 100644
--- a/compiler/cpp/src/thrift/generate/t_hs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
@@ -33,7 +33,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -87,22 +87,22 @@
 
   void generate_hs_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_hs_struct_definition(ofstream& out,
+  void generate_hs_struct_definition(ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false,
                                      bool helper = false);
 
-  void generate_hs_struct_reader(ofstream& out, t_struct* tstruct);
+  void generate_hs_struct_reader(ostream& out, t_struct* tstruct);
 
-  void generate_hs_struct_writer(ofstream& out, t_struct* tstruct);
+  void generate_hs_struct_writer(ostream& out, t_struct* tstruct);
 
-  void generate_hs_struct_arbitrary(ofstream& out, t_struct* tstruct);
+  void generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct);
 
   void generate_hs_function_helpers(t_function* tfunction);
 
-  void generate_hs_typemap(ofstream& out, t_struct* tstruct);
+  void generate_hs_typemap(ostream& out, t_struct* tstruct);
 
-  void generate_hs_default(ofstream& out, t_struct* tstruct);
+  void generate_hs_default(ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -118,29 +118,29 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(ofstream& out, t_field* tfield, string prefix);
+  void generate_deserialize_field(ostream& out, t_field* tfield, string prefix);
 
-  void generate_deserialize_struct(ofstream& out, t_struct* tstruct, string name = "");
+  void generate_deserialize_struct(ostream& out, t_struct* tstruct, string name = "");
 
-  void generate_deserialize_container(ofstream& out, t_type* ttype, string arg = "");
+  void generate_deserialize_container(ostream& out, t_type* ttype, string arg = "");
 
-  void generate_deserialize_set_element(ofstream& out, t_set* tset);
+  void generate_deserialize_set_element(ostream& out, t_set* tset);
 
-  void generate_deserialize_list_element(ofstream& out, t_list* tlist, string prefix = "");
+  void generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix = "");
 
-  void generate_deserialize_type(ofstream& out, t_type* type, string arg = "");
+  void generate_deserialize_type(ostream& out, t_type* type, string arg = "");
 
-  void generate_serialize_type(ofstream& out, t_type* type, string name = "");
+  void generate_serialize_type(ostream& out, t_type* type, string name = "");
 
-  void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
+  void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
 
-  void generate_serialize_container(ofstream& out, t_type* ttype, string prefix = "");
+  void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
 
-  void generate_serialize_map_element(ofstream& out, t_map* tmap, string kiter, string viter);
+  void generate_serialize_map_element(ostream& out, t_map* tmap, string kiter, string viter);
 
-  void generate_serialize_set_element(ofstream& out, t_set* tmap, string iter);
+  void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
 
-  void generate_serialize_list_element(ofstream& out, t_list* tlist, string iter);
+  void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
 
   /**
    * Helper rendering functions
@@ -170,11 +170,11 @@
   string render_hs_type_for_function_name(t_type* type);
 
 private:
-  ofstream f_types_;
-  ofstream f_consts_;
-  ofstream f_service_;
-  ofstream f_iface_;
-  ofstream f_client_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
+  ofstream_with_content_based_conditional_update f_iface_;
+  ofstream_with_content_based_conditional_update f_client_;
 };
 
 /**
@@ -530,7 +530,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_hs_generator::generate_hs_struct_definition(ofstream& out,
+void t_hs_generator::generate_hs_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception,
                                                    bool helper) {
@@ -586,7 +586,7 @@
   generate_hs_default(out, tstruct);
 }
 
-void t_hs_generator::generate_hs_struct_arbitrary(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct) {
   string tname = type_name(tstruct);
   string name = tstruct->get_name();
   const vector<t_field*>& members = tstruct->get_members();
@@ -652,7 +652,7 @@
 /**
  * Generates the read method for a struct
  */
-void t_hs_generator::generate_hs_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -722,7 +722,7 @@
   out << "T.deserializeVal iprot (T.T_STRUCT " << tmap << ") bs" << endl;
 }
 
-void t_hs_generator::generate_hs_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_struct_writer(ostream& out, t_struct* tstruct) {
   string name = type_name(tstruct);
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -906,7 +906,7 @@
  * Generate the map from field names to (type, id)
  * @param tstruct the Struct
  */
-void t_hs_generator::generate_hs_typemap(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_typemap(ostream& out, t_struct* tstruct) {
   string name = type_name(tstruct);
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -932,7 +932,7 @@
  * generate the struct with default values filled in
  * @param tstruct the Struct
  */
-void t_hs_generator::generate_hs_default(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_default(ostream& out, t_struct* tstruct) {
   string name = type_name(tstruct);
   string fname = type_name(tstruct, "default_");
   const vector<t_field*>& fields = tstruct->get_sorted_members();
@@ -1342,7 +1342,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_hs_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_hs_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   (void)prefix;
   t_type* type = tfield->get_type();
   generate_deserialize_type(out, type, prefix);
@@ -1351,7 +1351,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_hs_generator::generate_deserialize_type(ofstream& out, t_type* type, string arg) {
+void t_hs_generator::generate_deserialize_type(ostream& out, t_type* type, string arg) {
   type = get_true_type(type);
   string val = tmp("_val");
   out << "(case " << arg << " of {" << type_to_constructor(type) << " " << val << " -> ";
@@ -1388,7 +1388,7 @@
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_hs_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string name) {
+void t_hs_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string name) {
 
   out << "(" << type_name(tstruct, "to_") << " (T.TStruct " << name << "))";
 }
@@ -1397,7 +1397,7 @@
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_hs_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string arg) {
+void t_hs_generator::generate_deserialize_container(ostream& out, t_type* ttype, string arg) {
 
   string val = tmp("_v");
   // Declare variables, read header
@@ -1429,7 +1429,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_hs_generator::generate_serialize_type(ofstream& out, t_type* type, string name) {
+void t_hs_generator::generate_serialize_type(ostream& out, t_type* type, string name) {
 
   type = get_true_type(type);
   // Do nothing for void types
@@ -1467,11 +1467,11 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_hs_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_hs_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << type_name(tstruct, "from_") << " " << prefix;
 }
 
-void t_hs_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_hs_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   string k = tmp("_k");
   string v = tmp("_v");
 
diff --git a/compiler/cpp/src/thrift/generate/t_html_generator.cc b/compiler/cpp/src/thrift/generate/t_html_generator.cc
index 5b06370..8dfa389 100644
--- a/compiler/cpp/src/thrift/generate/t_html_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_html_generator.cc
@@ -90,7 +90,7 @@
   std::string escape_html(std::string const& str);
   std::string escape_html_tags(std::string const& str);
   void generate_css();
-  void generate_css_content(std::ofstream& f_target);
+  void generate_css_content(std::ostream& f_target);
   void generate_style_tag();
   std::string make_file_link(std::string name);
   bool is_utf8_sequence(std::string const& str, size_t firstpos);
@@ -114,7 +114,7 @@
   void print_fn_args_doc(t_function* tfunction);
 
 private:
-  std::ofstream f_out_;
+  ofstream_with_content_based_conditional_update f_out_;
   std::string current_file_;
   input_type input_type_;
   std::map<std::string, int> allowed_markup;
@@ -359,7 +359,7 @@
   }
 }
 
-void t_html_generator::generate_css_content(std::ofstream& f_target) {
+void t_html_generator::generate_css_content(std::ostream& f_target) {
   f_target << BOOTSTRAP_CSS() << endl;
   f_target << "/* Auto-generated CSS for generated Thrift docs */" << endl;
   f_target << "h3, h4 { margin-bottom: 6px; }" << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 34ba65f..4d81c98 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -36,7 +36,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::setfill;
 using std::setw;
@@ -138,13 +138,13 @@
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(std::ofstream& out, t_type* type, t_const_value* value);
+  std::string render_const_value(std::ostream& out, t_type* type, t_const_value* value);
 
   /**
    * Service-level generation functions
@@ -152,26 +152,26 @@
 
   void generate_java_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_java_struct_definition(std::ofstream& out,
+  void generate_java_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool in_class = false,
                                        bool is_result = false);
-  void generate_java_struct_parcelable(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_equality(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_compare_to(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_java_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_write_object(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_read_object(std::ofstream& out, t_struct* tstruct);
-  void generate_java_meta_data_map(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_java_struct_parcelable(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_equality(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_compare_to(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_java_validator(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_clear(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_write_object(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_read_object(std::ostream& out, t_struct* tstruct);
+  void generate_java_meta_data_map(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_java_type_string(t_type* type);
-  void generate_java_struct_field_by_id(ofstream& out, t_struct* tstruct);
+  void generate_java_struct_field_by_id(ostream& out, t_struct* tstruct);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
                                    std::string field_name,
@@ -180,9 +180,9 @@
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_java_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_java_bean_boilerplate(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string as_camel_case(std::string name, bool ucfirst = true);
@@ -190,7 +190,7 @@
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field, std::string prefix);
+  void generate_isset_set(ostream& out, t_field* field, std::string prefix);
   std::string isset_field_id(t_field* field);
 
   void generate_service_interface(t_service* tservice);
@@ -204,102 +204,102 @@
   void generate_process_async_function(t_service* tservice, t_function* tfunction);
 
   void generate_java_union(t_struct* tstruct);
-  void generate_union_constructor(ofstream& out, t_struct* tstruct);
-  void generate_union_getters_and_setters(ofstream& out, t_struct* tstruct);
-  void generate_union_is_set_methods(ofstream& out, t_struct* tstruct);
-  void generate_union_abstract_methods(ofstream& out, t_struct* tstruct);
-  void generate_check_type(ofstream& out, t_struct* tstruct);
-  void generate_standard_scheme_read_value(ofstream& out, t_struct* tstruct);
-  void generate_standard_scheme_write_value(ofstream& out, t_struct* tstruct);
-  void generate_tuple_scheme_read_value(ofstream& out, t_struct* tstruct);
-  void generate_tuple_scheme_write_value(ofstream& out, t_struct* tstruct);
-  void generate_get_field_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_field_name(ofstream& out, t_struct* tstruct);
+  void generate_union_constructor(ostream& out, t_struct* tstruct);
+  void generate_union_getters_and_setters(ostream& out, t_struct* tstruct);
+  void generate_union_is_set_methods(ostream& out, t_struct* tstruct);
+  void generate_union_abstract_methods(ostream& out, t_struct* tstruct);
+  void generate_check_type(ostream& out, t_struct* tstruct);
+  void generate_standard_scheme_read_value(ostream& out, t_struct* tstruct);
+  void generate_standard_scheme_write_value(ostream& out, t_struct* tstruct);
+  void generate_tuple_scheme_read_value(ostream& out, t_struct* tstruct);
+  void generate_tuple_scheme_write_value(ostream& out, t_struct* tstruct);
+  void generate_get_field_desc(ostream& out, t_struct* tstruct);
+  void generate_get_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_get_field_name(ostream& out, t_struct* tstruct);
 
-  void generate_union_comparisons(ofstream& out, t_struct* tstruct);
-  void generate_union_hashcode(ofstream& out, t_struct* tstruct);
+  void generate_union_comparisons(ostream& out, t_struct* tstruct);
+  void generate_union_hashcode(ostream& out, t_struct* tstruct);
 
-  void generate_scheme_map(ofstream& out, t_struct* tstruct);
-  void generate_standard_writer(ofstream& out, t_struct* tstruct, bool is_result);
-  void generate_standard_reader(ofstream& out, t_struct* tstruct);
-  void generate_java_struct_standard_scheme(ofstream& out, t_struct* tstruct, bool is_result);
+  void generate_scheme_map(ostream& out, t_struct* tstruct);
+  void generate_standard_writer(ostream& out, t_struct* tstruct, bool is_result);
+  void generate_standard_reader(ostream& out, t_struct* tstruct);
+  void generate_java_struct_standard_scheme(ostream& out, t_struct* tstruct, bool is_result);
 
-  void generate_java_struct_tuple_scheme(ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tuple_reader(ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tuple_writer(ofstream& out, t_struct* tstruct);
+  void generate_java_struct_tuple_scheme(ostream& out, t_struct* tstruct);
+  void generate_java_struct_tuple_reader(ostream& out, t_struct* tstruct);
+  void generate_java_struct_tuple_writer(ostream& out, t_struct* tstruct);
 
-  void generate_java_scheme_lookup(ofstream& out);
+  void generate_java_scheme_lookup(ostream& out);
 
-  void generate_javax_generated_annotation(ofstream& out);
+  void generate_javax_generated_annotation(ostream& out);
   /**
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool has_metadata = true);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out,
+  void generate_deserialize_container(std::ostream& out,
                                       t_type* ttype,
                                       std::string prefix = "",
                                       bool has_metadata = true);
 
-  void generate_deserialize_set_element(std::ofstream& out,
+  void generate_deserialize_set_element(std::ostream& out,
                                         t_set* tset,
                                         std::string prefix = "",
                                         std::string obj = "",
                                         bool has_metadata = true);
 
-  void generate_deserialize_map_element(std::ofstream& out,
+  void generate_deserialize_map_element(std::ostream& out,
                                         t_map* tmap,
                                         std::string prefix = "",
                                         std::string obj = "",
                                         bool has_metadata = true);
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "",
                                          std::string obj = "",
                                          bool has_metadata = true);
 
-  void generate_serialize_field(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 bool has_metadata = true);
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out,
+  void generate_serialize_container(std::ostream& out,
                                     t_type* ttype,
                                     std::string prefix = "",
                                     bool has_metadata = true);
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map,
                                       bool has_metadata = true);
 
-  void generate_serialize_set_element(std::ofstream& out,
+  void generate_serialize_set_element(std::ostream& out,
                                       t_set* tmap,
                                       std::string iter,
                                       bool has_metadata = true);
 
-  void generate_serialize_list_element(std::ofstream& out,
+  void generate_serialize_list_element(std::ostream& out,
                                        t_list* tlist,
                                        std::string iter,
                                        bool has_metadata = true);
 
-  void generate_deep_copy_container(std::ofstream& out,
+  void generate_deep_copy_container(std::ostream& out,
                                     std::string source_name_p1,
                                     std::string source_name_p2,
                                     std::string result_name,
                                     t_type* type);
-  void generate_deep_copy_non_container(std::ofstream& out,
+  void generate_deep_copy_non_container(std::ostream& out,
                                         std::string source_name,
                                         std::string dest_name,
                                         t_type* type);
@@ -334,9 +334,9 @@
                                   t_type* ttype,
                                   bool include_types = false);
   std::string type_to_enum(t_type* ttype);
-  void generate_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_field_descs(ofstream& out, t_struct* tstruct);
-  void generate_field_name_constants(ofstream& out, t_struct* tstruct);
+  void generate_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_field_descs(ostream& out, t_struct* tstruct);
+  void generate_field_name_constants(ostream& out, t_struct* tstruct);
 
   std::string make_valid_java_filename(std::string const& fromName);
   std::string make_valid_java_identifier(std::string const& fromName);
@@ -398,7 +398,7 @@
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 
   bool bean_style_;
@@ -491,7 +491,7 @@
   bool is_deprecated = this->is_deprecated(tenum->annotations_);
   // Make output file
   string f_enum_name = package_dir_ + "/" + make_valid_java_filename(tenum->get_name()) + ".java";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
@@ -583,7 +583,7 @@
 
   string f_consts_name = package_dir_ + '/' + make_valid_java_filename(program_name_)
                          + "Constants.java";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -612,7 +612,7 @@
  * is NOT performed in this function as it is always run beforehand using the
  * validate_types method in main.cc
  */
-void t_java_generator::print_const_value(std::ofstream& out,
+void t_java_generator::print_const_value(std::ostream& out,
                                          string name,
                                          t_type* type,
                                          t_const_value* value,
@@ -717,7 +717,7 @@
   }
 }
 
-string t_java_generator::render_const_value(ofstream& out, t_type* type, t_const_value* value) {
+string t_java_generator::render_const_value(ostream& out, t_type* type, t_const_value* value) {
   type = get_true_type(type);
   std::ostringstream render;
 
@@ -799,7 +799,7 @@
   // Make output file
   string f_struct_name = package_dir_ + "/" + make_valid_java_filename(tstruct->get_name())
                          + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_suppressions();
@@ -817,7 +817,7 @@
   // Make output file
   string f_struct_name = package_dir_ + "/" + make_valid_java_filename(tstruct->get_name())
                          + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_suppressions();
@@ -888,7 +888,7 @@
   f_struct.close();
 }
 
-void t_java_generator::generate_union_constructor(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_constructor(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -950,7 +950,7 @@
   }
 }
 
-void t_java_generator::generate_union_getters_and_setters(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_getters_and_setters(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -1055,7 +1055,7 @@
   }
 }
 
-void t_java_generator::generate_union_is_set_methods(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_is_set_methods(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -1078,7 +1078,7 @@
   }
 }
 
-void t_java_generator::generate_union_abstract_methods(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) {
   generate_check_type(out, tstruct);
   out << endl;
   generate_standard_scheme_read_value(out, tstruct);
@@ -1099,7 +1099,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_check_type(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out)
       << "protected void checkType(_Fields setField, java.lang.Object value) throws java.lang.ClassCastException {"
@@ -1136,7 +1136,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_standard_scheme_read_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_standard_scheme_read_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected java.lang.Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol "
                  "iprot, org.apache.thrift.protocol.TField field) throws "
@@ -1192,7 +1192,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_standard_scheme_write_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_standard_scheme_write_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected void standardSchemeWriteValue(org.apache.thrift.protocol.TProtocol "
                  "oprot) throws org.apache.thrift.TException {" << endl;
@@ -1229,7 +1229,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_tuple_scheme_read_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_tuple_scheme_read_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected java.lang.Object tupleSchemeReadValue(org.apache.thrift.protocol.TProtocol "
                  "iprot, short fieldID) throws org.apache.thrift.TException {" << endl;
@@ -1275,7 +1275,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_tuple_scheme_write_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_tuple_scheme_write_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected void tupleSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) "
                  "throws org.apache.thrift.TException {" << endl;
@@ -1312,7 +1312,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) {"
               << endl;
@@ -1340,7 +1340,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_get_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "@Override" << endl;
   indent(out) << "protected org.apache.thrift.protocol.TStruct getStructDesc() {" << endl;
@@ -1348,7 +1348,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_union_comparisons(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) {
   // equality
   indent(out) << "public boolean equals(java.lang.Object other) {" << endl;
   indent(out) << "  if (other instanceof " << tstruct->get_name() << ") {" << endl;
@@ -1379,7 +1379,7 @@
   out << endl;
 }
 
-void t_java_generator::generate_union_hashcode(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "@Override" << endl;
   indent(out) << "public int hashCode() {" << endl;
@@ -1409,7 +1409,7 @@
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_java_generator::generate_java_struct_definition(ofstream& out,
+void t_java_generator::generate_java_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
                                                        bool in_class,
@@ -1674,7 +1674,7 @@
 /**
  * generates parcelable interface implementation
  */
-void t_java_generator::generate_java_struct_parcelable(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* tstruct) {
   string tname = tstruct->get_name();
 
   const vector<t_field*>& members = tstruct->get_members();
@@ -1890,7 +1890,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_equality(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) {
   out << indent() << "@Override" << endl << indent() << "public boolean equals(java.lang.Object that) {"
       << endl;
   indent_up();
@@ -2021,7 +2021,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_java_generator::generate_java_struct_compare_to(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl;
   indent_up();
@@ -2064,7 +2064,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot) throws "
                  "org.apache.thrift.TException {" << endl;
@@ -2076,7 +2076,7 @@
 
 // generates java method to perform various checks
 // (e.g. check that all required fields are set)
-void t_java_generator::generate_java_validator(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public void validate() throws org.apache.thrift.TException {" << endl;
   indent_up();
 
@@ -2126,7 +2126,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws "
                  "org.apache.thrift.TException {" << endl;
@@ -2145,7 +2145,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws "
                  "org.apache.thrift.TException {" << endl;
@@ -2156,7 +2156,7 @@
   indent(out) << "  }" << endl << endl;
 }
 
-void t_java_generator::generate_java_struct_field_by_id(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_field_by_id(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << java_nullable_annotation() << endl;
   indent(out) << "public _Fields fieldForId(int fieldId) {" << endl;
@@ -2201,7 +2201,7 @@
   indent_down();
 }
 
-void t_java_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_java_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                               t_struct* tstruct) {
   std::ostringstream getter_stream;
   std::ostringstream setter_stream;
@@ -2243,7 +2243,7 @@
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_java_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -2278,7 +2278,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_bean_boilerplate(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* tstruct) {
   isset_type issetType = needs_isset(tstruct);
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -2603,7 +2603,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) {
   out << indent() << "@Override" << endl << indent() << "public java.lang.String toString() {" << endl;
   indent_up();
 
@@ -2674,7 +2674,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_meta_data_map(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_meta_data_map(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -2775,7 +2775,7 @@
   }
 }
 
-void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_java_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -3724,7 +3724,7 @@
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_java_generator::generate_deserialize_field(ofstream& out,
+void t_java_generator::generate_deserialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool has_metadata) {
@@ -3791,7 +3791,7 @@
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_java_generator::generate_deserialize_struct(ofstream& out,
+void t_java_generator::generate_deserialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
 
@@ -3810,7 +3810,7 @@
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_java_generator::generate_deserialize_container(ofstream& out,
+void t_java_generator::generate_deserialize_container(ostream& out,
                                                       t_type* ttype,
                                                       string prefix,
                                                       bool has_metadata) {
@@ -3913,7 +3913,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_java_generator::generate_deserialize_map_element(ofstream& out,
+void t_java_generator::generate_deserialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string prefix,
                                                         string obj,
@@ -3960,7 +3960,7 @@
 /**
  * Deserializes a set element
  */
-void t_java_generator::generate_deserialize_set_element(ofstream& out,
+void t_java_generator::generate_deserialize_set_element(ostream& out,
                                                         t_set* tset,
                                                         string prefix,
                                                         string obj,
@@ -3998,7 +3998,7 @@
 /**
  * Deserializes a list element
  */
-void t_java_generator::generate_deserialize_list_element(ofstream& out,
+void t_java_generator::generate_deserialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string prefix,
                                                          string obj,
@@ -4039,7 +4039,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_java_generator::generate_serialize_field(ofstream& out,
+void t_java_generator::generate_serialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool has_metadata) {
@@ -4112,7 +4112,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_java_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_java_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".write(oprot);" << endl;
 }
@@ -4123,7 +4123,7 @@
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_java_generator::generate_serialize_container(ofstream& out,
+void t_java_generator::generate_serialize_container(ostream& out,
                                                     t_type* ttype,
                                                     string prefix,
                                                     bool has_metadata) {
@@ -4188,7 +4188,7 @@
 /**
  * Serializes the members of a map.
  */
-void t_java_generator::generate_serialize_map_element(ofstream& out,
+void t_java_generator::generate_serialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       string iter,
                                                       string map,
@@ -4203,7 +4203,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_java_generator::generate_serialize_set_element(ofstream& out,
+void t_java_generator::generate_serialize_set_element(ostream& out,
                                                       t_set* tset,
                                                       string iter,
                                                       bool has_metadata) {
@@ -4214,7 +4214,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_java_generator::generate_serialize_list_element(ofstream& out,
+void t_java_generator::generate_serialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        string iter,
                                                        bool has_metadata) {
@@ -4342,7 +4342,7 @@
   result += type_name(tfield->get_type()) + " " + tfield->get_name();
   if (init) {
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -4658,7 +4658,7 @@
   return constant_name;
 }
 
-void t_java_generator::generate_deep_copy_container(ofstream& out,
+void t_java_generator::generate_deep_copy_container(ostream& out,
                                                     std::string source_name_p1,
                                                     std::string source_name_p2,
                                                     std::string result_name,
@@ -4808,7 +4808,7 @@
   }
 }
 
-void t_java_generator::generate_deep_copy_non_container(ofstream& out,
+void t_java_generator::generate_deep_copy_non_container(ostream& out,
                                                         std::string source_name,
                                                         std::string dest_name,
                                                         t_type* type) {
@@ -4838,19 +4838,19 @@
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_java_generator::generate_isset_set(ofstream& out, t_field* field, string prefix) {
+void t_java_generator::generate_isset_set(ostream& out, t_field* field, string prefix) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << prefix << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet")
                 << "(true);" << endl;
   }
 }
 
-void t_java_generator::generate_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_struct_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new "
                  "org.apache.thrift.protocol.TStruct(\"" << tstruct->get_name() << "\");" << endl;
 }
 
-void t_java_generator::generate_field_descs(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_field_descs(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -4863,14 +4863,14 @@
   }
 }
 
-void t_java_generator::generate_scheme_map(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_scheme_map(ostream& out, t_struct* tstruct) {
   indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new "
       << tstruct->get_name() << "StandardSchemeFactory();" << endl;
   indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new "
       << tstruct->get_name() << "TupleSchemeFactory();" << endl;
 }
 
-void t_java_generator::generate_field_name_constants(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tstruct) {
   indent(out) << "/** The set of fields this struct contains, along with convenience methods for "
                  "finding and manipulating them. */" << endl;
   indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << endl;
@@ -4998,7 +4998,7 @@
   }
 }
 
-void t_java_generator::generate_java_struct_clear(std::ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) {
   if (!java5_) {
     indent(out) << "@Override" << endl;
   }
@@ -5062,7 +5062,7 @@
 }
 
 // generates java method to serialize (in the Java sense) the object
-void t_java_generator::generate_java_struct_write_object(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_write_object(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out)
       << "private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {"
@@ -5078,7 +5078,7 @@
 }
 
 // generates java method to serialize (in the Java sense) the object
-void t_java_generator::generate_java_struct_read_object(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_read_object(ostream& out, t_struct* tstruct) {
   indent(out) << "private void readObject(java.io.ObjectInputStream in) throws "
                  "java.io.IOException, java.lang.ClassNotFoundException {" << endl;
   indent(out) << "  try {" << endl;
@@ -5107,7 +5107,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_java_generator::generate_standard_reader(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_standard_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public void read(org.apache.thrift.protocol.TProtocol iprot, "
       << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
   indent_up();
@@ -5197,7 +5197,7 @@
   out << indent() << "}" << endl;
 }
 
-void t_java_generator::generate_standard_writer(ofstream& out, t_struct* tstruct, bool is_result) {
+void t_java_generator::generate_standard_writer(ostream& out, t_struct* tstruct, bool is_result) {
   indent_up();
   out << indent() << "public void write(org.apache.thrift.protocol.TProtocol oprot, "
       << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
@@ -5250,7 +5250,7 @@
   indent_down();
 }
 
-void t_java_generator::generate_java_struct_standard_scheme(ofstream& out,
+void t_java_generator::generate_java_struct_standard_scheme(ostream& out,
                                                             t_struct* tstruct,
                                                             bool is_result) {
   indent(out) << "private static class " << tstruct->get_name()
@@ -5275,7 +5275,7 @@
   out << indent() << "}" << endl << endl;
 }
 
-void t_java_generator::generate_java_struct_tuple_reader(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tuple_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "public void read(org.apache.thrift.protocol.TProtocol prot, "
               << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
@@ -5316,7 +5316,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_java_struct_tuple_writer(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tuple_writer(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "public void write(org.apache.thrift.protocol.TProtocol prot, "
               << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
@@ -5370,7 +5370,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_java_struct_tuple_scheme(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tuple_scheme(ostream& out, t_struct* tstruct) {
   indent(out) << "private static class " << tstruct->get_name()
               << "TupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" << endl;
   indent_up();
@@ -5391,7 +5391,7 @@
   out << indent() << "}" << endl << endl;
 }
 
-void t_java_generator::generate_java_scheme_lookup(ofstream& out) {
+void t_java_generator::generate_java_scheme_lookup(ostream& out) {
   indent(out) << "private static <S extends org.apache.thrift.scheme.IScheme> S scheme("
       << "org.apache.thrift.protocol.TProtocol proto) {" << endl;
   indent_up();
@@ -5403,7 +5403,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_javax_generated_annotation(ofstream& out) {
+void t_java_generator::generate_javax_generated_annotation(ostream& out) {
   time_t seconds = time(NULL);
   struct tm* now = localtime(&seconds);
   indent(out) << "@javax.annotation.Generated(value = \"" << autogen_summary() << "\"";
diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
index 0f4181d..fa743ca 100644
--- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -81,13 +81,13 @@
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(std::ofstream& out,
+  std::string render_const_value(std::ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -98,20 +98,20 @@
 
   void generate_java_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_java_struct_definition(std::ofstream& out,
+  void generate_java_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool in_class = false,
                                        bool is_result = false);
-  void generate_java_struct_equality(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_compare_to(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_java_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_java_struct_equality(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_compare_to(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_java_validator(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_clear(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_java_type_string(t_type* type);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
@@ -121,14 +121,14 @@
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_java_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_java_bean_boilerplate(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
   std::string isset_field_id(t_field* field);
 
   void generate_primitive_service_interface(t_service* tservice);
@@ -139,66 +139,66 @@
   void generate_process_function(t_service* tservice, t_function* tfunction);
 
   void generate_java_union(t_struct* tstruct);
-  void generate_union_constructor(ofstream& out, t_struct* tstruct);
-  void generate_union_getters_and_setters(ofstream& out, t_struct* tstruct);
-  void generate_union_abstract_methods(ofstream& out, t_struct* tstruct);
-  void generate_check_type(ofstream& out, t_struct* tstruct);
-  void generate_read_value(ofstream& out, t_struct* tstruct);
-  void generate_write_value(ofstream& out, t_struct* tstruct);
-  void generate_get_field_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_field_name(ofstream& out, t_struct* tstruct);
+  void generate_union_constructor(ostream& out, t_struct* tstruct);
+  void generate_union_getters_and_setters(ostream& out, t_struct* tstruct);
+  void generate_union_abstract_methods(ostream& out, t_struct* tstruct);
+  void generate_check_type(ostream& out, t_struct* tstruct);
+  void generate_read_value(ostream& out, t_struct* tstruct);
+  void generate_write_value(ostream& out, t_struct* tstruct);
+  void generate_get_field_desc(ostream& out, t_struct* tstruct);
+  void generate_get_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_get_field_name(ostream& out, t_struct* tstruct);
 
-  void generate_union_comparisons(ofstream& out, t_struct* tstruct);
-  void generate_union_hashcode(ofstream& out, t_struct* tstruct);
+  void generate_union_comparisons(ostream& out, t_struct* tstruct);
+  void generate_union_hashcode(ostream& out, t_struct* tstruct);
 
   /**
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_java_doc(std::ofstream& out, t_field* field);
+  void generate_java_doc(std::ostream& out, t_field* field);
 
-  void generate_java_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_java_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_java_doc(std::ofstream& out, t_function* tdoc);
+  void generate_java_doc(std::ostream& out, t_function* tdoc);
 
-  void generate_java_docstring_comment(std::ofstream& out, string contents);
+  void generate_java_docstring_comment(std::ostream& out, string contents);
 
-  void generate_deep_copy_container(std::ofstream& out,
+  void generate_deep_copy_container(std::ostream& out,
                                     std::string source_name_p1,
                                     std::string source_name_p2,
                                     std::string result_name,
                                     t_type* type);
-  void generate_deep_copy_non_container(std::ofstream& out,
+  void generate_deep_copy_non_container(std::ostream& out,
                                         std::string source_name,
                                         std::string dest_name,
                                         t_type* type);
@@ -222,8 +222,8 @@
   std::string argument_list(t_struct* tstruct, bool include_types = true);
   std::string type_to_enum(t_type* ttype);
   std::string get_enum_class_name(t_type* type);
-  void generate_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_field_descs(ofstream& out, t_struct* tstruct);
+  void generate_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_field_descs(ostream& out, t_struct* tstruct);
   std::string box_type(t_type* type, string value);
 
   bool type_can_be_null(t_type* ttype) {
@@ -241,7 +241,7 @@
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 };
 
@@ -329,7 +329,7 @@
 void t_javame_generator::generate_enum(t_enum* tenum) {
   // Make output file
   string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".java";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
@@ -408,7 +408,7 @@
   }
 
   string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.java";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -434,7 +434,7 @@
  * is NOT performed in this function as it is always run beforehand using the
  * validate_types method in main.cc
  */
-void t_javame_generator::print_const_value(std::ofstream& out,
+void t_javame_generator::print_const_value(std::ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value,
@@ -535,7 +535,7 @@
   }
 }
 
-string t_javame_generator::render_const_value(ofstream& out,
+string t_javame_generator::render_const_value(ostream& out,
                                               string name,
                                               t_type* type,
                                               t_const_value* value) {
@@ -638,7 +638,7 @@
 void t_javame_generator::generate_java_struct(t_struct* tstruct, bool is_exception) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports();
@@ -655,7 +655,7 @@
 void t_javame_generator::generate_java_union(t_struct* tstruct) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports();
@@ -699,7 +699,7 @@
   f_struct.close();
 }
 
-void t_javame_generator::generate_union_constructor(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_constructor(ostream& out, t_struct* tstruct) {
   indent(out) << "public " << type_name(tstruct) << "() {" << endl;
   indent(out) << "  super();" << endl;
   indent(out) << "}" << endl << endl;
@@ -730,7 +730,7 @@
   }
 }
 
-void t_javame_generator::generate_union_getters_and_setters(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_getters_and_setters(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -772,7 +772,7 @@
   }
 }
 
-void t_javame_generator::generate_union_abstract_methods(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) {
   generate_check_type(out, tstruct);
   out << endl;
   generate_read_value(out, tstruct);
@@ -785,7 +785,7 @@
   out << endl;
 }
 
-void t_javame_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) {
   indent(out)
       << "protected void checkType(_Fields setField, Object value) throws ClassCastException {"
       << endl;
@@ -821,7 +821,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_read_value(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) {
   indent(out) << "protected Object readValue(TProtocol iprot, TField field) throws TException {"
               << endl;
 
@@ -875,7 +875,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_write_value(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) {
   indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << endl;
 
   indent_up();
@@ -910,7 +910,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "protected TField getFieldDesc(_Fields setField) {" << endl;
   indent_up();
 
@@ -936,14 +936,14 @@
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_get_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "protected TStruct getStructDesc() {" << endl;
   indent(out) << "  return STRUCT_DESC;" << endl;
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_union_comparisons(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) {
   // equality
   indent(out) << "public boolean equals(Object other) {" << endl;
   indent(out) << "  if (other instanceof " << tstruct->get_name() << ") {" << endl;
@@ -973,7 +973,7 @@
   out << endl;
 }
 
-void t_javame_generator::generate_union_hashcode(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "/**" << endl;
   indent(out)
@@ -995,7 +995,7 @@
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_javame_generator::generate_java_struct_definition(ofstream& out,
+void t_javame_generator::generate_java_struct_definition(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_exception,
                                                          bool in_class,
@@ -1177,7 +1177,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_equality(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) {
   out << indent() << "public boolean equals(Object that) {" << endl;
   indent_up();
   out << indent() << "if (that == null)" << endl << indent() << "  return false;" << endl
@@ -1246,7 +1246,7 @@
   indent(out) << "}" << endl << endl;
 }
 
-void t_javame_generator::generate_java_struct_compare_to(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) {
   indent(out) << "public int compareTo(Object otherObject) {" << endl;
   //  indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl;
   indent_up();
@@ -1297,7 +1297,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public void read(TProtocol iprot) throws TException {" << endl;
   indent_up();
 
@@ -1365,7 +1365,7 @@
 
 // generates java method to perform various checks
 // (e.g. check that all required fields are set)
-void t_javame_generator::generate_java_validator(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public void validate() throws TException {" << endl;
   indent_up();
 
@@ -1390,7 +1390,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public void write(TProtocol oprot) throws TException {" << endl;
   indent_up();
 
@@ -1449,7 +1449,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public void write(TProtocol oprot) throws TException {" << endl;
   indent_up();
 
@@ -1527,7 +1527,7 @@
   indent_down();
 }
 
-void t_javame_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_javame_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                                 t_struct* tstruct) {
   (void)out;
   std::ostringstream getter_stream;
@@ -1555,7 +1555,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_bean_boilerplate(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@@ -1708,7 +1708,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) {
   out << indent() << "public String toString() {" << endl;
   indent_up();
 
@@ -1819,7 +1819,7 @@
   }
 }
 
-void t_javame_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_javame_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -1894,7 +1894,7 @@
              << endl << endl;
 
   string f_interface_name = package_dir_ + "/" + service_name_ + "Iface.java";
-  std::ofstream f_iface;
+  ofstream_with_content_based_conditional_update f_iface;
   f_iface.open(f_interface_name.c_str());
 
   string extends_iface = "";
@@ -2391,7 +2391,7 @@
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_javame_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
@@ -2455,7 +2455,7 @@
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_javame_generator::generate_deserialize_struct(ofstream& out,
+void t_javame_generator::generate_deserialize_struct(ostream& out,
                                                      t_struct* tstruct,
                                                      string prefix) {
   out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
@@ -2465,7 +2465,7 @@
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_javame_generator::generate_deserialize_container(ofstream& out,
+void t_javame_generator::generate_deserialize_container(ostream& out,
                                                         t_type* ttype,
                                                         string prefix) {
   scope_up(out);
@@ -2527,7 +2527,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_javame_generator::generate_deserialize_map_element(ofstream& out,
+void t_javame_generator::generate_deserialize_map_element(ostream& out,
                                                           t_map* tmap,
                                                           string prefix) {
   string key = tmp("_key");
@@ -2548,7 +2548,7 @@
 /**
  * Deserializes a set element
  */
-void t_javame_generator::generate_deserialize_set_element(ofstream& out,
+void t_javame_generator::generate_deserialize_set_element(ostream& out,
                                                           t_set* tset,
                                                           string prefix) {
   string elem = tmp("_elem");
@@ -2565,7 +2565,7 @@
 /**
  * Deserializes a list element
  */
-void t_javame_generator::generate_deserialize_list_element(ofstream& out,
+void t_javame_generator::generate_deserialize_list_element(ostream& out,
                                                            t_list* tlist,
                                                            string prefix) {
   string elem = tmp("_elem");
@@ -2584,7 +2584,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_javame_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2654,7 +2654,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_javame_generator::generate_serialize_struct(ofstream& out,
+void t_javame_generator::generate_serialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   (void)tstruct;
@@ -2667,7 +2667,7 @@
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_javame_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2733,7 +2733,7 @@
 /**
  * Serializes the members of a map.
  */
-void t_javame_generator::generate_serialize_map_element(ofstream& out,
+void t_javame_generator::generate_serialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string iter,
                                                         string map) {
@@ -2747,7 +2747,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_javame_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_javame_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2755,7 +2755,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_javame_generator::generate_serialize_list_element(ofstream& out,
+void t_javame_generator::generate_serialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string iter) {
   t_field efield(tlist->get_elem_type(), iter);
@@ -2847,7 +2847,7 @@
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2997,11 +2997,11 @@
   return constant_name;
 }
 
-void t_javame_generator::generate_java_docstring_comment(ofstream& out, string contents) {
+void t_javame_generator::generate_java_docstring_comment(ostream& out, string contents) {
   generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
 }
 
-void t_javame_generator::generate_java_doc(ofstream& out, t_field* field) {
+void t_javame_generator::generate_java_doc(ostream& out, t_field* field) {
   if (field->get_type()->is_enum()) {
     string combined_message = field->get_doc() + "\n@see " + get_enum_class_name(field->get_type());
     generate_java_docstring_comment(out, combined_message);
@@ -3013,7 +3013,7 @@
 /**
  * Emits a JavaDoc comment if the provided object has a doc in Thrift
  */
-void t_javame_generator::generate_java_doc(ofstream& out, t_doc* tdoc) {
+void t_javame_generator::generate_java_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_java_docstring_comment(out, tdoc->get_doc());
   }
@@ -3022,7 +3022,7 @@
 /**
  * Emits a JavaDoc comment if the provided function object has a doc in Thrift
  */
-void t_javame_generator::generate_java_doc(ofstream& out, t_function* tfunction) {
+void t_javame_generator::generate_java_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -3039,7 +3039,7 @@
   }
 }
 
-void t_javame_generator::generate_deep_copy_container(ofstream& out,
+void t_javame_generator::generate_deep_copy_container(ostream& out,
                                                       std::string source_name_p1,
                                                       std::string source_name_p2,
                                                       std::string result_name,
@@ -3169,7 +3169,7 @@
   }
 }
 
-void t_javame_generator::generate_deep_copy_non_container(ofstream& out,
+void t_javame_generator::generate_deep_copy_non_container(ostream& out,
                                                           std::string source_name,
                                                           std::string dest_name,
                                                           t_type* type) {
@@ -3200,7 +3200,7 @@
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_javame_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_javame_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);"
                 << endl;
@@ -3216,12 +3216,12 @@
   return package + type->get_name();
 }
 
-void t_javame_generator::generate_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_struct_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "private static final TStruct STRUCT_DESC = new TStruct(\"" << tstruct->get_name()
               << "\");" << endl;
 }
 
-void t_javame_generator::generate_field_descs(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -3245,7 +3245,7 @@
   return false;
 }
 
-void t_javame_generator::generate_java_struct_clear(std::ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) {
   indent(out) << "public void clear() {" << endl;
 
   const vector<t_field*>& members = tstruct->get_members();
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index 7d160b9..6f73c1c 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -34,7 +34,7 @@
 #include "thrift/version.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -135,12 +135,12 @@
    * Structs!
    */
   void generate_js_struct(t_struct* tstruct, bool is_exception);
-  void generate_js_struct_definition(std::ofstream& out,
+  void generate_js_struct_definition(std::ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false,
                                      bool is_exported = true);
-  void generate_js_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_js_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_js_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_js_struct_writer(std::ostream& out, t_struct* tstruct);
   void generate_js_function_helpers(t_function* tfunction);
 
   /**
@@ -157,37 +157,37 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool inclass = false);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -354,10 +354,10 @@
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_service_;
-  std::ofstream f_types_ts_;
-  std::ofstream f_service_ts_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_service_;
+  ofstream_with_content_based_conditional_update f_types_ts_;
+  ofstream_with_content_based_conditional_update f_service_ts_;
 };
 
 /**
@@ -686,7 +686,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_js_generator::generate_js_struct_definition(ofstream& out,
+void t_js_generator::generate_js_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception,
                                                    bool is_exported) {
@@ -848,7 +848,7 @@
 /**
  * Generates the read() method for a struct
  */
-void t_js_generator::generate_js_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_js_generator::generate_js_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -927,7 +927,7 @@
 /**
  * Generates the write() method for a struct
  */
-void t_js_generator::generate_js_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_js_generator::generate_js_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1712,7 +1712,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_js_generator::generate_deserialize_field(ofstream& out,
+void t_js_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool inclass) {
@@ -1784,12 +1784,12 @@
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_js_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_js_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << indent() << prefix << " = new " << js_type_namespace(tstruct->get_program())
       << tstruct->get_name() << "();" << endl << indent() << prefix << ".read(input);" << endl;
 }
 
-void t_js_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -1863,7 +1863,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_js_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_js_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("key");
   string val = tmp("val");
   t_field fkey(tmap->get_key_type(), key);
@@ -1878,7 +1878,7 @@
   indent(out) << prefix << "[" << key << "] = " << val << ";" << endl;
 }
 
-void t_js_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_js_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -1889,7 +1889,7 @@
   indent(out) << prefix << ".push(" << elem << ");" << endl;
 }
 
-void t_js_generator::generate_deserialize_list_element(ofstream& out,
+void t_js_generator::generate_deserialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        string prefix) {
   string elem = tmp("elem");
@@ -1908,7 +1908,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_js_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -1979,7 +1979,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_js_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_js_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ".write(output);" << endl;
 }
@@ -1987,7 +1987,7 @@
 /**
  * Writes out a container
  */
-void t_js_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     indent(out) << "output.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
                 << type_to_enum(((t_map*)ttype)->get_val_type()) << ", "
@@ -2050,7 +2050,7 @@
  * Serializes the members of a map.
  *
  */
-void t_js_generator::generate_serialize_map_element(ofstream& out,
+void t_js_generator::generate_serialize_map_element(ostream& out,
                                                     t_map* tmap,
                                                     string kiter,
                                                     string viter) {
@@ -2064,7 +2064,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_js_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_js_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
@@ -2072,7 +2072,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_js_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_js_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc
index cf5f801..cd53612 100644
--- a/compiler/cpp/src/thrift/generate/t_json_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc
@@ -89,7 +89,7 @@
 private:
   bool should_merge_includes_;
 
-  std::ofstream f_json_;
+  ofstream_with_content_based_conditional_update f_json_;
   std::stack<bool> comma_needed_;
 
   template <typename T>
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index b4a6793..adee896 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -21,7 +21,7 @@
 #include "thrift/platform.h"
 #include "thrift/generate/t_oop_generator.h"
 
-using std::ofstream;
+using std::ostream;
 using std::string;
 using std::vector;
 using std::map;
@@ -80,65 +80,65 @@
   /**
    * Struct-level generation functions
    */
-  void generate_lua_struct_definition(std::ofstream& out,
+  void generate_lua_struct_definition(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_xception = false);
-  void generate_lua_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_lua_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_lua_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_lua_struct_writer(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
    */
-  void generate_service_client(std::ofstream& out, t_service* tservice);
-  void generate_service_interface(std::ofstream& out, t_service* tservice);
-  void generate_service_processor(std::ofstream& out, t_service* tservice);
-  void generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction);
-  void generate_service_helpers(ofstream& out, t_service* tservice);
-  void generate_function_helpers(ofstream& out, t_function* tfunction);
+  void generate_service_client(std::ostream& out, t_service* tservice);
+  void generate_service_interface(std::ostream& out, t_service* tservice);
+  void generate_service_processor(std::ostream& out, t_service* tservice);
+  void generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction);
+  void generate_service_helpers(ostream& out, t_service* tservice);
+  void generate_function_helpers(ostream& out, t_function* tfunction);
 
   /**
    * Deserialization (Read)
    */
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   bool local,
                                   std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out,
                                    t_struct* tstruct,
                                    bool local,
                                    std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out,
+  void generate_deserialize_container(std::ostream& out,
                                       t_type* ttype,
                                       bool local,
                                       std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
   /**
    * Serialization (Write)
    */
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -159,9 +159,9 @@
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
 };
 
 /**
@@ -366,7 +366,7 @@
 /**
  * Generate a thrift struct or exception (lua table)
  */
-void t_lua_generator::generate_lua_struct_definition(ofstream& out,
+void t_lua_generator::generate_lua_struct_definition(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception) {
   vector<t_field*>::const_iterator m_iter;
@@ -402,7 +402,7 @@
 /**
  * Generate a struct/exception reader
  */
-void t_lua_generator::generate_lua_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_lua_generator::generate_lua_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -459,7 +459,7 @@
 /**
  * Generate a struct/exception writer
  */
-void t_lua_generator::generate_lua_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_lua_generator::generate_lua_struct_writer(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -527,7 +527,7 @@
   f_service_.close();
 }
 
-void t_lua_generator::generate_service_interface(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_interface(ostream& out, t_service* tservice) {
   string classname = tservice->get_name() + "Iface";
   t_service* extends_s = tservice->get_extends();
 
@@ -541,7 +541,7 @@
   out << "  __type = '" << classname << "'" << endl << "}" << endl << endl;
 }
 
-void t_lua_generator::generate_service_client(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) {
   string classname = tservice->get_name() + "Client";
   t_service* extends_s = tservice->get_extends();
 
@@ -637,7 +637,7 @@
   }
 }
 
-void t_lua_generator::generate_service_processor(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_processor(ostream& out, t_service* tservice) {
   string classname = tservice->get_name() + "Processor";
   t_service* extends_s = tservice->get_extends();
 
@@ -680,7 +680,7 @@
   }
 }
 
-void t_lua_generator::generate_process_function(ofstream& out,
+void t_lua_generator::generate_process_function(ostream& out,
                                                 t_service* tservice,
                                                 t_function* tfunction) {
   string classname = tservice->get_name() + "Processor";
@@ -731,7 +731,7 @@
 }
 
 // Service helpers
-void t_lua_generator::generate_service_helpers(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_helpers(ostream& out, t_service* tservice) {
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
 
@@ -743,7 +743,7 @@
   }
 }
 
-void t_lua_generator::generate_function_helpers(ofstream& out, t_function* tfunction) {
+void t_lua_generator::generate_function_helpers(ostream& out, t_function* tfunction) {
   if (!tfunction->is_oneway()) {
     t_struct result(program_, tfunction->get_name() + "_result");
     t_field success(tfunction->get_returntype(), "success", 0);
@@ -764,7 +764,7 @@
 /**
  * Deserialize (Read)
  */
-void t_lua_generator::generate_deserialize_field(ofstream& out,
+void t_lua_generator::generate_deserialize_field(ostream& out,
                                                  t_field* tfield,
                                                  bool local,
                                                  string prefix) {
@@ -825,7 +825,7 @@
   }
 }
 
-void t_lua_generator::generate_deserialize_struct(ofstream& out,
+void t_lua_generator::generate_deserialize_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   bool local,
                                                   string prefix) {
@@ -833,7 +833,7 @@
               << endl << indent() << prefix << ":read(iprot)" << endl;
 }
 
-void t_lua_generator::generate_deserialize_container(ofstream& out,
+void t_lua_generator::generate_deserialize_container(ostream& out,
                                                      t_type* ttype,
                                                      bool local,
                                                      string prefix) {
@@ -883,7 +883,7 @@
   }
 }
 
-void t_lua_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_lua_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   // A map is represented by a table indexable by any lua type
   string key = tmp("_key");
   string val = tmp("_val");
@@ -896,7 +896,7 @@
   indent(out) << prefix << "[" << key << "] = " << val << endl;
 }
 
-void t_lua_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   // A set is represented by a table indexed by the value
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
@@ -906,7 +906,7 @@
   indent(out) << prefix << "[" << elem << "] = " << elem << endl;
 }
 
-void t_lua_generator::generate_deserialize_list_element(ofstream& out,
+void t_lua_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   // A list is represented by a table indexed by integer values
@@ -922,7 +922,7 @@
 /**
  * Serialize (Write)
  */
-void t_lua_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
   string name = prefix + tfield->get_name();
 
@@ -979,12 +979,12 @@
   }
 }
 
-void t_lua_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_lua_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ":write(oprot)" << endl;
 }
 
-void t_lua_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   // Begin writing
   if (ttype->is_map()) {
     indent(out) << "oprot:writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
@@ -1034,7 +1034,7 @@
   }
 }
 
-void t_lua_generator::generate_serialize_map_element(ofstream& out,
+void t_lua_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string kiter,
                                                      string viter) {
@@ -1045,12 +1045,12 @@
   generate_serialize_field(out, &vfield, "");
 }
 
-void t_lua_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_lua_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
 
-void t_lua_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_lua_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
diff --git a/compiler/cpp/src/thrift/generate/t_netcore_generator.cc b/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
index dbf2fd0..d2e7da0 100644
--- a/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
@@ -38,7 +38,7 @@
 #include "thrift/generate/t_netcore_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -332,7 +332,7 @@
 	netcore_keywords["when"] = 1;
 }
 
-void t_netcore_generator::start_netcore_namespace(ofstream& out)
+void t_netcore_generator::start_netcore_namespace(ostream& out)
 {
     if (!namespace_name_.empty())
     {
@@ -341,7 +341,7 @@
     }
 }
 
-void t_netcore_generator::end_netcore_namespace(ofstream& out)
+void t_netcore_generator::end_netcore_namespace(ostream& out)
 {
     if (!namespace_name_.empty())
     {
@@ -398,7 +398,7 @@
 	int ic = indent_count();
     string f_enum_name = namespace_dir_ + "/" + tenum->get_name() + ".cs";
 
-    ofstream f_enum;
+    ofstream_with_content_based_conditional_update f_enum;
     f_enum.open(f_enum_name.c_str());
 
 	generate_enum(f_enum, tenum);
@@ -407,7 +407,7 @@
 	indent_validate(ic, "generate_enum");
 }
 
-void t_netcore_generator::generate_enum(ofstream& out, t_enum* tenum)
+void t_netcore_generator::generate_enum(ostream& out, t_enum* tenum)
 {
 	out << autogen_comment() << endl;
 
@@ -439,7 +439,7 @@
     }
 
     string f_consts_name = namespace_dir_ + '/' + program_name_ + ".Constants.cs";
-    ofstream f_consts;
+    ofstream_with_content_based_conditional_update f_consts;
     f_consts.open(f_consts_name.c_str());
 
     generate_consts(f_consts, consts);
@@ -447,7 +447,7 @@
     f_consts.close();
 }
 
-void t_netcore_generator::generate_consts(ofstream& out, vector<t_const*> consts)
+void t_netcore_generator::generate_consts(ostream& out, vector<t_const*> consts)
 {
     if (consts.empty())
     {
@@ -482,7 +482,7 @@
     end_netcore_namespace(out);
 }
 
-void t_netcore_generator::print_const_def_value(ofstream& out, string name, t_type* type, t_const_value* value)
+void t_netcore_generator::print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value)
 {
     if (type->is_struct() || type->is_xception())
     {
@@ -552,7 +552,7 @@
     }
 }
 
-void t_netcore_generator::print_const_constructor(ofstream& out, vector<t_const*> consts)
+void t_netcore_generator::print_const_constructor(ostream& out, vector<t_const*> consts)
 {
     out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << endl;
     scope_up(out);
@@ -569,7 +569,7 @@
     scope_down(out);
 }
 
-bool t_netcore_generator::print_const_value(ofstream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval, bool needtype)
+bool t_netcore_generator::print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval, bool needtype)
 {
     out << indent();
     bool need_static_construction = !in_static;
@@ -615,7 +615,7 @@
     return need_static_construction;
 }
 
-string t_netcore_generator::render_const_value(ofstream& out, string name, t_type* type, t_const_value* value)
+string t_netcore_generator::render_const_value(ostream& out, string name, t_type* type, t_const_value* value)
 {
     (void)name;
     ostringstream render;
@@ -687,7 +687,7 @@
     int ic = indent_count();
 
     string f_struct_name = namespace_dir_ + "/" + (tstruct->get_name()) + ".cs";
-    ofstream f_struct;
+    ofstream_with_content_based_conditional_update f_struct;
 
     f_struct.open(f_struct_name.c_str());
 
@@ -700,7 +700,7 @@
     indent_validate(ic, "generate_netcore_struct");
 }
 
-void t_netcore_generator::generate_netcore_struct_definition(ofstream& out, t_struct* tstruct, bool is_exception, bool in_class, bool is_result)
+void t_netcore_generator::generate_netcore_struct_definition(ostream& out, t_struct* tstruct, bool is_exception, bool in_class, bool is_result)
 {
     if (!in_class)
     {
@@ -929,7 +929,7 @@
     }
 }
 
-void t_netcore_generator::generate_netcore_wcffault(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_wcffault(ostream& out, t_struct* tstruct)
 {
     out << endl;
     out << indent() << "[DataContract]" << endl;
@@ -959,7 +959,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_reader(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_reader(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public async Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)" << endl
         << indent() << "{" << endl;
@@ -1063,7 +1063,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_writer(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_writer(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
         << indent() << "{" << endl;
@@ -1140,7 +1140,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_result_writer(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_result_writer(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
         << indent() << "{" << endl;
@@ -1228,7 +1228,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_tostring(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_tostring(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public override string ToString()" << endl
         << indent() << "{" << endl;
@@ -1324,7 +1324,7 @@
     int ic = indent_count();
 
     string f_union_name = namespace_dir_ + "/" + (tunion->get_name()) + ".cs";
-    ofstream f_union;
+    ofstream_with_content_based_conditional_update f_union;
 
     f_union.open(f_union_name.c_str());
 
@@ -1337,7 +1337,7 @@
     indent_validate(ic, "generate_netcore_union.");
 }
 
-void t_netcore_generator::generate_netcore_union_definition(ofstream& out, t_struct* tunion)
+void t_netcore_generator::generate_netcore_union_definition(ostream& out, t_struct* tunion)
 {
     // Let's define the class first
     start_netcore_namespace(out);
@@ -1388,7 +1388,7 @@
     end_netcore_namespace(out);
 }
 
-void t_netcore_generator::generate_netcore_union_class(ofstream& out, t_struct* tunion, t_field* tfield)
+void t_netcore_generator::generate_netcore_union_class(ostream& out, t_struct* tunion, t_field* tfield)
 {
     out << indent() << "public class " << tfield->get_name() << " : " << tunion->get_name() << endl
         << indent() << "{" << endl;
@@ -1438,7 +1438,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_equals(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_equals(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public override bool Equals(object that)" << endl
         << indent() << "{" << endl;
@@ -1500,7 +1500,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_hashcode(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_hashcode(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public override int GetHashCode() {" << endl;
     indent_up();
@@ -1552,7 +1552,7 @@
     int ic = indent_count();
 
     string f_service_name = namespace_dir_ + "/" + service_name_ + ".cs";
-    ofstream f_service;
+    ofstream_with_content_based_conditional_update f_service;
     f_service.open(f_service_name.c_str());
 
     f_service << autogen_comment() << netcore_type_usings() << netcore_thrift_usings() << endl;
@@ -1577,7 +1577,7 @@
     indent_validate(ic, "generate_service.");
 }
 
-void t_netcore_generator::generate_service_interface(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_interface(ostream& out, t_service* tservice)
 {
     string extends = "";
     string extends_iface = "";
@@ -1625,7 +1625,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_service_helpers(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_helpers(ostream& out, t_service* tservice)
 {
     vector<t_function*> functions = tservice->get_functions();
     vector<t_function*>::iterator f_iter;
@@ -1638,7 +1638,7 @@
     }
 }
 
-void t_netcore_generator::generate_service_client(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_client(ostream& out, t_service* tservice)
 {
     string extends = "";
     string extends_client = "";
@@ -1809,7 +1809,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_service_server(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_server(ostream& out, t_service* tservice)
 {
     vector<t_function*> functions = tservice->get_functions();
     vector<t_function*>::iterator f_iter;
@@ -1937,7 +1937,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_function_helpers(ofstream& out, t_function* tfunction)
+void t_netcore_generator::generate_function_helpers(ostream& out, t_function* tfunction)
 {
     if (tfunction->is_oneway())
     {
@@ -1962,7 +1962,7 @@
     generate_netcore_struct_definition(out, &result, false, true, true);
 }
 
-void t_netcore_generator::generate_process_function_async(ofstream& out, t_service* tservice, t_function* tfunction)
+void t_netcore_generator::generate_process_function_async(ostream& out, t_service* tservice, t_function* tfunction)
 {
     (void)tservice;
     out << indent() << "public async Task " << tfunction->get_name()
@@ -2104,7 +2104,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_union_reader(ofstream& out, t_struct* tunion)
+void t_netcore_generator::generate_netcore_union_reader(ostream& out, t_struct* tunion)
 {
     // Thanks to THRIFT-1768, we don't need to check for required fields in the union
     const vector<t_field*>& fields = tunion->get_members();
@@ -2180,7 +2180,7 @@
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix, bool is_propertyless)
+void t_netcore_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless)
 {
     t_type* type = tfield->get_type();
     while (type->is_typedef())
@@ -2266,7 +2266,7 @@
     }
 }
 
-void t_netcore_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix)
+void t_netcore_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix)
 {
     if (union_ && tstruct->is_union())
     {
@@ -2279,7 +2279,7 @@
     }
 }
 
-void t_netcore_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix)
+void t_netcore_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix)
 {
     out << indent() << "{" << endl;
     indent_up();
@@ -2351,7 +2351,7 @@
     out << indent() << "}" << endl;
 }
 
-void t_netcore_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix)
+void t_netcore_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix)
 {
     string key = tmp("_key");
     string val = tmp("_val");
@@ -2368,7 +2368,7 @@
     out << indent() << prefix << "[" << key << "] = " << val << ";" << endl;
 }
 
-void t_netcore_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix)
+void t_netcore_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix)
 {
     string elem = tmp("_elem");
     t_field felem(tset->get_elem_type(), elem);
@@ -2380,7 +2380,7 @@
     out << indent() << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_netcore_generator::generate_deserialize_list_element(ofstream& out, t_list* tlist, string prefix)
+void t_netcore_generator::generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix)
 {
     string elem = tmp("_elem");
     t_field felem(tlist->get_elem_type(), elem);
@@ -2392,7 +2392,7 @@
     out << indent() << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_netcore_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix, bool is_element, bool is_propertyless)
+void t_netcore_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix, bool is_element, bool is_propertyless)
 {
     t_type* type = tfield->get_type();
     while (type->is_typedef())
@@ -2473,13 +2473,13 @@
     }
 }
 
-void t_netcore_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix)
+void t_netcore_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix)
 {
     (void)tstruct;
     out << indent() << "await " << prefix << ".WriteAsync(oprot, cancellationToken);" << endl;
 }
 
-void t_netcore_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix)
+void t_netcore_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix)
 {
     out << indent() << "{" << endl;
     indent_up();
@@ -2556,7 +2556,7 @@
     out << indent() << "}" << endl;
 }
 
-void t_netcore_generator::generate_serialize_map_element(ofstream& out, t_map* tmap, string iter, string map)
+void t_netcore_generator::generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map)
 {
     t_field kfield(tmap->get_key_type(), iter);
     generate_serialize_field(out, &kfield, "", true);
@@ -2564,24 +2564,24 @@
     generate_serialize_field(out, &vfield, "", true);
 }
 
-void t_netcore_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter)
+void t_netcore_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter)
 {
     t_field efield(tset->get_elem_type(), iter);
     generate_serialize_field(out, &efield, "", true);
 }
 
-void t_netcore_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter)
+void t_netcore_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter)
 {
     t_field efield(tlist->get_elem_type(), iter);
     generate_serialize_field(out, &efield, "", true);
 }
 
-void t_netcore_generator::generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset)
+void t_netcore_generator::generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset)
 {
     generate_netcore_property(out, tfield, isPublic, generateIsset, "_");
 }
 
-void t_netcore_generator::generate_netcore_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset, string fieldPrefix)
+void t_netcore_generator::generate_netcore_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset, string fieldPrefix)
 {
     if ((serialize_ || wcf_) && isPublic)
     {
@@ -2866,7 +2866,7 @@
         }
         if (ttype->is_base_type() && field_has_default(tfield))
         {
-            ofstream dummy;
+            std::ofstream dummy;
             result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
         }
         else if (ttype->is_base_type())
@@ -3011,12 +3011,12 @@
     throw "INVALID TYPE IN type_to_enum: " + type->get_name();
 }
 
-void t_netcore_generator::generate_netcore_docstring_comment(ofstream& out, string contents)
+void t_netcore_generator::generate_netcore_docstring_comment(ostream& out, string contents)
 {
     docstring_comment(out, "/// <summary>" + endl, "/// ", contents, "/// </summary>" + endl);
 }
 
-void t_netcore_generator::generate_netcore_doc(ofstream& out, t_field* field)
+void t_netcore_generator::generate_netcore_doc(ostream& out, t_field* field)
 {
     if (field->get_type()->is_enum())
     {
@@ -3029,7 +3029,7 @@
     }
 }
 
-void t_netcore_generator::generate_netcore_doc(ofstream& out, t_doc* tdoc)
+void t_netcore_generator::generate_netcore_doc(ostream& out, t_doc* tdoc)
 {
     if (tdoc->has_doc())
     {
@@ -3037,7 +3037,7 @@
     }
 }
 
-void t_netcore_generator::generate_netcore_doc(ofstream& out, t_function* tfunction)
+void t_netcore_generator::generate_netcore_doc(ostream& out, t_function* tfunction)
 {
     if (tfunction->has_doc())
     {
@@ -3065,7 +3065,7 @@
     }
 }
 
-void t_netcore_generator::docstring_comment(ofstream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end)
+void t_netcore_generator::docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end)
 {
     if (comment_start != "")
     {
diff --git a/compiler/cpp/src/thrift/generate/t_netcore_generator.h b/compiler/cpp/src/thrift/generate/t_netcore_generator.h
index 8d52307..6efc922 100644
--- a/compiler/cpp/src/thrift/generate/t_netcore_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_netcore_generator.h
@@ -14,7 +14,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -47,58 +47,58 @@
     void init_generator();
     void close_generator();
     void generate_consts(vector<t_const*> consts);
-    void generate_consts(ofstream& out, vector<t_const*> consts);
+    void generate_consts(ostream& out, vector<t_const*> consts);
     void generate_typedef(t_typedef* ttypedef);
     void generate_enum(t_enum* tenum);
-    void generate_enum(ofstream& out, t_enum* tenum);
+    void generate_enum(ostream& out, t_enum* tenum);
     void generate_struct(t_struct* tstruct);
     void generate_xception(t_struct* txception);
     void generate_service(t_service* tservice);
 
-    void generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset);
-    void generate_netcore_property(ofstream& out, t_field* tfield, bool isPublic, bool includeIsset = true, string fieldPrefix = "");
-    bool print_const_value(ofstream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval = false, bool needtype = false);
-    string render_const_value(ofstream& out, string name, t_type* type, t_const_value* value);
-    void print_const_constructor(ofstream& out, vector<t_const*> consts);
-    void print_const_def_value(ofstream& out, string name, t_type* type, t_const_value* value);
+    void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
+    void generate_netcore_property(ostream& out, t_field* tfield, bool isPublic, bool includeIsset = true, string fieldPrefix = "");
+    bool print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval = false, bool needtype = false);
+    string render_const_value(ostream& out, string name, t_type* type, t_const_value* value);
+    void print_const_constructor(ostream& out, vector<t_const*> consts);
+    void print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value);
     void generate_netcore_struct(t_struct* tstruct, bool is_exception);
     void generate_netcore_union(t_struct* tunion);
-    void generate_netcore_struct_definition(ofstream& out, t_struct* tstruct, bool is_xception = false, bool in_class = false, bool is_result = false);
-    void generate_netcore_union_definition(ofstream& out, t_struct* tunion);
-    void generate_netcore_union_class(ofstream& out, t_struct* tunion, t_field* tfield);
-    void generate_netcore_wcffault(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_reader(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_result_writer(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_writer(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_tostring(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_equals(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_hashcode(ofstream& out, t_struct* tstruct);
-    void generate_netcore_union_reader(ofstream& out, t_struct* tunion);
-    void generate_function_helpers(ofstream& out, t_function* tfunction);
-    void generate_service_interface(ofstream& out, t_service* tservice);
-    void generate_service_helpers(ofstream& out, t_service* tservice);
-    void generate_service_client(ofstream& out, t_service* tservice);
-    void generate_service_server(ofstream& out, t_service* tservice);
-    void generate_process_function_async(ofstream& out, t_service* tservice, t_function* function);
-    void generate_deserialize_field(ofstream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
-    void generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
-    void generate_deserialize_container(ofstream& out, t_type* ttype, string prefix = "");
-    void generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix = "");
-    void generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix = "");
-    void generate_deserialize_list_element(ofstream& out, t_list* list, string prefix = "");
-    void generate_serialize_field(ofstream& out, t_field* tfield, string prefix = "", bool is_element = false, bool is_propertyless = false);
-    void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
-    void generate_serialize_container(ofstream& out, t_type* ttype, string prefix = "");
-    void generate_serialize_map_element(ofstream& out, t_map* tmap, string iter, string map);
-    void generate_serialize_set_element(ofstream& out, t_set* tmap, string iter);
-    void generate_serialize_list_element(ofstream& out, t_list* tlist, string iter);
-    void generate_netcore_doc(ofstream& out, t_field* field);
-    void generate_netcore_doc(ofstream& out, t_doc* tdoc);
-    void generate_netcore_doc(ofstream& out, t_function* tdoc);
-    void generate_netcore_docstring_comment(ofstream& out, string contents);
-    void docstring_comment(ofstream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end);
-    void start_netcore_namespace(ofstream& out);
-    void end_netcore_namespace(ofstream& out);
+    void generate_netcore_struct_definition(ostream& out, t_struct* tstruct, bool is_xception = false, bool in_class = false, bool is_result = false);
+    void generate_netcore_union_definition(ostream& out, t_struct* tunion);
+    void generate_netcore_union_class(ostream& out, t_struct* tunion, t_field* tfield);
+    void generate_netcore_wcffault(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_reader(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_result_writer(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_writer(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_tostring(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_equals(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_hashcode(ostream& out, t_struct* tstruct);
+    void generate_netcore_union_reader(ostream& out, t_struct* tunion);
+    void generate_function_helpers(ostream& out, t_function* tfunction);
+    void generate_service_interface(ostream& out, t_service* tservice);
+    void generate_service_helpers(ostream& out, t_service* tservice);
+    void generate_service_client(ostream& out, t_service* tservice);
+    void generate_service_server(ostream& out, t_service* tservice);
+    void generate_process_function_async(ostream& out, t_service* tservice, t_function* function);
+    void generate_deserialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
+    void generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
+    void generate_deserialize_container(ostream& out, t_type* ttype, string prefix = "");
+    void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix = "");
+    void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix = "");
+    void generate_deserialize_list_element(ostream& out, t_list* list, string prefix = "");
+    void generate_serialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_element = false, bool is_propertyless = false);
+    void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
+    void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
+    void generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map);
+    void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
+    void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
+    void generate_netcore_doc(ostream& out, t_field* field);
+    void generate_netcore_doc(ostream& out, t_doc* tdoc);
+    void generate_netcore_doc(ostream& out, t_function* tdoc);
+    void generate_netcore_docstring_comment(ostream& out, string contents);
+    void docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end);
+    void start_netcore_namespace(ostream& out);
+    void end_netcore_namespace(ostream& out);
 
     string netcore_type_usings() const;
     string netcore_thrift_usings() const;
diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
index 2bf85d1..0ec81ba 100644
--- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
@@ -32,7 +32,7 @@
 
 using std::ios;
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -90,16 +90,16 @@
    */
 
   void generate_ocaml_struct(t_struct* tstruct, bool is_exception);
-  void generate_ocaml_struct_definition(std::ofstream& out,
+  void generate_ocaml_struct_definition(std::ostream& out,
                                         t_struct* tstruct,
                                         bool is_xception = false);
-  void generate_ocaml_struct_member(std::ofstream& out, string tname, t_field* tmember);
-  void generate_ocaml_struct_sig(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_ocaml_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_ocaml_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_ocaml_struct_member(std::ostream& out, string tname, t_field* tmember);
+  void generate_ocaml_struct_sig(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_ocaml_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_ocaml_struct_writer(std::ostream& out, t_struct* tstruct);
   void generate_ocaml_function_helpers(t_function* tfunction);
-  void generate_ocaml_method_copy(std::ofstream& out, const vector<t_field*>& members);
-  void generate_ocaml_member_copy(std::ofstream& out, t_field* member);
+  void generate_ocaml_method_copy(std::ostream& out, const vector<t_field*>& members);
+  void generate_ocaml_member_copy(std::ostream& out, t_field* member);
 
   /**
    * Service-level generation functions
@@ -115,33 +115,33 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix);
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct);
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct);
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype);
+  void generate_deserialize_container(std::ostream& out, t_type* ttype);
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset);
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset);
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
-  void generate_deserialize_type(std::ofstream& out, t_type* type);
+  void generate_deserialize_type(std::ostream& out, t_type* type);
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string name = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string name = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -161,12 +161,12 @@
    * File streams
    */
 
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
 
-  std::ofstream f_types_i_;
-  std::ofstream f_service_i_;
+  ofstream_with_content_based_conditional_update f_types_i_;
+  ofstream_with_content_based_conditional_update f_service_i_;
 };
 
 /*
@@ -499,7 +499,7 @@
   generate_ocaml_struct_sig(f_types_i_, tstruct, is_exception);
 }
 
-void t_ocaml_generator::generate_ocaml_method_copy(ofstream& out, const vector<t_field*>& members) {
+void t_ocaml_generator::generate_ocaml_method_copy(ostream& out, const vector<t_field*>& members) {
   vector<t_field*>::const_iterator m_iter;
 
   /* Create a copy of the current object */
@@ -555,7 +555,7 @@
   return what;
 }
 
-void t_ocaml_generator::generate_ocaml_member_copy(ofstream& out, t_field* tmember) {
+void t_ocaml_generator::generate_ocaml_member_copy(ostream& out, t_field* tmember) {
   string mname = decapitalize(tmember->get_name());
   t_type* type = get_true_type(tmember->get_type());
 
@@ -576,7 +576,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_ocaml_generator::generate_ocaml_struct_definition(ofstream& out,
+void t_ocaml_generator::generate_ocaml_struct_definition(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -611,7 +611,7 @@
  * @param tname Name of the parent structure for the member
  * @param tmember Member definition
  */
-void t_ocaml_generator::generate_ocaml_struct_member(ofstream& out,
+void t_ocaml_generator::generate_ocaml_struct_member(ostream& out,
                                                      string tname,
                                                      t_field* tmember) {
   string x = tmp("_x");
@@ -713,7 +713,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_ocaml_generator::generate_ocaml_struct_sig(ofstream& out,
+void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -752,7 +752,7 @@
 /**
  * Generates the read method for a struct
  */
-void t_ocaml_generator::generate_ocaml_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_ocaml_generator::generate_ocaml_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
   string sname = type_name(tstruct);
@@ -812,7 +812,7 @@
   indent_down();
 }
 
-void t_ocaml_generator::generate_ocaml_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1309,7 +1309,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_ocaml_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_ocaml_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = tfield->get_type();
 
   string name = decapitalize(tfield->get_name());
@@ -1321,7 +1321,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_ocaml_generator::generate_deserialize_type(ofstream& out, t_type* type) {
+void t_ocaml_generator::generate_deserialize_type(ostream& out, t_type* type) {
   type = get_true_type(type);
 
   if (type->is_void()) {
@@ -1374,7 +1374,7 @@
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_ocaml_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct) {
+void t_ocaml_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct) {
   string prefix = "";
   t_program* program = tstruct->get_program();
   if (program != NULL && program != program_) {
@@ -1388,7 +1388,7 @@
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_ocaml_generator::generate_deserialize_container(ofstream& out, t_type* ttype) {
+void t_ocaml_generator::generate_deserialize_container(ostream& out, t_type* ttype) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -1454,7 +1454,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_ocaml_generator::generate_serialize_field(ofstream& out, t_field* tfield, string name) {
+void t_ocaml_generator::generate_serialize_field(ostream& out, t_field* tfield, string name) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -1523,12 +1523,12 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_ocaml_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_ocaml_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << "#write(oprot)";
 }
 
-void t_ocaml_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_ocaml_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     indent(out) << "oprot#writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ",";
     out << type_to_enum(((t_map*)ttype)->get_val_type()) << ",";
@@ -1579,7 +1579,7 @@
  * Serializes the members of a map.
  *
  */
-void t_ocaml_generator::generate_serialize_map_element(ofstream& out,
+void t_ocaml_generator::generate_serialize_map_element(ostream& out,
                                                        t_map* tmap,
                                                        string kiter,
                                                        string viter) {
@@ -1593,7 +1593,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_ocaml_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_ocaml_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
@@ -1601,7 +1601,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_ocaml_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_ocaml_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
diff --git a/compiler/cpp/src/thrift/generate/t_oop_generator.h b/compiler/cpp/src/thrift/generate/t_oop_generator.h
index 8fb580d..f8da547 100644
--- a/compiler/cpp/src/thrift/generate/t_oop_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_oop_generator.h
@@ -65,11 +65,11 @@
     return package + type->get_name();
   }
 
-  virtual void generate_java_docstring_comment(std::ofstream& out, std::string contents) {
+  virtual void generate_java_docstring_comment(std::ostream& out, std::string contents) {
     generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
   }
 
-  virtual void generate_java_doc(std::ofstream& out, t_field* field) {
+  virtual void generate_java_doc(std::ostream& out, t_field* field) {
     if (field->get_type()->is_enum()) {
       std::string combined_message = field->get_doc() + "\n@see "
                                      + get_enum_class_name(field->get_type());
@@ -82,7 +82,7 @@
   /**
    * Emits a JavaDoc comment if the provided object has a doc in Thrift
    */
-  virtual void generate_java_doc(std::ofstream& out, t_doc* tdoc) {
+  virtual void generate_java_doc(std::ostream& out, t_doc* tdoc) {
     if (tdoc->has_doc()) {
       generate_java_docstring_comment(out, tdoc->get_doc());
     }
@@ -91,7 +91,7 @@
   /**
    * Emits a JavaDoc comment if the provided function object has a doc in Thrift
    */
-  virtual void generate_java_doc(std::ofstream& out, t_function* tfunction) {
+  virtual void generate_java_doc(std::ostream& out, t_function* tfunction) {
     if (tfunction->has_doc()) {
       std::stringstream ss;
       ss << tfunction->get_doc();
diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
index 76d343e..5a308cf 100644
--- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -87,11 +87,11 @@
    */
 
   void generate_perl_struct(t_struct* tstruct, bool is_exception);
-  void generate_perl_struct_definition(std::ofstream& out,
+  void generate_perl_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false);
-  void generate_perl_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_perl_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_perl_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_perl_struct_writer(std::ostream& out, t_struct* tstruct);
   void generate_perl_function_helpers(t_function* tfunction);
 
   /**
@@ -110,37 +110,37 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool inclass = false);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -208,10 +208,10 @@
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_helpers_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_helpers_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   bool f_types_use_includes_emitted_;
 };
@@ -453,7 +453,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_perl_generator::generate_perl_struct_definition(ofstream& out,
+void t_perl_generator::generate_perl_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -531,7 +531,7 @@
 /**
  * Generates the read() method for a struct
  */
-void t_perl_generator::generate_perl_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -601,7 +601,7 @@
 /**
  * Generates the write() method for a struct
  */
-void t_perl_generator::generate_perl_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_perl_generator::generate_perl_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1183,7 +1183,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_perl_generator::generate_deserialize_field(ofstream& out,
+void t_perl_generator::generate_deserialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool inclass) {
@@ -1256,7 +1256,7 @@
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_perl_generator::generate_deserialize_struct(ofstream& out,
+void t_perl_generator::generate_deserialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   out << indent() << "$" << prefix << " = " << perl_namespace(tstruct->get_program())
@@ -1264,7 +1264,7 @@
       << "->read($input);" << endl;
 }
 
-void t_perl_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string size = tmp("_size");
@@ -1332,7 +1332,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_perl_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_perl_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("key");
   string val = tmp("val");
   t_field fkey(tmap->get_key_type(), key);
@@ -1347,7 +1347,7 @@
   indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << endl;
 }
 
-void t_perl_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_perl_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -1358,7 +1358,7 @@
   indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << endl;
 }
 
-void t_perl_generator::generate_deserialize_list_element(ofstream& out,
+void t_perl_generator::generate_deserialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string prefix) {
   string elem = tmp("elem");
@@ -1377,7 +1377,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_perl_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -1448,7 +1448,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_perl_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_perl_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << "$xfer += $" << prefix << "->write($output);" << endl;
 }
@@ -1456,7 +1456,7 @@
 /**
  * Writes out a container
  */
-void t_perl_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -1520,7 +1520,7 @@
  * Serializes the members of a map.
  *
  */
-void t_perl_generator::generate_serialize_map_element(ofstream& out,
+void t_perl_generator::generate_serialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       string kiter,
                                                       string viter) {
@@ -1534,7 +1534,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_perl_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_perl_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
@@ -1542,7 +1542,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_perl_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_perl_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc
index 6ab6bf8..50a4415 100644
--- a/compiler/cpp/src/thrift/generate/t_php_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc
@@ -29,7 +29,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -130,26 +130,26 @@
    */
 
   void generate_php_struct(t_struct* tstruct, bool is_exception);
-  void generate_php_struct_definition(std::ofstream& out,
+  void generate_php_struct_definition(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_xception = false,
                                       bool is_result = false);
-  void generate_php_struct_reader(std::ofstream& out, t_struct* tstruct, bool is_result);
-  void generate_php_struct_writer(std::ofstream& out, t_struct* tstruct, bool is_result);
+  void generate_php_struct_reader(std::ostream& out, t_struct* tstruct, bool is_result);
+  void generate_php_struct_writer(std::ostream& out, t_struct* tstruct, bool is_result);
   void generate_php_function_helpers(t_service* tservice, t_function* tfunction);
-  void generate_php_struct_required_validator(ofstream& out,
+  void generate_php_struct_required_validator(ostream& out,
                                               t_struct* tstruct,
                                               std::string method_name,
                                               bool write_mode);
-  void generate_php_struct_read_validator(ofstream& out, t_struct* tstruct);
-  void generate_php_struct_write_validator(ofstream& out, t_struct* tstruct);
-  void generate_php_struct_json_serialize(ofstream& out, t_struct* tstruct, bool is_result);
+  void generate_php_struct_read_validator(ostream& out, t_struct* tstruct);
+  void generate_php_struct_write_validator(ostream& out, t_struct* tstruct);
+  void generate_php_struct_json_serialize(ostream& out, t_struct* tstruct, bool is_result);
   bool needs_php_write_validator(t_struct* tstruct, bool is_result);
   bool needs_php_read_validator(t_struct* tstruct, bool is_result);
   int get_php_num_required_fields(const vector<t_field*>& fields, bool write_mode);
 
-  void generate_php_type_spec(std::ofstream& out, t_type* t);
-  void generate_php_struct_spec(std::ofstream& out, t_struct* tstruct);
+  void generate_php_type_spec(std::ostream& out, t_type* t);
+  void generate_php_struct_spec(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -160,53 +160,53 @@
   void generate_service_rest(t_service* tservice);
   void generate_service_client(t_service* tservice);
   void generate_service_processor(t_service* tservice);
-  void generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction);
-  void generate_service_header(t_service* tservice, std::ofstream& file);
-  void generate_program_header(std::ofstream& file);
+  void generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction);
+  void generate_service_header(t_service* tservice, std::ostream& file);
+  void generate_program_header(std::ostream& file);
 
   /**
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool inclass = false);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_php_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_php_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_php_doc(std::ofstream& out, t_field* tfield);
+  void generate_php_doc(std::ostream& out, t_field* tfield);
 
-  void generate_php_doc(std::ofstream& out, t_function* tfunction);
+  void generate_php_doc(std::ostream& out, t_function* tfunction);
 
-  void generate_php_docstring_comment(std::ofstream& out, string contents);
+  void generate_php_docstring_comment(std::ostream& out, string contents);
 
   /**
    * Helper rendering functions
@@ -357,8 +357,8 @@
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   std::string package_dir_;
   /**
@@ -477,7 +477,7 @@
 /**
  * Generates service header contains namespace suffix and includes inside file specified
  */
-void t_php_generator::generate_service_header(t_service* tservice, std::ofstream& file) {
+void t_php_generator::generate_service_header(t_service* tservice, std::ostream& file) {
   file << "<?php" << endl;
   if (!php_namespace_suffix(tservice->get_program()).empty()) {
     file << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl
@@ -491,7 +491,7 @@
 /**
  * Generates program header contains namespace suffix and includes inside file specified
  */
-void t_php_generator::generate_program_header(std::ofstream& file) {
+void t_php_generator::generate_program_header(std::ostream& file) {
   file << "<?php" << endl;
   if (!php_namespace_suffix(get_program()).empty()) {
     file << "namespace " << php_namespace_suffix(get_program()) << ";" << endl
@@ -509,7 +509,7 @@
  * @param tenum The enumeration
  */
 void t_php_generator::generate_enum(t_enum* tenum) {
-  std::ofstream& f_enum = f_types_;
+  ofstream_with_content_based_conditional_update& f_enum = f_types_;
   if (!classmap_) {
     string f_enum_name = package_dir_ + tenum->get_name() + ".php";
     f_enum.open(f_enum_name.c_str());
@@ -563,7 +563,7 @@
   // Create class only if needed
   if (consts.size() > 0) {
 
-    std::ofstream& f_consts = f_types_;
+    ofstream_with_content_based_conditional_update& f_consts = f_types_;
     if (!classmap_) {
       string f_consts_name = package_dir_ + "Constant.php";
       f_consts.open(f_consts_name.c_str());
@@ -730,7 +730,7 @@
  * Structs can be normal or exceptions.
  */
 void t_php_generator::generate_php_struct(t_struct* tstruct, bool is_exception) {
-  std::ofstream& f_struct = f_types_;
+  ofstream_with_content_based_conditional_update& f_struct = f_types_;
   if (!classmap_) {
     string f_struct_name = package_dir_ + tstruct->get_name() + ".php";
     f_struct.open(f_struct_name.c_str());
@@ -742,7 +742,7 @@
   }
 }
 
-void t_php_generator::generate_php_type_spec(ofstream& out, t_type* t) {
+void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) {
   t = get_true_type(t);
   indent(out) << "'type' => " << type_to_enum(t) << "," << endl;
 
@@ -788,7 +788,7 @@
  * Generates the struct specification structure, which fully qualifies enough
  * type information to generalize serialization routines.
  */
-void t_php_generator::generate_php_struct_spec(ofstream& out, t_struct* tstruct) {
+void t_php_generator::generate_php_struct_spec(ostream& out, t_struct* tstruct) {
   indent(out) << "static public $_TSPEC = array(" << endl;
   indent_up();
 
@@ -816,7 +816,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_php_generator::generate_php_struct_definition(ofstream& out,
+void t_php_generator::generate_php_struct_definition(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception,
                                                      bool is_result) {
@@ -924,7 +924,7 @@
 /**
  * Generates the read() method for a struct
  */
-void t_php_generator::generate_php_struct_reader(ofstream& out, t_struct* tstruct, bool is_result) {
+void t_php_generator::generate_php_struct_reader(ostream& out, t_struct* tstruct, bool is_result) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1044,7 +1044,7 @@
 /**
  * Generates the write() method for a struct
  */
-void t_php_generator::generate_php_struct_writer(ofstream& out, t_struct* tstruct, bool is_result) {
+void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct, bool is_result) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1132,15 +1132,15 @@
   out << indent() << "}" << endl;
 }
 
-void t_php_generator::generate_php_struct_read_validator(ofstream& out, t_struct* tstruct) {
+void t_php_generator::generate_php_struct_read_validator(ostream& out, t_struct* tstruct) {
   generate_php_struct_required_validator(out, tstruct, "_validateForRead", false);
 }
 
-void t_php_generator::generate_php_struct_write_validator(ofstream& out, t_struct* tstruct) {
+void t_php_generator::generate_php_struct_write_validator(ostream& out, t_struct* tstruct) {
   generate_php_struct_required_validator(out, tstruct, "_validateForWrite", true);
 }
 
-void t_php_generator::generate_php_struct_required_validator(ofstream& out,
+void t_php_generator::generate_php_struct_required_validator(ostream& out,
                                                              t_struct* tstruct,
                                                              std::string method_name,
                                                              bool write_mode) {
@@ -1170,7 +1170,7 @@
   indent(out) << "}" << endl;
 }
 
-void t_php_generator::generate_php_struct_json_serialize(ofstream& out,
+void t_php_generator::generate_php_struct_json_serialize(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_result) {
   indent(out) << "public function jsonSerialize() {" << endl;
@@ -1280,7 +1280,7 @@
  * @param tservice The service to generate a server for.
  */
 void t_php_generator::generate_service_processor(t_service* tservice) {
-  std::ofstream& f_service_processor = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_processor = f_service_;
   if (!classmap_) {
     string f_service_processor_name = package_dir_ + service_name_ + "Processor.php";
     f_service_processor.open(f_service_processor_name.c_str());
@@ -1386,7 +1386,7 @@
  *
  * @param tfunction The function to write a dispatcher for
  */
-void t_php_generator::generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction) {
+void t_php_generator::generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction) {
   // Open function
   out << indent() << "protected function process_" << tfunction->get_name() << "($seqid, $input, $output)" << endl
       << indent() << "{" << endl;
@@ -1544,7 +1544,7 @@
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
 
-  std::ofstream& f_struct_definition = f_service_;
+  ofstream_with_content_based_conditional_update& f_struct_definition = f_service_;
   if (classmap_) {
     f_struct_definition << "// HELPER FUNCTIONS AND STRUCTURES" << endl << endl;
   }
@@ -1590,7 +1590,7 @@
       result.append(*f_iter);
     }
 
-    std::ofstream& f_struct_helper = f_service_;
+    ofstream_with_content_based_conditional_update& f_struct_helper = f_service_;
     if (!classmap_) {
       string f_struct_helper_name = package_dir_ + result.get_name() + ".php";
       f_struct_helper.open(f_struct_helper_name.c_str());
@@ -1609,7 +1609,7 @@
  * @param tservice The service to generate a header definition for
  */
 void t_php_generator::generate_service_interface(t_service* tservice) {
-  std::ofstream& f_service_interface = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_interface = f_service_;
   if (!classmap_) {
     string f_service_interface_name = package_dir_ + service_name_ + "If.php";
     f_service_interface.open(f_service_interface_name.c_str());
@@ -1648,7 +1648,7 @@
  * Generates a REST interface
  */
 void t_php_generator::generate_service_rest(t_service* tservice) {
-  std::ofstream& f_service_rest = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_rest = f_service_;
   if (!classmap_) {
     string f_service_rest_name = package_dir_ + service_name_ + "Rest.php";
     f_service_rest.open(f_service_rest_name.c_str());
@@ -1729,7 +1729,7 @@
  * @param tservice The service to generate a server for.
  */
 void t_php_generator::generate_service_client(t_service* tservice) {
-  std::ofstream& f_service_client = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_client = f_service_;
   if (!classmap_) {
     string f_service_client_name = package_dir_ + service_name_ + "Client.php";
     f_service_client.open(f_service_client_name.c_str());
@@ -1993,7 +1993,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_php_generator::generate_deserialize_field(ofstream& out,
+void t_php_generator::generate_deserialize_field(ostream& out,
                                                  t_field* tfield,
                                                  string prefix,
                                                  bool inclass) {
@@ -2125,13 +2125,13 @@
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_php_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_php_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << indent() << "$" << prefix << " = new " << php_namespace(tstruct->get_program())
       << tstruct->get_name() << "();" << endl << indent() << "$xfer += $" << prefix
       << "->read($input);" << endl;
 }
 
-void t_php_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -2208,7 +2208,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_php_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_php_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("key");
   string val = tmp("val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2223,7 +2223,7 @@
   indent(out) << "$" << prefix << "[$" << key << "] = $" << val << ";" << endl;
 }
 
-void t_php_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_php_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2239,7 +2239,7 @@
   }
 }
 
-void t_php_generator::generate_deserialize_list_element(ofstream& out,
+void t_php_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   string elem = tmp("elem");
@@ -2258,7 +2258,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_php_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2363,7 +2363,7 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_php_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_php_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << "$xfer += $" << prefix << "->write($output);" << endl;
 }
@@ -2371,7 +2371,7 @@
 /**
  * Writes out a container
  */
-void t_php_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     if (binary_inline_) {
       out << indent() << "$output .= pack('c', " << type_to_enum(((t_map*)ttype)->get_key_type())
@@ -2451,7 +2451,7 @@
  * Serializes the members of a map.
  *
  */
-void t_php_generator::generate_serialize_map_element(ofstream& out,
+void t_php_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string kiter,
                                                      string viter) {
@@ -2465,7 +2465,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_php_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_php_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2473,7 +2473,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_php_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_php_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2481,14 +2481,14 @@
 /**
  * Emits a PHPDoc comment for the given contents
  */
-void t_php_generator::generate_php_docstring_comment(ofstream& out, string contents) {
+void t_php_generator::generate_php_docstring_comment(ostream& out, string contents) {
   generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
 }
 
 /**
  * Emits a PHPDoc comment if the provided object has a doc in Thrift
  */
-void t_php_generator::generate_php_doc(ofstream& out, t_doc* tdoc) {
+void t_php_generator::generate_php_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_php_docstring_comment(out, tdoc->get_doc());
   }
@@ -2497,7 +2497,7 @@
 /**
  * Emits a PHPDoc comment for a field
  */
-void t_php_generator::generate_php_doc(ofstream& out, t_field* field) {
+void t_php_generator::generate_php_doc(ostream& out, t_field* field) {
   stringstream ss;
 
   // prepend free-style doc if available
@@ -2515,7 +2515,7 @@
 /**
  * Emits a PHPDoc comment for a function
  */
-void t_php_generator::generate_php_doc(ofstream& out, t_function* function) {
+void t_php_generator::generate_php_doc(ostream& out, t_function* function) {
   stringstream ss;
   if (function->has_doc()) {
     ss << function->get_doc() << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index f8692bb..fba9f9d 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -34,7 +34,7 @@
 #include "thrift/generate/t_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -167,13 +167,13 @@
    */
 
   void generate_py_struct(t_struct* tstruct, bool is_exception);
-  void generate_py_thrift_spec(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_py_struct_definition(std::ofstream& out,
+  void generate_py_thrift_spec(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_py_struct_definition(std::ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false);
-  void generate_py_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_py_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_py_struct_required_validator(std::ofstream& out, t_struct* tstruct);
+  void generate_py_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_py_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_py_struct_required_validator(std::ostream& out, t_struct* tstruct);
   void generate_py_function_helpers(t_function* tfunction);
 
   /**
@@ -191,47 +191,47 @@
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_python_docstring(std::ofstream& out, t_struct* tstruct);
+  void generate_python_docstring(std::ostream& out, t_struct* tstruct);
 
-  void generate_python_docstring(std::ofstream& out, t_function* tfunction);
+  void generate_python_docstring(std::ostream& out, t_function* tfunction);
 
-  void generate_python_docstring(std::ofstream& out,
+  void generate_python_docstring(std::ostream& out,
                                  t_doc* tdoc,
                                  t_struct* tstruct,
                                  const char* subheader);
 
-  void generate_python_docstring(std::ofstream& out, t_doc* tdoc);
+  void generate_python_docstring(std::ostream& out, t_doc* tdoc);
 
   /**
    * Helper rendering functions
@@ -328,9 +328,9 @@
    * File streams
    */
 
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   std::string package_dir_;
   std::string module_;
@@ -375,7 +375,7 @@
   f_consts_.open(f_consts_name.c_str());
 
   string f_init_name = package_dir_ + "/__init__.py";
-  ofstream f_init;
+  ofstream_with_content_based_conditional_update f_init;
   f_init.open(f_init_name.c_str());
   f_init << "__all__ = ['ttypes', 'constants'";
   vector<t_service*> services = program_->get_services();
@@ -678,7 +678,7 @@
  *       (1, TType.LIST, 'Children', (TType.STRUCT, (Recursive, None), False), None, ),  # 1
  *   )
  */
-void t_py_generator::generate_py_thrift_spec(ofstream& out,
+void t_py_generator::generate_py_thrift_spec(ostream& out,
                                              t_struct* tstruct,
                                              bool /*is_exception*/) {
   const vector<t_field*>& sorted_members = tstruct->get_sorted_members();
@@ -721,7 +721,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_py_generator::generate_py_struct_definition(ofstream& out,
+void t_py_generator::generate_py_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -920,7 +920,7 @@
 /**
  * Generates the read method for a struct
  */
-void t_py_generator::generate_py_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1025,7 +1025,7 @@
   out << endl;
 }
 
-void t_py_generator::generate_py_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_py_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1071,7 +1071,7 @@
   generate_py_struct_required_validator(out, tstruct);
 }
 
-void t_py_generator::generate_py_struct_required_validator(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_py_struct_required_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "def validate(self):" << endl;
   indent_up();
 
@@ -1584,7 +1584,7 @@
   vector<t_function*>::iterator f_iter;
 
   string f_remote_name = package_dir_ + "/" + service_name_ + "-remote";
-  ofstream f_remote;
+  ofstream_with_content_based_conditional_update f_remote;
   f_remote.open(f_remote_name.c_str());
 
   f_remote <<
@@ -2157,7 +2157,7 @@
 /**
  * Deserializes a field of any type.
  */
-void t_py_generator::generate_deserialize_field(ofstream& out,
+void t_py_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix) {
   t_type* type = get_true_type(tfield->get_type());
@@ -2225,7 +2225,7 @@
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_py_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_py_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   if (is_immutable(tstruct)) {
     out << indent() << prefix << " = " << type_name(tstruct) << ".read(iprot)" << endl;
   } else {
@@ -2238,7 +2238,7 @@
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_py_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_py_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -2300,7 +2300,7 @@
 /**
  * Generates code to deserialize a map
  */
-void t_py_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_py_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2315,7 +2315,7 @@
 /**
  * Write a set element
  */
-void t_py_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_py_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2327,7 +2327,7 @@
 /**
  * Write a list element
  */
-void t_py_generator::generate_deserialize_list_element(ofstream& out,
+void t_py_generator::generate_deserialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        string prefix) {
   string elem = tmp("_elem");
@@ -2344,7 +2344,7 @@
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_py_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2416,12 +2416,12 @@
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_py_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_py_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ".write(oprot)" << endl;
 }
 
-void t_py_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_py_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     indent(out) << "oprot.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
                 << type_to_enum(((t_map*)ttype)->get_val_type()) << ", "
@@ -2469,7 +2469,7 @@
  * Serializes the members of a map.
  *
  */
-void t_py_generator::generate_serialize_map_element(ofstream& out,
+void t_py_generator::generate_serialize_map_element(ostream& out,
                                                     t_map* tmap,
                                                     string kiter,
                                                     string viter) {
@@ -2483,7 +2483,7 @@
 /**
  * Serializes the members of a set.
  */
-void t_py_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_py_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2491,7 +2491,7 @@
 /**
  * Serializes the members of a list.
  */
-void t_py_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_py_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2499,21 +2499,21 @@
 /**
  * Generates the docstring for a given struct.
  */
-void t_py_generator::generate_python_docstring(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_python_docstring(ostream& out, t_struct* tstruct) {
   generate_python_docstring(out, tstruct, tstruct, "Attributes");
 }
 
 /**
  * Generates the docstring for a given function.
  */
-void t_py_generator::generate_python_docstring(ofstream& out, t_function* tfunction) {
+void t_py_generator::generate_python_docstring(ostream& out, t_function* tfunction) {
   generate_python_docstring(out, tfunction, tfunction->get_arglist(), "Parameters");
 }
 
 /**
  * Generates the docstring for a struct or function.
  */
-void t_py_generator::generate_python_docstring(ofstream& out,
+void t_py_generator::generate_python_docstring(ostream& out,
                                                t_doc* tdoc,
                                                t_struct* tstruct,
                                                const char* subheader) {
@@ -2551,7 +2551,7 @@
 /**
  * Generates the docstring for a generic object.
  */
-void t_py_generator::generate_python_docstring(ofstream& out, t_doc* tdoc) {
+void t_py_generator::generate_python_docstring(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "\"\"\"\n", "", tdoc->get_doc(), "\"\"\"\n");
   }
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index 6001d8f..df75d07 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -100,7 +100,7 @@
   string gen_dir_;
 
   // File to which generated code is written.
-  std::ofstream f_gen_;
+  ofstream_with_content_based_conditional_update f_gen_;
 
   // Write the common compiler attributes and module includes to the top of the auto-generated file.
   void render_attributes_and_includes();
diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc
index c45666a..595a949 100644
--- a/compiler/cpp/src/thrift/generate/t_st_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc
@@ -93,8 +93,8 @@
    * Struct generation code
    */
 
-  void generate_st_struct(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_accessors(std::ofstream& out, t_struct* tstruct);
+  void generate_st_struct(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_accessors(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -124,15 +124,15 @@
 
   std::string st_autogen_comment();
 
-  void st_class_def(std::ofstream& out, std::string name);
-  void st_method(std::ofstream& out, std::string cls, std::string name);
-  void st_method(std::ofstream& out, std::string cls, std::string name, std::string category);
-  void st_close_method(std::ofstream& out);
-  void st_class_method(std::ofstream& out, std::string cls, std::string name);
-  void st_class_method(std::ofstream& out, std::string cls, std::string name, std::string category);
-  void st_setter(std::ofstream& out, std::string cls, std::string name, std::string type);
-  void st_getter(std::ofstream& out, std::string cls, std::string name);
-  void st_accessors(std::ofstream& out, std::string cls, std::string name, std::string type);
+  void st_class_def(std::ostream& out, std::string name);
+  void st_method(std::ostream& out, std::string cls, std::string name);
+  void st_method(std::ostream& out, std::string cls, std::string name, std::string category);
+  void st_close_method(std::ostream& out);
+  void st_class_method(std::ostream& out, std::string cls, std::string name);
+  void st_class_method(std::ostream& out, std::string cls, std::string name, std::string category);
+  void st_setter(std::ostream& out, std::string cls, std::string name, std::string type);
+  void st_getter(std::ostream& out, std::string cls, std::string name);
+  void st_accessors(std::ostream& out, std::string cls, std::string name, std::string type);
 
   std::string class_name();
   static bool is_valid_namespace(const std::string& sub_namespace);
@@ -156,7 +156,7 @@
    * File streams
    */
   int temporary_var;
-  std::ofstream f_;
+  ofstream_with_content_based_conditional_update f_;
 };
 
 /**
@@ -250,7 +250,7 @@
   (void)ttypedef;
 }
 
-void t_st_generator::st_class_def(std::ofstream& out, string name) {
+void t_st_generator::st_class_def(std::ostream& out, string name) {
   out << "Object subclass: #" << prefix(name) << endl;
   indent_up();
   out << indent() << "instanceVariableNames: ''" << endl << indent() << "classVariableNames: ''"
@@ -258,19 +258,19 @@
       << generated_category() << "'!" << endl << endl;
 }
 
-void t_st_generator::st_method(std::ofstream& out, string cls, string name) {
+void t_st_generator::st_method(std::ostream& out, string cls, string name) {
   st_method(out, cls, name, "as yet uncategorized");
 }
 
-void t_st_generator::st_class_method(std::ofstream& out, string cls, string name) {
+void t_st_generator::st_class_method(std::ostream& out, string cls, string name) {
   st_method(out, cls + " class", name);
 }
 
-void t_st_generator::st_class_method(std::ofstream& out, string cls, string name, string category) {
+void t_st_generator::st_class_method(std::ostream& out, string cls, string name, string category) {
   st_method(out, cls, name, category);
 }
 
-void t_st_generator::st_method(std::ofstream& out, string cls, string name, string category) {
+void t_st_generator::st_method(std::ostream& out, string cls, string name, string category) {
   char timestr[50];
   time_t rawtime;
   struct tm* tinfo;
@@ -286,12 +286,12 @@
   out << indent();
 }
 
-void t_st_generator::st_close_method(std::ofstream& out) {
+void t_st_generator::st_close_method(std::ostream& out) {
   out << "! !" << endl << endl;
   indent_down();
 }
 
-void t_st_generator::st_setter(std::ofstream& out,
+void t_st_generator::st_setter(std::ostream& out,
                                string cls,
                                string name,
                                string type = "anObject") {
@@ -300,13 +300,13 @@
   st_close_method(out);
 }
 
-void t_st_generator::st_getter(std::ofstream& out, string cls, string name) {
+void t_st_generator::st_getter(std::ostream& out, string cls, string name) {
   st_method(out, cls, name + "");
   out << "^ " << name;
   st_close_method(out);
 }
 
-void t_st_generator::st_accessors(std::ofstream& out,
+void t_st_generator::st_accessors(std::ostream& out,
                                   string cls,
                                   string name,
                                   string type = "anObject") {
@@ -490,7 +490,7 @@
 /**
  * Generates a smalltalk class to represent a struct
  */
-void t_st_generator::generate_st_struct(std::ofstream& out,
+void t_st_generator::generate_st_struct(std::ostream& out,
                                         t_struct* tstruct,
                                         bool is_exception = false) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -542,7 +542,7 @@
   return prefix + capitalize(type_name(type));
 }
 
-void t_st_generator::generate_accessors(std::ofstream& out, t_struct* tstruct) {
+void t_st_generator::generate_accessors(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
   string type;
diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
index b6bf7e4..a1d3211 100644
--- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
@@ -31,7 +31,6 @@
 
 using std::map;
 using std::ostream;
-using std::ofstream;
 using std::ostringstream;
 using std::set;
 using std::string;
@@ -115,34 +114,34 @@
                           t_type* type,
                           t_const_value* value);
 
-  void generate_swift_struct(ofstream& out,
+  void generate_swift_struct(ostream& out,
                              t_struct* tstruct,
                              bool is_private);
 
-  void generate_swift_struct_init(ofstream& out,
+  void generate_swift_struct_init(ostream& out,
                                   t_struct* tstruct,
                                   bool all,
                                   bool is_private);
 
-  void generate_swift_struct_implementation(ofstream& out,
+  void generate_swift_struct_implementation(ostream& out,
                                             t_struct* tstruct,
                                             bool is_result,
                                             bool is_private);
-  void generate_swift_struct_hashable_extension(ofstream& out,
+  void generate_swift_struct_hashable_extension(ostream& out,
                                                 t_struct* tstruct,
                                                 bool is_private);
-  void generate_swift_struct_equatable_extension(ofstream& out,
+  void generate_swift_struct_equatable_extension(ostream& out,
                                                  t_struct* tstruct,
                                                  bool is_private);
-  void generate_swift_struct_thrift_extension(ofstream& out,
+  void generate_swift_struct_thrift_extension(ostream& out,
                                               t_struct* tstruct,
                                               bool is_result,
                                               bool is_private);
-  void generate_swift_struct_reader(ofstream& out, t_struct* tstruct, bool is_private);
+  void generate_swift_struct_reader(ostream& out, t_struct* tstruct, bool is_private);
 
 
-  void generate_swift_struct_printable_extension(ofstream& out, t_struct* tstruct);
-  void generate_swift_union_reader(ofstream& out, t_struct* tstruct);
+  void generate_swift_struct_printable_extension(ostream& out, t_struct* tstruct);
+  void generate_swift_union_reader(ostream& out, t_struct* tstruct);
 
   string function_result_helper_struct_type(t_service *tservice, t_function* tfunction);
   string function_args_helper_struct_type(t_service* tservice, t_function* tfunction);
@@ -152,28 +151,28 @@
    * Service-level generation functions
    */
 
-  void generate_swift_service_protocol(ofstream& out, t_service* tservice);
-  void generate_swift_service_protocol_async(ofstream& out, t_service* tservice);
+  void generate_swift_service_protocol(ostream& out, t_service* tservice);
+  void generate_swift_service_protocol_async(ostream& out, t_service* tservice);
 
-  void generate_swift_service_client(ofstream& out, t_service* tservice);
-  void generate_swift_service_client_async(ofstream& out, t_service* tservice);
+  void generate_swift_service_client(ostream& out, t_service* tservice);
+  void generate_swift_service_client_async(ostream& out, t_service* tservice);
 
-  void generate_swift_service_client_send_function_implementation(ofstream& out,
+  void generate_swift_service_client_send_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_swift_service_client_send_function_invocation(ofstream& out, t_function* tfunction);
-  void generate_swift_service_client_send_async_function_invocation(ofstream& out,
+  void generate_swift_service_client_send_function_invocation(ostream& out, t_function* tfunction);
+  void generate_swift_service_client_send_async_function_invocation(ostream& out,
                                                                     t_function* tfunction);
-  void generate_swift_service_client_recv_function_implementation(ofstream& out,
+  void generate_swift_service_client_recv_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_swift_service_client_implementation(ofstream& out, t_service* tservice);
-  void generate_swift_service_client_async_implementation(ofstream& out, t_service* tservice);
+  void generate_swift_service_client_implementation(ostream& out, t_service* tservice);
+  void generate_swift_service_client_async_implementation(ostream& out, t_service* tservice);
 
-  void generate_swift_service_server(ofstream& out, t_service* tservice);
-  void generate_swift_service_server_implementation(ofstream& out, t_service* tservice);
+  void generate_swift_service_server(ostream& out, t_service* tservice);
+  void generate_swift_service_server_implementation(ostream& out, t_service* tservice);
   void generate_swift_service_helpers(t_service* tservice);
 
   /**
@@ -196,22 +195,22 @@
   /** Swift 3 specific */
   string enum_case_name(t_enum_value* tenum_case, bool declaration);
   string enum_const_name(string enum_identifier);
-  void function_docstring(ofstream& out, t_function* tfunction);
-  void async_function_docstring(ofstream& out, t_function* tfunction);
-  void generate_docstring(ofstream& out, string& doc);
+  void function_docstring(ostream& out, t_function* tfunction);
+  void async_function_docstring(ostream& out, t_function* tfunction);
+  void generate_docstring(ostream& out, string& doc);
 
   /** Swift 2/Cocoa carryover */
   string promise_function_signature(t_function* tfunction);
   string function_name(t_function* tfunction);
-  void generate_old_swift_struct_writer(ofstream& out,t_struct* tstruct, bool is_private);
-  void generate_old_swift_struct_result_writer(ofstream& out, t_struct* tstruct);
+  void generate_old_swift_struct_writer(ostream& out,t_struct* tstruct, bool is_private);
+  void generate_old_swift_struct_result_writer(ostream& out, t_struct* tstruct);
 
   /** Swift 2/Cocoa backwards compatibility*/
   void generate_old_enum(t_enum* tenum);
-  void generate_old_swift_struct(ofstream& out,
+  void generate_old_swift_struct(ostream& out,
                                  t_struct* tstruct,
                                  bool is_private);
-  void generate_old_swift_service_client_async_implementation(ofstream& out,
+  void generate_old_swift_service_client_async_implementation(ostream& out,
                                                               t_service* tservice);
 
   static std::string get_real_swift_module(const t_program* program) {
@@ -273,8 +272,8 @@
    * File streams
    */
 
-  ofstream f_decl_;
-  ofstream f_impl_;
+  ofstream_with_content_based_conditional_update f_decl_;
+  ofstream_with_content_based_conditional_update f_impl_;
 
   bool log_unexpected_;
   bool async_clients_;
@@ -621,7 +620,7 @@
   generate_swift_struct_implementation(f_impl_, txception, false, false);
 }
 
-void t_swift_generator::generate_docstring(ofstream& out, string& doc) {
+void t_swift_generator::generate_docstring(ostream& out, string& doc) {
   if (doc != "") {
     std::vector<std::string> strings;
 
@@ -657,7 +656,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct(ofstream& out,
+void t_swift_generator::generate_swift_struct(ostream& out,
                                               t_struct* tstruct,
                                               bool is_private) {
 
@@ -735,7 +734,7 @@
  */
 
 
-void t_swift_generator::generate_old_swift_struct(ofstream& out,
+void t_swift_generator::generate_old_swift_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_private) {
   string visibility = is_private ? "private" : "public";
@@ -787,7 +786,7 @@
  * @param is_private
  *                Is the initializer public or private
  */
-void t_swift_generator::generate_swift_struct_init(ofstream& out,
+void t_swift_generator::generate_swift_struct_init(ostream& out,
                                                    t_struct* tstruct,
                                                    bool all,
                                                    bool is_private) {
@@ -846,7 +845,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_hashable_extension(ofstream& out,
+void t_swift_generator::generate_swift_struct_hashable_extension(ostream& out,
                                                                  t_struct* tstruct,
                                                                  bool is_private) {
 
@@ -898,7 +897,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_equatable_extension(ofstream& out,
+void t_swift_generator::generate_swift_struct_equatable_extension(ostream& out,
                                                                   t_struct* tstruct,
                                                                   bool is_private) {
 
@@ -960,7 +959,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_implementation(ofstream& out,
+void t_swift_generator::generate_swift_struct_implementation(ostream& out,
                                                              t_struct* tstruct,
                                                              bool is_result,
                                                              bool is_private) {
@@ -986,7 +985,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_thrift_extension(ofstream& out,
+void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out,
                                                                t_struct* tstruct,
                                                                bool is_result,
                                                                bool is_private) {
@@ -1042,7 +1041,7 @@
   out << endl;
 }
 
-void t_swift_generator::generate_swift_union_reader(ofstream& out, t_struct* tstruct) {
+void t_swift_generator::generate_swift_union_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "public static func read(from proto: TProtocol) throws -> "
               << tstruct->get_name();
   block_open(out);
@@ -1128,7 +1127,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_reader(ofstream& out,
+void t_swift_generator::generate_swift_struct_reader(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_private) {
 
@@ -1335,7 +1334,7 @@
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_old_swift_struct_writer(ofstream& out,
+void t_swift_generator::generate_old_swift_struct_writer(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_private) {
 
@@ -1391,7 +1390,7 @@
  *
  * @param tstruct The structure definition
  */
-void t_swift_generator::generate_old_swift_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_swift_generator::generate_old_swift_struct_result_writer(ostream& out, t_struct* tstruct) {
 
   indent(out) << "private static func writeValue(__value: " << tstruct->get_name()
               << ", toProtocol __proto: TProtocol) throws";
@@ -1429,7 +1428,7 @@
  *
  * @param tstruct The struct definition
  */
-void t_swift_generator::generate_swift_struct_printable_extension(ofstream& out, t_struct* tstruct) {
+void t_swift_generator::generate_swift_struct_printable_extension(ostream& out, t_struct* tstruct) {
 
   // Allow use of debugDescription so the app can add description via a cateogory/extension
 
@@ -1595,7 +1594,7 @@
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_swift_generator::generate_swift_service_protocol(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     string doc = tservice->get_doc();
     generate_docstring(out, doc);
@@ -1644,7 +1643,7 @@
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_swift_generator::generate_swift_service_protocol_async(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_protocol_async(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     string doc = tservice->get_doc();
     generate_docstring(out, doc);
@@ -1681,7 +1680,7 @@
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_swift_generator::generate_swift_service_client(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_client(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     indent(out) << "open class " << tservice->get_name() << "Client";// : "
 
@@ -1724,7 +1723,7 @@
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_swift_generator::generate_swift_service_client_async(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_client_async(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     indent(out) << "open class " << tservice->get_name()
                 << "AsyncClient<Protocol: TProtocol, Factory: TAsyncTransportFactory>";// : "
@@ -1762,7 +1761,7 @@
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_swift_generator::generate_swift_service_server(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_server(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     indent(out) << "open class " << tservice->get_name() << "Processor /* " << tservice->get_name() << " */";
 
@@ -1807,7 +1806,7 @@
  *                  Wether the first parameter must be a protocol or if
  *                  the protocol is to be assumed
  */
-void t_swift_generator::generate_swift_service_client_send_function_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_send_function_implementation(ostream& out,
                                                                                    t_service *tservice,
                                                                                    t_function* tfunction,
                                                                                    bool needs_protocol) {
@@ -1893,7 +1892,7 @@
  *                  Wether the first parameter must be a protocol or if
  *                  the protocol is to be assumed
  */
-void t_swift_generator::generate_swift_service_client_recv_function_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_recv_function_implementation(ostream& out,
                                                                                    t_service* tservice,
                                                                                    t_function* tfunction,
                                                                                    bool needs_protocol) {
@@ -2018,7 +2017,7 @@
  *
  * @param tfunction The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_send_function_invocation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_send_function_invocation(ostream& out,
                                                                                t_function* tfunction) {
 
   indent(out) << "try send_" << tfunction->get_name() << "(";
@@ -2044,7 +2043,7 @@
  *
  * @param tfunction The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_send_async_function_invocation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_send_async_function_invocation(ostream& out,
                                                                                      t_function* tfunction) {
 
   t_struct* arg_struct = tfunction->get_arglist();
@@ -2069,7 +2068,7 @@
  *
  * @param tservice The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = tservice->get_name() + "Client";
@@ -2121,7 +2120,7 @@
  *
  * @param tservice The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_async_implementation(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_client_async_implementation(ostream& out, t_service* tservice) {
   if (gen_cocoa_) {
     generate_old_swift_service_client_async_implementation(out, tservice);
     return;
@@ -2203,7 +2202,7 @@
   out << endl;
 }
 
-void t_swift_generator::generate_old_swift_service_client_async_implementation(ofstream& out,
+void t_swift_generator::generate_old_swift_service_client_async_implementation(ostream& out,
                                                                                t_service* tservice) {
 
   string name = tservice->get_name() + "AsyncClient";
@@ -2338,7 +2337,7 @@
  *
  * @param tservice The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_server_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_server_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = tservice->get_name() + "Processor";
@@ -2785,7 +2784,7 @@
  * @param tfunction Function definition
  * @return String of rendered function definition
  */
-void t_swift_generator::function_docstring(ofstream& out, t_function* tfunction) {
+void t_swift_generator::function_docstring(ostream& out, t_function* tfunction) {
 
     // Generate docstring with following format:
     // /// <Description>
@@ -2840,7 +2839,7 @@
  * @param tfunction Function definition
  * @return String of rendered function definition
  */
-void t_swift_generator::async_function_docstring(ofstream& out, t_function* tfunction) {
+void t_swift_generator::async_function_docstring(ostream& out, t_function* tfunction) {
     // Generate docstring with following format:
     // /// <Description>
     // /// <empty line>
diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
index a832afd..35fed14 100644
--- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
@@ -101,7 +101,7 @@
   bool should_use_default_ns_;
   bool should_use_namespaces_;
 
-  std::ofstream f_xml_;
+  ofstream_with_content_based_conditional_update f_xml_;
 
   std::set<string> programs_;
   std::stack<string> elements_;
diff --git a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
index fa51ba0..e487ffc 100644
--- a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
@@ -103,8 +103,8 @@
   /**
    * Output xsd/php file
    */
-  std::ofstream f_xsd_;
-  std::ofstream f_php_;
+  ofstream_with_content_based_conditional_update f_xsd_;
+  ofstream_with_content_based_conditional_update f_php_;
 
   /**
    * Output string stream
diff --git a/compiler/cpp/test/CMakeLists.txt b/compiler/cpp/test/CMakeLists.txt
index c1fe914..7cf98a5 100644
--- a/compiler/cpp/test/CMakeLists.txt
+++ b/compiler/cpp/test/CMakeLists.txt
@@ -75,3 +75,6 @@
                  -DSRCDIR=${CMAKE_CURRENT_SOURCE_DIR}
                  -P ${CMAKE_CURRENT_SOURCE_DIR}/cpp_plugin_test.cmake)
 endif()
+
+find_package(PythonInterp REQUIRED)
+add_test(NAME StalenessCheckTest COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/compiler/staleness_check.py ${THRIFT_COMPILER})
\ No newline at end of file
diff --git a/compiler/cpp/test/compiler/Included.thrift b/compiler/cpp/test/compiler/Included.thrift
new file mode 100644
index 0000000..ce84ab6
--- /dev/null
+++ b/compiler/cpp/test/compiler/Included.thrift
@@ -0,0 +1,18 @@
+const string foo = "bar"
+
+struct a_struct {
+  1: bool im_true,
+  2: bool im_false,
+  3: i8 a_bite,
+  4: i16 integer16,
+  5: i32 integer32,
+  6: i64 integer64,
+  7: double double_precision,
+  8: string some_characters,
+  9: string zomg_unicode,
+  10: bool what_who,
+}
+
+service AService {
+  i32 a_procedure(1: i32 arg)
+}
diff --git a/compiler/cpp/test/compiler/Including.thrift b/compiler/cpp/test/compiler/Including.thrift
new file mode 100644
index 0000000..677af7b
--- /dev/null
+++ b/compiler/cpp/test/compiler/Including.thrift
@@ -0,0 +1,7 @@
+include "Included.thrift"
+
+const string s = "string"
+
+struct BStruct {
+  1: Included.a_struct one_of_each
+}
diff --git a/compiler/cpp/test/compiler/Single.thrift b/compiler/cpp/test/compiler/Single.thrift
new file mode 100644
index 0000000..2ec301f
--- /dev/null
+++ b/compiler/cpp/test/compiler/Single.thrift
@@ -0,0 +1 @@
+const string foo = "bar"
diff --git a/compiler/cpp/test/compiler/staleness_check.py b/compiler/cpp/test/compiler/staleness_check.py
new file mode 100755
index 0000000..5b11dff
--- /dev/null
+++ b/compiler/cpp/test/compiler/staleness_check.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+from __future__ import print_function
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+import time
+import unittest
+
+
+class TestStalenessCheck(unittest.TestCase):
+
+    CURRENT_DIR_PATH = os.path.dirname(os.path.realpath(__file__))
+    THRIFT_EXECUTABLE_PATH = None
+    SINGLE_THRIFT_FILE_PATH = os.path.join(CURRENT_DIR_PATH, "Single.thrift")
+    INCLUDING_THRIFT_FILE_PATH = os.path.join(CURRENT_DIR_PATH, "Including.thrift")
+    INCLUDED_THRIFT_FILE_PATH = os.path.join(CURRENT_DIR_PATH, "Included.thrift")
+
+    def test_staleness_check_of_single_thrift_file_without_changed_output(self):
+        temp_dir = tempfile.mkdtemp(dir=TestStalenessCheck.CURRENT_DIR_PATH)
+
+        command = [TestStalenessCheck.THRIFT_EXECUTABLE_PATH, "-gen", "cpp", "-o", temp_dir]
+        command += [TestStalenessCheck.SINGLE_THRIFT_FILE_PATH]
+        subprocess.call(command)
+
+        used_file_path = os.path.join(temp_dir, "gen-cpp", "Single_constants.cpp")
+
+        first_modification_time = os.path.getmtime(os.path.join(used_file_path))
+
+        time.sleep(0.1)
+
+        subprocess.call(command)
+
+        second_modification_time = os.path.getmtime(used_file_path)
+
+        self.assertEqual(second_modification_time, first_modification_time)
+
+        shutil.rmtree(temp_dir, ignore_errors=True)
+
+    def test_staleness_check_of_single_thrift_file_with_changed_output(self):
+        temp_dir = tempfile.mkdtemp(dir=TestStalenessCheck.CURRENT_DIR_PATH)
+
+        command = [TestStalenessCheck.THRIFT_EXECUTABLE_PATH, "-gen", "cpp", "-o", temp_dir]
+        command += [TestStalenessCheck.SINGLE_THRIFT_FILE_PATH]
+        subprocess.call(command)
+
+        used_file_path = os.path.join(temp_dir, "gen-cpp", "Single_constants.cpp")
+
+        first_modification_time = os.path.getmtime(os.path.join(used_file_path))
+        used_file = open(used_file_path, "r")
+        first_contents = used_file.read()
+        used_file.close()
+
+        used_file = open(used_file_path, "a")
+        used_file.write("\n/* This is a comment */\n")
+        used_file.close()
+
+        time.sleep(0.1)
+
+        subprocess.call(command)
+
+        second_modification_time = os.path.getmtime(used_file_path)
+        used_file = open(used_file_path, "r")
+        second_contents = used_file.read()
+        used_file.close()
+
+        self.assertGreater(second_modification_time, first_modification_time)
+        self.assertEqual(first_contents, second_contents)
+
+        shutil.rmtree(temp_dir, ignore_errors=True)
+
+    def test_staleness_check_of_included_file(self):
+        temp_dir = tempfile.mkdtemp(dir=TestStalenessCheck.CURRENT_DIR_PATH)
+
+        temp_included_file_path = os.path.join(temp_dir, "Included.thrift")
+        temp_including_file_path = os.path.join(temp_dir, "Including.thrift")
+
+        shutil.copy2(TestStalenessCheck.INCLUDED_THRIFT_FILE_PATH, temp_included_file_path)
+        shutil.copy2(TestStalenessCheck.INCLUDING_THRIFT_FILE_PATH, temp_including_file_path)
+
+        command = [TestStalenessCheck.THRIFT_EXECUTABLE_PATH, "-gen", "cpp", "-recurse", "-o", temp_dir]
+        command += [temp_including_file_path]
+
+        subprocess.call(command)
+
+        included_constants_cpp_file_path = os.path.join(temp_dir, "gen-cpp", "Included_constants.cpp")
+        including_constants_cpp_file_path = os.path.join(temp_dir, "gen-cpp", "Including_constants.cpp")
+
+        included_constants_cpp_first_modification_time = os.path.getmtime(included_constants_cpp_file_path)
+        including_constants_cpp_first_modification_time = os.path.getmtime(including_constants_cpp_file_path)
+
+        temp_included_file = open(temp_included_file_path, "a")
+        temp_included_file.write("\nconst i32 an_integer = 42\n")
+        temp_included_file.close()
+
+        time.sleep(0.1)
+
+        subprocess.call(command)
+
+        included_constants_cpp_second_modification_time = os.path.getmtime(included_constants_cpp_file_path)
+        including_constants_cpp_second_modification_time = os.path.getmtime(including_constants_cpp_file_path)
+
+        self.assertGreater(
+            included_constants_cpp_second_modification_time, included_constants_cpp_first_modification_time)
+        self.assertEqual(
+            including_constants_cpp_first_modification_time, including_constants_cpp_second_modification_time)
+
+        shutil.rmtree(temp_dir, ignore_errors=True)
+
+
+def suite():
+    suite = unittest.TestSuite()
+    loader = unittest.TestLoader()
+    suite.addTest(loader.loadTestsFromTestCase(TestStalenessCheck))
+    return suite
+
+
+if __name__ == "__main__":
+    # The path of Thrift compiler  is  passed as an argument to the test script.
+    # Remove it to not confuse the unit testing framework
+    TestStalenessCheck.THRIFT_EXECUTABLE_PATH = sys.argv[-1]
+    del sys.argv[-1]
+    unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))