http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests.cc 
b/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests.cc
new file mode 100644
index 0000000..0b8c837
--- /dev/null
+++ b/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests.cc
@@ -0,0 +1,339 @@
+// 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.
+
+#include "../catch/catch.hpp"
+#include <thrift/parse/t_program.h>
+#include <thrift/generate/t_netcore_generator.h>
+#include "t_netcore_generator_functional_tests_helpers.h"
+
+TEST_CASE( "t_netcore_generator should generate valid enum", "[functional]" )
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+
+    std::pair<string, t_enum*> pair = 
TestDataGenerator::get_test_enum_data(program);
+    string expected_result = pair.first;
+    t_enum* test_enum = pair.second;
+
+    string file_path = test_enum->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_enum(out, test_enum));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete test_enum;
+    delete gen;
+    delete program;    
+}
+
+TEST_CASE("t_netcore_generator should generate valid void", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_void_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_THROWS(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid string with escaping 
keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_string_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid bool with escaping 
keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_bool_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid sbyte (i8) with escaping 
keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_i8_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid short (i16) with escaping 
keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_i16_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid integer (i32) with 
escaping keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_i32_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid long (i64) with escaping 
keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_i64_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should generate valid double with escaping 
keyword", "[functional]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+
+    std::pair<string, t_const*> pair = 
TestDataGenerator::get_test_double_const_data(gen);
+    string expected_result = pair.first;
+    t_const* const_ = pair.second;
+    vector<t_const*> consts_;
+    consts_.push_back(const_);
+
+    string file_path = const_->get_name() + ".cs";
+    ofstream out;
+    out.open(file_path.c_str());
+
+    REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
+
+    out.close();
+
+    std::ifstream ifs(file_path);
+    string actual_result((std::istreambuf_iterator<char>(ifs)), 
(std::istreambuf_iterator<char>()));
+    std::remove(file_path.c_str());
+
+    REQUIRE(expected_result == actual_result);
+
+    delete const_;
+    delete gen;
+    delete program;
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.cc
----------------------------------------------------------------------
diff --git 
a/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.cc 
b/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.cc
new file mode 100644
index 0000000..92c170b
--- /dev/null
+++ b/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.cc
@@ -0,0 +1,237 @@
+// 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.
+
+#include <thrift/parse/t_program.h>
+#include "thrift/common.h"
+#include <thrift/generate/t_netcore_generator.h>
+#include "t_netcore_generator_functional_tests_helpers.h"
+
+const string TestDataGenerator::DEFAULT_FILE_HEADER = "/**" "\n"
+            " * Autogenerated by Thrift Compiler ()" "\n"
+            " *" "\n"
+            " * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE 
DOING" "\n"
+            " *  @generated" "\n"
+            " */";
+
+std::pair<string, t_enum*> TestDataGenerator::get_test_enum_data(t_program* 
program)
+{
+    string expected_result = DEFAULT_FILE_HEADER +
+        "\n"
+        "\n"
+        "/// <summary>\n"
+        "/// TestDoc\n"
+        "/// </summary>\n"
+        "public enum TestName\n"
+        "{\n"
+        "  None = 0,\n"
+        "  First = 1,\n"
+        "  Second = 2,\n"
+        "}\n";
+
+    t_enum* enum_ = new t_enum(program);
+    enum_->set_name("TestName");
+    enum_->set_doc("TestDoc");
+    enum_->append(new t_enum_value("None", 0));
+    enum_->append(new t_enum_value("First", 1));
+    enum_->append(new t_enum_value("Second", 2));
+
+    return std::pair<string, t_enum*>(expected_result, enum_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_void_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER;
+
+    t_type* type_ = new t_base_type("void", t_base_type::TYPE_VOID);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_string("VoidValue");
+
+    t_const* const_ = new t_const(type_, "void", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_string_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() + 
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const string @string = \"StringValue\";\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("string", t_base_type::TYPE_STRING);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_string("StringValue");
+
+    t_const* const_ = new t_const(type_, "string", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_bool_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() +
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const bool @bool = true;\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("bool", t_base_type::TYPE_BOOL);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_integer(1);
+
+    t_const* const_ = new t_const(type_, "bool", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_i8_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() +
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const sbyte @sbyte = 127;\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("I8", t_base_type::TYPE_I8);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_integer(127);
+
+    t_const* const_ = new t_const(type_, "sbyte", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_i16_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() +
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const short @short = 32767;\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("i16", t_base_type::TYPE_I16);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_integer(32767);
+
+    t_const* const_ = new t_const(type_, "short", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_i32_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() +
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const int @int = 2147483647;\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("i32", t_base_type::TYPE_I32);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_integer(2147483647);
+
+    t_const* const_ = new t_const(type_, "int", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_i64_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() +
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const long @long = 9223372036854775807;\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("i64", t_base_type::TYPE_I64);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_integer(9223372036854775807);
+
+    t_const* const_ = new t_const(type_, "long", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}
+
+std::pair<string, t_const*> 
TestDataGenerator::get_test_double_const_data(t_netcore_generator* gen)
+{
+    string expected_result = DEFAULT_FILE_HEADER + "\n" 
+gen->netcore_type_usings() +
+        "\n"
+        "public static class netcoreConstants\n"
+        "{\n"
+        "  /// <summary>\n"
+        "  /// TestDoc\n"
+        "  /// </summary>\n"
+        "  public const double @double = 9.22337e+18;\n"
+        "}\n";
+
+    t_type* type_ = new t_base_type("double", t_base_type::TYPE_DOUBLE);
+    type_->set_doc("TestDoc");
+
+    t_const_value* const_value_ = new t_const_value();
+    const_value_->set_double(9223372036854775807.1);
+
+    t_const* const_ = new t_const(type_, "double", const_value_);
+    const_->set_doc("TestDoc");
+
+    return std::pair<string, t_const*>(expected_result, const_);
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.h
----------------------------------------------------------------------
diff --git 
a/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.h 
b/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.h
new file mode 100644
index 0000000..c6eaac2
--- /dev/null
+++ b/compiler/cpp/tests/netcore/t_netcore_generator_functional_tests_helpers.h
@@ -0,0 +1,34 @@
+// 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.
+
+#include <thrift/parse/t_program.h>
+
+class TestDataGenerator
+{
+public:
+    static const string DEFAULT_FILE_HEADER;
+
+    static std::pair<string, t_enum*> get_test_enum_data(t_program* program);
+    static std::pair<string, t_const*> 
get_test_void_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_string_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_bool_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_i8_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_i16_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_i32_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_i64_const_data(t_netcore_generator* gen);
+    static std::pair<string, t_const*> 
get_test_double_const_data(t_netcore_generator* gen);
+};

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc 
b/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc
new file mode 100644
index 0000000..0bcbeed
--- /dev/null
+++ b/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc
@@ -0,0 +1,209 @@
+// 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.
+
+#include "../catch/catch.hpp"
+#include <thrift/parse/t_program.h>
+#include <thrift/generate/t_netcore_generator.h>
+
+using std::vector;
+
+TEST_CASE("t_netcore_generator::netcore_type_usings() without option wcf 
should return valid namespaces", "[helpers]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "union", "union" } };
+    string option_string = "";
+
+    string expected_namespaces = "using System;\n"
+                                "using System.Collections;\n"
+                                "using System.Collections.Generic;\n"
+                                "using System.Text;\n"
+                                "using System.IO;\n"
+                                "using System.Threading;\n"
+                                "using System.Threading.Tasks;\n"
+                                "using Thrift;\n"
+                                "using Thrift.Collections;\n" + endl;
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+
+    REQUIRE_FALSE(gen->is_wcf_enabled());
+    REQUIRE(gen->netcore_type_usings() == expected_namespaces);
+
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator::netcore_type_usings() with option wcf should 
return valid namespaces", "[helpers]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+
+    string expected_namespaces_wcf = "using System;\n"
+                                    "using System.Collections;\n"
+                                    "using System.Collections.Generic;\n"
+                                    "using System.Text;\n"
+                                    "using System.IO;\n"
+                                    "using System.Threading;\n"
+                                    "using System.Threading.Tasks;\n"
+                                    "using Thrift;\n"
+                                    "using Thrift.Collections;\n"
+                                    "using System.ServiceModel;\n"
+                                    "using System.Runtime.Serialization;\n" + 
endl;
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+
+    REQUIRE(gen->is_wcf_enabled());
+    REQUIRE(gen->netcore_type_usings() == expected_namespaces_wcf);
+
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should contains latest C# keywords to normalize 
with @", "[helpers]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" } };
+    string option_string = "";
+    vector<string> current_keywords = {
+        { "abstract" },
+        { "as" },
+        { "base" },
+        { "bool" },
+        { "break" },
+        { "byte" },
+        { "case" },
+        { "catch" },
+        { "char" },
+        { "checked" },
+        { "class" },
+        { "const" },
+        { "continue" },
+        { "decimal" },
+        { "default" },
+        { "delegate" },
+        { "do" },
+        { "double" },
+        { "else" },
+        { "enum" },
+        { "event" },
+        { "explicit" },
+        { "extern" },
+        { "false" },
+        { "finally" },
+        { "fixed" },
+        { "float" },
+        { "for" },
+        { "foreach" },
+        { "goto" },
+        { "if" },
+        { "implicit" },
+        { "in" },
+        { "int" },
+        { "interface" },
+        { "internal" },
+        { "is" },
+        { "lock" },
+        { "long" },
+        { "namespace" },
+        { "new" },
+        { "null" },
+        { "object" },
+        { "operator" },
+        { "out" },
+        { "override" },
+        { "params" },
+        { "private" },
+        { "protected" },
+        { "public" },
+        { "readonly" },
+        { "ref" },
+        { "return" },
+        { "sbyte" },
+        { "sealed" },
+        { "short" },
+        { "sizeof" },
+        { "stackalloc" },
+        { "static" },
+        { "string" },
+        { "struct" },
+        { "switch" },
+        { "this" },
+        { "throw" },
+        { "true" },
+        { "try" },
+        { "typeof" },
+        { "uint" },
+        { "ulong" },
+        { "unchecked" },
+        { "unsafe" },
+        { "ushort" },
+        { "using" },
+        { "void" },
+        { "volatile" },
+        { "while" },
+        // Contextual Keywords
+        { "add" },
+        { "alias" },
+        { "ascending" },
+        { "async" },
+        { "await" },
+        { "descending" },
+        { "dynamic" },
+        { "from" },
+        { "get" },
+        { "global" },
+        { "group" },
+        { "into" },
+        { "join" },
+        { "let" },
+        { "orderby" },
+        { "partial" },
+        { "remove" },
+        { "select" },
+        { "set" },
+        { "value" },
+        { "var" },
+        { "when" },
+        { "where" },
+        { "yield" }
+    };
+
+    string missed_keywords = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+    gen->init_generator();
+    map<string, int> generators_keywords = gen->get_keywords_list();
+
+    for (vector<string>::iterator it = current_keywords.begin(); it != 
current_keywords.end(); ++it)
+    {
+        if (generators_keywords.find(*it) == generators_keywords.end())
+        {
+            missed_keywords = missed_keywords + *it + ",";
+        }
+    }
+
+    REQUIRE(missed_keywords == "");
+
+    delete gen;
+    delete program;
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/compiler/cpp/tests/netcore/t_netcore_generator_initialization_tests.cc
----------------------------------------------------------------------
diff --git 
a/compiler/cpp/tests/netcore/t_netcore_generator_initialization_tests.cc 
b/compiler/cpp/tests/netcore/t_netcore_generator_initialization_tests.cc
new file mode 100644
index 0000000..ec17733
--- /dev/null
+++ b/compiler/cpp/tests/netcore/t_netcore_generator_initialization_tests.cc
@@ -0,0 +1,74 @@
+// 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.
+
+#include "../catch/catch.hpp"
+#include <thrift/parse/t_program.h>
+#include <thrift/generate/t_netcore_generator.h>
+
+TEST_CASE( "t_netcore_generator should throw error with unknown options", 
"[initialization]" )
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "keys", "keys" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = nullptr;
+
+    REQUIRE_THROWS(gen = new t_netcore_generator(program, parsed_options, 
option_string));     
+
+    delete gen;
+    delete program;    
+}
+
+TEST_CASE("t_netcore_generator should create valid instance with valid 
options", "[initialization]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" }, { "nullable", 
"nullable"} };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = nullptr;
+
+    REQUIRE_NOTHROW(gen = new t_netcore_generator(program, parsed_options, 
option_string));
+    REQUIRE(gen != nullptr);
+    REQUIRE(gen->is_wcf_enabled());
+    REQUIRE(gen->is_nullable_enabled());
+    REQUIRE_FALSE(gen->is_hashcode_enabled());
+    REQUIRE_FALSE(gen->is_serialize_enabled());
+    REQUIRE_FALSE(gen->is_union_enabled());
+
+    delete gen;
+    delete program;
+}
+
+TEST_CASE("t_netcore_generator should pass init succesfully", 
"[initialization]")
+{
+    string path = "CassandraTest.thrift";
+    string name = "netcore";
+    map<string, string> parsed_options = { { "wcf", "wcf" },{ "nullable", 
"nullable" } };
+    string option_string = "";
+
+    t_program* program = new t_program(path, name);
+    t_netcore_generator* gen = new t_netcore_generator(program, 
parsed_options, option_string);
+
+    REQUIRE_NOTHROW(gen->init_generator());
+
+    delete gen;
+    delete program;
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/compiler/cpp/tests/tests_main.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/tests/tests_main.cc b/compiler/cpp/tests/tests_main.cc
new file mode 100644
index 0000000..21d09b9
--- /dev/null
+++ b/compiler/cpp/tests/tests_main.cc
@@ -0,0 +1,19 @@
+// 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.
+
+#define CATCH_CONFIG_MAIN
+#include "catch/catch.hpp"

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/netcore/Makefile.am b/lib/netcore/Makefile.am
index facee11..992558b 100644
--- a/lib/netcore/Makefile.am
+++ b/lib/netcore/Makefile.am
@@ -19,86 +19,25 @@
 
 SUBDIRS = . 
 
-THRIFT = $(top_builddir)/compiler/cpp/thrift
-
-TESTDIR = Tests/Thrift.PublicInterfaces.Compile.Tests
-GENDIR = $(TESTDIR)/gen-netcore
-
 THRIFTCODE = \
-                       Thrift/Thrift.csproj \
-                       Thrift/ITAsyncProcessor.cs \
-                       Thrift/ITProcessorFactory.cs \
-                       Thrift/SingletonTProcessorFactory.cs \
-                       Thrift/TApplicationException.cs \
-                       Thrift/TBaseClient.cs \
-                       Thrift/TException.cs \
-                       Thrift/TMultiplexedProcessor.cs \
-                       Thrift/Collections/TCollections.cs \
-                       Thrift/Collections/THashSet.cs \
-                       Thrift/Properties/AssemblyInfo.cs \
-                       Thrift/Protocols/ITProtocolFactory.cs \
-                       Thrift/Protocols/TAbstractBase.cs \
-                       Thrift/Protocols/TBase.cs \
-                       Thrift/Protocols/TBinaryProtocol.cs \
-                       Thrift/Protocols/TCompactProtocol.cs \
-                       Thrift/Protocols/TJSONProtocol.cs \
-                       Thrift/Protocols/TMultiplexedProtocol.cs \
-                       Thrift/Protocols/TProtocol.cs \
-                       Thrift/Protocols/TProtocolDecorator.cs \
-                       Thrift/Protocols/TProtocolException.cs \
-                       Thrift/Protocols/Entities/TField.cs \
-                       Thrift/Protocols/Entities/TList.cs \
-                       Thrift/Protocols/Entities/TMap.cs \
-                       Thrift/Protocols/Entities/TMessage.cs \
-                       Thrift/Protocols/Entities/TMessageType.cs \
-                       Thrift/Protocols/Entities/TSet.cs \
-                       Thrift/Protocols/Entities/TStruct.cs \
-                       Thrift/Protocols/Entities/TType.cs \
-                       Thrift/Protocols/Utilities/TBase64Utils.cs \
-                       Thrift/Protocols/Utilities/TProtocolUtil.cs \
-                       Thrift/Server/AsyncBaseServer.cs \
-                       Thrift/Server/TBaseServer.cs \
-                       Thrift/Server/TServerEventHandler.cs \
-                       Thrift/Transports/TClientTransport.cs \
-                       Thrift/Transports/TServerTransport.cs \
-                       Thrift/Transports/TTransportException.cs \
-                       Thrift/Transports/TTransportFactory.cs \
-                       Thrift/Transports/Client/TBufferedClientTransport.cs \
-                       Thrift/Transports/Client/TFramedClientTransport.cs \
-                       Thrift/Transports/Client/THttpClientTransport.cs \
-                       
Thrift/Transports/Client/TMemoryBufferClientTransport.cs \
-                       Thrift/Transports/Client/TNamedPipeClientTransport.cs \
-                       Thrift/Transports/Client/TSocketClientTransport.cs \
-                       Thrift/Transports/Client/TStreamClientTransport.cs \
-                       Thrift/Transports/Client/TTlsSocketClientTransport.cs \
-                       Thrift/Transports/Server/THttpServerTransport.cs \
-                       Thrift/Transports/Server/TNamedPipeServerTransport.cs \
-                       Thrift/Transports/Server/TServerFramedTransport.cs \
-                       Thrift/Transports/Server/TServerSocketTransport.cs \
-                       Thrift/Transports/Server/TTlsServerSocketTransport.cs 
+                       Thrift/Thrift.csproj
 
 all-local: \
        Thrift.dll
 
 Thrift.dll: $(THRIFTCODE)
-       $(MKDIR_P) $(GENDIR)
-       $(THRIFT)  -gen netcore:wcf   -r  -out $(GENDIR)  
$(TESTDIR)/CassandraTest.thrift
-       $(THRIFT)  -gen netcore:wcf   -r  -out $(GENDIR)  
$(top_srcdir)/test/ThriftTest.thrift
-       $(THRIFT)  -gen netcore:wcf   -r  -out $(GENDIR)  
$(top_srcdir)/contrib/fb303/if/fb303.thrift
-       $(DOTNETCORE) --info
-       $(DOTNETCORE) restore
+#      $(MKDIR_P) $(GENDIR)
+#      $(THRIFT)  -gen netcore:wcf   -r  -out $(GENDIR)  
$(TESTDIR)/CassandraTest.thrift
+#      $(THRIFT)  -gen netcore:wcf   -r  -out $(GENDIR)  
$(top_srcdir)/test/ThriftTest.thrift
+#      $(THRIFT)  -gen netcore:wcf   -r  -out $(GENDIR)  
$(top_srcdir)/contrib/fb303/if/fb303.thrift
        $(DOTNETCORE) build
 
 clean-local:
-       $(RM) Thrift.dll
-       $(RM) -r $(GENDIR)
        $(RM) -r Thrift/bin
        $(RM) -r Thrift/obj
-       $(RM) -r Tests/Thrift.PublicInterfaces.Compile.Tests/bin
-       $(RM) -r Tests/Thrift.PublicInterfaces.Compile.Tests/obj
 
 EXTRA_DIST = \
-                        $(THRIFTCODE) \
+                        Thrift \
                         Thrift.sln \
                         Tests \
                         README.md

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/README.md
----------------------------------------------------------------------
diff --git a/lib/netcore/README.md b/lib/netcore/README.md
index 39492f3..94b047f 100644
--- a/lib/netcore/README.md
+++ b/lib/netcore/README.md
@@ -10,7 +10,10 @@ Thrift client library ported to Microsoft .Net Core
 - .NET Standard 1.6 (SDK 2.0.0)
 
 # How to build on Windows
+- Get Thrift IDL compiler executable, add to some folder and add path to this 
folder into PATH variable
 - Open the Thrift.sln project with Visual Studio and build.
+or 
+- Build with scripts
 
 # How to build on Unix
 - Ensure you have .NET Core 2.0.0 SDK installed or use the Ubuntu Xenial 
docker image

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore
----------------------------------------------------------------------
diff --git a/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore 
b/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore
new file mode 100644
index 0000000..7254c31
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore
@@ -0,0 +1,2 @@
+# ignore for autogenerated files
+/Apache

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
----------------------------------------------------------------------
diff --git 
a/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
 
b/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
new file mode 100644
index 0000000..bc4afa1
--- /dev/null
+++ 
b/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
@@ -0,0 +1,502 @@
+// 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.
+
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using KellermanSoftware.CompareNetObjects;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Protocols;
+using Thrift.Protocols.Entities;
+using Thrift.Transports.Client;
+
+namespace Thrift.IntegrationTests.Protocols
+{
+    [TestClass]
+    public class ProtocolsOperationsTests
+    {
+        private readonly CompareLogic _compareLogic = new CompareLogic();
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol), TMessageType.Call)]
+        [DataRow(typeof(TBinaryProtocol), TMessageType.Exception)]
+        [DataRow(typeof(TBinaryProtocol), TMessageType.Oneway)]
+        [DataRow(typeof(TBinaryProtocol), TMessageType.Reply)]
+        [DataRow(typeof(TCompactProtocol), TMessageType.Call)]
+        [DataRow(typeof(TCompactProtocol), TMessageType.Exception)]
+        [DataRow(typeof(TCompactProtocol), TMessageType.Oneway)]
+        [DataRow(typeof(TCompactProtocol), TMessageType.Reply)]
+        [DataRow(typeof(TJsonProtocol), TMessageType.Call)]
+        [DataRow(typeof(TJsonProtocol), TMessageType.Exception)]
+        [DataRow(typeof(TJsonProtocol), TMessageType.Oneway)]
+        [DataRow(typeof(TJsonProtocol), TMessageType.Reply)]
+        public async Task WriteReadMessage_Test(Type protocolType, 
TMessageType messageType)
+        {
+            var expected = new TMessage(nameof(TMessage), messageType, 1);
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteMessageBeginAsync(expected);
+                    await protocol.WriteMessageEndAsync();
+
+                    stream.Seek(0, SeekOrigin.Begin);
+
+                    var actualMessage = await protocol.ReadMessageBeginAsync();
+                    await protocol.ReadMessageEndAsync();
+
+                    var result = _compareLogic.Compare(expected, 
actualMessage);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        [ExpectedException(typeof(Exception))]
+        public async Task WriteReadStruct_Test(Type protocolType)
+        {
+            var expected = new TStruct(nameof(TStruct));
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteStructBeginAsync(expected);
+                    await protocol.WriteStructEndAsync();
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadStructBeginAsync();
+                    await protocol.ReadStructEndAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        [ExpectedException(typeof(Exception))]
+        public async Task WriteReadField_Test(Type protocolType)
+        {
+            var expected = new TField(nameof(TField), TType.String, 1);
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteFieldBeginAsync(expected);
+                    await protocol.WriteFieldEndAsync();
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadFieldBeginAsync();
+                    await protocol.ReadFieldEndAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadMap_Test(Type protocolType)
+        {
+            var expected = new TMap(TType.String, TType.String, 1);
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteMapBeginAsync(expected);
+                    await protocol.WriteMapEndAsync();
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadMapBeginAsync();
+                    await protocol.ReadMapEndAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadList_Test(Type protocolType)
+        {
+            var expected = new TList(TType.String, 1);
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteListBeginAsync(expected);
+                    await protocol.WriteListEndAsync();
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadListBeginAsync();
+                    await protocol.ReadListEndAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadSet_Test(Type protocolType)
+        {
+            var expected = new TSet(TType.String, 1);
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteSetBeginAsync(expected);
+                    await protocol.WriteSetEndAsync();
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadSetBeginAsync();
+                    await protocol.ReadSetEndAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadBool_Test(Type protocolType)
+        {
+            var expected = true;
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteBoolAsync(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadBoolAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadByte_Test(Type protocolType)
+        {
+            var expected = sbyte.MaxValue;
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteByteAsync(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadByteAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadI16_Test(Type protocolType)
+        {
+            var expected = short.MaxValue;
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteI16Async(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadI16Async();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadI32_Test(Type protocolType)
+        {
+            var expected = int.MaxValue;
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteI32Async(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadI32Async();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadI64_Test(Type protocolType)
+        {
+            var expected = long.MaxValue;
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteI64Async(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadI64Async();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadDouble_Test(Type protocolType)
+        {
+            var expected = double.MaxValue;
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteDoubleAsync(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadDoubleAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadString_Test(Type protocolType)
+        {
+            var expected = nameof(String);
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteStringAsync(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadStringAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        [DataTestMethod]
+        [DataRow(typeof(TBinaryProtocol))]
+        [DataRow(typeof(TCompactProtocol))]
+        [DataRow(typeof(TJsonProtocol))]
+        public async Task WriteReadBinary_Test(Type protocolType)
+        {
+            var expected = Encoding.UTF8.GetBytes(nameof(String));
+
+            try
+            {
+                var tuple = GetProtocolInstance(protocolType);
+                using (var stream = tuple.Item1)
+                {
+                    var protocol = tuple.Item2;
+
+                    await protocol.WriteBinaryAsync(expected);
+
+                    stream?.Seek(0, SeekOrigin.Begin);
+
+                    var actual = await protocol.ReadBinaryAsync();
+
+                    var result = _compareLogic.Compare(expected, actual);
+                    Assert.IsTrue(result.AreEqual, result.DifferencesString);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new Exception($"Exception during testing of protocol: 
{protocolType.FullName}", e);
+            }
+        }
+
+        private static Tuple<Stream, TProtocol> GetProtocolInstance(Type 
protocolType)
+        {
+            var memoryStream = new MemoryStream();
+            var streamClientTransport = new 
TStreamClientTransport(memoryStream, memoryStream);
+            var protocol = (TProtocol) Activator.CreateInstance(protocolType, 
streamClientTransport);
+            return new Tuple<Stream, TProtocol>(memoryStream, protocol);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
----------------------------------------------------------------------
diff --git 
a/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj 
b/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
new file mode 100644
index 0000000..f25dac5
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
+    <AssemblyName>Thrift.IntegrationTests</AssemblyName>
+    <PackageId>Thrift.IntegrationTests</PackageId>
+    <OutputType>Exe</OutputType>
+    <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+    
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+    
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+    
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="CompareNETObjects" Version="4.3.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
+    <PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
+    <PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.4.0" 
/>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore
----------------------------------------------------------------------
diff --git a/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore 
b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore
new file mode 100644
index 0000000..ae929a3
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore
@@ -0,0 +1,4 @@
+# ignore for autogenerated files
+/ThriftTest
+/Apache
+/Facebook

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
----------------------------------------------------------------------
diff --git 
a/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
 
b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
index f551116..c4a84a3 100644
--- 
a/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
+++ 
b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
@@ -18,4 +18,19 @@
     <PackageReference Include="System.ServiceModel.Primitives" 
Version="[4.1.0,)" />
   </ItemGroup>
 
+  <Target Name="PreBuild" 
BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+    <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" 
ConsoleToMSBuild="true">
+      <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+    </Exec>
+    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out 
$(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./CassandraTest.thrift" 
/>
+    <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen 
netcore:wcf,union,serial,hashcode -r ./CassandraTest.thrift" />
+    <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" 
Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen 
netcore:wcf,union,serial,hashcode -r ./CassandraTest.thrift" />
+    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out 
$(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r 
./../../../../test/ThriftTest.thrift" />
+    <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen 
netcore:wcf,union,serial,hashcode -r ./../../../../test/ThriftTest.thrift" />
+    <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" 
Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen 
netcore:wcf,union,serial,hashcode -r ./../../../../test/ThriftTest.thrift" />
+    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out 
$(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r 
./../../../../contrib/fb303/if/fb303.thrift" />
+    <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen 
netcore:wcf,union,serial,hashcode -r 
./../../../../contrib/fb303/if/fb303.thrift" />
+    <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" 
Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen 
netcore:wcf,union,serial,hashcode -r 
./../../../../contrib/fb303/if/fb303.thrift" />
+  </Target>
+
 </Project>

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs 
b/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
new file mode 100644
index 0000000..1be99b4
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
@@ -0,0 +1,83 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Collections;
+
+namespace Thrift.Tests.Collections
+{
+    // ReSharper disable once InconsistentNaming
+    [TestClass]
+    public class TCollectionsTests
+    {
+        //TODO: Add tests for IEnumerable with objects and primitive values 
inside
+
+        [TestMethod]
+        public void TCollection_Equals_Primitive_Test()
+        {
+            var collection1 = new List<int> {1,2,3};
+            var collection2 = new List<int> {1,2,3};
+
+            var result = TCollections.Equals(collection1, collection2);
+
+            Assert.IsTrue(result);
+        }
+
+        [TestMethod]
+        public void TCollection_Equals_Primitive_Different_Test()
+        {
+            var collection1 = new List<int> { 1, 2, 3 };
+            var collection2 = new List<int> { 1, 2 };
+
+            var result = TCollections.Equals(collection1, collection2);
+
+            Assert.IsFalse(result);
+        }
+
+        [TestMethod]
+        public void TCollection_Equals_Objects_Test()
+        {
+            var collection1 = new List<ExampleClass> { new ExampleClass { X = 
1 }, new ExampleClass { X = 2 } };
+            var collection2 = new List<ExampleClass> { new ExampleClass { X = 
1 }, new ExampleClass { X = 2 } };
+
+            var result = TCollections.Equals(collection1, collection2);
+
+            // references to different collections
+            Assert.IsFalse(result);
+        }
+
+        [TestMethod]
+        public void TCollection_Equals_OneAndTheSameObject_Test()
+        {
+            var collection1 = new List<ExampleClass> { new ExampleClass { X = 
1 }, new ExampleClass { X = 2 } };
+            var collection2 = collection1;
+
+            var result = TCollections.Equals(collection1, collection2);
+
+            // references to one and the same collection
+            Assert.IsTrue(result);
+        }
+
+        private class ExampleClass
+        {
+            public int X { get; set; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs 
b/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs
new file mode 100644
index 0000000..8de573e
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs
@@ -0,0 +1,71 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Collections;
+
+namespace Thrift.Tests.Collections
+{
+    // ReSharper disable once InconsistentNaming
+    [TestClass]
+    public class THashSetTests
+    {
+        [TestMethod]
+        public void THashSet_Equals_Primitive_Test()
+        {
+            const int value = 1;
+
+            var hashSet = new THashSet<int> {value};
+            
+            Assert.IsTrue(hashSet.Contains(value));
+
+            hashSet.Remove(value);
+
+            Assert.IsTrue(hashSet.Count == 0);
+
+            hashSet.Add(value);
+
+            Assert.IsTrue(hashSet.Contains(value));
+
+            hashSet.Clear();
+
+            Assert.IsTrue(hashSet.Count == 0);
+
+            var newArr = new int[1];
+            hashSet.Add(value);
+            hashSet.CopyTo(newArr, 0);
+
+            Assert.IsTrue(newArr.Contains(value));
+
+            var en = hashSet.GetEnumerator();
+            en.MoveNext();
+
+            Assert.IsTrue((int)en.Current == value);
+            
+            using (var ien = ((IEnumerable<int>)hashSet).GetEnumerator())
+            {
+                ien.MoveNext();
+
+                Assert.IsTrue(ien.Current == value);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
----------------------------------------------------------------------
diff --git 
a/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs 
b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
new file mode 100644
index 0000000..cdc8317
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
@@ -0,0 +1,172 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Protocols;
+using Thrift.Protocols.Entities;
+using Thrift.Protocols.Utilities;
+
+namespace Thrift.Tests.Protocols
+{
+    [TestClass]
+    public class TJSONProtocolHelperTests
+    {
+        [TestMethod]
+        public void GetTypeNameForTypeId_Test()
+        {
+            // input/output
+            var sets = new List<Tuple<TType, byte[]>>
+            {
+                new Tuple<TType, byte[]>(TType.Bool, 
TJSONProtocolConstants.TypeNames.NameBool),
+                new Tuple<TType, byte[]>(TType.Byte, 
TJSONProtocolConstants.TypeNames.NameByte),
+                new Tuple<TType, byte[]>(TType.I16, 
TJSONProtocolConstants.TypeNames.NameI16),
+                new Tuple<TType, byte[]>(TType.I32, 
TJSONProtocolConstants.TypeNames.NameI32),
+                new Tuple<TType, byte[]>(TType.I64, 
TJSONProtocolConstants.TypeNames.NameI64),
+                new Tuple<TType, byte[]>(TType.Double, 
TJSONProtocolConstants.TypeNames.NameDouble),
+                new Tuple<TType, byte[]>(TType.String, 
TJSONProtocolConstants.TypeNames.NameString),
+                new Tuple<TType, byte[]>(TType.Struct, 
TJSONProtocolConstants.TypeNames.NameStruct),
+                new Tuple<TType, byte[]>(TType.Map, 
TJSONProtocolConstants.TypeNames.NameMap),
+                new Tuple<TType, byte[]>(TType.Set, 
TJSONProtocolConstants.TypeNames.NameSet),
+                new Tuple<TType, byte[]>(TType.List, 
TJSONProtocolConstants.TypeNames.NameList),
+            };
+
+            foreach (var t in sets)
+            {
+                
Assert.IsTrue(TJSONProtocolHelper.GetTypeNameForTypeId(t.Item1) == t.Item2, 
$"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}");
+            }
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(TProtocolException))]
+        public void GetTypeNameForTypeId_TStop_Test()
+        {
+            TJSONProtocolHelper.GetTypeNameForTypeId(TType.Stop);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(TProtocolException))]
+        public void GetTypeNameForTypeId_NonExistingTType_Test()
+        {
+            TJSONProtocolHelper.GetTypeNameForTypeId((TType)100);
+        }
+
+        [TestMethod]
+        public void GetTypeIdForTypeName_Test()
+        {
+            // input/output
+            var sets = new List<Tuple<TType, byte[]>>
+            {
+                new Tuple<TType, byte[]>(TType.Bool, 
TJSONProtocolConstants.TypeNames.NameBool),
+                new Tuple<TType, byte[]>(TType.Byte, 
TJSONProtocolConstants.TypeNames.NameByte),
+                new Tuple<TType, byte[]>(TType.I16, 
TJSONProtocolConstants.TypeNames.NameI16),
+                new Tuple<TType, byte[]>(TType.I32, 
TJSONProtocolConstants.TypeNames.NameI32),
+                new Tuple<TType, byte[]>(TType.I64, 
TJSONProtocolConstants.TypeNames.NameI64),
+                new Tuple<TType, byte[]>(TType.Double, 
TJSONProtocolConstants.TypeNames.NameDouble),
+                new Tuple<TType, byte[]>(TType.String, 
TJSONProtocolConstants.TypeNames.NameString),
+                new Tuple<TType, byte[]>(TType.Struct, 
TJSONProtocolConstants.TypeNames.NameStruct),
+                new Tuple<TType, byte[]>(TType.Map, 
TJSONProtocolConstants.TypeNames.NameMap),
+                new Tuple<TType, byte[]>(TType.Set, 
TJSONProtocolConstants.TypeNames.NameSet),
+                new Tuple<TType, byte[]>(TType.List, 
TJSONProtocolConstants.TypeNames.NameList),
+            };
+
+            foreach (var t in sets)
+            {
+                
Assert.IsTrue(TJSONProtocolHelper.GetTypeIdForTypeName(t.Item2) == t.Item1, 
$"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}");
+            }
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(TProtocolException))]
+        public void GetTypeIdForTypeName_TStopTypeName_Test()
+        {
+            TJSONProtocolHelper.GetTypeIdForTypeName(new []{(byte)TType.Stop, 
(byte)TType.Stop});
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(TProtocolException))]
+        public void GetTypeIdForTypeName_NonExistingTypeName_Test()
+        {
+            TJSONProtocolHelper.GetTypeIdForTypeName(new byte[]{100});
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(TProtocolException))]
+        public void GetTypeIdForTypeName_EmptyName_Test()
+        {
+            TJSONProtocolHelper.GetTypeIdForTypeName(new byte[] {});
+        }
+
+        [TestMethod]
+        public void IsJsonNumeric_Test()
+        {
+            // input/output
+            var correctJsonNumeric = "+-.0123456789Ee";
+            var incorrectJsonNumeric = "AaBcDd/*\\";
+
+            var sets = correctJsonNumeric.Select(ch => new Tuple<byte, 
bool>((byte) ch, true)).ToList();
+            sets.AddRange(incorrectJsonNumeric.Select(ch => new Tuple<byte, 
bool>((byte) ch, false)));
+
+            foreach (var t in sets)
+            {
+                Assert.IsTrue(TJSONProtocolHelper.IsJsonNumeric(t.Item1) == 
t.Item2, $"Wrong mapping of Char {t.Item1} to bool: {t.Item2}");
+            }
+        }
+
+        [TestMethod]
+        public void ToHexVal_Test()
+        {
+            // input/output
+            var chars = "0123456789abcdef";
+            var expectedHexValues = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
10, 11, 12, 13, 14, 15};
+
+            var sets = chars.Select((ch, i) => new Tuple<char, byte>(ch, 
expectedHexValues[i])).ToList();
+
+            foreach (var t in sets)
+            {
+                var actualResult = TJSONProtocolHelper.ToHexVal((byte)t.Item1);
+                Assert.IsTrue(actualResult == t.Item2, $"Wrong mapping of char 
byte {t.Item1} to it expected hex value: {t.Item2}. Actual hex value: 
{actualResult}");
+            }
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(TProtocolException))]
+        public void ToHexVal_WrongInputChar_Test()
+        {
+            TJSONProtocolHelper.ToHexVal((byte)'s');
+        }
+
+        [TestMethod]
+        public void ToHexChar_Test()
+        {
+            // input/output
+            var hexValues = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
12, 13, 14, 15 };
+            var expectedChars = "0123456789abcdef";
+            
+
+            var sets = hexValues.Select((hv, i) => new Tuple<byte, char>(hv, 
expectedChars[i])).ToList();
+
+            foreach (var t in sets)
+            {
+                var actualResult = TJSONProtocolHelper.ToHexChar(t.Item1);
+                Assert.IsTrue(actualResult == t.Item2, $"Wrong mapping of hex 
value {t.Item1} to it expected char: {t.Item2}. Actual hex value: 
{actualResult}");
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs 
b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs
new file mode 100644
index 0000000..5237360
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs
@@ -0,0 +1,67 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NSubstitute;
+using Thrift.Protocols;
+using Thrift.Protocols.Entities;
+using Thrift.Transports;
+using Thrift.Transports.Client;
+
+namespace Thrift.Tests.Protocols
+{
+    // ReSharper disable once InconsistentNaming
+    [TestClass]
+    public class TJSONProtocolTests
+    {
+        [TestMethod]
+        public void TJSONProtocol_Can_Create_Instance_Test()
+        {
+            var httpClientTransport = Substitute.For<THttpClientTransport>(new 
Uri("http://localhost";), null);
+
+            var result = new TJSONProtocolWrapper(httpClientTransport);
+
+            Assert.IsNotNull(result);
+            Assert.IsNotNull(result.WrappedContext);
+            Assert.IsNotNull(result.WrappedReader);
+            Assert.IsNotNull(result.Transport);
+            Assert.IsTrue(result.WrappedRecursionDepth == 0);
+            Assert.IsTrue(result.WrappedRecursionLimit == 
TProtocol.DefaultRecursionDepth);
+
+            Assert.IsTrue(result.Transport.Equals(httpClientTransport));
+            
Assert.IsTrue(result.WrappedContext.GetType().Name.Equals("JSONBaseContext", 
StringComparison.OrdinalIgnoreCase));
+            
Assert.IsTrue(result.WrappedReader.GetType().Name.Equals("LookaheadReader", 
StringComparison.OrdinalIgnoreCase));
+        }
+
+        private class TJSONProtocolWrapper : TJsonProtocol
+        {
+            public TJSONProtocolWrapper(TClientTransport trans) : base(trans)
+            {
+            }
+
+            public object WrappedContext => Context;
+            public object WrappedReader => Reader;
+            public int WrappedRecursionDepth => RecursionDepth;
+            public int WrappedRecursionLimit => RecursionLimit;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj
----------------------------------------------------------------------
diff --git a/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj 
b/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj
new file mode 100644
index 0000000..e46f165
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj
@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="CompareNETObjects" Version="4.3.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
+    <PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
+    <PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
+    <PackageReference Include="NSubstitute" Version="3.1.0" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Thrift.sln
----------------------------------------------------------------------
diff --git a/lib/netcore/Thrift.sln b/lib/netcore/Thrift.sln
index a730269..fe30aa5 100644
--- a/lib/netcore/Thrift.sln
+++ b/lib/netcore/Thrift.sln
@@ -4,10 +4,14 @@ VisualStudioVersion = 15.0.26730.12
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", 
"{F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = 
"Thrift.PublicInterfaces.Compile.Tests", 
"Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj",
 "{0676962B-98C2-49EC-B4C4-7A0451D0640B}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", 
"Thrift\Thrift.csproj", "{D85F572F-7D80-40A4-9A9B-2731ED187C24}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", 
"Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj", 
"{9F9A11BF-3C95-4E80-AFBF-768541996844}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Tests", 
"Tests\Thrift.Tests\Thrift.Tests.csproj", 
"{75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = 
"Thrift.PublicInterfaces.Compile.Tests", 
"Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj",
 "{A429F05B-F511-45EF-AE7B-04E1AE9C9367}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
@@ -18,18 +22,6 @@ Global
                Release|x86 = Release|x86
        EndGlobalSection
        GlobalSection(ProjectConfigurationPlatforms) = postSolution
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|Any CPU.ActiveCfg 
= Debug|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x64.ActiveCfg = 
Debug|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x64.Build.0 = 
Debug|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x86.ActiveCfg = 
Debug|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x86.Build.0 = 
Debug|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|Any 
CPU.ActiveCfg = Release|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|Any CPU.Build.0 
= Release|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x64.ActiveCfg = 
Release|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x64.Build.0 = 
Release|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x86.ActiveCfg = 
Release|Any CPU
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x86.Build.0 = 
Release|Any CPU
                {D85F572F-7D80-40A4-9A9B-2731ED187C24}.Debug|Any CPU.ActiveCfg 
= Debug|Any CPU
                {D85F572F-7D80-40A4-9A9B-2731ED187C24}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
                {D85F572F-7D80-40A4-9A9B-2731ED187C24}.Debug|x64.ActiveCfg = 
Debug|Any CPU
@@ -42,12 +34,50 @@ Global
                {D85F572F-7D80-40A4-9A9B-2731ED187C24}.Release|x64.Build.0 = 
Release|Any CPU
                {D85F572F-7D80-40A4-9A9B-2731ED187C24}.Release|x86.ActiveCfg = 
Release|Any CPU
                {D85F572F-7D80-40A4-9A9B-2731ED187C24}.Release|x86.Build.0 = 
Release|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|Any CPU.ActiveCfg 
= Debug|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x64.ActiveCfg = 
Debug|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x64.Build.0 = 
Debug|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x86.ActiveCfg = 
Debug|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x86.Build.0 = 
Debug|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|Any 
CPU.ActiveCfg = Release|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|Any CPU.Build.0 
= Release|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x64.ActiveCfg = 
Release|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x64.Build.0 = 
Release|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x86.ActiveCfg = 
Release|Any CPU
+               {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x86.Build.0 = 
Release|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|Any CPU.ActiveCfg 
= Debug|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x64.ActiveCfg = 
Debug|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x64.Build.0 = 
Debug|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x86.ActiveCfg = 
Debug|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x86.Build.0 = 
Debug|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|Any 
CPU.ActiveCfg = Release|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|Any CPU.Build.0 
= Release|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x64.ActiveCfg = 
Release|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x64.Build.0 = 
Release|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x86.ActiveCfg = 
Release|Any CPU
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x86.Build.0 = 
Release|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|Any CPU.ActiveCfg 
= Debug|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|Any CPU.Build.0 = 
Debug|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x64.ActiveCfg = 
Debug|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x64.Build.0 = 
Debug|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x86.ActiveCfg = 
Debug|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x86.Build.0 = 
Debug|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|Any 
CPU.ActiveCfg = Release|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|Any CPU.Build.0 
= Release|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x64.ActiveCfg = 
Release|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x64.Build.0 = 
Release|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x86.ActiveCfg = 
Release|Any CPU
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x86.Build.0 = 
Release|Any CPU
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
        GlobalSection(NestedProjects) = preSolution
-               {0676962B-98C2-49EC-B4C4-7A0451D0640B} = 
{F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
+               {9F9A11BF-3C95-4E80-AFBF-768541996844} = 
{F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
+               {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1} = 
{F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
+               {A429F05B-F511-45EF-AE7B-04E1AE9C9367} = 
{F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {FD20BC4A-0109-41D8-8C0C-893E784D7EF9}

http://git-wip-us.apache.org/repos/asf/thrift/blob/54993296/lib/netcore/Thrift/Protocols/TAbstractBase.cs
----------------------------------------------------------------------
diff --git a/lib/netcore/Thrift/Protocols/TAbstractBase.cs 
b/lib/netcore/Thrift/Protocols/TAbstractBase.cs
index eddb85e..4e18681 100644
--- a/lib/netcore/Thrift/Protocols/TAbstractBase.cs
+++ b/lib/netcore/Thrift/Protocols/TAbstractBase.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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

Reply via email to