CAC-1 Fixed how URIs are escaped when code is generated.

--- src/Cachifier/CodeGenerator.cs
+++ src/Cachifier/CodeGenerator.cs
@@ -99,13 +99,10 @@
                         writer.Indent++;
                         writer.WriteLine("definition = new ScriptResourceDefinition();");

+                        string relativeUri;
                         if (!resource.IsEmbedded)
                         {
-                            var relativeUri = resource.RelativePath.Replace('\\', '/');
-                            if (forceLowercase)
-                            {
-                                relativeUri = relativeUri.ToLowerInvariant();
-                            }
+                            relativeUri = NormalizeRelativeUri(resource.RelativePath, forceLowercase);
                             writer.WriteLine("if(IsDebuggingEnabled)");
                             writer.WriteLine("{");
                             writer.Indent++;
@@ -116,11 +113,7 @@
                             writer.WriteLine("else");
                             writer.WriteLine("{");
                             writer.Indent++;
-                            relativeUri = resource.RelativeHashifiedPath.Replace('\\', '/');
-                            if (forceLowercase)
-                            {
-                                relativeUri = relativeUri.ToLowerInvariant();
-                            }
+                            relativeUri = NormalizeRelativeUri(resource.RelativeHashifiedPath, forceLowercase);
                             writer.WriteLine("definition.Path = \"~/{1}/{0}\";", relativeUri, outputPath);
                             writer.WriteLine("definition.DebugPath = \"~/{1}/{0}\";", relativeUri, outputPath);
                             writer.Indent--;
@@ -132,21 +125,28 @@
                             writer.WriteLine("definition.ResourceName = \"{0}\";", resource.Name);
                         }

-
-                        var relativeUri1 = resource.RelativeHashifiedPath.Replace('\\', '/');
-                        if (forceLowercase)
+                        if (resource.RelativeHashifiedPath != null)
                         {
-                            relativeUri1 = relativeUri1.ToLowerInvariant();
+                            if (!string.IsNullOrWhiteSpace(cdnBaseUri))
+                            {
+                                Uri baseUri;
+                                if (Uri.TryCreate(cdnBaseUri, UriKind.Absolute, out baseUri))
+                                {
+                                    relativeUri = NormalizeRelativeUri(resource.RelativeHashifiedPath, forceLowercase);
+                                    // Double escape the damn string because creating a Uri will unescape it... Go figure.
+                                    relativeUri = NormalizeRelativeUri(relativeUri, forceLowercase);
+                                    Uri uri;
+                                    if (Uri.TryCreate(baseUri, relativeUri, out uri))
+                                    {
+                                        writer.WriteLine("definition.CdnPath = \"{0}\";", uri);
+                                        writer.WriteLine("definition.CdnDebugPath = \"{0}\";", uri);
+                                        writer.WriteLine("definition.CdnSupportsSecureConnection = true;");
+                                    }
+                                }
+                            }
                         }
-                        var baseUri = new Uri(cdnBaseUri, UriKind.Absolute);
-                        var uri1 = new Uri(baseUri, relativeUri1);
-                        var uri = uri1;

-                        writer.WriteLine("definition.CdnPath = \"{0}\";", uri);
-                        writer.WriteLine("definition.CdnDebugPath = \"{0}\";", uri);
-                        writer.WriteLine("definition.CdnSupportsSecureConnection = true;");
-                        writer.WriteLine(
-                                         "ScriptManager.ScriptResourceMapping.AddDefinition(\"{0}\", {1}, definition);",
+                        writer.WriteLine("ScriptManager.ScriptResourceMapping.AddDefinition(\"{0}\", {1}, definition);",
                             resource.Name,
                             assemblyName);
                         writer.WriteLine();
@@ -177,5 +177,20 @@
                 }
             }
         }
+
+        [NotNull]
+        private static string NormalizeRelativeUri([NotNull] string relativePath, bool forceLowercase)
+        {
+            if (relativePath == null)
+            {
+                throw new ArgumentNullException("relativePath");
+            }
+            var relativeUri = relativePath.Replace('\\', '/');
+            if (forceLowercase)
+            {
+                relativeUri = relativeUri.ToLowerInvariant();
+            }
+            return Uri.EscapeUriString(relativeUri);
+        }
     }
 }


Unbind queue when disposing

Unbind queue when disposing

--- Thinktecture.Relay.Server/Communication/RabbitMq/RabbitMqMessageDispatcher.cs
+++ Thinktecture.Relay.Server/Communication/RabbitMq/RabbitMqMessageDispatcher.cs
@@ -138,6 +138,7 @@
 					lock (_model)
 					{
 						_model.BasicCancel(consumerTag);
+						_model.QueueUnbind(queueName, _EXCHANGE_NAME, null);
 					}
 				});
 			});


Remove static method

Remove static method

--- WindowsSolutionUniversal/UnityProject/UnityProject.Shared/Config/AppConfig.cs
+++ WindowsSolutionUniversal/UnityProject/UnityProject.Shared/Config/AppConfig.cs
@@ -62,7 +62,7 @@
             }
         }

-        internal async static Task<string> GetFacebookConfigValue(string node, string attribute)
+        internal async Task<string> GetFacebookConfigValue(string node, string attribute)
         {
             var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///FacebookConfig.xml"));
             using (Stream strm = await file.OpenStreamForReadAsync())


Re-added support for reduce and aggregate in the Bohrium CIL bridge

--- bridge/NumCIL/NumCIL.Bohrium/BohriumAccessor.cs
+++ bridge/NumCIL/NumCIL.Bohrium/BohriumAccessor.cs
@@ -191,7 +191,9 @@

             res[typeof(NumCIL.CopyOp<T>)] = bh_opcode.BH_IDENTITY;
             res[typeof(NumCIL.GenerateOp<T>)] = bh_opcode.BH_IDENTITY;
-            if (VEM.Instance.SupportsRandom)
+			res[typeof(NumCIL.UFunc.LazyReduceOperation<T>)] = bh_opcode.BH_USERFUNC;
+			res[typeof(NumCIL.UFunc.LazyAggregateOperation<T>)] = bh_opcode.BH_USERFUNC;
+			if (VEM.Instance.SupportsRandom)
 			{
                 res[typeof(NumCIL.Generic.IRandomGeneratorOp<T>)] = bh_opcode.BH_USERFUNC;
 				try { res[basic.Assembly.GetType("NumCIL.Generic.RandomGeneratorOp" + typeof(T).Name)] = bh_opcode.BH_USERFUNC; }
@@ -702,10 +704,37 @@

 			if (continuationList.Count > 0)
 				ExecuteWithFailureDetection(continuationList);
-
+		}
+
+		private bh_opcode GetReduceOpCode(IBinaryOp<T> operation)
+		{
+			bh_opcode reduce_opcode;
+			if (OpcodeMap.TryGetValue(operation.GetType(), out reduce_opcode))
+			{
+				switch(reduce_opcode)
+				{
+					case bh_opcode.BH_ADD:
+						return bh_opcode.BH_ADD_REDUCE;
+					case bh_opcode.BH_MULTIPLY:
+						return bh_opcode.BH_MULTIPLY_REDUCE;
+					case bh_opcode.BH_MINIMUM:
+						return bh_opcode.BH_MINIMUM_REDUCE;
+					case bh_opcode.BH_MAXIMUM:
+						return bh_opcode.BH_MAXIMUM_REDUCE;
+					case bh_opcode.BH_BITWISE_AND:
+						return bh_opcode.BH_BITWISE_AND_REDUCE;
+					case bh_opcode.BH_BITWISE_OR:
+						return bh_opcode.BH_BITWISE_OR_REDUCE;
+					case bh_opcode.BH_LOGICAL_AND:
+						return bh_opcode.BH_LOGICAL_AND_REDUCE;
+					case bh_opcode.BH_LOGICAL_OR:
+						return bh_opcode.BH_LOGICAL_OR_REDUCE;
+				}
+			}

+			return bh_opcode.BH_NONE;
 		}
-
+
 		/// <summary>
 		/// Executes all pending operations in the list
 		/// </summary>
@@ -747,7 +776,9 @@

                     if (opcode == bh_opcode.BH_USERFUNC)
                     {
-                        if (VEM.SupportsRandom && ops is NumCIL.Generic.IRandomGeneratorOp<T>)
+						isSupported = false;
+
+						if (VEM.SupportsRandom && ops is NumCIL.Generic.IRandomGeneratorOp<T>)
                         {
                             //Bohrium only supports random for plain arrays
                             if (operands[0].Shape.IsPlain && operands[0].Shape.Offset == 0 && operands[0].Shape.Elements == operands[0].DataAccessor.Length)
@@ -759,9 +790,47 @@
                         else if (VEM.SupportsMatmul && ops is NumCIL.UFunc.LazyMatmulOperation<T>)
                         {
                             supported.Add(VEM.CreateMatmulInstruction<T>(BH_TYPE, operands[0], operands[1], operands[2]));
+                            isSupported = true;
                         }
-
-                        if (!isSupported)
+						else if (ops is NumCIL.UFunc.LazyReduceOperation<T>)
+						{
+							NumCIL.UFunc.LazyReduceOperation<T> lzop = (NumCIL.UFunc.LazyReduceOperation<T>)op.Operation;
+							bh_opcode rop = GetReduceOpCode(lzop.Operation);
+							if (rop != bh_opcode.BH_NONE)
+							{
+								supported.Add(VEM.CreateInstruction<T>(BH_TYPE, rop, operands[0], operands[1], new PInvoke.bh_constant(lzop.Axis)));
+								isSupported = true;
+							}
+						}
+						else if (ops is NumCIL.UFunc.LazyAggregateOperation<T>)
+						{
+							NumCIL.UFunc.LazyAggregateOperation<T> lzop = (NumCIL.UFunc.LazyAggregateOperation<T>)op.Operation;
+							bh_opcode rop = GetReduceOpCode(lzop.Operation);
+							if (rop != bh_opcode.BH_NONE)
+							{
+								var sourceOp = operands[1];
+								NumCIL.Generic.NdArray<T> targetOp;
+
+								if (sourceOp.Shape.Dimensions.LongLength > 1)
+								{
+									do
+									{
+										var targetShape = new Shape.ShapeDimension[sourceOp.Shape.Dimensions.LongLength - 1];
+										Array.Copy(sourceOp.Shape.Dimensions, targetShape, targetShape.LongLength);
+										targetOp = new NumCIL.Generic.NdArray<T>(new Shape(targetShape));
+
+										supported.Add(VEM.CreateInstruction<T>(BH_TYPE, rop, targetOp, sourceOp, new PInvoke.bh_constant(targetOp.Shape.Dimensions.LongLength)));
+										sourceOp = targetOp;
+
+									} while(targetOp.Shape.Dimensions.LongLength > 1);
+								}
+
+								supported.Add(VEM.CreateInstruction<T>(BH_TYPE, rop, operands[0], sourceOp, new PInvoke.bh_constant(0L)));
+								isSupported = true;
+							}
+						}
+
+						if (!isSupported)
                         {
                             if (supported.Count > 0)
                                 ExecuteWithFailureDetection(supported);


fixing bug forcing file output regardless of arguments

--- Program.cs
+++ Program.cs
@@ -233,6 +233,7 @@
                 if (args.Length < 1)
                     return;

+                this.OutputToFile = false;
                 for (int i = 0; i < args.Length; i += 1)
                 {
                     switch (args[i])
@@ -246,6 +247,10 @@
                         case "-f":
                         case "--file":
                             this.OutputToFile = true;
+                            break;
+                        case "-f-":
+                        case "--file-":
+                            this.OutputToFile = false;
                             break;
                         case "-i":
                         case "--ignore":
@@ -272,12 +277,14 @@

                 if (this.DisplayHelp)
                 {
-                    Console.WriteLine(@"{0} [-f] [-i <ignore pattern>] [<path to project file or directory>]
+                    Console.WriteLine(@"{0} [-f] [-i <ignore pattern>] [<path to project file or dir>]

 Scans Visual Studio project files for missing, duplicate, or dead references.

-  -f/file   (Optional) Writes issues to file and opens it after scanning,
-          otherwise writes output to the console.
+  -f[-]/file[-] (Optional) Writes issues to file and opens it after scanning,
+          otherwise writes output to the console. If includes a trailing
+          dash, disables file writing (useful to disable default file output
+          when running with no arguments).

   -i/ignore (Optional) Adds a path to ignore if missing. Ignore patterns can
           be regexes, full file/folder names, or path substrings.


Markup.Split fix when given run is longer; closes #1

--- Program.cs
+++ Program.cs
@@ -138,8 +138,17 @@
             }

             public T Split<T>(Run run, Func<Markup, Markup, T> selector) =>
-                selector(new Markup(Run.Index, run.Index - Run.Index, Color, Priority),
-                         new Markup(run.End, Run.End - run.End, Color, Priority));
+                // Undefined...
+                // if (run.End < Run.Index || run.Index > Run.End) throw new ArgumentOutOfRangeException("run");
+                // if (run.Index < Run.Index) throw new ArgumentOutOfRangeException("run");
+                run.End == Run.Index
+                ? selector(new Markup(run.Index, run.Length, Color, Priority), this)
+                : run.Index == Run.End
+                ? selector(this, new Markup(run.Index, run.Length, Color, Priority))
+                : selector(new Markup(Run.Index, run.Index - Run.Index, Color, Priority),
+                           run.End > Run.End
+                           ? new Markup(Run.End, run.End - Run.End, Color, Priority)
+                           : new Markup(run.End, Run.End - run.End, Color, Priority));
         }

         delegate IEnumerable<Markup> Marker(string line);


Add function findProgram

Add function findProgram

--- Program.cs
+++ Program.cs
@@ -128,6 +128,37 @@
             }
         }

+        static string findProgram(string name)
+        {
+            Process Where = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    FileName = "C:\\Windows\\System32\\where.exe",
+                    Arguments = name,
+                    UseShellExecute = false,
+                    RedirectStandardOutput = true,
+                    CreateNoWindow = true
+                }
+            };
+
+            try
+            {
+                Where.Start();
+                while (!Where.StandardOutput.EndOfStream)
+                {
+                    return (string)Where.StandardOutput.ReadLine();
+                }
+                throw new Exception(name + ".exe was not found in path");
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+                Environment.Exit(1);
+                return "";
+            }
+        }
+
         static void ManageStartup(string arguments, bool remove = false)
         {
             RegistryKey registryKey = Registry.CurrentUser.OpenSubKey


Delete Program.cs

Delete Program.cs

--- Program.cs
+++ Program.cs
@@ -1,42 +0,0 @@
-using System;
-using System.Linq;
-using System.IO;
-using System.Reflection;
-using c = System.Console;
-using e = System.Environment;
-
-namespace RandomizeFileLines
-{
-
-	/// Класс программы
-	internal class Program
-	{
-
-		/// Точка входа
-		/// <param name="args">Аргументы командной строки</param>
-		private static void Main(string[] args)
-		{
-			c.Clear();
-			c.Title = "Randomize File Lines";
-			c.CursorVisible = false;
-			c.Write($"{e.NewLine} *{e.NewLine} * Randomize File Lines version {Assembly.GetEntryAssembly().GetName().Version}{e.NewLine} * http://computerraru.ru/software/rfl{e.NewLine} * Larin Alexsandr{e.NewLine} *{e.NewLine}");
-			c.ForegroundColor = ConsoleColor.White;
-			if (!args.Length.Equals(1))
-			{
-				c.WriteLine($"{e.NewLine}   Ошибочка...{e.NewLine}   Укажите первым параметром имя файла, например:{e.NewLine}{e.NewLine}   > RandomizeFileLines.exe worktodo.txt{e.NewLine}");
-				c.ForegroundColor = ConsoleColor.Gray;
-				c.WriteLine("   Press a key to exit...");
-				c.ReadKey();
-				return;
-			}
-			if (args.Length.Equals(0)) return;
-			var file = args[0];
-			if (!File.Exists(file)) return;
-			// must be here, outside the expression!
-			var r = new Random();
-			File.WriteAllLines(file, File.ReadAllLines(file).OrderBy(x => r.Next()).ToArray());
-		}
-
-	}
-
-}


Remove debug lines.

Remove debug lines.

--- Program.cs
+++ Program.cs
@@ -19,7 +19,7 @@
             //args = new string[] { @"parse", "Kamisama_no_Memochou", "-v", "2", "-c" };
             //args = new string[] { @"convert", "http://www.zomg.ch/baka/config/hantsuki.json" };
             //args = new string[] { @"E:\Dev\prince\hakomari1.json", "-c", "-s", "stylesheet.css" };
-            args = new string[] { @"convert", @"E:\Dev\prince\tests\Accel World1Return of Princess Snow Black978-4-04-867517-8.json" };
+           // args = new string[] { @"convert", @"E:\Dev\prince\tests\Accel World1Return of Princess Snow Black978-4-04-867517-8.json" };

             Command command = null;
             string commandName;
@@ -97,7 +97,6 @@
                 ShowHelp(p);
             }

-            Console.ReadLine();
         }

         static void ShowHelp(OptionSet p)


Release 1.4

Release 1.4

--- Program.cs
+++ Program.cs
@@ -23,8 +23,8 @@

         public const string BrowserSubprocess = BrandName+".Browser.exe";

-        public const string VersionTag = "1.3.3";
-        public const string VersionFull = "1.3.3.0";
+        public const string VersionTag = "1.4";
+        public const string VersionFull = "1.4.0.0";

         public static readonly Version Version = new Version(VersionTag);


Trying to fix MeTL hanging during unit tests Test 4

Former-commit-id: 5ac7e1e48c25e06c4b846dfc49508e50e0df4135

--- MeTLMeeting/Functional/ShutdownTests.cs
+++ MeTLMeeting/Functional/ShutdownTests.cs
@@ -1,6 +1,7 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System.Windows.Automation;
 using UITestFramework;
+using System.Threading;

 namespace Functional
 {
@@ -25,13 +26,15 @@

             Assert.IsTrue(success, ErrorMessages.PROBLEM_SHUTTING_DOWN);
         }
-
+
         [TestMethod]
         public void CloseInstance()
         {
             // TODO: Test that there is only one instance
             if (metlWindows == null)
                 metlWindows = MeTL.GetAllMainWindows();
+
+            Thread.Sleep(8000);

             foreach (AutomationElement window in metlWindows)
             {


Using namespace changed

Using namespace changed

--- MonoGame.PortableUI/Controls/Control.cs
+++ MonoGame.PortableUI/Controls/Control.cs
@@ -4,6 +4,7 @@
 using Microsoft.Xna.Framework.Input;
 using Microsoft.Xna.Framework.Input.Touch;
 using MonoGame.PortableUI.Common;
+using MonoGame.PortableUI.Exceptions;

 namespace MonoGame.PortableUI.Controls
 {


Fix memory leak inside SpriteFont

Fix memory leak inside SpriteFont

--- MonoHaven.Client/Graphics/SpriteFont.cs
+++ MonoHaven.Client/Graphics/SpriteFont.cs
@@ -12,6 +12,8 @@
 		private readonly TextureAtlas atlas;
 		private readonly Dictionary<char, Glyph> glyphs;
 		private readonly uint pixelSize;
+		private readonly int ascent;
+		private readonly int height;

 		public SpriteFont(Face face, uint pixelSize)
 		{
@@ -19,24 +21,23 @@
 			glyphs = new Dictionary<char, Glyph>();
 			this.face = face;
 			this.pixelSize = pixelSize;
+
+			EnsureSize();
+			using (var size = face.Size)
+			{
+				ascent = size.Metrics.Ascender >> 6;
+				height = size.Metrics.Height >> 6;
+			}
 		}

 		public int Ascent
 		{
-			get
-			{
-				EnsureSize();
-				return face.Size.Metrics.Ascender >> 6;
-			}
+			get { return ascent; }
 		}

 		public int Height
 		{
-			get
-			{
-				EnsureSize();
-				return face.Size.Metrics.Height >> 6;
-			}
+			get { return height; }
 		}

 		public void Dispose()


Minor refactorings based on review comments

--- NLog.Windows.Forms/RichTextBoxTarget.cs
+++ NLog.Windows.Forms/RichTextBoxTarget.cs
@@ -83,7 +83,7 @@
         }

         public static void ReInitializeAllTextboxes(Form form)
-        {
+        {
             InternalLogger.Info("Executing ReInitializeAllTextboxes for Form {0}", form);
             foreach (Target target in LogManager.Configuration.AllTargets)
             {
@@ -93,7 +93,7 @@
                     //can't use InitializeTarget here as the Application.OpenForms would not work from Form's constructor
                     RichTextBox textboxControl = FormHelper.FindControl<RichTextBox>(textboxTarget.ControlName, form);
                     if (textboxControl != null)
-                    {
+                    {
                         InternalLogger.Info("Attaching target {0} to textbox {1}", textboxTarget, textboxControl);
                         textboxTarget.TargetForm = form;
                         textboxTarget.TargetRichTextBox = textboxControl;
@@ -112,7 +112,7 @@
             WordColoringRules = new List<RichTextBoxWordColoringRule>();
             RowColoringRules = new List<RichTextBoxRowColoringRule>();
             ToolWindow = true;
-            CreateFormIfNotFound = true;
+            AllowAccessoryFormCreation = true;
         }

         private delegate void DelSendTheMessageToRichTextBox(string logMessage, RichTextBoxRowColoringRule rule);
@@ -229,12 +229,12 @@
         /// <summary>
         /// Gets or sets a value indicating whether to create custom form if the specified control was not found.
         /// </summary>
-        /// <remarks>
+        /// <remarks>
         /// If set to false and the control was not found during target initialiation, the target would skip events until the control is found during ReInitializeAllTextboxes() call
         /// </remarks>
         /// <docgen category='Form Options' order='10' />
         [DefaultValue(true)]
-        public bool CreateFormIfNotFound { get; set; }
+        public bool AllowAccessoryFormCreation { get; set; }

         /// <summary>
         /// Initializes the target. Can be used by inheriting classes
@@ -243,75 +243,85 @@
         protected override void InitializeTarget()
         {
             if (FormName == null)
+            {
+                if (AllowAccessoryFormCreation)
+                {
+                    InternalLogger.Info("FormName not set, creating a new form");
+                    CreateAccessoryForm();
+                }
+                else
+                {
+                    HandleError("FormName should be specified for " + GetType().Name + "." + this.Name);
+                }
+                return;
+            }
+
+            if (string.IsNullOrEmpty(ControlName))
             {
-                if (CreateFormIfNotFound)
+                if (AllowAccessoryFormCreation)
                 {
-                    InternalLogger.Info("FormName not set, creating a new form");
-                    FormName = "NLogForm" + Guid.NewGuid().ToString("N");
-                    InitWithNewForm();
+                    InternalLogger.Info("ontrol name is not set, creating a new form");
+                    CreateAccessoryForm();
                 }
                 else
                 {
-                    DoException("FormName should be specified for " + GetType().Name + "." + this.Name);
-                }
-                return;
-            }
-
-            if (string.IsNullOrEmpty(ControlName))
-            {
-                DoException("Rich text box control name must be specified for " + GetType().Name + "." + this.Name);
-                InitWithNewForm();
-                return;
-            }
-
-            Form openFormByName = Application.OpenForms[FormName];
-            if (openFormByName == null)
-            {
-                if (CreateFormIfNotFound)
-                {
-                    InternalLogger.Info("Form {0} not found, creating a new one.", FormName);
-                    InitWithNewForm();
-                }
-                else
-                {
-                    InternalLogger.Info("Form {0} not found, waiting for ReInitializeAllTextboxes.", FormName);
-                }
-                return;
+                    HandleError("Rich text box control name must be specified for " + GetType().Name + "." + this.Name);
+                }
+                return;
+            }
+
+            Form openFormByName = Application.OpenForms[FormName];
+            if (openFormByName == null)
+            {
+                if (AllowAccessoryFormCreation)
+                {
+                    InternalLogger.Info("Form {0} not found, creating a new one.", FormName);
+                    CreateAccessoryForm();
+                }
+                else
+                {
+                    InternalLogger.Info("Form {0} not found, waiting for ReInitializeAllTextboxes.", FormName);
+                }
+                return;
             }

             TargetForm = openFormByName;
             CreatedForm = false;
             TargetRichTextBox = FormHelper.FindControl<RichTextBox>(ControlName, TargetForm);
             if (TargetRichTextBox == null)
+            {
+                string message = "Rich text box control '" + ControlName + "' cannot be found on form '" + FormName + "'.";
+                if (AllowAccessoryFormCreation)
+                {
+                    HandleError(message);
+                    CreateAccessoryForm();
+                    return;
+                }
+                else
+                {
+                    InternalLogger.Info(message + " Waiting for ReInitializeAllTextboxes.");
+                }
+            }
+        }
+
+        private static void HandleError(string message)
+        {
+            if (LogManager.ThrowExceptions)
+            {
+                throw new NLogConfigurationException(message);
+            }
+            InternalLogger.Error(message);
+        }
+
+        private void CreateAccessoryForm()
+        {
+            if (FormName == null)
             {
-                string message = "Rich text box control '" + ControlName + "' cannot be found on form '" + FormName + "'.";
-                if (CreateFormIfNotFound)
-                {
-                    DoException(message);
-                    InitWithNewForm();
-                    return;
-                }
-                else
-                {
-                    InternalLogger.Info(message + " Waiting for ReInitializeAllTextboxes.");
-                }
-            }
-        }
-
-        private void DoException(string message)
-        {
-            if (LogManager.ThrowExceptions)
-            {
-                throw new NLogConfigurationException(message);
-            }
-            InternalLogger.Error(message);
-        }
-
-        private void InitWithNewForm()
-        {
-            TargetForm = FormHelper.CreateForm(FormName, Width, Height, true, ShowMinimized, ToolWindow);
-            TargetRichTextBox = FormHelper.CreateRichTextBox(ControlName, TargetForm);
-            CreatedForm = true;
+                FormName = "NLogForm" + Guid.NewGuid().ToString("N");
+            }
+            TargetForm = FormHelper.CreateForm(FormName, Width, Height, true, ShowMinimized, ToolWindow);
+            TargetRichTextBox = FormHelper.CreateRichTextBox(ControlName, TargetForm);
+            CreatedForm = true;
         }

         /// <summary>
@@ -347,14 +357,14 @@
         {
             RichTextBox textbox = TargetRichTextBox;
             if (textbox == null)
-            {
+            {
                 InternalLogger.Debug("Textbox for target {0} is null, skipping logging", this.Name);
                 return;
-            }
-            if (textbox.IsDisposed)
-            {
-                InternalLogger.Debug("Textbox for target {0} is disposed, skipping logging", this.Name);
-                return;
+            }
+            if (textbox.IsDisposed)
+            {
+                InternalLogger.Debug("Textbox for target {0} is disposed, skipping logging", this.Name);
+                return;
             }

             var matchingRule = FindMatchingRule(logEvent);
@@ -362,7 +372,7 @@
             string logMessage = Layout.Render(logEvent);

             try
-            {
+            {
                 textbox.BeginInvoke(new DelSendTheMessageToRichTextBox(SendTheMessageToRichTextBox), logMessage, matchingRule);
             }
             catch (Exception ex)


Fixed test issue.

Fixed test issue.

--- Naos.MessageBus.Test/PostmasterTests.cs
+++ Naos.MessageBus.Test/PostmasterTests.cs
@@ -39,7 +39,7 @@
             var eventRepository = GetEventSourcedRepository(eventConnectionString);

             var parcel = this.GetParcel();
-            var trackingCode = new TrackingCode { ParcelId = parcel.Id, EnvelopeId = "Something" };
+            var trackingCode = new TrackingCode { ParcelId = parcel.Id, EnvelopeId = parcel.Envelopes.Single().Id };

             var postmaster = new Postmaster(eventConnectionString, commandConnectionString, readConnectionString);


RGR Use AsserterBase for EmptyAsserter

RGR Use AsserterBase for EmptyAsserter

--- Nilgiri/Core/Asserters/EmptyAsserter.cs
+++ Nilgiri/Core/Asserters/EmptyAsserter.cs
@@ -14,54 +14,35 @@
     {
       if(typeof(T) == typeof(String))
       {
-        Assert<int>(
-          new AssertionState<int>(() => (assertionState.TestExpression() as string).Length)
-          {
-            IsNegated = assertionState.IsNegated
-          },
-          0);
-
+        if(!AreEqual(assertionState, x => (x as String).Length, 0))
+        {
+          throw new Exception();
+        }
         return;
       }

       if(typeof(IEnumerable).IsAssignableFrom(typeof(T)))
       {
-        Assert<int>(
-          new AssertionState<int>(() =>
+        if(!AreEqual(assertionState, x =>
+        {
+          if (x as ICollection != null) { return ((ICollection)x).Count; }
+
+          var count = 0;
+          var enumerator = ((IEnumerable)x).GetEnumerator();
+          try
           {
-            var ienumerable = assertionState.TestExpression();
+            while (enumerator.MoveNext()) { count++; }
+          }
+          finally
+          {
+            if (enumerator as IDisposable != null) { ((IDisposable)enumerator).Dispose(); }
+          }

-            var possibleCollection = ienumerable as ICollection;
-            if (possibleCollection != null)
-            {
-              return possibleCollection.Count;
-            }
-
-            var count = 0;
-            var enumerator = ((IEnumerable)ienumerable).GetEnumerator();
-            try
-            {
-              while (enumerator.MoveNext())
-              {
-                count++;
-              }
-            }
-            finally
-            {
-              IDisposable possibleDisposable = enumerator as IDisposable;
-              if (possibleDisposable != null)
-              {
-                possibleDisposable.Dispose();
-              }
-            }
-
-            return count;
-          })
-          {
-            IsNegated = assertionState.IsNegated
-          },
-          0);
-
+          return count;
+        }, 0))
+        {
+          throw new Exception();
+        }
         return;
       }


No longer generate intermediate json file

--- src/ContentCompiler/Program.cs
+++ src/ContentCompiler/Program.cs
@@ -33,8 +33,6 @@
             foreach (var character in characters)
             {
                 var scheduleRaw = content.Load<Dictionary<string, string>>("characters\\schedules\\" + character);
-                var json = JsonConvert.SerializeObject(scheduleRaw, Formatting.Indented);
-                File.WriteAllText(Path.Combine(root, "characters\\schedules", character) + ".json", json);
                 var schedule = new Schedule() { Character = character };
                 foreach(var keyPair in scheduleRaw)
                 {


Set HttpProtocol version to 1.0 to avoid connection issue.
Work items: 1448

--HG--
branch : 1.5oob

--- src/Core/Http/RequestHelper.cs
+++ src/Core/Http/RequestHelper.cs
@@ -50,9 +50,11 @@
                         !String.Equals(authType, "Kerberos", StringComparison.OrdinalIgnoreCase)) {
                         // This is to work around the "The underlying connection was closed: An unexpected error occurred on a receive."
                         // exception.
-                        ((HttpWebRequest)request).KeepAlive = false;
+                        var httpRequest = (HttpWebRequest)request;
+                        httpRequest.KeepAlive = false;
+                        httpRequest.ProtocolVersion = HttpVersion.Version10;
                     }
-
+
                     // Prepare the request, we do something like write to the request stream
                     // which needs to happen last before the request goes out
                     prepareRequest(request);
@@ -73,7 +75,7 @@
                 }
                 catch (WebException ex) {
                     IHttpWebResponse response = GetResponse(ex.Response);
-                    if (response == null &&
+                    if (response == null &&
                         ex.Status != WebExceptionStatus.SecureChannelFailure) {
                         // No response, someting went wrong so just rethrow
                         throw;


assume zero weight if node not exists

assume zero weight if node not exists

--- hkxPoser/Renderer3d.cs
+++ hkxPoser/Renderer3d.cs
@@ -237,7 +237,7 @@
                         if (hkabone_idx != -1)
                             UpdateBoneMatrix(hkabone_idx, mesh.GetBoneLocal(submesh.bones[i]), out bone_matrices[i]);
                         else
-                            bone_matrices[i] = Matrix.Identity;
+                            bone_matrices[i] = Matrix.Zero;
                     }
                     context.UpdateSubresource<Matrix>(bone_matrices, cb_mat);
                     shader_flags[0] = mesh.SLSF1;


Set lifetime scope of services to instance per request

--- Oogstplanner.Web/App_Start/IocConfig.cs
+++ Oogstplanner.Web/App_Start/IocConfig.cs
@@ -24,8 +24,8 @@
                 .As<IOogstplannerContext>()
                 .InstancePerRequest();

-            var repositoryInstances = new RepositoryFactories();
-            builder.RegisterInstance(repositoryInstances)
+            var repositoryFactories = new RepositoryFactories();
+            builder.RegisterInstance(repositoryFactories)
                 .As<RepositoryFactories>()
                 .SingleInstance();

@@ -36,12 +36,15 @@
             builder.RegisterAssemblyTypes(typeof(ServiceBase).Assembly)
                 .AsImplementedInterfaces()
                 .Except<UserService>()
-                .Except<AnonymousUserService>();
+                .Except<AnonymousUserService>()
+                .InstancePerRequest();

             builder.RegisterType<AnonymousUserService>()
-                .Keyed<IUserService>(AuthenticatedStatus.Anonymous);
+                .Keyed<IUserService>(AuthenticatedStatus.Anonymous)
+                .InstancePerRequest();
             builder.RegisterType<UserService>()
-                .Keyed<IUserService>(AuthenticatedStatus.Authenticated);
+                .Keyed<IUserService>(AuthenticatedStatus.Authenticated)
+                .InstancePerRequest();

             var container = builder.Build();
             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));


Minor fix

Minor fix

--- Program.cs
+++ Program.cs
@@ -19,8 +19,6 @@
     {
         public const string Version = "210721";

-        public static string AppPath = Application.StartupPath;
-
         public static Configuration Config;
         public static LanguageManager LanguageManager;
         public static ChatClient ChatServer;
@@ -42,6 +40,8 @@
         public static ServerInfo Server;
         public static Dictionary<string, ServerInfo> CheckmateServerList = new Dictionary<string, ServerInfo>();
         public static Random Rand = new Random();
+
+        public static string AppPath = Application.StartupPath;

         [STAThread]
         private static void Main()


Avoid calling GetComponent as it allocates memory.

--- AGXUnity/Constraint.cs
+++ AGXUnity/Constraint.cs
@@ -279,6 +279,8 @@
     [SerializeField]
     private bool m_drawGizmosEnable = true;

+    private bool m_isAnimated = false;
+
     /// <summary>
     /// Enable/disable gizmos drawing of this constraint. Enabled by default.
     /// </summary>
@@ -745,18 +747,31 @@
         bool valid = added && Native.getValid();
         Simulation.Instance.StepCallbacks.PreSynchronizeTransforms += OnPreStepForwardUpdate;

+        // It's not possible to check which properties an animator
+        // is controlling, for now we update all properties in the
+        // controllers if we have an animator.
+        m_isAnimated = GetComponent<Animator>() != null;
+
         return valid;
       }
       catch ( System.Exception e ) {
         Debug.LogException( e, gameObject );
         return false;
       }
+
+
     }

     protected override void OnEnable()
     {
       if ( Native != null && !Native.getEnable() )
         Native.setEnable( true );
+
+
+      // It's not possible to check which properties an animator
+      // is controlling, for now we update all properties in the
+      // controllers if we have an animator.
+      m_isAnimated = GetComponent<Animator>() != null;
     }

     protected override void OnDisable()
@@ -784,12 +799,8 @@

       SynchronizeNativeFramesWithAttachmentPair();

-      // It's not possible to check which properties an animator
-      // is controlling, for now we update all properties in the
-      // controllers if we have an animator. This could probably
-      // be a flag (IsAnimated).
-      var isAnimated = GetComponent<Animator>() != null;
-      if ( isAnimated ) {
+
+      if (m_isAnimated) {
         var controllers = GetElementaryConstraintControllers();
         for ( int i = 0; i < controllers.Length; ++i )
           PropertySynchronizer.Synchronize( controllers[ i ] );


attempt connection added

attempt connection added

--- Program.cs
+++ Program.cs
@@ -65,7 +65,7 @@
             else
             {
                 int attempts = 0;
-                while (!_clientSocket.Connected)
+                while (!_connection.Connected)
                 {
                     try
                     {


Cleaned up parsing.

Cleaned up parsing.

--- Program.cs
+++ Program.cs
@@ -128,7 +128,7 @@
             {
                 if (a is Rational rational)
                 {
-                    return new RationalPolynomial(null, rational);
+                    return new RationalPolynomial(MinimalPolynomial, rational);
                 }
                 if ((MinimalPolynomial.Coefficients.Count - 1) %
                     (a.MinimalPolynomial.Coefficients.Count - 1) != 0)
@@ -200,7 +200,8 @@
                     }
                     if (factorEqualsA())
                     {
-                        return candidateFactors[i];
+                        return new RationalPolynomial(candidateFactors[i].Coefficients,
+                            MinimalPolynomial);
                     }
                 }
                 return null;
@@ -1044,7 +1045,7 @@
                 return a * this;
             }
             public Division<Integer> EuclideanDivideBy(Integer divisor)
-            {
+            {
                 if (divisor.Sign == 0)
                 {
                     throw new DivideByZeroException();
@@ -2258,7 +2259,7 @@
                                 outputTerms = new List<Term>(Terms);
                                 outputTerms.Add(term);
                                 oldTermsInTermsOfNewPrimitiveElement.Add(
-                                newTermInTermsOfNewPrimitiveElement);
+                                    newTermInTermsOfNewPrimitiveElement);
                                 return new LinearlyIndependentSum(outputTerms,
                                     oldTermsInTermsOfNewPrimitiveElement, newPrimitiveElement);
                             }
@@ -2302,7 +2303,6 @@
                         return thisPlusTerm(PrimitiveElement, TermsInTermsOfPrimitiveElement,
                             termInTermsOfPrimitiveElement);
                     }
-                    RationalPolynomial x = new RationalPolynomial(null, Zero, One);
                     List<RationalPolynomial> convertTermsToNewPrimitiveElement(
                         RationalPolynomial newPrimitiveElementInTermsOfOld)
                     {
@@ -2334,7 +2334,8 @@
                     if (primitiveElementInTermsOfTerm != null)
                     {
                         return thisPlusTerm(term,
-                            convertTermsToNewPrimitiveElement(primitiveElementInTermsOfTerm), x);
+                            convertTermsToNewPrimitiveElement(primitiveElementInTermsOfTerm),
+                            new RationalPolynomial(term.MinimalPolynomial, Zero, One));
                     }
                     Integer k = One;
                     while (true)
@@ -2347,8 +2348,9 @@
                         if (termInTermsOfPrimitive != null)
                         {
                             return thisPlusTerm(PrimitiveElement_,
-                                convertTermsToNewPrimitiveElement(x - k * termInTermsOfPrimitive),
-                                termInTermsOfPrimitive);
+                                convertTermsToNewPrimitiveElement(new RationalPolynomial(
+                                PrimitiveElement_.MinimalPolynomial, Zero, One) -
+                                k * termInTermsOfPrimitive), termInTermsOfPrimitive);
                         }
                         ++k;
                     }
@@ -5277,45 +5279,66 @@
             output.BOverGCD = a.GetAdditiveIdentity().Minus(output.BOverGCD);
             return output;
         }
+        abstract class Token
+        {
+            public virtual bool Equals(char a)
+            {
+                return false;
+            }
+        }
+        class NumericToken : Token
+        {
+            public Number Value;
+            public NumericToken(Number value)
+            {
+                Value = value;
+            }
+        }
+        class TextToken : Token
+        {
+            public char Value;
+            public TextToken(char value)
+            {
+                Value = value;
+            }
+            public override bool Equals(char a)
+            {
+                return Value == a;
+            }
+        }
         static void Main(string[] args)
         {
-            Number EvaluateExpression(List<char> operations, List<Number> numbers)
-            {
-                for (int i = 0; i < operations.Count;)
-                {
-                    if (operations[i] == ')')
+            Number EvaluateExpression(List<Token> tokens)
+            {
+                for (int i = 0; i < tokens.Count;)
+                {
+                    if (tokens[i].Equals(')'))
                     {
                         throw new InvalidUserInput("Unmatched parentheses.");
                     }
-                    if (operations[i] == '(')
+                    if (tokens[i].Equals('('))
                     {
                         int numOfUnmatchedParens = 1;
                         int matchingParenIndex = i;
                         while (numOfUnmatchedParens > 0)
                         {
                             matchingParenIndex += 1;
-                            try
-                            {
-                                if (operations[matchingParenIndex] == '(')
-                                {
-                                    numOfUnmatchedParens += 1;
-                                }
-                                else if (operations[matchingParenIndex] == ')')
-                                {
-                                    numOfUnmatchedParens -= 1;
-                                }
-                            }
-                            catch (ArgumentOutOfRangeException)
+                            if (matchingParenIndex == tokens.Count)
                             {
                                 throw new InvalidUserInput("Unmatched parentheses.");
                             }
-                        }
-                        numbers[i] = EvaluateExpression(
-                            operations.GetRange(i + 1, matchingParenIndex - i - 1),
-                            numbers.GetRange(i + 1, matchingParenIndex - i - 1));
-                        operations[i] = ' ';
-                        numbers.RemoveRange(i + 1, matchingParenIndex - i);
-                        operations.RemoveRange(i + 1, matchingParenIndex - i);
+                            if (tokens[matchingParenIndex].Equals('('))
+                            {
+                                numOfUnmatchedParens += 1;
+                            }
+                            else if (tokens[matchingParenIndex].Equals(')'))
+                            {
+                                numOfUnmatchedParens -= 1;
+                            }
+                        }
+                        tokens[i] = new NumericToken(
+                            EvaluateExpression(tokens.GetRange(i + 1, matchingParenIndex - i - 1)));
+                        tokens.RemoveRange(i + 1, matchingParenIndex - i);
                     }
                     else
                     {
@@ -5324,42 +5347,83 @@
                 }
                 void executeOperations()
                 {
-                    for (int i = 0; i < operations.Count;)
-                    {
-                        if (i == 0 || numbers[i - 1] == null)
-                        {
-                            if (operations[i] == '+')
+                    int i = 0;
+                    while (i < tokens.Count)
+                    {
+                        if (i == 0 || tokens[i - 1] is TextToken)
+                        {
+                            if (tokens[i].Equals('+'))
                             {
-                                if (numbers[i + 1] != null || operations[i + 1] == '+' ||
-                                    operations[i + 1] == '-')
-                                {
-                                    numbers.RemoveAt(i);
-                                    operations.RemoveAt(i);
-                                }
-                                else
+                                if (tokens.Count < i + 2 || (tokens[i + 1] is TextToken &&
+                                    !tokens[i + 1].Equals('+') && !tokens[i + 1].Equals('-')))
                                 {
                                     throw new InvalidUserInput("Operator missing operand.");
                                 }
+                                tokens.RemoveAt(i);
                             }
-                            else if (operations[i] == '-')
+                            else
                             {
-                                if (numbers[i + 1] != null)
+                                ++i;
+                            }
+                        }
+                        else
+                        {
+                            ++i;
+                        }
+                    }
+                    i = 0;
+                    while (i < tokens.Count)
+                    {
+                        if (tokens[i].Equals('^'))
+                        {
+                            if (tokens.Count < i + 2)
+                            {
+                                throw new InvalidUserInput("Operator missing operand.");
+                            }
+                            if (tokens[i + 1] is NumericToken n && n.Value is Rational exponent)
+                            {
+                                tokens[i - 1] = new NumericToken(
+                                    ((NumericToken)tokens[i - 1]).Value.Exponentiate(exponent));
+                            }
+                            else
+                            {
+                                throw new InvalidUserInput(
+                                    "The input expression contains an exponentiation\n" +
+                                    "whose exponent is not both real and rational;\n" +
+                                    "this program doesn't handle transcendental numbers.");
+                            }
+                            tokens.RemoveRange(i, 2);
+                        }
+                        else
+                        {
+                            ++i;
+                        }
+                    }
+                    i = 0;
+                    while (i < tokens.Count)
+                    {
+                        if (i == 0 || tokens[i - 1] is TextToken)
+                        {
+                            if (tokens[i].Equals('-'))
+                            {
+                                if (tokens.Count < i + 2)
                                 {
-                                    numbers[i + 1] = -numbers[i + 1];
-                                    numbers.RemoveAt(i);
-                                    operations.RemoveAt(i);
+                                    throw new InvalidUserInput("Operator missing operand.");
                                 }
-                                else if (operations[i + 1] == '+')
+                                if (tokens[i + 1] is NumericToken n)
                                 {
-                                    operations[i + 1] = '-';
-                                    numbers.RemoveAt(i);
-                                    operations.RemoveAt(i);
+                                    tokens[i + 1] = new NumericToken(-n.Value);
+                                    tokens.RemoveAt(i);
                                 }
-                                else if (operations[i + 1] == '-')
+                                else if (tokens[i + 1].Equals('+'))
                                 {
-                                    operations[i + 1] = '+';
-                                    numbers.RemoveAt(i);
-                                    operations.RemoveAt(i);
+                                    tokens[i + 1] = new TextToken('-');
+                                    tokens.RemoveAt(i);
+                                }
+                                else if (tokens[i + 1].Equals('-'))
+                                {
+                                    tokens[i + 1] = new TextToken('+');
+                                    tokens.RemoveAt(i);
                                 }
                                 else
                                 {
@@ -5376,90 +5440,69 @@
                             ++i;
                         }
                     }
-                    for (int i = 0; i < operations.Count;)
-                    {
-                        if (operations[i] == '^')
-                        {
-                            if (numbers[i + 1] is Rational exponent)
+                    i = 0;
+                    while (i < tokens.Count)
+                    {
+                        if (tokens[i].Equals('*'))
+                        {
+                            if (tokens.Count < i + 2)
                             {
-                                numbers[i - 1] = numbers[i - 1].Exponentiate(exponent);
+                                throw new InvalidUserInput("Operator missing operand.");
                             }
-                            else
+                            tokens[i - 1] = new NumericToken(((NumericToken)tokens[i - 1]).Value *
+                                ((NumericToken)tokens[i + 1]).Value);
+                            tokens.RemoveRange(i, 2);
+                        }
+                        else if (tokens[i].Equals('/'))
+                        {
+                            if (tokens.Count < i + 2)
                             {
-                                throw new InvalidUserInput("The input expression contains an " +
-                                    "exponentiation\nwhose exponent is not both real and " +
-                                    "rational;\nthis program doesn't handle transcendental " +
-                                    "numbers.");
+                                throw new InvalidUserInput("Operator missing operand.");
                             }
-                            numbers.RemoveRange(i, 2);
-                            operations.RemoveRange(i, 2);
+                            tokens[i - 1] = new NumericToken(((NumericToken)tokens[i - 1]).Value /
+                                ((NumericToken)tokens[i + 1]).Value);
+                            tokens.RemoveRange(i, 2);
                         }
                         else
                         {
                             ++i;
                         }
                     }
-                    for (int i = 0; i < operations.Count;)
-                    {
-                        if (operations[i] == '*')
-                        {
-                            numbers[i - 1] *= numbers[i + 1];
-                            numbers.RemoveRange(i, 2);
-                            operations.RemoveRange(i, 2);
-                        }
-                        else if (operations[i] == '/')
-                        {
-                            numbers[i - 1] /= numbers[i + 1];
-                            numbers.RemoveRange(i, 2);
-                            operations.RemoveRange(i, 2);
+                    i = 0;
+                    while (i < tokens.Count)
+                    {
+                        if (tokens[i].Equals('+'))
+                        {
+                            if (tokens.Count < i + 2)
+                            {
+                                throw new InvalidUserInput("Operator missing operand.");
+                            }
+                            tokens[i - 1] = new NumericToken(((NumericToken)tokens[i - 1]).Value +
+                                ((NumericToken)tokens[i + 1]).Value);
+                            tokens.RemoveRange(i, 2);
+                        }
+                        else if (tokens[i].Equals('-'))
+                        {
+                            if (tokens.Count < i + 2)
+                            {
+                                throw new InvalidUserInput("Operator missing operand.");
+                            }
+                            tokens[i - 1] = new NumericToken(((NumericToken)tokens[i - 1]).Value -
+                                ((NumericToken)tokens[i + 1]).Value);
+                            tokens.RemoveRange(i, 2);
                         }
                         else
                         {
                             ++i;
                         }
                     }
-                    for (int i = 0; i < operations.Count;)
-                    {
-                        if (operations[i] == '+')
-                        {
-                            numbers[i - 1] += numbers[i + 1];
-                            numbers.RemoveRange(i, 2);
-                            operations.RemoveRange(i, 2);
-                        }
-                        else if (operations[i] == '-')
-                        {
-                            numbers[i - 1] -= numbers[i + 1];
-                            numbers.RemoveRange(i, 2);
-                            operations.RemoveRange(i, 2);
-                        }
-                        else
-                        {
-                            ++i;
-                        }
-                    }
-                }
-#if DEBUG
+                }
                 executeOperations();
-#else
-                try
-                {
-                    executeOperations();
-                }
-                catch (ArgumentOutOfRangeException)
-                {
-                    throw new InvalidUserInput("Operator missing operand.");
-                }
-#endif
-                if (numbers.Count == 0)
-                {
-                    return null;
-                }
-                return numbers[0];
+                return ((NumericToken)tokens[0]).Value;
             }
             void EvaluateString(string input)
             {
-                List<char> operations = new List<char>();
-                List<Number> numbers = new List<Number>();
+                List<Token> tokens = new List<Token>();
                 StringBuilder numberCollector = new StringBuilder();
                 bool lastCharWasDigit = false;
                 try
@@ -5480,10 +5523,9 @@
                                 }
                                 else
                                 {
-                                    numbers.Add(Integer.Parse(numberCollector.ToString()));
-                                    operations.Add(' ');
-                                    operations.Add(c);
-                                    numbers.Add(null);
+                                    tokens.Add(new NumericToken(
+                                        Integer.Parse(numberCollector.ToString())));
+                                    tokens.Add(new TextToken(c));
                                 }
                                 lastCharWasDigit = false;
                             }
@@ -5499,28 +5541,24 @@
                         }
                         else
                         {
-                            operations.Add(c);
-                            numbers.Add(null);
+                            tokens.Add(new TextToken(c));
                         }
                     }
                     if (lastCharWasDigit)
                     {
-                        operations.Add(' ');
-                        numbers.Add(Integer.Parse(numberCollector.ToString()));
-                    }
-                    for (int i = 0; i < operations.Count;)
-                    {
-                        if (operations[i] == '(' && i > 0 && numbers[i - 1] != null)
-                        {
-                            operations.Insert(i, '*');
-                            numbers.Insert(i, null);
+                        tokens.Add(new NumericToken(Integer.Parse(numberCollector.ToString())));
+                    }
+                    for (int i = 0; i < tokens.Count;)
+                    {
+                        if (tokens[i].Equals('(') && i > 0 && tokens[i - 1] is NumericToken)
+                        {
+                            tokens.Insert(i, new TextToken('*'));
                             i += 2;
                         }
-                        else if (operations[i] == ')' && i + 1 < operations.Count &&
-                            (numbers[i + 1] != null || operations[i + 1] == '('))
-                        {
-                            operations.Insert(i + 1, '*');
-                            numbers.Insert(i + 1, null);
+                        else if (tokens[i].Equals(')') && i + 1 < tokens.Count &&
+                            (tokens[i + 1].Equals('(') || tokens[i + 1] is NumericToken))
+                        {
+                            tokens.Insert(i + 1, new TextToken('*'));
                             i += 2;
                         }
                         else
@@ -5528,37 +5566,32 @@
                             ++i;
                         }
                     }
-                    Number expression = EvaluateExpression(operations, numbers);
-                    if (expression == null)
-                    {
-                        Console.WriteLine("=\n");
-                    }
-                    else
-                    {
-                        Console.Write("=\n" + expression.ToString() + "\n\n");
-                    }
+                    Console.Write("=\n" + EvaluateExpression(tokens).ToString() + "\n\n");
                 }
                 catch (InvalidUserInput e)
                 {
                     Console.WriteLine(e.Message);
                 }
-                catch (DivideByZeroException e)
-                {
-                    Console.WriteLine(e.Message);
+                catch (DivideByZeroException)
+                {
+                    Console.WriteLine("Tried to divide by 0.");
                 }
             }
 #if DEBUG
-            EvaluateString("1/(1+2^(1/3))");
+            EvaluateString("(2^(1/2)+3^(1/2)+5^(1/2))-3^(1/2)");
 #else
             while (true)
             {
                 string input = Console.ReadLine();
-                if (input[0] == 'q')
-                {
-                    return;
-                }
-                EvaluateString(input);
-            }
+                if (input != "")
+                {
+                    if (input[0] == 'q')
+                    {
+                        return;
+                    }
+                    EvaluateString(input);
+                }
+            }
 #endif
         }
     }


Add CultureInfo.CurrentCulture to time in logger

--- Program.cs
+++ Program.cs
@@ -182,7 +182,7 @@
                 build.Append("Please, report all issues to: https://github.com/chylex/TweetDuck/issues\r\n\r\n");
             }

-            build.Append("[").Append(DateTime.Now.ToString("G")).Append("]\r\n");
+            build.Append("[").Append(DateTime.Now.ToString("G", CultureInfo.CurrentCulture)).Append("]\r\n");
             build.Append(data).Append("\r\n\r\n");

             try{


Processing function now returns outcome

Processing function now returns outcome

--- Program.cs
+++ Program.cs
@@ -50,8 +50,13 @@
                         var files = System.IO.Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly);
                         Parallel.ForEach(files, f =>
                         {
-                            ProcessFile(f, outputPath);
-                        });
+							int status = ProcessFile(f, outputPath);
+
+	                        if(status = -1)
+	                        	Console.WriteLine("Unexpected character during file processing");
+	                        else
+	                        	Console.WriteLine("File prcessing complete");
+	                        });
                     }
                     else
                     {
@@ -71,7 +76,12 @@

                     if (CanProcessFile(path, outputPath))
                     {
-                        ProcessFile(path, outputPath);
+                        int status = ProcessFile(path, outputPath);
+
+                        if(status = -1)
+                        	Console.WriteLine("Unexpected character during file processing");
+                        else
+                        	Console.WriteLine("File prcessing complete");
                     }
                     else
                     {
@@ -85,7 +95,7 @@
             }
         }

-        private static void ProcessFile(string path, string outputPath)
+        private static int ProcessFile(string path, string outputPath)
         {
             var ext = System.IO.Path.GetExtension(path);
             string outputFileName = System.IO.Path.GetFileNameWithoutExtension(path) + "_CLEAN_.txt";
@@ -94,7 +104,7 @@
             {
                 using (FileStream fs = new FileStream(path, FileMode.Open))
                 {
-                    CleanCopyUsingStateMachine(fs, sw);
+                    return CleanCopyUsingStateMachine(fs, sw);
                 }
             }
         }
@@ -104,12 +114,13 @@
             return System.IO.File.Exists(inputFile) && System.IO.Directory.Exists(outputPath);
         }

-        public static void CleanCopyUsingStateMachine(FileStream fs, StreamWriter sw)
+        public static int CleanCopyUsingStateMachine(FileStream fs, StreamWriter sw)
         {
             int index = 1;
             bool isEOF = false;
             bool toClean = false;
             bool error = false;
+            int finalStatus = 0;
             char c = '\0';

             // set stream to beginning
@@ -158,13 +169,15 @@
                 else if ((error = q == 0) || c == char.MaxValue)
                 {// exit reader...
                     if (error)
-                        Console.WriteLine("Unexpected file structure");
+						finalStatus = -1;
                     else
-                        Console.WriteLine("Processing Complete");
+                        finalStatus = 1;

                     isEOF = true;
                 }
             }// end while
+
+            return finalStatus;
         }// end function
     }
 }


Add hack to deidentify students from a CSV.

--- Program.cs
+++ Program.cs
@@ -5,11 +5,22 @@
 using System.Threading.Tasks;
 using System.IO;
 using System.IO.Compression;
+using System.Security.Cryptography;

 namespace TabulateSmarterTestResults
 {
     class Program
     {
+ 	static readonly UTF8Encoding UTF8NoByteOrderMark = new UTF8Encoding(false);
+
+	static string ByteArrayToHexString(byte[] inputArray)
+        {
+            if (inputArray == null) return null;
+            StringBuilder o = new StringBuilder();
+            for (int i = 0; i < inputArray.Length; i++) o.Append(inputArray[i].ToString("X2"));
+            return o.ToString();
+        }
+

         static string sSyntax =
 @"This tool tabulates XML test results files in SmarterApp Test Results
@@ -89,6 +100,7 @@
                 string osFilename = null;
                 string oiFilename = null;
                 string hashPassPhrase = null;
+		string didcsv = null;
                 DIDFlags didFlags = DIDFlags.None;
                 OutputFormat outputFormat = OutputFormat.Dw;
                 int maxResponse = 0;
@@ -145,6 +157,14 @@
                                 hashPassPhrase = args[i];
                             }
                             break;
+
+			case "-didcsv":
+			    {
+				++i;
+                                if (i >= args.Length) throw new ArgumentException("Invalid command line. '-didcsv' needs file arg.");
+				didcsv = args[i];
+			    }
+			    break;

                         case "-did":
                             {
@@ -183,6 +203,7 @@
                             break;

                         case "-fmt":
+			    Console.WriteLine("WTF");
                             ++i;
                             if (i >= args.Length) throw new ArgumentException("Invalid command line. '-fmt' option not followed by format type.");
                             switch (args[i])
@@ -213,8 +234,50 @@
                 if (help || args.Length == 0)
                 {
                     Console.WriteLine(sSyntax);
-                }
-
+                } else if (didcsv != "") {
+		  	var reader = new StreamReader(File.OpenRead(didcsv));
+
+                       SHA1 sha = new SHA1CryptoServiceProvider();
+                       byte[] pfb = UTF8NoByteOrderMark.GetBytes("smarter");
+                       byte[] m_hashKey = sha.ComputeHash(pfb);
+
+
+			List<string> listA = new List<string>();
+    			//List<string> listB = new List<string>();
+    			while (!reader.EndOfStream)
+    			{
+        			var line = reader.ReadLine();
+				listA.Add(line);
+        			//var values = line.Split(',');
+
+        			//listA.Add(values[0]);
+        			//listB.Add(values[1]);
+    			}
+
+			foreach (string l in listA) {
+				//Console.WriteLine(l);
+        			var values = l.Split(',');
+				if (values[0] == "State") {
+					Console.WriteLine(l);
+					continue;
+				}
+	                	HMACSHA1 hmac = new HMACSHA1(m_hashKey);
+				//Console.WriteLine(values[10]);
+                		byte[] bid = UTF8NoByteOrderMark.GetBytes(values[10]);
+                		byte[] hash = hmac.ComputeHash(bid);
+                		string new10 = ByteArrayToHexString(hash);
+				values[9] = ""; //fname
+				values[8] = ""; //mname
+				values[7] = ""; //lname
+				values[14] = ""; //bday
+				values[10] = new10; //ssid
+				values[11] = new10; //altssid
+				string newline = string.Join(",", values);
+				Console.WriteLine(newline);
+
+			}
+
+		}
                 else
                 {
                     if (inputFilenames.Count == 0 || (osFilename == null && oiFilename == null)) throw new ArgumentException("Invalid command line. Use '-h' for syntax help");


Wrap Service Host in in try catch to allow launching of application when .net pipe is in use

--- Program.cs
+++ Program.cs
@@ -106,17 +106,23 @@
 				return;
 			}
 			//#endif
-
-			var serviceHost = new ServiceHost(
-				typeof(LocalService),
-				new Uri[] { new Uri("net.pipe://localhost/") });
-
-			serviceHost.AddServiceEndpoint(typeof(IMainService), new NetNamedPipeBinding(), mainServiceName);
-			serviceHost.Open();
-
-			Console.Write(
-				"Service started: {0};",
-				string.Join(", ", serviceHost.Description.Endpoints.Select(s => s.ListenUri.AbsoluteUri).ToArray()));
+			try
+			{
+
+				var serviceHost = new ServiceHost(
+					typeof(LocalService),
+					new Uri[] { new Uri("net.pipe://localhost/") });
+
+				serviceHost.AddServiceEndpoint(typeof(IMainService), new NetNamedPipeBinding(), mainServiceName);
+				serviceHost.Open();
+
+				Console.Write(
+					"Service started: {0};",
+					string.Join(", ", serviceHost.Description.Endpoints.Select(s => s.ListenUri.AbsoluteUri).ToArray()));
+			}catch (Exception e)
+			{
+				Console.WriteLine(e.Message);
+			}

 			// Load optional user configuration
 			IConfiguration config = new ConfigurationBuilder()


Prevent unnecessary CardInfo updates

Prevent unnecessary CardInfo updates

--- Program.cs
+++ Program.cs
@@ -426,6 +426,7 @@
 		private int m_selectedPreviewIndex = -1; // selected card in card list in preview window
 		private bool m_previewWindow_isShiftPressed = false;
 		private bool m_previewWindow_isControlPressed = false;
+		private bool m_ignoreBufferChanges = false;

 		// ##################################################################33
 		// Variables for Subtitle-Options-Window
@@ -786,6 +787,8 @@

 			Action<UtilsCommon.LanguageType> onBufferChange = delegate(UtilsCommon.LanguageType languageType) {
+				if(m_ignoreBufferChanges) return;
+
 				var textview = GetTextViewByLanguageType(languageType);
 				var cardInfo = m_cardInfos[m_selectedPreviewIndex];
 				var settingsSuccessful = cardInfo.SetLineInfosByMultiLineString(languageType, textview.Buffer.Text);
@@ -1143,8 +1146,10 @@
 			m_liststoreLines.SetValue(treeIter.Value, 2, beginString + GLib.Markup.EscapeText(cardInfo.GetActorString()) + endString);

 			if(updateSelectedEntryTextView && index == m_selectedPreviewIndex) {
+				m_ignoreBufferChanges = true;
 				m_textviewTargetLanguage.Buffer.Text = cardInfo.ToMultiLine(UtilsCommon.LanguageType.TARGET);
 				m_textviewNativeLanguage.Buffer.Text = cardInfo.ToMultiLine(UtilsCommon.LanguageType.NATIVE);
+				m_ignoreBufferChanges = false;
 			}
 		}

@@ -1509,8 +1514,10 @@
 			CardInfo cardInfo = m_cardInfos [selectedIndex];

 			Gtk.Application.Invoke (delegate {
+				m_ignoreBufferChanges = true;
 				m_textviewTargetLanguage.Buffer.Text = cardInfo.ToMultiLine(UtilsCommon.LanguageType.TARGET);
 				m_textviewNativeLanguage.Buffer.Text = cardInfo.ToMultiLine(UtilsCommon.LanguageType.NATIVE);
+				m_ignoreBufferChanges = false;
 			});

 			// wait and see if the selected image is still the same (if user scrolls through list, is highly unperformant to extract all images


Tokens are now 8 characters rather than 10.

--- Program.cs
+++ Program.cs
@@ -38,7 +38,7 @@
         {
             using (RandomNumberGenerator rng = new RNGCryptoServiceProvider())
             {
-                byte[] tokenBytes = new byte[5];
+                byte[] tokenBytes = new byte[4];
                 rng.GetBytes(tokenBytes);
                 return BitConverter.ToString(tokenBytes);
             }


Release 1.14.2.1

Release 1.14.2.1

--- Program.cs
+++ Program.cs
@@ -19,7 +19,7 @@
         public const string BrandName = "TweetDuck";
         public const string Website = "https://tweetduck.chylex.com";

-        public const string VersionTag = "1.14.2";
+        public const string VersionTag = "1.14.2.1";

         public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
         public static readonly bool IsPortable = File.Exists(Path.Combine(ProgramPath, "makeportable"));


Version++

Version++

--- Program.cs
+++ Program.cs
@@ -16,7 +16,7 @@
 {
     static class Program
     {
-        public const string Version = "194500";
+        public const string Version = "195000";
         public static Configuration Config;
         public static LanguageManager LanguageManager;
         public static ChatClient ChatServer;


Added file size checking to precommit - More safety checking - Tweaked log formatting - Removed a bunch of debug prints and early exits - Spelling & punctuation

--- Program.cs
+++ Program.cs
@@ -27,12 +27,22 @@

     class Program
     {
+        const int Kilobytes = 1024;
+        const int Megabytes = 1024 * 1024;
         const int Version = 1;
         const int StartingBufferSize = 1024 * 1024;
         const string LocalStoreLocation = "./.git/bifrost/data";
         const string GitEmptySha = "0000000000000000000000000000000000000000";
-        const int Succeeded = 1;
+        const int Succeeded = 0;
         const int Failed = 1;
+        const int FirstFewBytes = 8000;
+
+        const string BifrostProxyId = "git-bifrost-proxy-file";
+
+        const string TextSizeThresholdKey = "repo.text-size-threshold";
+        const int DefaultTextSizeThreshold = 5 * Megabytes;
+        const string BinSizeThresholdKey = "repo.bin-size-threshold";
+        const int DefaultBinSizeThreshold = 100 * Kilobytes;

         static StreamWriter LogWriter = null;
         static int GitExitCode = 0;
@@ -51,18 +61,19 @@
 //
             int result = Succeeded;

-            using (LogWriter = new StreamWriter(File.Open("bifrostlog.txt", FileMode.Append, FileAccess.Write)))
+//            using (LogWriter = new StreamWriter(File.Open("bifrostlog.txt", FileMode.Append, FileAccess.Write)))
             {
                 Dictionary<string, CommandDelegate> Commands = new Dictionary<string, CommandDelegate>(10);

-                Commands["hook-sync"] = HookSync;
-                Commands["hook-push"] = HookPush;
-                Commands["filter-clean"] = FilterClean;
-                Commands["filter-smudge"] = FilterSmudge;
-                Commands["help"] = Help;
-                Commands["clone"] = Clone;
-                Commands["init"] = Init;
-                Commands["activate"] = Activate;
+                Commands["hook-sync"] = CmdHookSync;
+                Commands["hook-push"] = CmdHookPush;
+                Commands["hook-pre-commit"] = CmdHookPreCommit;
+                Commands["filter-clean"] = CmdFilterClean;
+                Commands["filter-smudge"] = CmdFilterSmudge;
+                Commands["help"] = CmdHelp;
+                Commands["clone"] = CmdClone;
+                Commands["init"] = CmdInit;
+                Commands["activate"] = CmdActivate;

                 string arg_command = args.Length > 0 ? args[0].ToLower() : null;
@@ -73,26 +84,24 @@
                     // LogLine("Current Dir: {0}", Directory.GetCurrentDirectory());
                     // LogLine("PATH: {0}", Environment.GetEnvironmentVariable("PATH"));

-                    result = Commands[arg_command](args);
+                    CommandDelegate command;
+                    if (!Commands.TryGetValue(arg_command, out command))
+                    {
+                        command = CmdHelp;
+                    }
+                    result = command(args);
                 }
                 else
                 {
-                    Help(args);
+                    CmdHelp(args);
                 }
             }

             return result;
         }

-        static int HookSync(string[] args)
-        {
-            return Succeeded;
-        }
-
-        static int HookPreCommit(string[] args)
-        {
-
-
+        static int CmdHookSync(string[] args)
+        {
             return Succeeded;
         }

@@ -100,7 +109,7 @@
         /// </summary>
         /// <param name="args"></param>
         /// <returns></returns>
-        static int HookPush(string[] args)
+        static int CmdHookPush(string[] args)
         {
             // This hook is called with the following parameters:
             //
@@ -129,7 +138,9 @@
                 string push_info = null;
                 while ((push_info = stdin.ReadLine()) != null)
                 {
+
                     LogLine("Bifrost: push info ({0})", push_info);
+
                     string[] push_tokens = push_info.Split(' ');

 //                     string local_ref = push_tokens[0];
@@ -167,7 +178,7 @@
                             if (git_proc == null) { return Failed; }

                             string status = null;
-                            while ((status = ReadToEscape(git_proc.StandardOutput)) != null)
+                            while ((status = ReadToNull(git_proc.StandardOutput)) != null)
                             {
                                 if (status == "X")
                                 {
@@ -180,14 +191,9 @@
                                 {
                                     try
                                     {
-                                        string file = ReadToEscape(git_proc.StandardOutput);
-
-                                        Process git_check_attr = StartGit("check-attr -z filter", file);
-                                        if (git_check_attr == null) { return Failed; }
-
-                                        git_check_attr.StandardOutput.ReadLine(); // File name
-                                        git_check_attr.StandardOutput.ReadLine(); // Attribute (filter)
-                                        string filter_tag = git_check_attr.StandardOutput.ReadLine();
+                                        string file = ReadToNull(git_proc.StandardOutput);
+
+                                        string filter_tag = GetFilterAttribute(file);

                                         if (filter_tag == "bifrost")
                                         {
@@ -196,7 +202,7 @@
                                     }
                                     catch
                                     {
-                                        LogLine("Failed to get file from diff-tree");
+                                        LogLine("Failed to get file from diff-tree.");
                                         return Failed;
                                     }
                                 }
@@ -260,23 +266,28 @@

                 foreach (var file_rev in file_revs)
                 {
-
                     // Read in the proxy for this revision of the file
                     string rile_rev_string = string.Format("{0}:{1}", file_rev.Item1, file_rev.Item2);

-                    Process git_proc = StartGit("show ", rile_rev_string);
+                    Process git_proc = StartGit(string.Format("show \"{0}\"", rile_rev_string));

                     if (git_proc == null) { return Failed; }

                     string bifrost_ver = git_proc.StandardOutput.ReadLine();
+
+                    if (!bifrost_ver.StartsWith(BifrostProxyId))
+                    {
+                        LogLine("Bifrost: Expected '{0}' to be a bifrost proxy file but got something else.", file_rev.Item2);
+                        return Failed;
+                    }
+
                     string file_sha = git_proc.StandardOutput.ReadLine();
-//                    int file_size = int.Parse(git_proc.StandardOutput.ReadLine());
+                    int file_size = int.Parse(git_proc.StandardOutput.ReadLine());

                     if (git_proc.WaitForExitCode() != 0) { return git_proc.ExitCode; }

                     // Build the mangled name
-
-                    string mangled_filename = string.Format("{0}-{1}.bin", file_sha, Path.GetFileName(bifrost_ver));
+                    string mangled_filename = string.Format("{0}-{1}.bin", file_sha, Path.GetFileName(file_rev.Item2));
                     string mangled_filepath = Path.Combine(LocalStoreLocation, mangled_filename);

                     SyncResult result = SyncResult.Failed;
@@ -287,12 +298,12 @@
                     }
                     else
                     {
-                        LogLine("Bifrost: Failed to find revision '{0}' of '{1}' in local store", file_rev.Item1, file_rev.Item2);
+                        LogLine("Bifrost: Failed to find revision '{0}' of '{1}' in local store.", file_rev.Item1, file_rev.Item2);
                     }

                     if (result == SyncResult.Failed)
                     {
-                        LogLine("Bifrost: Failed to push file {0} to {1}", mangled_filepath, store_remote_uri.AbsolutePath);
+                        LogLine("Bifrost: Failed to push file {0} to {1}.", mangled_filepath, store_remote_uri.AbsolutePath);
                         return Failed;
                     }
                     else if (result == SyncResult.Success)
@@ -321,12 +332,91 @@

             return Succeeded;
+        }
+
+        // Check the staged files for things that are too big and/or are binaries
+        static int CmdHookPreCommit(string[] args)
+        {
+            Process git_proc = StartGit("diff --name-only --cached");
+            if (git_proc == null) { return Failed; }
+
+            bool succeeded = true;
+
+            string file = null;
+            while ((file = git_proc.StandardOutput.ReadLine()) != null)
+            {
+                bool bifrost_filtered = GetFilterAttribute(file) == "bifrost";
+
+                Process git_show_proc = StartGit(string.Format("show :\"{0}\"", file));
+                if (git_show_proc == null) { return Failed; }
+
+                if (bifrost_filtered)
+                {
+                    // If the file is already filtered by bifrost, make sure that the staged file is in fact
+                    // a bifrost proxy file if it isn't the user needs to restage the file in order to allow the clean filter to run.
+
+                    string proxyfile_tag = git_show_proc.StandardOutput.ReadLine();
+
+                    if (!proxyfile_tag.StartsWith(BifrostProxyId))
+                    {
+                        LogLine("Bifrost: You need to restage '{0}'.", file);
+
+                        succeeded = false;
+                    }
+                }
+                else
+                {
+                    bool is_binary = GetAttributeSet(file, "binary");
+                    int size = 0;
+
+                    // Count the bytes & see if this is a binary file
+                    int file_byte = 0;
+                    while ((file_byte = git_show_proc.StandardOutput.Read()) != -1)
+                    {
+                        if (!is_binary && file_byte == 0)
+                        {
+                            is_binary = true;
+                        }
+                        ++size;
+                    }
+
+                    if (git_show_proc.WaitForExitCode() != 0) { return git_show_proc.ExitCode; }
+
+                    int threshold;
+                    if (is_binary)
+                    {
+                        threshold = GitConfigGetInt(BinSizeThresholdKey, DefaultBinSizeThreshold, ".gitbifrost");
+                    }
+                    else
+                    {
+                        threshold = GitConfigGetInt(TextSizeThresholdKey, DefaultTextSizeThreshold, ".gitbifrost");
+                    }
+
+                    if (threshold > -1 && size > threshold)
+                    {
+                        succeeded = false;
+                        string type = is_binary ? "binary" : "text";
+
+                        LogLine("Bifrost: The {0} file '{1}' is too big ({2} bytes)\t. Filter for the file or extention with bifrost in and restage.",
+                            type, file, size);
+                    }
+                }
+            }
+
+            if (git_proc.WaitForExitCode() != 0) { LogLine("Git failed"); return git_proc.ExitCode; }
+
+            if (!succeeded)
+            {
+                LogLine("Bifrost: Aborting commit.");
+            }
+
+            return succeeded ? Succeeded : Failed;
         }

         /// <summary>
         /// Updates the local data store with files from a git commit/add
         /// </summary>
-        static int FilterClean(string[] args)
+        static int CmdFilterClean(string[] args)
         {
             string arg_filepath = null;

@@ -347,6 +437,23 @@
                 file_stream.Position = 0;
             }

+            bool is_bifrost_proxy = false;
+
+            using (StreamReader reader = new StreamReader(file_stream))
+            {
+                is_bifrost_proxy = reader.ReadLine().StartsWith(BifrostProxyId);
+            }
+
+            if (is_bifrost_proxy)
+            {
+                // Acording to the git docs, it's possible for a filter to run on the same file multiple times so we need to handle
+                // the case where a proxy is passed in for a clean at some point. So far I've not seen this scenario occur,
+                // so until it's clear when and why this could happen in our setup, I'll leave this fail condition here to catch it.
+                LogLine("Bifrost: File '{0}' is already bifrost proxy, why are you cleaning again?", arg_filepath);
+
+                return Failed;
+            }
+
             byte[] file_hash_bytes = SHA1.Create().ComputeHash(file_stream);
             string file_hash = BitConverter.ToString(file_hash_bytes).Replace("-", "");

@@ -354,16 +461,16 @@

             using (StreamWriter output_writer = new StreamWriter(Console.OpenStandardOutput()))
             {
-                output_writer.WriteLine("git-bifrost {0}", Version);
+                output_writer.WriteLine("{0} {1}", BifrostProxyId, Version);
                 output_writer.WriteLine(file_hash);
                 output_writer.WriteLine(file_stream.Length);
             }

             if (NoiseLevel == LogNoiseLevel.Loud)
             {
-                LogLine("Name: {0}", arg_filepath);
+                LogLine(" Name: {0}", arg_filepath);
+                LogLine(" Hash: {0}", file_hash);
                 LogLine("Bytes: {0}", file_stream.Length);
-                LogLine("Hash: {0}", file_hash);
             }

             string output_filename = String.Format("{0}-{1}.bin", file_hash, Path.GetFileName(arg_filepath));
@@ -373,7 +480,7 @@
             return Succeeded;
         }

-        static int FilterSmudge(string[] args)
+        static int CmdFilterSmudge(string[] args)
         {
 //            Debugger.Break();

@@ -393,8 +500,14 @@

             using (StreamReader input_reader = new StreamReader(Console.OpenStandardInput()))
             {
-                input_reader.ReadLine(); // First line is currently unused "git-bifrost <version number>"
-                expected_file_hash = input_reader.ReadLine();
+                string bifrost_ver = input_reader.ReadLine(); // First line is currently unused "git-bifrost-prox-file <version number>"
+
+                if (!bifrost_ver.StartsWith(BifrostProxyId))
+                {
+                    LogLine("Bifrost: '{0}' is not a bifrost proxy file but is being smudged.", arg_filepath);
+                }
+
+                expected_file_hash = input_reader.ReadLine();
                 expected_file_size = int.Parse(input_reader.ReadLine());
             }

@@ -406,7 +519,7 @@

 			string[] loaded_stores = GitConfigGetRegex(@".*\.url$", ".gitbifrost");

-            Uri[] data_stores = new Uri[1];//loaded_stores.Length + 1];
+            Uri[] data_stores = new Uri[loaded_stores.Length + 1];
             data_stores[0] = new Uri(Path.Combine(Directory.GetCurrentDirectory(), LocalStoreLocation));

             int index = 1;
@@ -437,12 +550,12 @@

                         if (NoiseLevel == LogNoiseLevel.Loud)
                         {
-                            LogLine("Repo File: {0}", arg_filepath);
-                            LogLine("Store Name: {0}", input_filename);
-                            LogLine("Expect Hash: {0}", expected_file_hash);
-                            LogLine("Loaded Hash: {0}", loaded_file_hash);
+                            LogLine("    Repo File: {0}", arg_filepath);
+                            LogLine("   Store Name: {0}", input_filename);
+                            LogLine("  Expect Hash: {0}", expected_file_hash);
+                            LogLine("  Loaded Hash: {0}", loaded_file_hash);
                             LogLine("Expected Size: {0}", expected_file_size);
-                            LogLine("Loaded Size: {0}", loaded_file_size);
+                            LogLine("  Loaded Size: {0}", loaded_file_size);
                         }

                         //
@@ -482,6 +595,12 @@

                         break;
                     }
+                    else
+                    {
+                        LogLine("Bifrost: Store {0} does not contain file.", store_uri.AbsoluteUri);
+                        LogLine("    Repo File: {0}", arg_filepath);
+                        LogLine("   Store Name: {0}", input_filename);
+                    }
                 }
                 else
                 {
@@ -497,7 +616,7 @@
             return succeeded ? Succeeded : Failed;
         }

-        static int Help(string[] args)
+        static int CmdHelp(string[] args)
         {
             LogLine("usage: git-bifrost <command> [options]");
             LogLine("");
@@ -509,7 +628,7 @@
             return Succeeded;
         }

-        static int Clone(string[] args)
+        static int CmdClone(string[] args)
         {
             string clone_args = string.Join(" ", args, 1, args.Length - 1);

@@ -529,7 +648,7 @@
             return GitExitCode;
         }

-        static int Init(string[] args)
+        static int CmdInit(string[] args)
         {
             string init_args = string.Join(" ", args);

@@ -550,7 +669,7 @@
             return GitExitCode;
         }

-        static int Activate(string[] args)
+        static int CmdActivate(string[] args)
         {
             if (!Directory.Exists(".git"))
             {
@@ -561,6 +680,9 @@
             InstallBifrost();

             // Generate sample config
+
+            GitConfigSet(TextSizeThresholdKey, DefaultTextSizeThreshold.ToString(), ".gitbifrost");
+            GitConfigSet(BinSizeThresholdKey, DefaultBinSizeThreshold.ToString(), ".gitbifrost");

             GitConfigSet("localstore.depth", "0", ".gitbifrost");

@@ -638,7 +760,35 @@
             return Succeeded;
         }

-        static string ReadToEscape(StreamReader reader)
+        static string GetFilterAttribute(string file)
+        {
+            Process git_check_attr = StartGit(string.Format("check-attr -z filter \"{0}\"", file));
+            if (git_check_attr == null) { return null; }
+
+            ReadToNull(git_check_attr.StandardOutput); // File name
+            ReadToNull(git_check_attr.StandardOutput); // Attribute (filter)
+            string filter_tag = ReadToNull(git_check_attr.StandardOutput);
+
+            if (git_check_attr.WaitForExitCode() != 0) { return null; }
+
+            return filter_tag;
+        }
+
+        static bool GetAttributeSet(string file, string attribute)
+        {
+            Process git_check_attr = StartGit(string.Format("check-attr -z {0} \"{1}\"", attribute, file));
+            if (git_check_attr == null) { return false; }
+
+            ReadToNull(git_check_attr.StandardOutput); // File name
+            ReadToNull(git_check_attr.StandardOutput); // attribute
+            string value = ReadToNull(git_check_attr.StandardOutput);
+
+            if (git_check_attr.WaitForExitCode() != 0) { return false; }
+
+            return value == "set";
+        }
+
+        static string ReadToNull(StreamReader reader)
         {
             var bytes = new List<byte>();

@@ -681,12 +831,12 @@
                 {
                     file_stream.CopyTo(output_stream);

-                    LogLine("Bifrost: Local store - updated {0}", filepath);
+                    LogLine("Bifrost: Local store updated {0}", filepath);
                 }
             }
             else
             {
-                LogLine("Bifost: Local store - skipped");
+                LogLine("Bifrost: Local store skipped");
             }
         }

@@ -695,7 +845,7 @@
         {
             try
             {
-                LogWriter.WriteLine(format, arg);
+//                LogWriter.WriteLine(format, arg);
                 Console.Error.WriteLine(format, arg);
             }
             catch
@@ -769,6 +919,33 @@
             }

             return lines.ToArray();
+        }
+
+        static int GitConfigGetInt(string key, int defaultValue, string file)
+        {
+            string fileArg = string.IsNullOrWhiteSpace(file) ? "" : "-f " + file;
+
+            Process git_proc = StartGit("config --null --get", fileArg, key);
+
+            if (git_proc == null)
+            {
+                return defaultValue;
+            }
+
+            string value_str = ReadToNull(git_proc.StandardOutput);
+
+            if (git_proc.WaitForExitCode() != 0)
+            {
+                return defaultValue;
+            }
+
+            int value;
+            if (int.TryParse(value_str, out value))
+            {
+                return value;
+            }
+
+            return defaultValue;
         }

         static Process NewGit(string arguments)