Revert "THRIFT-4982 Remove deprecated C# bindings from the code base"

Only compiler, test, lib and tutorial code.
diff --git a/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs b/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f5f0000
--- /dev/null
+++ b/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ThriftMSBuildTask")]
+[assembly: AssemblyDescription("MSBuild Task to generate csharp from .thrift files, and compile the code into a library: ThriftImpl.dll")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("ThriftMSBuildTask")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+//@TODO where to put License information?
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5095e09d-7b95-4be1-b250-e1c1db1c485e")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.14.0.*")]
+[assembly: AssemblyFileVersion("0.14.0.*")]
diff --git a/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs b/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
new file mode 100644
index 0000000..4e6d301
--- /dev/null
+++ b/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
@@ -0,0 +1,246 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Tasks;
+using System.IO;
+using System.Diagnostics;
+
+namespace ThriftMSBuildTask
+{
+    /// <summary>
+    /// MSBuild Task to generate csharp from .thrift files, and compile the code into a library: ThriftImpl.dll
+    /// </summary>
+    public class ThriftBuild : Task
+    {
+        /// <summary>
+        /// The full path to the thrift.exe compiler
+        /// </summary>
+        [Required]
+        public ITaskItem ThriftExecutable
+        {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// The full path to a thrift.dll C# library
+        /// </summary>
+        [Required]
+        public ITaskItem ThriftLibrary
+        {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// A direcotry containing .thrift files
+        /// </summary>
+        [Required]
+        public ITaskItem ThriftDefinitionDir
+        {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// The name of the auto-gen and compiled thrift library. It will placed in
+        /// the same directory as ThriftLibrary
+        /// </summary>
+        [Required]
+        public ITaskItem OutputName
+        {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// The full path to the compiled ThriftLibrary. This allows msbuild tasks to use this
+        /// output as a variable for use elsewhere.
+        /// </summary>
+        [Output]
+        public ITaskItem ThriftImplementation
+        {
+            get { return thriftImpl; }
+        }
+
+        private ITaskItem thriftImpl;
+        private const string lastCompilationName = "LAST_COMP_TIMESTAMP";
+
+        //use the Message Build Task to write something to build log
+        private void LogMessage(string text, MessageImportance importance)
+        {
+            Message m = new Message();
+            m.Text = text;
+            m.Importance = importance.ToString();
+            m.BuildEngine = this.BuildEngine;
+            m.Execute();
+        }
+
+        //recursively find .cs files in srcDir, paths should initially be non-null and empty
+        private void FindSourcesHelper(string srcDir, List<string> paths)
+        {
+            string[] files = Directory.GetFiles(srcDir, "*.cs");
+            foreach (string f in files)
+            {
+                paths.Add(f);
+            }
+            string[] dirs = Directory.GetDirectories(srcDir);
+            foreach (string dir in dirs)
+            {
+                FindSourcesHelper(dir, paths);
+            }
+        }
+
+        /// <summary>
+        /// Quote paths with spaces
+        /// </summary>
+        private string SafePath(string path)
+        {
+            if (path.Contains(' ') && !path.StartsWith("\""))
+            {
+                return "\"" + path + "\"";
+            }
+            return path;
+        }
+
+        private ITaskItem[] FindSources(string srcDir)
+        {
+            List<string> files = new List<string>();
+            FindSourcesHelper(srcDir, files);
+            ITaskItem[] items = new ITaskItem[files.Count];
+            for (int i = 0; i < items.Length; i++)
+            {
+                items[i] = new TaskItem(files[i]);
+            }
+            return items;
+        }
+
+        private string LastWriteTime(string defDir)
+        {
+            string[] files = Directory.GetFiles(defDir, "*.thrift");
+            DateTime d = (new DirectoryInfo(defDir)).LastWriteTime;
+            foreach(string file in files)
+            {
+                FileInfo f = new FileInfo(file);
+                DateTime curr = f.LastWriteTime;
+                if (DateTime.Compare(curr, d) > 0)
+                {
+                    d = curr;
+                }
+            }
+            return d.ToFileTimeUtc().ToString();
+        }
+
+        public override bool Execute()
+        {
+            string defDir = SafePath(ThriftDefinitionDir.ItemSpec);
+            //look for last compilation timestamp
+            string lastBuildPath = Path.Combine(defDir, lastCompilationName);
+            DirectoryInfo defDirInfo = new DirectoryInfo(defDir);
+            string lastWrite = LastWriteTime(defDir);
+            if (File.Exists(lastBuildPath))
+            {
+                string lastComp = File.ReadAllText(lastBuildPath);
+                //don't recompile if the thrift library has been updated since lastComp
+                FileInfo f = new FileInfo(ThriftLibrary.ItemSpec);
+                string thriftLibTime = f.LastWriteTimeUtc.ToFileTimeUtc().ToString();
+                if (lastComp.CompareTo(thriftLibTime) < 0)
+                {
+                    //new thrift library, do a compile
+                    lastWrite = thriftLibTime;
+                }
+                else if (lastComp == lastWrite || (lastComp == thriftLibTime && lastComp.CompareTo(lastWrite) > 0))
+                {
+                    //the .thrift dir hasn't been written to since last compilation, don't need to do anything
+                    LogMessage("ThriftImpl up-to-date", MessageImportance.High);
+                    return true;
+                }
+            }
+
+            //find the directory of the thriftlibrary (that's where output will go)
+            FileInfo thriftLibInfo = new FileInfo(SafePath(ThriftLibrary.ItemSpec));
+            string thriftDir = thriftLibInfo.Directory.FullName;
+
+            string genDir = Path.Combine(thriftDir, "gen-csharp");
+            if (Directory.Exists(genDir))
+            {
+                try
+                {
+                    Directory.Delete(genDir, true);
+                }
+                catch { /*eh i tried, just over-write now*/}
+            }
+
+            //run the thrift executable to generate C#
+            foreach (string thriftFile in Directory.GetFiles(defDir, "*.thrift"))
+            {
+                LogMessage("Generating code for: " + thriftFile, MessageImportance.Normal);
+                Process p = new Process();
+                p.StartInfo.FileName = SafePath(ThriftExecutable.ItemSpec);
+                p.StartInfo.Arguments = "--gen csharp -o " + SafePath(thriftDir) + " -r " + thriftFile;
+                p.StartInfo.UseShellExecute = false;
+                p.StartInfo.CreateNoWindow = true;
+                p.StartInfo.RedirectStandardOutput = false;
+                p.Start();
+                p.WaitForExit();
+                if (p.ExitCode != 0)
+                {
+                    LogMessage("thrift.exe failed to compile " + thriftFile, MessageImportance.High);
+                    return false;
+                }
+                if (p.ExitCode != 0)
+                {
+                    LogMessage("thrift.exe failed to compile " + thriftFile, MessageImportance.High);
+                    return false;
+                }
+            }
+
+            Csc csc = new Csc();
+            csc.TargetType = "library";
+            csc.References = new ITaskItem[] { new TaskItem(ThriftLibrary.ItemSpec) };
+            csc.EmitDebugInformation = true;
+            string outputPath = Path.Combine(thriftDir, OutputName.ItemSpec);
+            csc.OutputAssembly = new TaskItem(outputPath);
+            csc.Sources = FindSources(Path.Combine(thriftDir, "gen-csharp"));
+            csc.BuildEngine = this.BuildEngine;
+            LogMessage("Compiling generated cs...", MessageImportance.Normal);
+            if (!csc.Execute())
+            {
+                return false;
+            }
+
+            //write file to defDir to indicate a build was successfully completed
+            File.WriteAllText(lastBuildPath, lastWrite);
+
+            thriftImpl = new TaskItem(outputPath);
+
+            return true;
+        }
+    }
+}
diff --git a/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj b/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
new file mode 100644
index 0000000..2589970
--- /dev/null
+++ b/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+-->
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{EC0A0231-66EA-4593-A792-C6CA3BB8668E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ThriftMSBuildTask</RootNamespace>
+    <AssemblyName>ThriftMSBuildTask</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>0.14.0.0</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Build.Framework" />
+    <Reference Include="Microsoft.Build.Tasks" />
+    <Reference Include="Microsoft.Build.Utilities" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ThriftBuild.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>