Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/thrift
diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc
index 3f432da..baa229e 100644
--- a/compiler/cpp/src/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/generate/t_csharp_generator.cc
@@ -77,13 +77,13 @@
       iter = parsed_options.find("serial");
       serialize_ = (iter != parsed_options.end());
       if (serialize_) {
-	wcf_namespace_ = iter->second;  // since there can be only one namespace
+        wcf_namespace_ = iter->second;  // since there can be only one namespace
       }
       
       iter = parsed_options.find("wcf");
       wcf_ = (iter != parsed_options.end());
       if (wcf_) {
-	wcf_namespace_ = iter->second;
+        wcf_namespace_ = iter->second;
       }
 
       out_dir_base_ = "gen-csharp";
@@ -278,7 +278,7 @@
   vector<t_enum_value*> constants = tenum->get_constants();
   vector<t_enum_value*>::iterator c_iter;
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-	generate_csharp_doc(f_enum, *c_iter);
+        generate_csharp_doc(f_enum, *c_iter);
 
     int value = (*c_iter)->get_value();
     indent(f_enum) << (*c_iter)->get_name() << " = " << value << "," << endl;
@@ -575,7 +575,7 @@
       // if it is not required, if it has a default value, we need to generate Isset
       // if we are not nullable, then we generate Isset
       if (!is_required && (!nullable_ || has_default)) {
-	indent(out) << "public bool " << (*m_iter)->get_name() << ";" << endl;
+        indent(out) << "public bool " << (*m_iter)->get_name() << ";" << endl;
       }
     }
 
@@ -800,19 +800,19 @@
       bool is_required = field_is_required((*f_iter));
       bool has_default = field_has_default((*f_iter));
       if (nullable_ && !has_default && !is_required) {
-	indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
-	indent_up();
+        indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
+        indent_up();
       } else if (!is_required) {
-	bool null_allowed = type_can_be_null((*f_iter)->get_type());
-	if (null_allowed) {
-	  indent(out) <<
-	    "if (" << prop_name((*f_iter)) << " != null && __isset." << (*f_iter)->get_name() << ") {" << endl;
-	  indent_up();
-	} else {
-	  indent(out) <<
-	    "if (__isset." << (*f_iter)->get_name() << ") {" << endl;
-	  indent_up();
-	}
+        bool null_allowed = type_can_be_null((*f_iter)->get_type());
+        if (null_allowed) {
+          indent(out) <<
+            "if (" << prop_name((*f_iter)) << " != null && __isset." << (*f_iter)->get_name() << ") {" << endl;
+          indent_up();
+        } else {
+          indent(out) <<
+            "if (__isset." << (*f_iter)->get_name() << ") {" << endl;
+          indent_up();
+        }
       }
       indent(out) << "field.Name = \"" << (*f_iter)->get_name() << "\";" << endl;
       indent(out) << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl;
@@ -823,8 +823,8 @@
 
       indent(out) << "oprot.WriteFieldEnd();" << endl;
       if (!is_required) {
-	indent_down();
-	indent(out) << "}" << endl;
+        indent_down();
+        indent(out) << "}" << endl;
       }
     }
   }
@@ -863,10 +863,9 @@
       }
       
       if (nullable_) {
-	out << "(this." << prop_name((*f_iter)) << " != null) {" << endl;
+        out << "(this." << prop_name((*f_iter)) << " != null) {" << endl;
       } else {
-	out <<
-	  "(this.__isset." << (*f_iter)->get_name() << ") {" << endl;
+        out << "(this.__isset." << (*f_iter)->get_name() << ") {" << endl;
       }
       indent_up();
 
@@ -892,8 +891,8 @@
         "oprot.WriteFieldEnd();" << endl;
 
       if (null_allowed) {
-	indent_down();
-	indent(out) << "}" << endl;
+        indent_down();
+        indent(out) << "}" << endl;
       }
 
       indent_down();
@@ -918,36 +917,75 @@
   indent_up();
 
   indent(out) <<
-    "StringBuilder sb = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
+    "StringBuilder __sb = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
 
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
-  bool first = true;
+  bool useFirstFlag = false;
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    if( ! field_is_required((*f_iter))) {
+      indent(out) << "bool __first = true;" << endl;
+	  useFirstFlag = true;
+    }
+    break;
+  }
+
+  bool had_required = false;  // set to true after first required field has been processed
 
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if (first) {
-      first = false;
+    bool is_required = field_is_required((*f_iter));
+    bool has_default = field_has_default((*f_iter));
+    if (nullable_ && !has_default && !is_required) {
+      indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
+      indent_up();
+    } else if (!is_required) {
+      bool null_allowed = type_can_be_null((*f_iter)->get_type());
+      if (null_allowed) {
+        indent(out) <<
+          "if (" << prop_name((*f_iter)) << " != null && __isset." << (*f_iter)->get_name() << ") {" << endl;
+        indent_up();
+      } else {
+        indent(out) <<
+          "if (__isset." << (*f_iter)->get_name() << ") {" << endl;
+        indent_up();
+      }
+    }
+
+    if( useFirstFlag && (! had_required)) {
+      indent(out) << "if(!__first) { __sb.Append(\", \"); }" << endl;
+      if( ! is_required) {
+        indent(out) << "__first = false;" << endl;
+      }
       indent(out) <<
-        "sb.Append(\"" << prop_name((*f_iter)) << ": \");" << endl;
+        "__sb.Append(\"" << prop_name((*f_iter)) << ": \");" << endl;
     } else {
       indent(out) <<
-        "sb.Append(\"," << prop_name((*f_iter)) << ": \");" << endl;
+        "__sb.Append(\", " << prop_name((*f_iter)) << ": \");" << endl;
     }
+        
+          
     t_type* ttype = (*f_iter)->get_type();
     if (ttype->is_xception() || ttype->is_struct()) {
       indent(out) <<
-        "sb.Append(" << prop_name((*f_iter)) << "== null ? \"<null>\" : "<< prop_name((*f_iter))  << ".ToString());" << endl;
+        "__sb.Append(" << prop_name((*f_iter)) << "== null ? \"<null>\" : "<< prop_name((*f_iter))  << ".ToString());" << endl;
     } else {
       indent(out) <<
-        "sb.Append(" << prop_name((*f_iter))  << ");" << endl;
+        "__sb.Append(" << prop_name((*f_iter))  << ");" << endl;
+    }
+        
+    if (!is_required) {
+      indent_down();
+      indent(out) << "}" << endl;
+    } else {
+      had_required = true;  // now __first must be false, so we don't need to check it anymore
     }
   }
 
   indent(out) <<
-    "sb.Append(\")\");" << endl;
+    "__sb.Append(\")\");" << endl;
   indent(out) <<
-    "return sb.ToString();" << endl;
+    "return __sb.ToString();" << endl;
 
   indent_down();
   indent(out) << "}" << endl << endl;
@@ -1122,13 +1160,13 @@
       out << "(!__isset." << (*f_iter)->get_name() << " ? 0 : ";
     }
     if (ttype->is_container()) {
-    	out << "(TCollections.GetHashCode("
-    		<< prop_name((*f_iter))
-    		<< "))";
+            out << "(TCollections.GetHashCode("
+                    << prop_name((*f_iter))
+                    << "))";
     } else {
-		out << "("
-			<< prop_name((*f_iter))
-			<< ".GetHashCode())";
+                out << "("
+                        << prop_name((*f_iter))
+                        << ".GetHashCode())";
     }
     out << ");" << endl;
   }
@@ -1180,8 +1218,8 @@
   generate_csharp_doc(f_service_, tservice);
 
   if (wcf_) {
-	  indent(f_service_) <<
-		"[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+          indent(f_service_) <<
+                "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
   }
   indent(f_service_) <<
     "public interface Iface" << extends_iface << " {" << endl;
@@ -1191,19 +1229,19 @@
   vector<t_function*>::iterator f_iter;
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
   {
-	generate_csharp_doc(f_service_, *f_iter);
+        generate_csharp_doc(f_service_, *f_iter);
 
-	// if we're using WCF, add the corresponding attributes
-	if (wcf_) {
-		indent(f_service_) <<
-			"[OperationContract]" << endl;
+        // if we're using WCF, add the corresponding attributes
+        if (wcf_) {
+                indent(f_service_) <<
+                        "[OperationContract]" << endl;
 
-		const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
-		vector<t_field*>::const_iterator x_iter;
-		for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-		  indent(f_service_) << "[FaultContract(typeof(" + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
-		}
-	}
+                const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
+                vector<t_field*>::const_iterator x_iter;
+                for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
+                  indent(f_service_) << "[FaultContract(typeof(" + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
+                }
+        }
 
     indent(f_service_) <<
       function_signature(*f_iter) << ";" << endl;
@@ -1351,7 +1389,7 @@
     f_service_ << ");" << endl;
     scope_down(f_service_);
     f_service_ << endl;
-	
+        
     // End
     indent(f_service_) <<
       "public " << function_signature_async_end(*f_iter, "End_") << endl;
@@ -1373,7 +1411,7 @@
     bool first;
     if( async_||async_ctp_) {
       indent(f_service_) <<
-	"public async " << function_signature_async(*f_iter, "") << endl;
+        "public async " << function_signature_async(*f_iter, "") << endl;
       scope_up(f_service_);
       
       if (!(*f_iter)->get_returntype()->is_void()) {
@@ -1385,9 +1423,9 @@
         indent(f_service_);
       }
       if (async_) {
-	f_service_ << "await Task.Run(() =>" << endl;
+        f_service_ << "await Task.Run(() =>" << endl;
       } else {
-	f_service_ << "await TaskEx.Run(() =>" << endl;
+        f_service_ << "await TaskEx.Run(() =>" << endl;
       }
       scope_up(f_service_);
       indent(f_service_);
@@ -1397,7 +1435,7 @@
       }
       f_service_ << 
         funname << "(";
-	  first = true;
+          first = true;
       for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
         if (first) {
           first = false;
@@ -1414,7 +1452,7 @@
         indent(f_service_) << 
           "return retval;"  << endl;
       }
-	  scope_down(f_service_);
+          scope_down(f_service_);
       f_service_ << endl;
     }
     
@@ -1551,24 +1589,24 @@
         indent() << "iprot_.ReadMessageEnd();" << endl;
 
       if (!(*f_iter)->get_returntype()->is_void()) {
-	if (nullable_) {
-	  if (type_can_be_null((*f_iter)->get_returntype())) {
-	    f_service_ <<
-	      indent() << "if (result.Success != null) {" << endl <<
-	      indent() << "  return result.Success;" << endl <<
-	      indent() << "}" << endl;
-	  } else {
-	    f_service_ <<
-	      indent() << "if (result.Success.HasValue) {" << endl <<
-	      indent() << "  return result.Success.Value;" << endl <<
-	      indent() << "}" << endl;
-	  }
-	} else {
-	  f_service_ <<
-	    indent() << "if (result.__isset.success) {" << endl <<
-	    indent() << "  return result.Success;" << endl <<
-	    indent() << "}" << endl;
-	}
+        if (nullable_) {
+          if (type_can_be_null((*f_iter)->get_returntype())) {
+            f_service_ <<
+              indent() << "if (result.Success != null) {" << endl <<
+              indent() << "  return result.Success;" << endl <<
+              indent() << "}" << endl;
+          } else {
+            f_service_ <<
+              indent() << "if (result.Success.HasValue) {" << endl <<
+              indent() << "  return result.Success.Value;" << endl <<
+              indent() << "}" << endl;
+          }
+        } else {
+          f_service_ <<
+            indent() << "if (result.__isset.success) {" << endl <<
+            indent() << "  return result.Success;" << endl <<
+            indent() << "}" << endl;
+        }
       }
 
       t_struct *xs = (*f_iter)->get_xceptions();
@@ -1576,17 +1614,17 @@
       const std::vector<t_field*>& xceptions = xs->get_members();
       vector<t_field*>::const_iterator x_iter;
       for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-	if (nullable_) {
-	  f_service_ <<
-	    indent() << "if (result." << prop_name(*x_iter) << " != null) {" << endl <<
-	    indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
-	    indent() << "}" << endl;
-	} else {
-	  f_service_ <<
-	    indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl <<
-	    indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
-	    indent() << "}" << endl;
-	}
+        if (nullable_) {
+          f_service_ <<
+            indent() << "if (result." << prop_name(*x_iter) << " != null) {" << endl <<
+            indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
+            indent() << "}" << endl;
+        } else {
+          f_service_ <<
+            indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl <<
+            indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
+            indent() << "}" << endl;
+        }
       }
 
       if ((*f_iter)->get_returntype()->is_void()) {
@@ -2246,34 +2284,34 @@
                   << " " << prop_name(tfield) << " { get; set; }" << endl;
     } else {
       indent(out) << (isPublic ? "public " : "private ") << type_name(tfield->get_type(), false, false, true)
-		  << " " << prop_name(tfield) << endl;
+                  << " " << prop_name(tfield) << endl;
       scope_up(out);
       indent(out) << "get" << endl;
       scope_up(out);
       bool use_nullable = false;
       if (nullable_) {
-	t_type* ttype = tfield->get_type();
-	while (ttype->is_typedef()) {
-	  ttype = ((t_typedef*)ttype)->get_type();
-	}
-	if (ttype->is_base_type()) {
-	  use_nullable = ((t_base_type*)ttype)->get_base() != t_base_type::TYPE_STRING;
-	}
+        t_type* ttype = tfield->get_type();
+        while (ttype->is_typedef()) {
+          ttype = ((t_typedef*)ttype)->get_type();
+        }
+        if (ttype->is_base_type()) {
+          use_nullable = ((t_base_type*)ttype)->get_base() != t_base_type::TYPE_STRING;
+        }
       }
       indent(out) << "return " << fieldPrefix + tfield->get_name() << ";" << endl;
       scope_down(out);
       indent(out) << "set" << endl;
       scope_up(out);
       if (use_nullable) {
-	if (generateIsset) {
-	  indent(out) << "__isset." << tfield->get_name() << " = value.HasValue;" << endl;
-	}
-	indent(out) << "if (value.HasValue) this." << fieldPrefix + tfield->get_name() << " = value.Value;" << endl;
+        if (generateIsset) {
+          indent(out) << "__isset." << tfield->get_name() << " = value.HasValue;" << endl;
+        }
+        indent(out) << "if (value.HasValue) this." << fieldPrefix + tfield->get_name() << " = value.Value;" << endl;
       } else {
-	if (generateIsset) {
-	  indent(out) << "__isset." << tfield->get_name() << " = true;" << endl;
-	}
-	indent(out) << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl;
+        if (generateIsset) {
+          indent(out) << "__isset." << tfield->get_name() << " = true;" << endl;
+        }
+        indent(out) << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl;
       }
       scope_down(out);
       scope_down(out);
@@ -2525,23 +2563,23 @@
 
 void t_csharp_generator::generate_csharp_doc(ofstream &out, t_function* tfunction) {
   if (tfunction->has_doc()) {
-	stringstream ps;
+        stringstream ps;
     const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
     vector<t_field*>::const_iterator p_iter;
     for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) {
       t_field* p = *p_iter;
       ps << "\n<param name=\"" << p->get_name() << "\">";
       if (p->has_doc()) {
-		std::string str = p->get_doc();
-		str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); // remove the newlines that appear from the parser
-		ps << str;
+                std::string str = p->get_doc();
+                str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); // remove the newlines that appear from the parser
+                ps << str;
       }
-	  ps << "</param>";
+          ps << "</param>";
     }
     generate_docstring_comment(out,
                                "",
                                "/// ",
-							   "<summary>\n" + tfunction->get_doc() + "</summary>" + ps.str(),
+                                                           "<summary>\n" + tfunction->get_doc() + "</summary>" + ps.str(),
                                "");
   }
 }
diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc
index 2ad9c70..954735a 100644
--- a/compiler/cpp/src/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/generate/t_delphi_generator.cc
@@ -3165,12 +3165,22 @@
     cls_nm = type_name(tstruct,true,false);
   }
 
-  string tmp_sb = "sb";
+  string tmp_sb = "__sb";
+  string tmp_first = "__first";
+  bool useFirstFlag = false;
 
   indent_impl(out) << "function " << cls_prefix << cls_nm << ".ToString: string;" << endl;
   indent_impl(out) << "var" << endl;
   indent_up_impl();
   indent_impl(out) << tmp_sb << " : TThriftStringBuilder;" << endl;
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    bool is_optional  = ((*f_iter)->get_req() != t_field::T_REQUIRED);
+    if( is_optional) {
+      indent_impl(out) << tmp_first << " : Boolean;" << endl;
+      useFirstFlag = true;
+    }
+    break;
+  }
   indent_down_impl();
   indent_impl(out) << "begin" << endl;
   indent_up_impl();
@@ -3179,17 +3189,42 @@
   indent_impl(out) << "try" << endl;
   indent_up_impl();
 
-  bool first = true;
-
+  if( useFirstFlag) {
+    indent_impl(out) << tmp_first << " := TRUE;" << endl;
+  }
+  
+  bool had_required = false;  // set to true after first required field has been processed
+  
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if (first) {
-      first = false;
+    bool null_allowed = type_can_be_null((*f_iter)->get_type());
+    bool is_optional  = ((*f_iter)->get_req() != t_field::T_REQUIRED);
+    if (null_allowed) {
+      indent_impl(out) << "if (" << prop_name((*f_iter), is_exception) << " <> nil)";
+      if (is_optional) {
+        out << " and __isset_" << prop_name(*f_iter,is_exception);
+      }
+      out << " then begin" << endl;
+      indent_up_impl();
+    } else {
+      if (is_optional) {
+        indent_impl(out) << "if (__isset_" << prop_name(*f_iter,is_exception) << ") then begin" << endl;
+        indent_up_impl();
+      }
+    }
+
+    if( useFirstFlag && (! had_required)) {
+      indent_impl(out) << "if not " << tmp_first << " then " << tmp_sb << ".Append(',');" << endl;
+      if (is_optional) {
+        indent_impl(out) << tmp_first << " := FALSE;" << endl;
+      }
       indent_impl(out) <<
         tmp_sb << ".Append('" << prop_name((*f_iter), is_exception) << ": ');" << endl;
     } else {
       indent_impl(out) <<
-        tmp_sb << ".Append('," << prop_name((*f_iter), is_exception) << ": ');" << endl;
+        tmp_sb << ".Append(', " << prop_name((*f_iter), is_exception) << ": ');" << endl;
     }
+
+
     t_type* ttype = (*f_iter)->get_type();
     if (ttype->is_xception() || ttype->is_struct()) {
       indent_impl(out) <<
@@ -3201,12 +3236,25 @@
       indent_impl(out) <<
         tmp_sb << ".Append(" << prop_name((*f_iter), is_exception)  << ");" << endl;
     }
+    
+    if (null_allowed || is_optional) {
+      indent_down_impl();
+      indent_impl(out) << "end;" << endl;
+    } 
+    
+    if (!is_optional) {
+      had_required = true;  // now __first must be false, so we don't need to check it anymore
+    }
   }
 
   indent_impl(out) <<
     tmp_sb << ".Append(')');" << endl;
   indent_impl(out) <<
     "Result := " << tmp_sb <<  ".ToString;" << endl;
+  if( useFirstFlag) {
+    indent_impl(out) <<
+      "if " << tmp_first <<  " then {prevent warning};" << endl;
+  }
 
   indent_down_impl();
   indent_impl(out) << "finally" << endl;
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index b962378..559a20e 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -140,7 +140,8 @@
                                     bool        declare,
                                     std::string prefix = "",
                                     bool inclass = false,
-                                    bool coerceData = false);
+                                    bool coerceData = false,
+                                    bool inkey = false);
 
     void generate_deserialize_struct(std::ofstream &out,
                                      t_struct*   tstruct,
@@ -169,7 +170,8 @@
 
     void generate_serialize_field(std::ofstream &out,
                                   t_field*    tfield,
-                                  std::string prefix = "");
+                                  std::string prefix = "",
+                                  bool inkey = false);
 
     void generate_serialize_struct(std::ofstream &out,
                                    t_struct*   tstruct,
@@ -2442,7 +2444,8 @@
         bool declare,
         string prefix,
         bool inclass,
-        bool coerceData)
+        bool coerceData,
+        bool inkey)
 {
     t_type* orig_type = tfield->get_type();
     t_type* type = get_true_type(orig_type);
@@ -2462,7 +2465,9 @@
     } else if (type->is_base_type() || type->is_enum()) {
 
         if (declare) {
-            out << "var " << tfield->get_name() << " " << type_to_go_type(tfield->get_type()) << endl;
+            string type_name = inkey ? type_to_go_key_type(tfield->get_type()) :
+                type_to_go_type(tfield->get_type());
+            out << "var " << tfield->get_name() << " " << type_name << endl;
         }
 
         indent(out) <<
@@ -2478,7 +2483,7 @@
                 break;
 
             case t_base_type::TYPE_STRING:
-                if (((t_base_type*)type)->is_binary()) {
+                if (((t_base_type*)type)->is_binary() && !inkey) {
                     out << "ReadBinary()";
                 } else {
                     out << "ReadString()";
@@ -2586,7 +2591,7 @@
             indent() << "if err != nil {" << endl <<
             indent() << "  return fmt.Errorf(\"error reading map begin: %s\")" << endl <<
             indent() << "}" << endl <<
-            indent() << prefix << eq << "make(map[" << type_to_go_type(t->get_key_type()) << "]" <<  type_to_go_type(t->get_val_type()) << ", size)" << endl;
+            indent() << prefix << eq << "make(map[" << type_to_go_key_type(t->get_key_type()) << "]" <<  type_to_go_type(t->get_val_type()) << ", size)" << endl;
     } else if (ttype->is_set()) {
         t_set* t = (t_set*)ttype;
         out <<
@@ -2594,7 +2599,7 @@
             indent() << "if err != nil {" << endl <<
             indent() << "  return fmt.Errorf(\"error reading set being: %s\")" << endl <<
             indent() << "}" << endl <<
-            indent() << prefix << eq << "make(map[" << type_to_go_type(t->get_elem_type()) << "]bool, size)" << endl;
+            indent() << prefix << eq << "make(map[" << type_to_go_key_type(t->get_elem_type()) << "]bool, size)" << endl;
     } else if (ttype->is_list()) {
         t_list* t = (t_list*)ttype;
         out <<
@@ -2656,7 +2661,7 @@
     string val = tmp("_val");
     t_field fkey(tmap->get_key_type(), key);
     t_field fval(tmap->get_val_type(), val);
-    generate_deserialize_field(out, &fkey, true);
+    generate_deserialize_field(out, &fkey, true, "", false, false, true);
     generate_deserialize_field(out, &fval, true);
     indent(out) <<
                 prefix << "[" << key << "] = " << val << endl;
@@ -2702,7 +2707,8 @@
  */
 void t_go_generator::generate_serialize_field(ofstream &out,
         t_field* tfield,
-        string prefix)
+        string prefix,
+        bool inkey)
 {
     t_type* type = get_true_type(tfield->get_type());
     string name(prefix + publicize(variable_name_to_go_name(tfield->get_name())));
@@ -2734,7 +2740,7 @@
                 break;
 
             case t_base_type::TYPE_STRING:
-                if (((t_base_type*)type)->is_binary()) {
+                if (((t_base_type*)type)->is_binary() && !inkey) {
                     out << "WriteBinary(" << name << ")";
                 } else {
                     out << "WriteString(string(" << name << "))";
@@ -2882,7 +2888,7 @@
         string viter)
 {
     t_field kfield(tmap->get_key_type(), "");
-    generate_serialize_field(out, &kfield, kiter);
+    generate_serialize_field(out, &kfield, kiter, true);
     t_field vfield(tmap->get_val_type(), "");
     generate_serialize_field(out, &vfield, viter);
 }
@@ -3193,6 +3199,10 @@
         throw "Cannot produce a valid type for a Go map key: "  + type_to_go_type(type) + " - aborting.";
     }
 
+    if (resolved_type->is_string() &&
+        ((t_base_type*) resolved_type)->is_binary())
+        return "string";
+
     return type_to_go_type(type);
 }
 
diff --git a/lib/cocoa/src/protocol/TProtocolUtil.h b/lib/cocoa/src/protocol/TProtocolUtil.h
index c2d2521..757748a 100644
--- a/lib/cocoa/src/protocol/TProtocolUtil.h
+++ b/lib/cocoa/src/protocol/TProtocolUtil.h
@@ -26,4 +26,4 @@
 
 + (void) skipType: (int) type onProtocol: (id <TProtocol>) protocol;
 
-@end;
+@end
diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go
index ba5f722..74d36d0 100644
--- a/lib/go/thrift/compact_protocol.go
+++ b/lib/go/thrift/compact_protocol.go
@@ -719,8 +719,7 @@
 	switch byte(t) & 0x0f {
 	case STOP:
 		return STOP, nil
-	case COMPACT_BOOLEAN_FALSE:
-	case COMPACT_BOOLEAN_TRUE:
+	case COMPACT_BOOLEAN_FALSE, COMPACT_BOOLEAN_TRUE:
 		return BOOL, nil
 	case COMPACT_BYTE:
 		return BYTE, nil
diff --git a/lib/go/thrift/compact_protocol_test.go b/lib/go/thrift/compact_protocol_test.go
index c874379..72812f9 100644
--- a/lib/go/thrift/compact_protocol_test.go
+++ b/lib/go/thrift/compact_protocol_test.go
@@ -20,12 +20,12 @@
 package thrift
 
 import (
+	"bytes"
 	"testing"
 )
 
 func TestReadWriteCompactProtocol(t *testing.T) {
 	ReadWriteProtocolTest(t, NewTCompactProtocolFactory())
-	/*
 	   transports := []TTransport{
 	     NewTMemoryBuffer(),
 	     NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))),
@@ -50,5 +50,4 @@
 	     ReadWriteBinary(t, p, trans);
 	     trans.Close();
 	   }
-	*/
 }
diff --git a/lib/go/thrift/serializer_test.go b/lib/go/thrift/serializer_test.go
index ca8fb0e..0f3f7d7 100644
--- a/lib/go/thrift/serializer_test.go
+++ b/lib/go/thrift/serializer_test.go
@@ -145,7 +145,7 @@
 	var protocol_factories map[string]ProtocolFactory
 	protocol_factories = make(map[string]ProtocolFactory)
 	protocol_factories["Binary"] = NewTBinaryProtocolFactoryDefault()
-//	protocol_factories["Compact"] = NewTCompactProtocolFactory() - not working right now, see THRIFT-2158 
+	protocol_factories["Compact"] = NewTCompactProtocolFactory()
 	//protocol_factories["SimpleJSON"] = NewTSimpleJSONProtocolFactory() - write only, can't be read back by design
 	protocol_factories["JSON"] = NewTJSONProtocolFactory()
 
diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py
index cdec607..c34edb8 100644
--- a/lib/py/src/protocol/TCompactProtocol.py
+++ b/lib/py/src/protocol/TCompactProtocol.py
@@ -250,7 +250,7 @@
 
   @writer
   def writeDouble(self, dub):
-    self.trans.write(pack('!d', dub))
+    self.trans.write(pack('<d', dub))
 
   def __writeString(self, s):
     self.__writeSize(len(s))
@@ -383,7 +383,7 @@
   @reader
   def readDouble(self):
     buff = self.trans.readAll(8)
-    val, = unpack('!d', buff)
+    val, = unpack('<d', buff)
     return val
 
   def __readString(self):