Add unit tests for 2 hours for BuildUpTime method

--- UnitTestUsefullFunctions/UnitTestFunctionsDateTime.cs
+++ UnitTestUsefullFunctions/UnitTestFunctionsDateTime.cs
@@ -738,6 +738,319 @@
       string result = DateFunc.BuildUpTime(source);
       Assert.AreEqual(result, expected);
     }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_zero_two_hours()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 0 * second + 0 * millisecond;
+      const string expected = "2 hours 0 minute 0 second 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 0 * second + 1 * millisecond;
+      const string expected = "2 hours 0 minute 0 second 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_hundred_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 0 * second + 100 * millisecond;
+      const string expected = "2 hours 0 minute 0 second 100 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_second()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 1 * second + 0 * millisecond;
+      const string expected = "2 hours 0 minute 1 second 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_second_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 1 * second + 1 * millisecond;
+      const string expected = "2 hours 0 minute 1 second 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_second_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 1 * second + 2 * millisecond;
+      const string expected = "2 hours 0 minute 1 second 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_seconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 2 * second + 0 * millisecond;
+      const string expected = "2 hours 0 minute 2 seconds 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_seconds_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 2 * second + 1 * millisecond;
+      const string expected = "2 hours 0 minute 2 seconds 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_seconds_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 0 * minute + 2 * second + 2 * millisecond;
+      const string expected = "2 hours 0 minute 2 seconds 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_minute()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 1 * minute + 0 * second + 0 * millisecond;
+      const string expected = "2 hours 1 minute 0 second 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_minute_zero_second_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 1 * minute + 0 * second + 1 * millisecond;
+      const string expected = "2 hours 1 minute 0 second 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_minute_one_second_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 1 * minute + 1 * second + 1 * millisecond;
+      const string expected = "2 hours 1 minute 1 second 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_minute_one_second_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 1 * minute + 1 * second + 2 * millisecond;
+      const string expected = "2 hours 1 minute 1 second 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_minute_two_seconds_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 1 * minute + 2 * second + 1 * millisecond;
+      const string expected = "2 hours 1 minute 2 seconds 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_one_minute_two_seconds_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 1 * minute + 2 * second + 2 * millisecond;
+      const string expected = "2 hours 1 minute 2 seconds 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_zero_second_zero_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 0 * second + 0 * millisecond;
+      const string expected = "2 hours 2 minutes 0 second 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_zero_second_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 0 * second + 1 * millisecond;
+      const string expected = "2 hours 2 minutes 0 second 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_zero_second_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 0 * second + 2 * millisecond;
+      const string expected = "2 hours 2 minutes 0 second 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_one_second_zero_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 1 * second + 0 * millisecond;
+      const string expected = "2 hours 2 minutes 1 second 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_one_second_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 1 * second + 1 * millisecond;
+      const string expected = "2 hours 2 minutes 1 second 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_one_second_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 1 * second + 2 * millisecond;
+      const string expected = "2 hours 2 minutes 1 second 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_two_seconds_zero_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 2 * second + 0 * millisecond;
+      const string expected = "2 hours 2 minutes 2 seconds 0 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_two_seconds_one_millisecond()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 2 * second + 1 * millisecond;
+      const string expected = "2 hours 2 minutes 2 seconds 1 millisecond";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+
+    [TestMethod]
+    public void TestMethod_BuildUpTime_true_two_hours_two_minutes_two_seconds_two_milliseconds()
+    {
+      const int millisecond = 1;
+      const int second = 1000 * millisecond;
+      const int minute = 60 * second;
+      const int hour = 60 * minute;
+      const int source = 2 * hour + 2 * minute + 2 * second + 2 * millisecond;
+      const string expected = "2 hours 2 minutes 2 seconds 2 milliseconds";
+      string result = DateFunc.BuildUpTime(source);
+      Assert.AreEqual(result, expected);
+    }
+

     #endregion BuildUpTime
     #region HasHours


Set libsodium p/invoke signatures calling convention to cdecl. Fixes #7.

--- src/Sodium.Core/SodiumLibrary.cs
+++ src/Sodium.Core/SodiumLibrary.cs
@@ -9,259 +9,259 @@
   public static partial class SodiumLibrary
   {
     //sodium_init
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern void sodium_init();

     //randombytes_buf
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern void randombytes_buf(byte[] buffer, int size);

     //randombytes_uniform
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int randombytes_uniform(int upperBound);

     //sodium_increment
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern void sodium_increment(byte[] buffer, long length);

     //sodium_compare
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int sodium_compare(byte[] a, byte[] b, long length);

     //sodium_version_string
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern IntPtr sodium_version_string();

     //crypto_hash
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_hash(byte[] buffer, byte[] message, long length);

     //crypto_hash_sha512
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_hash_sha512(byte[] buffer, byte[] message, long length);

     //crypto_hash_sha256
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_hash_sha256(byte[] buffer, byte[] message, long length);

     //crypto_generichash
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_generichash(byte[] buffer, int bufferLength, byte[] message, long messageLength, byte[] key, int keyLength);

     //crypto_generichash_blake2b_salt_personal
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_generichash_blake2b_salt_personal(byte[] buffer, int bufferLength, byte[] message, long messageLength, byte[] key, int keyLength, byte[] salt, byte[] personal);

     //crypto_onetimeauth
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_onetimeauth(byte[] buffer, byte[] message, long messageLength, byte[] key);

     //crypto_onetimeauth_verify
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_onetimeauth_verify(byte[] signature, byte[] message, long messageLength, byte[] key);

     //crypto_pwhash_str
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_pwhash_str(byte[] buffer, byte[] password, long passwordLen, long opsLimit, int memLimit);

     //crypto_pwhash_str_verify
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_pwhash_str_verify(byte[] buffer, byte[] password, long passLength);

     //crypto_pwhash
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_pwhash(byte[] buffer, long bufferLen, byte[] password, long passwordLen, byte[] salt, long opsLimit, int memLimit, int alg);

     //crypto_pwhash_scryptsalsa208sha256_str
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_pwhash_scryptsalsa208sha256_str(byte[] buffer, byte[] password, long passwordLen, long opsLimit, int memLimit);

     //crypto_pwhash_scryptsalsa208sha256
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_pwhash_scryptsalsa208sha256(byte[] buffer, long bufferLen, byte[] password, long passwordLen, byte[] salt, long opsLimit, int memLimit);

     //crypto_pwhash_scryptsalsa208sha256_str_verify
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_pwhash_scryptsalsa208sha256_str_verify(byte[] buffer, byte[] password, long passLength);

     //crypto_sign_keypair
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_keypair(byte[] publicKey, byte[] secretKey);

     //crypto_sign_seed_keypair
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_seed_keypair(byte[] publicKey, byte[] secretKey, byte[] seed);

     //crypto_sign
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign(byte[] buffer, ref long bufferLength, byte[] message, long messageLength, byte[] key);

     //crypto_sign_open
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_open(byte[] buffer, ref long bufferLength, byte[] signedMessage, long signedMessageLength, byte[] key);

     //crypto_sign_detached
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_detached(byte[] signature, ref long signatureLength, byte[] message, long messageLength, byte[] key);

     //crypto_sign_verify_detached
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_verify_detached(byte[] signature, byte[] message, long messageLength, byte[] key);

     //crypto_sign_ed25519_sk_to_seed
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_ed25519_sk_to_seed(byte[] seed, byte[] secretKey);

     //crypto_sign_ed25519_sk_to_pk
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_ed25519_sk_to_pk(byte[] publicKey, byte[] secretKey);

     //crypto_sign_ed25519_pk_to_curve25519
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_ed25519_pk_to_curve25519(byte[] curve25519Pk, byte[] ed25519Pk);

     //crypto_sign_ed25519_sk_to_curve25519
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_sign_ed25519_sk_to_curve25519(byte[] curve25519Sk, byte[] ed25519Sk);

     //crypto_box_keypair
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_keypair(byte[] publicKey, byte[] secretKey);

     //crypto_box_easy
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_easy(byte[] buffer, byte[] message, long messageLength, byte[] nonce, byte[] publicKey, byte[] secretKey);

     //crypto_box_open_easy
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_detached(byte[] cipher, byte[] mac, byte[] message, long messageLength, byte[] nonce, byte[] pk, byte[] sk);

     //crypto_box_detached
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_open_easy(byte[] buffer, byte[] cipherText, long cipherTextLength, byte[] nonce, byte[] publicKey, byte[] secretKey);

     //crypto_box_open_detached
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_open_detached(byte[] buffer, byte[] cipherText, byte[] mac, long cipherTextLength, byte[] nonce, byte[] pk, byte[] sk);

     //crypto_scalarmult_bytes
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_scalarmult_bytes();

     //crypto_scalarmult_scalarbytes
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_scalarmult_scalarbytes();

     //crypto_scalarmult_primitive
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern byte crypto_scalarmult_primitive();

     //crypto_scalarmult_base
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_scalarmult_base(byte[] q, byte[] n);

     //crypto_scalarmult
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_scalarmult(byte[] q, byte[] n, byte[] p);

     //crypto_box_seal
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_seal(byte[] buffer, byte[] message, long messageLength, byte[] pk);

     //crypto_box_seal_open
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_box_seal_open(byte[] buffer, byte[] cipherText, long cipherTextLength, byte[] pk, byte[] sk);

     //crypto_secretbox_easy
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_secretbox_easy(byte[] buffer, byte[] message, long messageLength, byte[] nonce, byte[] key);

     //crypto_secretbox_open_easy
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_secretbox_open_easy(byte[] buffer, byte[] cipherText, long cipherTextLength, byte[] nonce, byte[] key);

     //crypto_secretbox_detached
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_secretbox_detached(byte[] cipher, byte[] mac, byte[] message, long messageLength, byte[] nonce, byte[] key);

     //crypto_secretbox_open_detached
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_secretbox_open_detached(byte[] buffer, byte[] cipherText, byte[] mac, long cipherTextLength, byte[] nonce, byte[] key);

     //crypto_auth
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_auth(byte[] buffer, byte[] message, long messageLength, byte[] key);

     //crypto_auth_verify
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_auth_verify(byte[] signature, byte[] message, long messageLength, byte[] key);

     //crypto_auth_hmacsha256
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_auth_hmacsha256(byte[] buffer, byte[] message, long messageLength, byte[] key);

     //crypto_auth_hmacsha256_verify
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_auth_hmacsha256_verify(byte[] signature, byte[] message, long messageLength, byte[] key);

     //crypto_auth_hmacsha512
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_auth_hmacsha512(byte[] signature, byte[] message, long messageLength, byte[] key);

     //crypto_auth_hmacsha512_verify
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_auth_hmacsha512_verify(byte[] signature, byte[] message, long messageLength, byte[] key);

     //crypto_shorthash
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_shorthash(byte[] buffer, byte[] message, long messageLength, byte[] key);

     //crypto_stream_xor
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_stream_xor(byte[] buffer, byte[] message, long messageLength, byte[] nonce, byte[] key);

     //crypto_stream_chacha20_xor
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_stream_chacha20_xor(byte[] buffer, byte[] message, long messageLength, byte[] nonce, byte[] key);

     //sodium_bin2hex
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern IntPtr sodium_bin2hex(byte[] hex, int hexMaxlen, byte[] bin, int binLen);

     //sodium_hex2bin
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int sodium_hex2bin(IntPtr bin, int binMaxlen, string hex, int hexLen, string ignore, out int binLen, string hexEnd);

     //crypto_aead_chacha20poly1305_encrypt
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_aead_chacha20poly1305_encrypt(IntPtr cipher, out long cipherLength, byte[] message, long messageLength, byte[] additionalData, long additionalDataLength, byte[] nsec, byte[] nonce, byte[] key);

     //crypto_aead_chacha20poly1305_decrypt
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_aead_chacha20poly1305_decrypt(IntPtr message, out long messageLength, byte[] nsec, byte[] cipher, long cipherLength, byte[] additionalData, long additionalDataLength, byte[] nonce, byte[] key);

     //crypto_aead_aes256gcm_is_available
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_aead_aes256gcm_is_available();

     //crypto_aead_aes256gcm_encrypt
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_aead_aes256gcm_encrypt(IntPtr cipher, out long cipherLength, byte[] message, long messageLength, byte[] additionalData, long additionalDataLength, byte[] nsec, byte[] nonce, byte[] key);

     //crypto_aead_aes256gcm_decrypt
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_aead_aes256gcm_decrypt(IntPtr message, out long messageLength, byte[] nsec, byte[] cipher, long cipherLength, byte[] additionalData, long additionalDataLength, byte[] nonce, byte[] key);

     //crypto_generichash_init
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_generichash_init(IntPtr state, byte[] key, int keySize, int hashSize);

     //crypto_generichash_update
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_generichash_update(IntPtr state, byte[] message, long messageLength);

     //crypto_generichash_final
-    [DllImport("libsodium")]
+    [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
     internal static extern int crypto_generichash_final(IntPtr state, byte[] buffer, int bufferLength);

     //crypto_generichash_state


[2015.12.7] push

[2015.12.7] push

--- Unity/Assets/Hellgate/Scripts/Push/iOSNotification.cs
+++ Unity/Assets/Hellgate/Scripts/Push/iOSNotification.cs
@@ -63,7 +63,6 @@

 		public virtual void ScheduleLocalNotification (DateTime date, string text, string id = "", string title = "")
 		{
-			Debug.Log ("ScheduleLocalNotification : " + date + " | " + text + " | " + id + " | " + title);
 			LocalNotification notif = new LocalNotification ();
 			notif.fireDate = date;
 			notif.alertBody = text;
@@ -77,12 +76,9 @@

 		public virtual void CancelLocalNotification (string id)
 		{
-			Debug.Log ("CancelLocalNotification : " + id);
 			LocalNotification[] notifis = NotificationServices.scheduledLocalNotifications;
-			Debug.Log ("CancelLocalNotification count : " + notifis.Length);
 			for (int i = 0; i < notifis.Length; i++) {
 				if (notifis [i].userInfo ["id"].ToString() == id) {
-					Debug.Log ("CancelLocalNotification clear : " + id);
 					NotificationServices.CancelLocalNotification (notifis[i]);
 				}
 			}


Script Changes

Script Changes

--- UnityProject/Assets/Scripts/Gateway/StationGateway.cs
+++ UnityProject/Assets/Scripts/Gateway/StationGateway.cs
@@ -38,18 +38,19 @@
 	[SerializeField]
 	private int RandomCountEnd = 1200;

-	private protected RegisterTile registerTile;
+	protected RegisterTile registerTile;

 	private Matrix Matrix => registerTile.Matrix;

 	public string WorldName = "The Station";

-	private protected Vector3Int Position;
-
-	private protected string Message;
-
-	private protected float timeElapsedServer = 0;
-	private protected float timeElapsedClient = 0;
+	protected Vector3Int Position;
+
+	protected string Message;
+
+	protected float timeElapsedServer = 0;
+	protected float timeElapsedClient = 0;
+	protected float timeElapsedServerSound = 0;
 	public float DetectionTime = 1;

 	[SyncVar(hook = nameof(SyncState))]
@@ -77,6 +78,14 @@
 			{
 				DetectPlayer();
 				timeElapsedServer = 0;
+			}
+
+			timeElapsedServerSound += Time.deltaTime;
+			if (timeElapsedServerSound > 7 && isOn)
+			{
+				DetectPlayer();
+				SoundManager.PlayNetworkedAtPos("machinehum4", Position + Vector3Int.up);
+				timeElapsedServerSound = 0;
 			}
 		}
 		else


Fix reflection call

Fix reflection call

--- src/Test/Utilities/CLRHelpers.cs
+++ src/Test/Utilities/CLRHelpers.cs
@@ -58,7 +58,7 @@
             // This API isn't available on Mono hence we must use reflection to access it.
             Debug.Assert(!IsRunningOnMono());

-            var getRuntimeInterfaceAsObject = typeof(RuntimeEnvironment).GetMethod("GetRuntimeInterfaceasObject");
+            var getRuntimeInterfaceAsObject = typeof(RuntimeEnvironment).GetMethod("GetRuntimeInterfaceasObject", BindingFlags.Public | BindingFlags.Static);
             return getRuntimeInterfaceAsObject.Invoke(null, new object[] { clsid, riid });
         }


change bgcolor and to v4 label

change bgcolor and to v4 label

--- src/ToDoListAngular/index.cshtml
+++ src/ToDoListAngular/index.cshtml
@@ -36,11 +36,11 @@

-

+

-
Todo List v3

+
Todo List v4


ShellViewModel won't open the file in a fixed place.

--- WpfHexEditor.Sample.MVVM/ViewModels/ShellViewModel.cs
+++ WpfHexEditor.Sample.MVVM/ViewModels/ShellViewModel.cs
@@ -19,7 +19,7 @@
         public DelegateCommand LoadedCommand => _loadedCommand ??
             (_loadedCommand = new DelegateCommand(
                 () => {
-                    Stream = File.OpenRead("D://s.exe");
+                    //Stream = File.OpenRead("D://s.exe");
                 }
             ));


Minor fix to the StaticTypeAnalyzer related to feeding runtime generation contexts to an expression constant resoler

--- ZScript/CodeGeneration/Analysis/StaticTypeAnalyzer.cs
+++ ZScript/CodeGeneration/Analysis/StaticTypeAnalyzer.cs
@@ -160,7 +160,7 @@
         /// <param name="scope">The code scope to process expressions on</param>
         private void ProcessExpressions(CodeScope scope)
         {
-            var resolver = new ExpressionConstantResolver(new RuntimeGenerationContext(typeProvider: TypeProvider), new TypeOperationProvider());
+            var resolver = new ExpressionConstantResolver(_generationContext, new TypeOperationProvider());
             var traverser = new ExpressionStatementsTraverser(_typeResolver, resolver);
             var definitions = scope.Definitions;


MainWindowViewModel cleaned up

MainWindowViewModel cleaned up

--- ZohoPeopleTimeLogger/ViewModel/MainWindowViewModel.cs
+++ ZohoPeopleTimeLogger/ViewModel/MainWindowViewModel.cs
@@ -1,8 +1,6 @@
 using System.Collections.ObjectModel;
 using System.Windows.Input;
 using GalaSoft.MvvmLight.CommandWpf;
-using Microsoft.Practices.ServiceLocation;
-using Microsoft.Practices.Unity;
 using ZohoPeopleClient;
 using ZohoPeopleTimeLogger.Controllers;
 using ZohoPeopleTimeLogger.Services;


Remove unnecessarily allocated indices.

Remove unnecessarily allocated indices.

--- src/Assets/CjLib/PrimitiveMeshFactory.cs
+++ src/Assets/CjLib/PrimitiveMeshFactory.cs
@@ -1016,8 +1016,8 @@
       {
         mesh = new Mesh();

-        int numVertsPerLong = (latSegments - 1) * 4 + 6;
-        int numTrisPerLong = (latSegments - 1) * 2 + 2;
+        int numVertsPerLong = (latSegments - 2) * 4 + 6;
+        int numTrisPerLong = (latSegments - 2) * 2 + 2;

         Vector3[] aVert = new Vector3[longSegments * numVertsPerLong];
         Vector3[] aNormal = new Vector3[longSegments * numVertsPerLong];


Updated version number.

Updated version number.

--- src/Augurk/Properties/AssemblyVersion.cs
+++ src/Augurk/Properties/AssemblyVersion.cs
@@ -9,6 +9,6 @@
 //
 // You can specify all the values or you can default the Revision and Build Numbers
 // by using the '*' as shown below:
-[assembly: AssemblyVersion("2.2.0")]
-[assembly: AssemblyFileVersion("2.2.0")]
-[assembly: AssemblyInformationalVersion("2.2.0")]
+[assembly: AssemblyVersion("2.3.0")]
+[assembly: AssemblyFileVersion("2.3.0")]
+[assembly: AssemblyInformationalVersion("2.3.0")]


Setup control characters and folding in the demo application for testing

--- src/AvaloniaEdit.Demo/MainWindow.xaml.cs
+++ src/AvaloniaEdit.Demo/MainWindow.xaml.cs
@@ -14,6 +14,7 @@
 using AvaloniaEdit.Demo.Resources;
 using AvaloniaEdit.Document;
 using AvaloniaEdit.Editing;
+using AvaloniaEdit.Folding;
 using AvaloniaEdit.Rendering;
 using AvaloniaEdit.TextMate;
 using AvaloniaEdit.TextMate.Grammars;
@@ -25,6 +26,7 @@
     public class MainWindow : Window
     {
         private readonly TextEditor _textEditor;
+        private FoldingManager _foldingManager;
         private readonly TextMate.TextMate.Installation _textMateInstallation;
         private CompletionWindow _completionWindow;
         private OverloadInsightWindow _insightWindow;
@@ -56,7 +58,7 @@
             _textEditor.TextArea.Background = this.Background;
             _textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered;
             _textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering;
-            _textEditor.Options.ConvertTabsToSpaces = true;
+            _textEditor.Options.ShowBoxForControlCharacters = true;
             _textEditor.TextArea.IndentationStrategy = new Indentation.CSharp.CSharpIndentationStrategy(_textEditor.Options);
             _textEditor.TextArea.Caret.PositionChanged += Caret_PositionChanged;
             _textEditor.TextArea.RightClickMovesCaret = true;
@@ -86,7 +88,9 @@

             string scopeName = _registryOptions.GetScopeByLanguageId(csharpLanguage.Id);

-            _textEditor.Document = new TextDocument(ResourceLoader.LoadSampleFile(scopeName));
+            _textEditor.Document = new TextDocument(
+                "// AvaloniaEdit supports displaying control chars: \a or \b or \v" + Environment.NewLine +
+                ResourceLoader.LoadSampleFile(scopeName));
             _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(csharpLanguage.Id));

             _statusTextBlock = this.Find<TextBlock>("StatusText");
@@ -117,10 +121,25 @@
         {
             Language language = (Language)_syntaxModeCombo.SelectedItem;

+            if (_foldingManager != null)
+            {
+                _foldingManager.Clear();
+                FoldingManager.Uninstall(_foldingManager);
+            }
+
             string scopeName = _registryOptions.GetScopeByLanguageId(language.Id);

             _textEditor.Document = new TextDocument(ResourceLoader.LoadSampleFile(scopeName));
             _textMateInstallation.SetGrammar(scopeName);
+
+            if (language.Id == "xml")
+            {
+                _foldingManager = FoldingManager.Install(_textEditor.TextArea);
+
+                var strategy = new XmlFoldingStrategy();
+                strategy.UpdateFoldings(_foldingManager, _textEditor.Document);
+                return;
+            }
         }

         private void ChangeThemeButton_Click(object sender, RoutedEventArgs e)


Add strikethrough and underline text to the demo

--- src/AvaloniaEdit.Demo/MainWindow.xaml.cs
+++ src/AvaloniaEdit.Demo/MainWindow.xaml.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Linq;
 using System.Runtime.CompilerServices;
 using Avalonia.Controls;
 using Avalonia.Input;
@@ -88,8 +89,10 @@

             _textEditor.Document = new TextDocument(
                 "// AvaloniaEdit supports displaying control chars: \a or \b or \v" + Environment.NewLine +
+                "// AvaloniaEdit supports displaying underline and strikethrough" + Environment.NewLine +
                 ResourceLoader.LoadSampleFile(scopeName));
             _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(csharpLanguage.Id));
+            _textEditor.TextArea.TextView.LineTransformers.Add(new CustomFormatTransformer());

             _statusTextBlock = this.Find<TextBlock>("StatusText");

@@ -117,6 +120,14 @@

         private void SyntaxModeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
         {
+            for (int i = _textEditor.TextArea.TextView.LineTransformers.Count - 1; i >= 0; i--)
+            {
+                if (_textEditor.TextArea.TextView.LineTransformers[i] is CustomFormatTransformer)
+                {
+                    _textEditor.TextArea.TextView.LineTransformers.RemoveAt(i);
+                }
+            }
+
             Language language = (Language)_syntaxModeCombo.SelectedItem;

             if (_foldingManager != null)
@@ -227,6 +238,31 @@
             }
         }

+        class CustomFormatTransformer : DocumentColorizingTransformer
+        {
+            protected override void ColorizeLine(DocumentLine line)
+            {
+
+                if (line.LineNumber == 2)
+                {
+                    string lineText = this.CurrentContext.Document.GetText(line);
+
+                    int indexOfUnderline = lineText.IndexOf("underline");
+                    int indexOfStrikeThrough = lineText.IndexOf("strikethrough");
+
+                    ChangeLinePart(
+                        line.Offset + indexOfUnderline,
+                        line.Offset + indexOfUnderline + "underline".Length,
+                        visualLine => visualLine.TextRunProperties.Underline = true);
+
+                    ChangeLinePart(
+                        line.Offset + indexOfStrikeThrough,
+                        line.Offset + indexOfStrikeThrough + "strikethrough".Length,
+                        visualLine => visualLine.TextRunProperties.Strikethrough = true);
+                }
+            }
+        }
+
         private class MyOverloadProvider : IOverloadProvider
         {
             private readonly IList<(string header, string content)> _items;


Fixed ItemInfoTest

Fixed ItemInfoTest

--- src/D2Reader.Test/Models/ItemInfoTest.cs
+++ src/D2Reader.Test/Models/ItemInfoTest.cs
@@ -19,7 +19,9 @@
                 ItemName = "somename",
                 ItemBaseName = "somebasename",
                 QualityColor = "somecolor",
-                Location = BodyLocation.Gloves,
+                Location = new ItemLocation {
+                    BodyLocation = BodyLocation.Gloves
+                },
                 Properties = new List<string> { "hello", "world" },
             };

@@ -33,7 +35,9 @@
                 ItemName = "somename",
                 ItemBaseName = "somebasename",
                 QualityColor = "somecolor",
-                Location = BodyLocation.Gloves,
+                Location = new ItemLocation {
+                    BodyLocation = BodyLocation.Gloves
+                },
                 Properties = new List<string> { "hello", "world" },
             };


minor changes on DateHumanizeTests

minor changes on DateHumanizeTests

--- src/Humanizer.Tests/DateHumanizeTests.cs
+++ src/Humanizer.Tests/DateHumanizeTests.cs
@@ -8,21 +8,15 @@
     {
         static void VerifyWithCurrentDate(string expectedString, TimeSpan deltaFromNow)
         {
-            if (expectedString == null)
-                throw new ArgumentNullException("expectedString");
-
             var utcNow = DateTime.UtcNow;
             var localNow = DateTime.Now;

-            Assert.Equal(expectedString, utcNow.Add(deltaFromNow).Humanize(true, utcNow));
-            Assert.Equal(expectedString, localNow.Add(deltaFromNow).Humanize(false, localNow));
+            Assert.Equal(expectedString, utcNow.Add(deltaFromNow).Humanize());
+            Assert.Equal(expectedString, localNow.Add(deltaFromNow).Humanize(false));
         }

         static void VerifyWithDateInjection(string expectedString, TimeSpan deltaFromNow)
         {
-            if (expectedString == null)
-                throw new ArgumentNullException("expectedString");
-
             var utcNow = new DateTime(2013, 6, 20, 9, 58, 22, DateTimeKind.Utc);
             var now = new DateTime(2013, 6, 20, 11, 58, 22, DateTimeKind.Local);

@@ -121,6 +115,12 @@
         }

         [Fact]
+        public void OneSecondAgo()
+        {
+            Verify(Resources.GetResource(ResourceKeys.DateHumanize.SingleSecondAgo), new TimeSpan(0, 0, 0, -1));
+        }
+
+        [Fact]
         public void SecondsAgo()
         {
             Verify(string.Format(Resources.GetResource(ResourceKeys.DateHumanize.MultipleSecondsAgo), 10), new TimeSpan(0, 0, 0, -10));


Added OSX support for steamvr settings. (Again! where did I commit this before?)

--- SteamvrSettings.cs
+++ SteamvrSettings.cs
@@ -1,90 +1,95 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using System.Text.RegularExpressions;
-
-#if UNITY_EDITOR
-using UnityEditor;
-#endif
-
-public class SteamVrSettings : MonoBehaviour
-{
-
-	const string SettingsFilename = "default.vrsettings";
-	const string RequireHmdKey = "requireHmd";
-
-	//	todo, work this out from env vars etc
-	const string SettingsFolder = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\SteamVR\\resources\\settings\\";
-
-	static string SettingsPath	{	get	{	return SettingsFolder + SettingsFilename;	}	}
-
-#if UNITY_EDITOR
-	[MenuItem("SteamVR/Set RequireHmd False")]
-	public static void Set_RequireHmd_False()
-	{
-		SetVrSettings( RequireHmdKey, "false" );
-	}
-#endif
-
-#if UNITY_EDITOR
-	[MenuItem("SteamVR/Set RequireHmd True")]
-	public static void Set_RequireHmd_True()
-	{
-		SetVrSettings( RequireHmdKey, "true" );
-	}
-#endif
-
-#if UNITY_EDITOR
-	[MenuItem("SteamVR/Show " + SettingsFilename)]
-	public static void ShowSettingsFile()
-	{
-		EditorUtility.RevealInFinder( SettingsPath );
-	}
-#endif
-
-#if UNITY_EDITOR
-	public static void SetVrSettings(string Key,string NewValue)
-	{
-
-		//	setup regular expression
-		string EscapedKey =  "\"" + Key + "\" : ";
-		string MatchPattern = EscapedKey + "(true|false),";
-		//	gr: I thought it would just repalce the match, but in c# the whole match is replaced :)
-		//string Replacement = NewCategory;
-		string Replacement = EscapedKey + NewValue + ",";
-		Regex RegExpression = new Regex(MatchPattern);
-
-		string NoChangeFilenames = null;
-
-		var FilePaths = new string[1] { SettingsPath };
-
-		foreach (var Path in FilePaths) {
-			try
-			{
-				var Contents = System.IO.File.ReadAllText( Path );
-				var NewContents = RegExpression.Replace( Contents, Replacement );
-				if ( Contents != NewContents )
-				{
-					System.IO.File.WriteAllText( Path, NewContents );
-					Debug.Log("Updated " + Path );
-				}
-				else
-				{
-					NoChangeFilenames += Path + " ";
-					//Debug.Log("skipped " + Path );
-				}
-			}
-			catch(System.Exception e) {
-				Debug.LogError ("Error replacing " + Key + " in " + Path);
-				Debug.LogException (e);
-			}
-		}
-
-		if (!string.IsNullOrEmpty (NoChangeFilenames))
-			Debug.Log ("Didn't change " + NoChangeFilenames);
-
-	}
-#endif
-
-
-}
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Text.RegularExpressions;
+using System.IO;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+public class SteamVrSettings : MonoBehaviour
+{
+
+	const string 	SettingsFilename = "default.vrsettings";
+	const string	RequireHmdKey = "requireHmd";
+	static string	SettingsPath	{	get	{	return SettingsFolder + SettingsFilename;	}	}
+
+	//	todo, work this out from env vars etc
+#if UNITY_EDITOR_OSX
+	static string	SettingsFolder	{	get	{	return Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Library/Application Support/Steam/steamapps/common/SteamVR/SteamVR.app/Contents/MacOS/runtime/resources/settings/" );	}	}
+#else
+	const string SettingsFolder = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\SteamVR\\resources\\settings\\";
+#endif
+
+
+#if UNITY_EDITOR
+	[MenuItem("SteamVR/Set RequireHmd False")]
+	public static void Set_RequireHmd_False()
+	{
+		SetVrSettings( RequireHmdKey, "false" );
+	}
+#endif
+
+#if UNITY_EDITOR
+	[MenuItem("SteamVR/Set RequireHmd True")]
+	public static void Set_RequireHmd_True()
+	{
+		SetVrSettings( RequireHmdKey, "true" );
+	}
+#endif
+
+#if UNITY_EDITOR
+	[MenuItem("SteamVR/Show " + SettingsFilename)]
+	public static void ShowSettingsFile()
+	{
+		EditorUtility.RevealInFinder( SettingsPath );
+	}
+#endif
+
+#if UNITY_EDITOR
+	public static void SetVrSettings(string Key,string NewValue)
+	{
+
+		//	setup regular expression
+		string EscapedKey =  "\"" + Key + "\" : ";
+		string MatchPattern = EscapedKey + "(true|false),";
+		//	gr: I thought it would just repalce the match, but in c# the whole match is replaced :)
+		//string Replacement = NewCategory;
+		string Replacement = EscapedKey + NewValue + ",";
+		Regex RegExpression = new Regex(MatchPattern);
+
+		string NoChangeFilenames = null;
+
+		var FilePaths = new string[1] { SettingsPath };
+
+		foreach (var Path in FilePaths) {
+			try
+			{
+				var Contents = File.ReadAllText( Path );
+				var NewContents = RegExpression.Replace( Contents, Replacement );
+				if ( Contents != NewContents )
+				{
+					System.IO.File.WriteAllText( Path, NewContents );
+					Debug.Log("Updated " + Path );
+				}
+				else
+				{
+					NoChangeFilenames += Path + " ";
+					//Debug.Log("skipped " + Path );
+				}
+			}
+			catch(System.Exception e) {
+				Debug.LogError ("Error replacing " + Key + " in " + Path);
+				Debug.LogException (e);
+			}
+		}
+
+		if (!string.IsNullOrEmpty (NoChangeFilenames))
+			Debug.Log ("Didn't change " + NoChangeFilenames);
+
+	}
+#endif
+
+
+}


Code cleanup

Code cleanup

Cleaned up comments, simplified property by using expression-bodied
properties, removed unnecessary rounding, inverted main conditional
statement to reduce nesting.

--- SupplyandDemand.cs
+++ SupplyandDemand.cs
@@ -1,56 +1,48 @@
 using System;
-using System.Reflection;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Reflection;
+using Harmony;
+using HugsLib;
 using RimWorld;
 using RimWorld.Planet;
-using HugsLib;
-using Harmony;
+using UnityEngine;
 using Verse;
-using UnityEngine;
-[assembly:AssemblyVersion("0.1.1.*")] //Syntax: [Game Major] [Mod Major] [Game Minor] [Mod Minor]
+
+// Syntax: [Game Major] [Mod Major] [Game Minor] [Mod Minor]
+[assembly: AssemblyVersion("0.1.1.*")]

 namespace TradeScalar
 {
     public class TradeScalar : ModBase
     {
-        public override string ModIdentifier
-        {
-            get
-            {
-                return "Supply_And_Demand";
-            }
-        }
-        private TradeScalar()
-        {
-
-        }
+        public override string ModIdentifier => "Supply_And_Demand";
+
+        private TradeScalar() { }
+
+        ///
+        /// Defines the method for scaling the result of RandomCountOf by colony wealth and difficulty level.
+        ///
         [HarmonyPatch(typeof(StockGenerator))]
         [HarmonyPatch("RandomCountOf")]
-        ///
-        ///Defines the method for scaling the result of RandomCountOf by colony wealth and difficulty level.
-        ///
         public static class scaleWares_patch
         {
-            //[HarmonyPrefix]
-            //public static void Conditioner()
-            //{
-
-
-            //}
             [HarmonyPostfix]
             public static void Scaled(ref int __result, StockGenerator __instance)
             {
-                //TradeScalar tradeScalar = new TradeScalar();
-                //var placeholder = __instance.trader.defName;
-                if (__instance.trader.orbital || __instance.trader.defName.Contains("Base_"))
-                {
-                    int random = UnityEngine.Random.Range(-3, 3);
-                    int wealthTotal = Mathf.RoundToInt(Find.VisibleMap.wealthWatcher.WealthTotal); //Uses Verse.Find to get colony wealth, rounded to an integer.
-                    float tradeLoss = (1f - Find.Storyteller.difficulty.tradePriceFactorLoss); //Finds the tradePriceFactorLoss. Value is 1, 0.95, 0.9, 0.85, or 0.8
-                    __result = random + Mathf.RoundToInt((float)Math.Log(Math.E + (wealthTotal * tradeLoss)) * __result); //Minimum value of scalar is 1 when wealthTotal = 0
-                }
+                if (!__instance.trader.orbital && !__instance.trader.defName.Contains("Base_")) return;
+
+                var random = UnityEngine.Random.Range(-3, 3);
+
+                // Uses Verse.Find to get colony wealth.
+                var wealthTotal = Find.VisibleMap.wealthWatcher.WealthTotal;
+
+                // Finds the tradePriceFactorLoss. Value is 1, 0.95, 0.9, 0.85, or 0.8
+                var tradeLoss = (1 - Find.Storyteller.difficulty.tradePriceFactorLoss);
+
+                // Minimum value of scalar is 1 when wealthTotal = 0
+                __result = random + (int)Math.Round(Math.Log(Math.E + (wealthTotal * tradeLoss)) * __result);
             }
-        }
+        }
     }
 }


Implemented logic for offset calculation.

--- TestApp/Program.cs
+++ TestApp/Program.cs
@@ -8,16 +8,16 @@
 {
 	class Program
 	{
-		private static double _offSet;
+		private static double _realLoad;
 		private static readonly BlockingCollection<float> CpuLoadValues = new BlockingCollection<float>();
 		private const int AnalysisLimit = 6;

 		static void Main(string[] args)
 		{
-			Console.WriteLine("Enter a desired CPU load (37 - 100 supported) in percentage:");
+			Console.WriteLine("Enter a desired CPU load in percentage:");
 			var loadString = Console.ReadLine();
 			int load;
-			while (!int.TryParse(loadString, out load) || load < 37 || load > 100)
+			while (!int.TryParse(loadString, out load) || load > 100)
 			{
 				Console.WriteLine("Invalid load format, try again:");
 				loadString = Console.ReadLine();
@@ -27,10 +27,9 @@
 			PrepareVariables(load);
 			Console.WriteLine("System ready!");

-			Console.WriteLine("Stressing the CPU on {0}% load...", load);
-
-			load = load - 37;
-
+			load = Math.Abs(load - (int)Math.Round(_realLoad));
+			Console.WriteLine("Stressing the CPU on {0}% load...", loadString);
+
 			for (var cpu = 0; cpu <= Environment.ProcessorCount; cpu++)
 			{
 				new Thread(() => Sleep(load)).Start();
@@ -45,7 +44,11 @@
 			{
 				for (var cpu = 0; cpu <= Environment.ProcessorCount; cpu++)
 				{
-					new Thread(() => Analyze(target)).Start();
+					var thread = new Thread(() => Analyze(target));
+					thread.Start();
+					while (thread.IsAlive)
+					{
+					}
 				}
 				CpuLoadValues.CompleteAdding();
 			});
@@ -53,7 +56,7 @@
 			{
 				foreach (var loadValue in CpuLoadValues.GetConsumingEnumerable())
 				{
-					_offSet = Math.Round((_offSet + loadValue) / 2);
+					_realLoad = Math.Round((_realLoad + loadValue) / 2);
 				}
 			});
 			Task.WaitAll(producer, consumer);


Checking for null value when running Show coro of UIWindowBase on a MB

--- UI/UIWindowBase.cs
+++ UI/UIWindowBase.cs
@@ -80,7 +80,7 @@

         public void Show(MonoBehaviour monoBehaviour)
         {
-            if(!in_progress)
+            if(!in_progress && monoBehaviour != null)
                 monoBehaviour.StartCoroutine(Show());
         }


Added active, onNormal, and onActive color declarations for other styles.

--- UnityREPLHelper.cs
+++ UnityREPLHelper.cs
@@ -196,13 +196,9 @@
         _Default = new GUIStyle("Label");
         _Default.name = "Default";
         _Default.normal.textColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
-        _Default.hover.textColor = Color.white;
         _Default.active.textColor = Color.white;
-        _Default.focused.textColor = Color.white;
         _Default.onNormal.textColor = Color.white;
-        _Default.onHover.textColor = Color.white;
         _Default.onActive.textColor = Color.white;
-        _Default.onFocused.textColor = Color.white;
       }
       return _Default;
     }
@@ -215,6 +211,9 @@
         _DefaultCommandStyle = new GUIStyle(Default);
         _DefaultCommandStyle.name = "DefaultCommandStyle";
         _DefaultCommandStyle.normal.textColor = Color.blue;
+        _DefaultCommandStyle.active.textColor = Color.blue;
+        _DefaultCommandStyle.onNormal.textColor = Color.blue;
+        _DefaultCommandStyle.onActive.textColor = Color.blue;
       }
       return _DefaultCommandStyle;
     }
@@ -242,6 +241,9 @@
         _OutputStyle = new GUIStyle(Default);
         _OutputStyle.name = "OutputStyle";
         _OutputStyle.normal.textColor = Color.green;
+        _OutputStyle.active.textColor = Color.green;
+        _OutputStyle.onNormal.textColor = Color.green;
+        _OutputStyle.onActive.textColor = Color.green;
       }
       return _OutputStyle;
     }
@@ -254,6 +256,9 @@
         _EvaluationErrorStyle = new GUIStyle(Default);
         _EvaluationErrorStyle.name = "EvaluationErrorStyle";
         _EvaluationErrorStyle.normal.textColor = Color.red;
+        _EvaluationErrorStyle.active.textColor = Color.red;
+        _EvaluationErrorStyle.onNormal.textColor = Color.red;
+        _EvaluationErrorStyle.onActive.textColor = Color.red;
       }
       return _EvaluationErrorStyle;
     }
@@ -266,6 +271,9 @@
         _SystemConsoleStyle = new GUIStyle(Default);
         _SystemConsoleStyle.name = "SystemConsoleStyle";
         _SystemConsoleStyle.normal.textColor = Color.yellow;
+        _SystemConsoleStyle.active.textColor = Color.yellow;
+        _SystemConsoleStyle.onNormal.textColor = Color.yellow;
+        _SystemConsoleStyle.onActive.textColor = Color.yellow;
       }
       return _SystemConsoleStyle;
     }
@@ -301,6 +309,9 @@
         _ConsoleLogStackTraceStyle = new GUIStyle(ConsoleLogStyle);
         _ConsoleLogStackTraceStyle.name = "ConsoleLogStackTraceStyle";
         _ConsoleLogStackTraceStyle.normal.textColor = Color.red;
+        _ConsoleLogStackTraceStyle.active.textColor = Color.red;
+        _ConsoleLogStackTraceStyle.onNormal.textColor = Color.red;
+        _ConsoleLogStackTraceStyle.onActive.textColor = Color.red;
       }
       return _ConsoleLogStackTraceStyle;
     }


Work.

Work.

--- WinCron/WinCron.cs
+++ WinCron/WinCron.cs
@@ -1,4 +1,7 @@
 using System;
+using System.IO;
+using System.Threading;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Configuration.Install;
@@ -9,11 +12,15 @@
     public class CronService : ServiceBase
     {

+        CronTab crontab;
+        List<Thread> threadtable;
+        Thread masterthread;
+
         public CronService()
         {
             this.ServiceName = "WinCron";
             this.CanStop = true;
-            this.CanPauseAndContinue = false;
+            this.CanPauseAndContinue = true;

             //Setup logging
             this.AutoLog = false;
@@ -27,18 +34,80 @@

             this.EventLog.Source = this.ServiceName;
             this.EventLog.Log = "Application";
+
+            crontab = new CronTab();
+            threadtable = new List<Thread>();
+            masterthread = new Thread(new ThreadStart(MasterThread));
+        }
+
+        public void MasterThread()
+        {
+            while (true)
+            {
+                // Clean up threadtable, remove finished or aborted threads.
+                threadtable.RemoveAll(t => !t.IsAlive);
+
+                // Run over jobs and create threads for the jobs that need to be run.
+                DateTime now = DateTime.Now;
+                foreach (CronJob job in crontab.GetJobs())
+                {
+                    if (job.ShouldRun(now))
+                    {
+                        Thread t = new Thread(new ThreadStart(job.ExecuteJob));
+                        threadtable.Add(t);
+                        t.Start(this.EventLog);
+                    }
+                }
+
+                // Sleep for one second which is the tick length.
+                Thread.Sleep(1000);
+            }
         }

         protected override void OnStart(string[] args)
         {
             // do startup stuff
             EventLog.WriteEntry("Starting WinCron service.");
+            foreach (string line in File.ReadLines("crontab.txt"))
+            {
+                if (line.StartsWith("#")) { continue; }
+                try
+                {
+                    CronJob job = new CronJob(line);
+                    crontab.AddJob(job);
+                }
+                catch (ArgumentException ex)
+                {
+                    this.EventLog.WriteEntry("Unparsable line: (" + line + ") - " + ex.Message);
+                    continue;
+                }
+            }
+            masterthread.Start();
         }

         protected override void OnStop()
         {
             // do shutdown stuff
             EventLog.WriteEntry("Stopping WinCron service.");
+            masterthread.Abort();
+            EventLog.WriteEntry("Aborting child threads.");
+            foreach (Thread t in threadtable)
+            {
+                t.Abort();
+            }
+            EventLog.WriteEntry("Child threads aborted, shutdown complete.");
+        }
+
+        protected override void OnPause()
+        {
+            masterthread.Suspend();
+            base.OnPause();
+        }
+
+        protected override void OnContinue()
+        {
+            masterthread.Resume();
+            base.OnContinue();
         }
     }
 }


Change grammar as suggested by GotenXiao

--- AirlockSystem.cs
+++ AirlockSystem.cs
@@ -136,7 +136,7 @@
                 this.door = door;
             }

-            public bool isClosed()
+            public bool IsClosed()
             {
                 return !this.door.Open;
             }
@@ -174,11 +174,11 @@
                 }
             }

-            public bool AreClosed()
+            public bool IsClosed()
             {
                 for (int i = 0; i < doors.Count; i++)
                 {
-                    if (!this.doors[i].isClosed())
+                    if (!this.doors[i].IsClosed())
                     {
                         return false;
                     }
@@ -256,7 +256,7 @@
                 }
             }

-            public bool AreActive()
+            public bool IsActive()
             {
                 for (int i = 0; i < this.sensors.Count; i++)
                 {
@@ -522,14 +522,14 @@
                         break;

                     case _state_WAITING_FOR_INTERIOR_DOORS:
-                        if (this.interiorDoors.AreClosed() || (tick > DOOR_TIMEOUT))
+                        if (this.interiorDoors.IsClosed() || (tick > DOOR_TIMEOUT))
                         {
                             this.ContinueDepressurisation();
                         }
                         break;

                     case _state_WAITING_FOR_EXTERIOR_DOORS:
-                        if (this.exteriorDoors.AreClosed() || (tick > DOOR_TIMEOUT))
+                        if (this.exteriorDoors.IsClosed() || (tick > DOOR_TIMEOUT))
                         {
                             this.ContinuePressurisation();
                         }
@@ -553,9 +553,9 @@
                 this.state = _state_LOCKED;

                 // Detect what's happening from what sensor
-                if (this.chamberSensors.AreActive())
-                {
-                    if (this.interiorDoors.AreClosed())
+                if (this.chamberSensors.IsActive())
+                {
+                    if (this.interiorDoors.IsClosed())
                     {
                         // Interior doors are closed, they probably walked from outside
                         this.PressuriseAirlock();
@@ -568,19 +568,19 @@
                     return;
                 }

-                if (this.interiorSensors.AreActive())
+                if (this.interiorSensors.IsActive())
                 {
                     // They walked up to the interior sensor
-                    if (this.interiorDoors.AreClosed())
+                    if (this.interiorDoors.IsClosed())
                     {
                         this.PressuriseAirlock();
                         return;
                     }
                 }

-                if (this.exteriorSensors.AreActive())
-                {
-                    if (this.exteriorDoors.AreClosed())
+                if (this.exteriorSensors.IsActive())
+                {
+                    if (this.exteriorDoors.IsClosed())
                     {
                         this.DepressuriseAirlock();
                         return;


Only find the next IObjectMapper if the equivalencyExpression is null.

--- src/AutoMapper.Collection/Mappers/EquivalentExpressionAddRemoveCollectionMapper.cs
+++ src/AutoMapper.Collection/Mappers/EquivalentExpressionAddRemoveCollectionMapper.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Reflection;
@@ -63,6 +64,7 @@
         }

         private static readonly MethodInfo _mapMethodInfo = typeof(EquivalentExpressionAddRemoveCollectionMapper).GetRuntimeMethods().Single(x => x.IsStatic && x.Name == nameof(Map));
+        private static readonly ConcurrentDictionary<TypePair, IObjectMapper> _objectMapperCache = new ConcurrentDictionary<TypePair, IObjectMapper>();

         public bool IsMatch(TypePair typePair)
         {
@@ -73,34 +75,35 @@
         public Expression MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, IMemberMap memberMap,
             Expression sourceExpression, Expression destExpression, Expression contextExpression)
         {
-            IObjectMapper nextMapper = _collectionMapper;
-            var typePair = new TypePair(sourceExpression.Type, destExpression.Type);
-            var mappers = new List<IObjectMapper>(configurationProvider.GetMappers());
-            for (var i = mappers.IndexOf(this) + 1; i < mappers.Count; i++)
-            {
-                var mapper = mappers[i];
-                if (mapper.IsMatch(typePair))
-                {
-                    nextMapper = mapper;
-                    break;
-                }
-            }
-            var nextMapperExpression = nextMapper.MapExpression(configurationProvider, profileMap, memberMap, sourceExpression, destExpression, contextExpression);
-
             var sourceType = TypeHelper.GetElementType(sourceExpression.Type);
             var destType = TypeHelper.GetElementType(destExpression.Type);

             var equivalencyExpression = this.GetEquivalentExpression(sourceType, destType);
             if (equivalencyExpression == null)
             {
-                return nextMapperExpression;
+                var typePair = new TypePair(sourceExpression.Type, destExpression.Type);
+                return _objectMapperCache.GetOrAdd(typePair, _ =>
+                {
+                    var mappers = new List<IObjectMapper>(configurationProvider.GetMappers());
+                    for (var i = mappers.IndexOf(this) + 1; i < mappers.Count; i++)
+                    {
+                        var mapper = mappers[i];
+                        if (mapper.IsMatch(typePair))
+                        {
+                            return mapper;
+                        }
+                    }
+                    return _collectionMapper;
+                })
+                .MapExpression(configurationProvider, profileMap, memberMap, sourceExpression, destExpression, contextExpression);
             }

             var method = _mapMethodInfo.MakeGenericMethod(sourceExpression.Type, sourceType, destExpression.Type, destType);
             var map = Call(null, method, sourceExpression, destExpression, contextExpression, Constant(equivalencyExpression));

             var notNull = NotEqual(destExpression, Constant(null));
-            return Condition(notNull, map, Convert(nextMapperExpression, destExpression.Type));
+            var collectionMapperExpression = _collectionMapper.MapExpression(configurationProvider, profileMap, memberMap, sourceExpression, destExpression, contextExpression);
+            return Condition(notNull, map, Convert(collectionMapperExpression, destExpression.Type));
         }
     }
 }


Adjust implementation of HasSameMetadataDefinitionAs to be resilient to failures of Expression.Compile.

[tfs-changeset: 1461633]

--- src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinderExtensions.cs
+++ src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinderExtensions.cs
@@ -305,13 +305,22 @@
                 else
                 {
                     var parameter = Expression.Parameter(memberInfo);
-                    s_GetMetadataToken = Expression.Lambda<Func<MemberInfo, int>>(Expression.Property(parameter, property), new[] { parameter }).Compile();
-                }
-            }
-
-            if ((object)s_GetMetadataToken != null)
-            {
-                return s_GetMetadataToken(mi1) == s_GetMetadataToken(mi2);
+                    try
+                    {
+                        s_GetMetadataToken = Expression.Lambda<Func<MemberInfo, int>>(Expression.Property(parameter, property), new[] { parameter }).Compile();
+                    }
+                    catch
+                    {
+                        // Platform might not allow access to the property
+                        s_GetMetadataToken = null;
+                    }
+                }
+            }
+
+            var getMetadataToken = s_GetMetadataToken;
+            if ((object)getMetadataToken != null)
+            {
+                return getMetadataToken(mi1) == getMetadataToken(mi2);
             }

             return mi1.IsEquivalentTo(mi2);


fix visual tests

fix visual tests

--- src/SFA.DAS.EmployerApprenticeshipsService.Web/Controllers/VisualTestController.cs
+++ src/SFA.DAS.EmployerApprenticeshipsService.Web/Controllers/VisualTestController.cs
@@ -244,7 +244,7 @@
                 {"~/Views/EmployerAccountPaye/AddNewLegalEntity.cshtml", confirmNewPayeScheme},
                 {"~/Views/EmployerAccountPaye/ChooseCompany.cshtml", addNewPayeScheme },
                 {"~/Views/EmployerAccountPaye/Confirm.cshtml", confirmNewPayeScheme },
-                {"~/Views/EmployerAccountPaye/ConfirmPayeScheme.cshtml", addNewPayeScheme },
+                {"~/Views/EmployerAccountPaye/ConfirmPayeScheme.cshtml", new OrchestratorResponse<AddNewPayeScheme>() {Data = addNewPayeScheme } },
                 {"~/Views/EmployerAccountPaye/Index.cshtml", new OrchestratorResponse<EmployerAccountPayeListViewModel>()
                 {
                     Data = new EmployerAccountPayeListViewModel()


更新版本号，Cache.Memcached v1.1.0 支持 .NET Core 2.0

--- src/Senparc.Weixin.Cache/Senparc.Weixin.Cache.Memcached/Properties/AssemblyInfo.cs
+++ src/Senparc.Weixin.Cache/Senparc.Weixin.Cache.Memcached/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
 //可以指定所有这些值，也可以使用“生成号”和“修订号”的默认值，
 // 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.3.0.*")]
+[assembly: AssemblyVersion("1.1.0.*")]
 //[assembly: AssemblyFileVersion("1.0.0.0")]


Fixed ordering unit test

Fixed ordering unit test

--- src/Services/Ordering/Ordering.UnitTests/Application/NewOrderCommandHandlerTest.cs
+++ src/Services/Ordering/Ordering.UnitTests/Application/NewOrderCommandHandlerTest.cs
@@ -10,6 +10,7 @@

 namespace UnitTest.Ordering.Application
 {
+    using global::Ordering.API.Application.IntegrationEvents;
     using global::Ordering.API.Application.Models;
     using MediatR;
     using System.Collections;
@@ -22,12 +23,14 @@
         private readonly Mock<IOrderRepository> _orderRepositoryMock;
         private readonly Mock<IIdentityService> _identityServiceMock;
         private readonly Mock<IMediator> _mediator;
+        private readonly Mock<IOrderingIntegrationEventService> _orderingIntegrationEventService;

         public NewOrderRequestHandlerTest()
         {

             _orderRepositoryMock = new Mock<IOrderRepository>();
             _identityServiceMock = new Mock<IIdentityService>();
+            _orderingIntegrationEventService = new Mock<IOrderingIntegrationEventService>();
             _mediator = new Mock<IMediator>();
         }

@@ -48,7 +51,7 @@
             _identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId);

             //Act
-            var handler = new CreateOrderCommandHandler(_mediator.Object, _orderRepositoryMock.Object, _identityServiceMock.Object);
+            var handler = new CreateOrderCommandHandler(_mediator.Object, _orderingIntegrationEventService.Object, _orderRepositoryMock.Object, _identityServiceMock.Object);
             var cltToken = new System.Threading.CancellationToken();
             var result = await handler.Handle(fakeOrderCmd, cltToken);


Filters state changed to initially be disabled (excluded from search filters used) to make it easier to check only desired filters during search.

--- Analyzers/Core/AssemblyPropertiesViewer.Analyzers.Models/Filtering/ISearchFilter.cs
+++ Analyzers/Core/AssemblyPropertiesViewer.Analyzers.Models/Filtering/ISearchFilter.cs
@@ -26,7 +26,7 @@
         /// <summary>
         /// Flag indicating if specific filter criteria model is enabled (or marked as active) and should be used in the filtering process.
         /// </summary>
-        public bool IsFilterEnabled { get; set; } = true;
+        public bool IsFilterEnabled { get; set; }

         public SearchFilterBase(string name, string description)
         {


send the right message code

send the right message code

--- GameServerSource/Assets/Contexts/ChatServer/Commands/ChatServerMessagingCommands.cs
+++ GameServerSource/Assets/Contexts/ChatServer/Commands/ChatServerMessagingCommands.cs
@@ -176,7 +176,7 @@
         var playerConn = UnityNetworkingData.Connections.Find(c => c.PlayFabId == Message.MemberId);
         if (playerConn != null)
         {
-            playerConn.Connection.Send(ChatServerMessageTypes.JoinChannelResponse, Message);
+            playerConn.Connection.Send(ChatServerMessageTypes.CreateChannelResponse, Message);
         }
     }
 }


factor inventory file loading into its own method

--- OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -77,18 +77,35 @@
         /// </value>
         private Stream m_loadStream;

-        /// <summary>
-        /// Record the creator id that should be associated with an asset.  This is used to adjust asset creator ids
-        /// after OSP resolution (since OSP creators are only stored in the item
-        /// </summary>
-        protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
-
         protected bool m_controlFileLoaded;
         protected bool m_assetsLoaded;
         protected bool m_inventoryNodesLoaded;

         protected int m_successfulAssetRestores;
         protected int m_failedAssetRestores;
+        protected int m_successfulItemRestores;
+
+        /// <summary>
+        /// Root destination folder for the IAR load.
+        /// </summary>
+        protected InventoryFolderBase m_rootDestinationFolder;
+
+        /// <summary>
+        /// Inventory nodes loaded from the iar.
+        /// </summary>
+        protected HashSet<InventoryNodeBase> m_loadedNodes = new HashSet<InventoryNodeBase>();
+
+        /// <summary>
+        /// In order to load identically named folders, we need to keep track of the folders that we have already
+        /// resolved.
+        /// </summary>
+        Dictionary <string, InventoryFolderBase> m_resolvedFolders = new Dictionary<string, InventoryFolderBase>();
+
+        /// <summary>
+        /// Record the creator id that should be associated with an asset.  This is used to adjust asset creator ids
+        /// after OSP resolution (since OSP creators are only stored in the item
+        /// </summary>
+        protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();

         public InventoryArchiveReadRequest(
             Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
@@ -114,6 +131,9 @@
         /// <summary>
         /// Execute the request
         /// </summary>
+        /// <remarks>
+        /// Only call this once.  To load another IAR, construct another request object.
+        /// </remarks>
         /// <returns>
         /// A list of the inventory nodes loaded.  If folders were loaded then only the root folders are
         /// returned
@@ -124,9 +144,6 @@
             try
             {
                 string filePath = "ERROR";
-                int successfulItemRestores = 0;
-
-                HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();

                 List<InventoryFolderBase> folderCandidates
                     = InventoryArchiveUtils.FindFolderByPath(
@@ -137,16 +154,11 @@
                     // Possibly provide an option later on to automatically create this folder if it does not exist
                     m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);

-                    return loadedNodes;
+                    return m_loadedNodes;
                 }

-                InventoryFolderBase rootDestinationFolder = folderCandidates[0];
+                m_rootDestinationFolder = folderCandidates[0];
                 archive = new TarArchiveReader(m_loadStream);
-
-                // In order to load identically named folders, we need to keep track of the folders that we have already
-                // resolved
-                Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
-
                 byte[] data;
                 TarArchiveReader.TarEntryType entryType;

@@ -162,44 +174,7 @@
                     }
                     else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
                     {
-                        if (!m_controlFileLoaded)
-                            throw new Exception(
-                                string.Format(
-                                    "The IAR you are trying to load does not list {0} before {1}.  Aborting load",
-                                    ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH));
-
-                        if (m_assetsLoaded)
-                            throw new Exception(
-                                string.Format(
-                                    "The IAR you are trying to load does not list all {0} before {1}.  Aborting load",
-                                    ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH));
-
-                        filePath = filePath.Substring(ArchiveConstants.INVENTORY_PATH.Length);
-
-                        // Trim off the file portion if we aren't already dealing with a directory path
-                        if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
-                            filePath = filePath.Remove(filePath.LastIndexOf("/") + 1);
-
-                        InventoryFolderBase foundFolder
-                            = ReplicateArchivePathToUserInventory(
-                                filePath, rootDestinationFolder, resolvedFolders, loadedNodes);
-
-                        if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
-                        {
-                            InventoryItemBase item = LoadItem(data, foundFolder);
-
-                            if (item != null)
-                            {
-                                successfulItemRestores++;
-
-                                // If we aren't loading the folder containing the item then well need to update the
-                                // viewer separately for that item.
-                                if (!loadedNodes.Contains(foundFolder))
-                                    loadedNodes.Add(item);
-                            }
-                        }
-
-                        m_inventoryNodesLoaded = true;
+                        LoadInventoryFile(filePath, entryType, data);
                     }
                 }

@@ -208,9 +183,9 @@
                 m_log.DebugFormat(
                     "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
                     m_successfulAssetRestores, m_failedAssetRestores);
-                m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
-
-                return loadedNodes;
+                m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores);
+
+                return m_loadedNodes;
             }
             finally
             {
@@ -549,6 +524,54 @@
         }

         /// <summary>
+        /// Load inventory file
+        /// </summary>
+        /// <param name="path"></param>
+        /// <param name="entryType"></param>
+        /// <param name="data"></param>
+        protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data)
+        {
+            if (!m_controlFileLoaded)
+                throw new Exception(
+                    string.Format(
+                        "The IAR you are trying to load does not list {0} before {1}.  Aborting load",
+                        ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH));
+
+            if (m_assetsLoaded)
+                throw new Exception(
+                    string.Format(
+                        "The IAR you are trying to load does not list all {0} before {1}.  Aborting load",
+                        ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH));
+
+            path = path.Substring(ArchiveConstants.INVENTORY_PATH.Length);
+
+            // Trim off the file portion if we aren't already dealing with a directory path
+            if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
+                path = path.Remove(path.LastIndexOf("/") + 1);
+
+            InventoryFolderBase foundFolder
+                = ReplicateArchivePathToUserInventory(
+                    path, m_rootDestinationFolder, m_resolvedFolders, m_loadedNodes);
+
+            if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
+            {
+                InventoryItemBase item = LoadItem(data, foundFolder);
+
+                if (item != null)
+                {
+                    m_successfulItemRestores++;
+
+                    // If we aren't loading the folder containing the item then well need to update the
+                    // viewer separately for that item.
+                    if (!m_loadedNodes.Contains(foundFolder))
+                        m_loadedNodes.Add(item);
+                }
+            }
+
+            m_inventoryNodesLoaded = true;
+        }
+
+        /// <summary>
         /// Load asset file
         /// </summary>
         /// <param name="path"></param>
@@ -578,6 +601,6 @@
                     m_successfulAssetRestores);

             m_assetsLoaded = true;
-        }
+        }
     }
 }


refactor: make boolean load indicators on load iars instance fields

--- OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -82,6 +82,10 @@
         /// after OSP resolution (since OSP creators are only stored in the item
         /// </summary>
         protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
+
+        protected bool m_controlFileLoaded;
+        protected bool m_assetsLoaded;
+        protected bool m_inventoryNodesLoaded;

         public InventoryArchiveReadRequest(
             Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
@@ -144,24 +148,23 @@

                 byte[] data;
                 TarArchiveReader.TarEntryType entryType;
-                bool controlFileLoaded = false, assetsLoaded = false, inventoryNodesLoaded = false;

                 while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
                 {
                     if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
                     {
                         LoadControlFile(filePath, data);
-                        controlFileLoaded = true;
+                        m_controlFileLoaded = true;
                     }
                     else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
                     {
-                        if (!controlFileLoaded)
+                        if (!m_controlFileLoaded)
                             throw new Exception(
                                 string.Format(
                                     "The IAR you are trying to load does not list {0} before {1}.  Aborting load",
                                     ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.ASSETS_PATH));

-                        if (!inventoryNodesLoaded)
+                        if (!m_inventoryNodesLoaded)
                             throw new Exception(
                                 string.Format(
                                     "The IAR you are trying to load does not list all {0} before {1}.  Aborting load",
@@ -177,17 +180,17 @@
                                 "[INVENTORY ARCHIVER]: Loaded {0} assets...",
                                 successfulAssetRestores);

-                        assetsLoaded = true;
+                        m_assetsLoaded = true;
                     }
                     else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
                     {
-                        if (!controlFileLoaded)
+                        if (!m_controlFileLoaded)
                             throw new Exception(
                                 string.Format(
                                     "The IAR you are trying to load does not list {0} before {1}.  Aborting load",
                                     ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH));

-                        if (assetsLoaded)
+                        if (m_assetsLoaded)
                             throw new Exception(
                                 string.Format(
                                     "The IAR you are trying to load does not list all {0} before {1}.  Aborting load",
@@ -218,7 +221,7 @@
                             }
                         }

-                        inventoryNodesLoaded = true;
+                        m_inventoryNodesLoaded = true;
                     }
                 }


Fixed typo.

Fixed typo.

--- Source/SharpBattleNet.Framework.Networking/Connections/TCP/ITCPConnectionFactory.cs
+++ Source/SharpBattleNet.Framework.Networking/Connections/TCP/ITCPConnectionFactory.cs
@@ -38,6 +38,6 @@

     public interface ITCPConnectionFactory
     {
-        IUDPConnection Create();
+        ITCPConnection Create();
     }
 }


Adding missing parenthesis.

Adding missing parenthesis.

--- WindowsAzurePowershell/src/Management.WebSites/Cmdlets/Common/WebsitesBaseCmdlet.cs
+++ WindowsAzurePowershell/src/Management.WebSites/Cmdlets/Common/WebsitesBaseCmdlet.cs
@@ -62,8 +62,8 @@
                                                             serviceError.Parameters.First());
                         }
                         else if (serviceError.MessageTemplate.Equals(Resources.CannotFind) &&
-                                 "WebSpace".Equals(serviceError.Parameters.FirstOrDefault()) ||
-                                 "GeoRegion".Equals(serviceError.Parameters.FirstOrDefault()))
+                                 ("WebSpace".Equals(serviceError.Parameters.FirstOrDefault()) ||
+                                 "GeoRegion".Equals(serviceError.Parameters.FirstOrDefault())))
                         {
                             message = string.Format(Resources.CannotFind, "Location",
                                                             serviceError.Parameters[1]);


Turn off iOS version of 40333 UI test (broken for unrelated reasons) (#177)

--- Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40333.cs
+++ Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40333.cs
@@ -46,14 +46,14 @@

 			protected override void Init()
 			{
-				Master = new NavigationPage(new _40333NavPusher("Root")) { Title = "MasterNav" };
-
 				if (_showTabVersion)
 				{
+					Master = new NavigationPage(new _40333TabPusher("Root")) { Title = "MasterNav" };
 					Detail = new TabbedPage() { Title = "DetailNav", Children = { new _40333DetailPage("T1") } };
 				}
 				else
 				{
+					Master = new NavigationPage(new _40333NavPusher("Root")) { Title = "MasterNav" };
 					Detail = new NavigationPage(new _40333DetailPage("Detail") { Title = "DetailPage" }) { Title = "DetailNav" };
 				}
 			}
@@ -195,6 +195,9 @@
 		}

 #if UITEST
+
+#if __ANDROID__ // This test doesn't work in iOS for unrelated reasons
+
 		[Test]
 		public void ClickingOnMenuItemInMasterDoesNotCrash_NavPageVersion()
 		{
@@ -207,6 +210,8 @@
 			RunningApp.Tap(q => q.Marked(ClickThisId));
 			RunningApp.WaitForElement(q => q.Marked(StillHereId)); // If the bug isn't fixed, the app will have crashed by now
 		}
+
+#endif

 		[Test]
 		public void ClickingOnMenuItemInMasterDoesNotCrash_TabPageVersion()


Fix handling FS delta

Fix handling FS delta

--- resharper/resharper-unity/src/Yaml/Psi/Modules/UnityExternalFilesModuleProcessor.cs
+++ resharper/resharper-unity/src/Yaml/Psi/Modules/UnityExternalFilesModuleProcessor.cs
@@ -38,14 +38,14 @@
         private readonly FileSystemPath mySolutionDirectory;

         public UnityExternalFilesModuleProcessor(Lifetime lifetime, ISolution solution, ChangeManager changeManager,
-                                                 IShellLocks locks,
-                                                 ISolutionLoadTasksScheduler scheduler,
-                                                 IFileSystemTracker fileSystemTracker,
-                                                 ProjectFilePropertiesFactory projectFilePropertiesFactory,
-                                                 UnityYamlPsiSourceFileFactory psiSourceFileFactory,
-                                                 UnityExternalFilesModuleFactory moduleFactory,
-                                                 AssetSerializationMode assetSerializationMode,
-                                                 YamlSupport yamlSupport)
+            IShellLocks locks,
+            ISolutionLoadTasksScheduler scheduler,
+            IFileSystemTracker fileSystemTracker,
+            ProjectFilePropertiesFactory projectFilePropertiesFactory,
+            UnityYamlPsiSourceFileFactory psiSourceFileFactory,
+            UnityExternalFilesModuleFactory moduleFactory,
+            AssetSerializationMode assetSerializationMode,
+            YamlSupport yamlSupport)
         {
             myLifetime = lifetime;
             mySolution = solution;
@@ -190,13 +190,13 @@
         {
             var builder = new PsiModuleChangeBuilder();
             var projectFilesToAdd = new FrugalLocalList<FileSystemPath>();
-            ProcessFileSystemChangeDelta(delta, builder, projectFilesToAdd);
+            ProcessFileSystemChangeDelta(delta, builder, ref projectFilesToAdd);
             AddAssetProjectFiles(projectFilesToAdd);
             FlushChanges(builder);
         }

         private void ProcessFileSystemChangeDelta(FileSystemChangeDelta delta, PsiModuleChangeBuilder builder,
-                                                  FrugalLocalList<FileSystemPath> projectFilesToAdd)
+            ref FrugalLocalList<FileSystemPath> projectFilesToAdd)
         {
             var module = myModuleFactory.PsiModule;
             if (module == null)
@@ -231,7 +231,7 @@
             }

             foreach (var child in delta.GetChildren())
-                ProcessFileSystemChangeDelta(child, builder, projectFilesToAdd);
+                ProcessFileSystemChangeDelta(child, builder, ref projectFilesToAdd);
         }

         [CanBeNull]
@@ -289,4 +289,4 @@

         public object Execute(IChangeMap changeMap) => null;
     }
-}
+}