--- a/c++/src/corelib/teamcity_messages.cpp
+++ b/c++/src/corelib/teamcity_messages.cpp
@@ -15,40 +15,61 @@
  * $Id: teamcity_messages.cpp 435791 2014-05-20 18:47:58Z camacho $
 */
 
-#include <ncbi_pch.hpp>
-
-#include <stdlib.h>
-#include <sstream>
-
 #include "teamcity_messages.h"
 
-using namespace std;
+#include <cstdlib>
+#include <sstream>
 
-namespace JetBrains {
+namespace jetbrains {
+namespace teamcity {
 
 std::string getFlowIdFromEnvironment() {
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
+    char *flowId = NULL;
+    size_t sz = 0;
+    std::string result;
+    if(!_dupenv_s(&flowId, &sz,"TEAMCITY_PROCESS_FLOW_ID")) {
+        result = flowId != NULL ? flowId : "";
+        free(flowId);
+    }
+
+    return result;
+#else
     const char *flowId = getenv("TEAMCITY_PROCESS_FLOW_ID");
     return flowId == NULL ? "" : flowId;
+#endif
 }
 
 bool underTeamcity() {
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
+    char *teamCityProjectName = 0;
+    size_t sz = 0;
+    bool result = false;
+    if(!_dupenv_s(&teamCityProjectName, &sz, "TEAMCITY_PROJECT_NAME")) {
+        result = teamCityProjectName != NULL;
+        free(teamCityProjectName);
+    }
+
+    return result;
+#else
     return getenv("TEAMCITY_PROJECT_NAME") != NULL;
+#endif
 }
 
 TeamcityMessages::TeamcityMessages()
-: m_out(&cout)
+: m_out(&std::cout)
 {}
 
-void TeamcityMessages::setOutput(ostream &out) {
+void TeamcityMessages::setOutput(std::ostream &out) {
     m_out = &out;
 }
 
-string TeamcityMessages::escape(string s) {
-    string result;
-    
+std::string TeamcityMessages::escape(std::string s) {
+    std::string result;
+
     for (size_t i = 0; i < s.length(); i++) {
         char c = s[i];
-        
+
         switch (c) {
         case '\n': result.append("|n"); break;
         case '\r': result.append("|r"); break;
@@ -58,56 +79,60 @@ string TeamcityMessages::escape(string s
         default:   result.append(&c, 1);
         }
     }
-    
+
     return result;
 }
 
-void TeamcityMessages::openMsg(const string &name) {
-    *m_out << "##teamcity[" << name;
+void TeamcityMessages::openMsg(const std::string &name) {
+    // endl for http://jetbrains.net/tracker/issue/TW-4412
+    *m_out << std::endl << "##teamcity[" << name;
 }
 
 void TeamcityMessages::closeMsg() {
     *m_out << "]";
     // endl for http://jetbrains.net/tracker/issue/TW-4412
-    *m_out << endl;
-    m_out->flush();
+    *m_out << std::endl;
 }
 
-void TeamcityMessages::writeProperty(string name, string value) {
+void TeamcityMessages::writeProperty(std::string name, std::string value) {
     *m_out << " " << name << "='" << escape(value) << "'";
 }
 
-void TeamcityMessages::suiteStarted(string name, string flowid) {
+void TeamcityMessages::suiteStarted(std::string name, std::string flowid) {
     openMsg("testSuiteStarted");
     writeProperty("name", name);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::suiteFinished(string name, string flowid) {
+void TeamcityMessages::suiteFinished(std::string name, std::string flowid) {
     openMsg("testSuiteFinished");
     writeProperty("name", name);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::testStarted(string name, string flowid) {
+void TeamcityMessages::testStarted(std::string name, std::string flowid, bool captureStandardOutput) {
     openMsg("testStarted");
     writeProperty("name", name);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
+    if(captureStandardOutput) {
+        writeProperty("captureStandardOutput", "true"); // false by default
+    }
+
     closeMsg();
 }
 
-void TeamcityMessages::testFinished(string name, int durationMs, string flowid) {
+void TeamcityMessages::testFinished(std::string name, int durationMs, std::string flowid) {
     openMsg("testFinished");
 
     writeProperty("name", name);
@@ -117,15 +142,15 @@ void TeamcityMessages::testFinished(stri
     }
 
     if(durationMs >= 0) {
-        stringstream out;
+        std::stringstream out(std::ios_base::out);
         out << durationMs;
         writeProperty("duration", out.str());
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::testFailed(string name, string message, string details, string flowid) {
+void TeamcityMessages::testFailed(std::string name, std::string message, std::string details, std::string flowid) {
     openMsg("testFailed");
     writeProperty("name", name);
     writeProperty("message", message);
@@ -133,19 +158,31 @@ void TeamcityMessages::testFailed(string
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::testIgnored(std::string name, std::string message, string flowid) {
+void TeamcityMessages::testIgnored(std::string name, std::string message, std::string flowid) {
     openMsg("testIgnored");
     writeProperty("name", name);
     writeProperty("message", message);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
+void TeamcityMessages::testOutput(std::string name, std::string output, std::string flowid, bool isStdError) {
+    openMsg(isStdError ? "testStdErr" : "testStdOut");
+    writeProperty("name", name);
+    writeProperty("out", output);
+    if(flowid.length() > 0) {
+        writeProperty("flowId", flowid);
+    }
+
+    closeMsg();
+}
+
+}
 }
--- a/c++/src/corelib/teamcity_messages.h
+++ b/c++/src/corelib/teamcity_messages.h
@@ -18,17 +18,18 @@
 #ifndef H_TEAMCITY_MESSAGES
 #define H_TEAMCITY_MESSAGES
 
-#include <string>
 #include <iostream>
+#include <string>
 
-namespace JetBrains {
+namespace jetbrains {
+namespace teamcity {
 
 std::string getFlowIdFromEnvironment();
 bool underTeamcity();
 
 class TeamcityMessages {
     std::ostream *m_out;
-    
+
 protected:
     std::string escape(std::string s);
 
@@ -37,19 +38,24 @@ protected:
     void closeMsg();
 
 public:
+    static const bool StdErr = true;
+    static const bool StdOut = false;
+
     TeamcityMessages();
-    
+
     void setOutput(std::ostream &);
-    
-    void suiteStarted(std::string name, std::string flowid = "");
-    void suiteFinished(std::string name, std::string flowid = "");
-    
-    void testStarted(std::string name, std::string flowid = "");
-    void testFailed(std::string name, std::string message, std::string details, std::string flowid = "");
-    void testIgnored(std::string name, std::string message, std::string flowid = "");
-    void testFinished(std::string name, int durationMs = -1, std::string flowid = "");    
+
+    void suiteStarted(std::string name, std::string flowid =  std::string());
+    void suiteFinished(std::string name, std::string flowid =  std::string());
+
+    void testStarted(std::string name, std::string flowid =  std::string(), bool captureStandardOutput = false);
+    void testFailed(std::string name, std::string message, std::string details, std::string flowid =  std::string());
+    void testIgnored(std::string name, std::string message, std::string flowid =  std::string());
+    void testOutput(std::string name, std::string output, std::string flowid, bool isStdErr = StdOut);
+    void testFinished(std::string name, int durationMs = -1, std::string flowid = std::string());
 };
 
 }
+}
 
 #endif /* H_TEAMCITY_MESSAGES */
