diff --git a/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs b/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
index 75bb339..4e6d301 100644
--- a/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
+++ b/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
@@ -33,214 +33,214 @@
 
 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>
+    /// 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>
+        /// 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>
+        /// 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 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; }
-		}
+        /// <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";
+        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();
-		}
+        //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);
-			}
-		}
+        //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;
-		}
+        /// <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 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();
-		}
+        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;
-				}
-			}
+        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;
+            //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*/}
-			}
+            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;
-				}
-			}
+            //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;
-			}
+            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);
+            //write file to defDir to indicate a build was successfully completed
+            File.WriteAllText(lastBuildPath, lastWrite);
 
-			thriftImpl = new TaskItem(outputPath);
+            thriftImpl = new TaskItem(outputPath);
 
-			return true;
-		}
-	}
+            return true;
+        }
+    }
 }
