Bulk Stream subscription (#12)

Bulk Stream subscription (#12)

* Normalize line endings

* Allow bulk subscription/unsubscription to assets/streams

--- LucidOcean.MultiChain/API/Asset.cs
+++ LucidOcean.MultiChain/API/Asset.cs
@@ -1,28 +1,28 @@
-/*=====================================================================
-Authors: Lucid Ocean PTY (LTD)
-Copyright © 2017 Lucid Ocean PTY (LTD). All Rights Reserved.
-
-License: Dual MIT / Lucid Ocean Wave Business License v1.0
-Please refer to http://www.lucidocean.co.za/wbl-license.html for restrictions and freedoms.
-The full license will also be found on the root of the main source-code directory.
-=====================================================================*/
-using LucidOcean.MultiChain.Response;
+/*=====================================================================
+Authors: Lucid Ocean PTY (LTD)
+Copyright © 2017 Lucid Ocean PTY (LTD). All Rights Reserved.
+
+License: Dual MIT / Lucid Ocean Wave Business License v1.0
+Please refer to http://www.lucidocean.co.za/wbl-license.html for restrictions and freedoms.
+The full license will also be found on the root of the main source-code directory.
+=====================================================================*/
+using LucidOcean.MultiChain.Response;
 using LucidOcean.MultiChain.Util;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace LucidOcean.MultiChain.API
-{
-    public class Asset
-    {
-        MultiChainClient _Client = null;
-
-        internal Asset(MultiChainClient client)
-        {
-            _Client = client;
-        }
-
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace LucidOcean.MultiChain.API
+{
+    public class Asset
+    {
+        MultiChainClient _Client = null;
+
+        internal Asset(MultiChainClient client)
+        {
+            _Client = client;
+        }
+
         /// <summary>
         /// Creates a new asset on the blockchain, sending the initial qty units to address. To create an asset with the default behavior, use an asset name only for name|params. For more control, use an object such as {"name":"asset1","open":true}. If open is true then additional units can be issued in future by the same key which signed the original issuance, via the issuemore or issuemorefrom command. The smallest transactable unit is given by units, e.g. 0.01. If the chain uses a native currency, you can send some with the new asset using the native-amount parameter. Returns the txid of the issuance transaction. For more information, see native assets.
         /// </summary>
@@ -36,14 +36,14 @@
         /// <param name="commentTo"></param>
         /// <param name="startBlock"></param>
         /// <param name="endBlock"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> Issue(string issueAddress, object assetName, int quantity, decimal units, [Optional]object metaData, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
-        {
-            if (metaData == null)
-                return _Client.Execute<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount);
-            else
-                return _Client.Execute<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount, metaData);
-        }
+        /// <returns></returns>
+        public JsonRpcResponse<string> Issue(string issueAddress, object assetName, int quantity, decimal units, [Optional]object metaData, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
+        {
+            if (metaData == null)
+                return _Client.Execute<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount);
+            else
+                return _Client.Execute<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount, metaData);
+        }

         /// <summary>
         /// Creates a new asset on the blockchain, sending the initial qty units to address. To create an asset with the default behavior, use an asset name only for name|params. For more control, use an object such as {"name":"asset1","open":true}. If open is true then additional units can be issued in future by the same key which signed the original issuance, via the issuemore or issuemorefrom command. The smallest transactable unit is given by units, e.g. 0.01. If the chain uses a native currency, you can send some with the new asset using the native-amount parameter. Returns the txid of the issuance transaction. For more information, see native assets.
@@ -58,17 +58,17 @@
         /// <param name="commentTo"></param>
         /// <param name="startBlock"></param>
         /// <param name="endBlock"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> IssueAsync(string issueAddress, object assetName, int quantity, decimal units, object metaData = null, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
-        {
-            if (metaData == null)
-                return _Client.ExecuteAsync<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount);
-            else
-                return _Client.ExecuteAsync<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount, metaData);
-        }
-
-
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> IssueAsync(string issueAddress, object assetName, int quantity, decimal units, object metaData = null, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
+        {
+            if (metaData == null)
+                return _Client.ExecuteAsync<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount);
+            else
+                return _Client.ExecuteAsync<string>("issue", 0, issueAddress, assetName, quantity, units, nativeAmount, metaData);
+        }
+
+
+
         /// <summary>
         /// This works like issue, but with control over the from-address used to issue the asset. It is useful if the node has multiple addresses with issue permissions.
         /// </summary>
@@ -83,15 +83,15 @@
         /// <param name="commentTo"></param>
         /// <param name="startBlock"></param>
         /// <param name="endBlock"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> IssueFrom(string fromAddress, string toAddress, object assetName, int quantity, decimal units, decimal nativeAmount, [Optional]object metaData, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
-        {
-            if (metaData == null)
-                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units, nativeAmount);
-            else
-                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units, nativeAmount, metaData);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> IssueFrom(string fromAddress, string toAddress, object assetName, int quantity, decimal units, decimal nativeAmount, [Optional]object metaData, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
+        {
+            if (metaData == null)
+                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units, nativeAmount);
+            else
+                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units, nativeAmount, metaData);
+        }
+
         /// <summary>
         /// This works like issue, but with control over the from-address used to issue the asset. It is useful if the node has multiple addresses with issue permissions.
         /// </summary>
@@ -106,15 +106,15 @@
         /// <param name="commentTo"></param>
         /// <param name="startBlock"></param>
         /// <param name="endBlock"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> IssueFromAsync(string fromAddress, string toAddress, object assetName, int quantity, decimal units, [Optional]object metaData, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
-        {
-            if (metaData == null)
-                return _Client.ExecuteAsync<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units);
-            else
-                return _Client.ExecuteAsync<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units, metaData);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> IssueFromAsync(string fromAddress, string toAddress, object assetName, int quantity, decimal units, [Optional]object metaData, decimal nativeAmount = 0, string comment = null, string commentTo = null, int startBlock = 0, int endBlock = 0)
+        {
+            if (metaData == null)
+                return _Client.ExecuteAsync<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units);
+            else
+                return _Client.ExecuteAsync<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, units, metaData);
+        }
+
         /// <summary>
         /// Issues qty additional units of asset, sending them to address. The asset can be specified using its name, ref or issuance txid – see native assets for more information. If the chain uses a native currency, you can send some with the new asset units using the native-amount parameter. Any custom fields will be attached to the new issuance event, and not affect the original values (use listassets with verbose=true to see both sets). Returns the txid of the issuance transaction.
         /// </summary>
@@ -122,15 +122,15 @@
         /// <param name="assetName"></param>
         /// <param name="quantity"></param>
         /// <param name="metaData"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> IssueMore(string fromAddress, object assetName, int quantity, [Optional]object metaData)
-        {
-            if (metaData == null)
-                return _Client.Execute<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
-            else
-                return _Client.Execute<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> IssueMore(string fromAddress, object assetName, int quantity, [Optional]object metaData)
+        {
+            if (metaData == null)
+                return _Client.Execute<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
+            else
+                return _Client.Execute<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
+        }
+
         /// <summary>
         /// Issues qty additional units of asset, sending them to address. The asset can be specified using its name, ref or issuance txid – see native assets for more information. If the chain uses a native currency, you can send some with the new asset units using the native-amount parameter. Any custom fields will be attached to the new issuance event, and not affect the original values (use listassets with verbose=true to see both sets). Returns the txid of the issuance transaction.
         /// </summary>
@@ -138,15 +138,15 @@
         /// <param name="assetName"></param>
         /// <param name="quantity"></param>
         /// <param name="metaData"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> IssueMoreAsync(string fromAddress, object assetName, int quantity, [Optional]object metaData)
-        {
-            if (metaData == null)
-                return _Client.ExecuteAsync<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
-            else
-                return _Client.ExecuteAsync<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> IssueMoreAsync(string fromAddress, object assetName, int quantity, [Optional]object metaData)
+        {
+            if (metaData == null)
+                return _Client.ExecuteAsync<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
+            else
+                return _Client.ExecuteAsync<string>("issuemore", 0, fromAddress, assetName, quantity, metaData);
+        }
+
         /// <summary>
         /// This works like issuemore, but with control over the from-address used.
         /// </summary>
@@ -156,15 +156,15 @@
         /// <param name="quantity"></param>
         /// <param name="nativeAmount"></param>
         /// <param name="metaData"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> IssueMoreFrom(string fromAddress, string toAddress, object assetName, int quantity, decimal nativeAmount, [Optional]object metaData)
-        {
-            if (metaData == null)
-                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount);
-            else
-                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, metaData);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> IssueMoreFrom(string fromAddress, string toAddress, object assetName, int quantity, decimal nativeAmount, [Optional]object metaData)
+        {
+            if (metaData == null)
+                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount);
+            else
+                return _Client.Execute<string>("issuefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, metaData);
+        }
+
         /// <summary>
         /// This works like issuemore, but with control over the from-address used.
         /// </summary>
@@ -174,110 +174,150 @@
         /// <param name="quantity"></param>
         /// <param name="nativeAmount"></param>
         /// <param name="metaData"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> IssueMoreFromAsync(string fromAddress, string toAddress, object assetName, int quantity, decimal nativeAmount, [Optional]object metaData)
-        {
-            if (metaData == null)
-                return _Client.ExecuteAsync<string>("issuemorefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount);
-            else
-                return _Client.ExecuteAsync<string>("issuemorefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, metaData);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> IssueMoreFromAsync(string fromAddress, string toAddress, object assetName, int quantity, decimal nativeAmount, [Optional]object metaData)
+        {
+            if (metaData == null)
+                return _Client.ExecuteAsync<string>("issuemorefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount);
+            else
+                return _Client.ExecuteAsync<string>("issuemorefrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, metaData);
+        }
+
         /// <summary>
         /// Returns information about assets issued on the blockchain. Pass an asset name, ref or issuance txid in assets to retrieve information about one asset only, an array thereof for multiple assets, or * for all assets. In assets with multiple issuance events, the top-level issuetxid and details fields refer to the first issuance only – set verbose to true for details about each of the individual issuances. Use count and start to retrieve part of the list only, with negative start values (like the default) indicating the most recently created assets. Extra fields are shown for assets to which this node is subscribed.
         /// </summary>
-        /// <returns></returns>
-        public JsonRpcResponse<List<AssetResponse>> ListAssets()
-        {
-            return _Client.Execute<List<AssetResponse>>("listassets", 0, "*", false);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<List<AssetResponse>> ListAssets()
+        {
+            return _Client.Execute<List<AssetResponse>>("listassets", 0, "*", false);
+        }
+
         /// <summary>
         /// Returns information about assets issued on the blockchain. Pass an asset name, ref or issuance txid in assets to retrieve information about one asset only, an array thereof for multiple assets, or * for all assets. In assets with multiple issuance events, the top-level issuetxid and details fields refer to the first issuance only – set verbose to true for details about each of the individual issuances. Use count and start to retrieve part of the list only, with negative start values (like the default) indicating the most recently created assets. Extra fields are shown for assets to which this node is subscribed.
         /// </summary>
         /// <param name="assetFilter"></param>
         /// <param name="verbose"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<List<AssetResponse>> ListAssets(string assetFilter = "*", bool verbose = false)
-        {
-            return _Client.Execute<List<AssetResponse>>("listassets", 0, assetFilter, verbose);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<List<AssetResponse>> ListAssets(string assetFilter = "*", bool verbose = false)
+        {
+            return _Client.Execute<List<AssetResponse>>("listassets", 0, assetFilter, verbose);
+        }
+
         /// <summary>
         /// Returns information about assets issued on the blockchain. Pass an asset name, ref or issuance txid in assets to retrieve information about one asset only, an array thereof for multiple assets, or * for all assets. In assets with multiple issuance events, the top-level issuetxid and details fields refer to the first issuance only – set verbose to true for details about each of the individual issuances. Use count and start to retrieve part of the list only, with negative start values (like the default) indicating the most recently created assets. Extra fields are shown for assets to which this node is subscribed.
         /// </summary>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<List<AssetResponse>>> ListAssetsAsync()
-        {
-            return _Client.ExecuteAsync<List<AssetResponse>>("listassets", 0, "*", false);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<List<AssetResponse>>> ListAssetsAsync()
+        {
+            return _Client.ExecuteAsync<List<AssetResponse>>("listassets", 0, "*", false);
+        }
+
         /// <summary>
         /// Returns information about assets issued on the blockchain. Pass an asset name, ref or issuance txid in assets to retrieve information about one asset only, an array thereof for multiple assets, or * for all assets. In assets with multiple issuance events, the top-level issuetxid and details fields refer to the first issuance only – set verbose to true for details about each of the individual issuances. Use count and start to retrieve part of the list only, with negative start values (like the default) indicating the most recently created assets. Extra fields are shown for assets to which this node is subscribed.
         /// </summary>
         /// <param name="assetFilter"></param>
         /// <param name="verbose"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<List<AssetResponse>>> ListAssetsAsync(string assetFilter = "*", bool verbose = false)
-        {
-            return _Client.ExecuteAsync<List<AssetResponse>>("listassets", 0, assetFilter, verbose);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<List<AssetResponse>>> ListAssetsAsync(string assetFilter = "*", bool verbose = false)
+        {
+            return _Client.ExecuteAsync<List<AssetResponse>>("listassets", 0, assetFilter, verbose);
+        }
+
         /// <summary>
         /// Instructs the node to start tracking one or more asset(s) or stream(s). These are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof. If rescan is true, the node will reindex all items from when the assets and/or streams were created, as well as those in other subscribed entities. Returns null if successful. See also the autosubscribe runtime parameter.
         /// </summary>
         /// <param name="assetName"></param>
         /// <param name="rescan"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SubscribeAsync(string assetName, bool rescan)
-        {
-            return _Client.ExecuteAsync<string>("subscribe", 0, assetName, rescan);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SubscribeAsync(string assetName, bool rescan = true)
+        {
+            return _Client.ExecuteAsync<string>("subscribe", 0, assetName, rescan);
+        }
+
         /// <summary>
         /// Instructs the node to start tracking one or more asset(s) or stream(s). These are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof. If rescan is true, the node will reindex all items from when the assets and/or streams were created, as well as those in other subscribed entities. Returns null if successful. See also the autosubscribe runtime parameter.
         /// </summary>
-        /// <param name="assetName"></param>
+        /// <param name="assetNames"></param>
         /// <param name="rescan"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> Subscribe(string assetName, bool rescan)
-        {
-            return _Client.Execute<string>("subscribe", 0, assetName, rescan);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SubscribeAsync(string[] assetNames, bool rescan = true)
+        {
+            return _Client.ExecuteAsync<string>("subscribe", 0, assetNames, rescan);
+        }
+
+        /// <summary>
+        /// Instructs the node to start tracking one or more asset(s) or stream(s). These are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof. If rescan is true, the node will reindex all items from when the assets and/or streams were created, as well as those in other subscribed entities. Returns null if successful. See also the autosubscribe runtime parameter.
+        /// </summary>
+        /// <param name="assetName"></param>
+        /// <param name="rescan"></param>
+        /// <returns></returns>
+        public JsonRpcResponse<string> Subscribe(string assetName, bool rescan = true)
+        {
+            return _Client.Execute<string>("subscribe", 0, assetName, rescan);
+        }
+
+        /// <summary>
+        /// Instructs the node to start tracking one or more asset(s) or stream(s). These are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof. If rescan is true, the node will reindex all items from when the assets and/or streams were created, as well as those in other subscribed entities. Returns null if successful. See also the autosubscribe runtime parameter.
+        /// </summary>
+        /// <param name="assetNames"></param>
+        /// <param name="rescan"></param>
+        /// <returns></returns>
+        public JsonRpcResponse<string> Subscribe(string[] assetNames, bool rescan = true)
+        {
+            return _Client.Execute<string>("subscribe", 0, assetNames, rescan);
+        }
+
         /// <summary>
         /// Instructs the node to stop tracking one or more asset(s) or stream(s). Assets or streams are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof.
         /// </summary>
         /// <param name="assetName"></param>
-        /// <param name="rescan"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> UnsubscribeAsync(string assetName, bool rescan)
-        {
-            return _Client.ExecuteAsync<string>("unsubscribe", 0, assetName, rescan);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> UnsubscribeAsync(string assetName)
+        {
+            return _Client.ExecuteAsync<string>("unsubscribe", 0, assetName);
+        }
+
         /// <summary>
         /// Instructs the node to stop tracking one or more asset(s) or stream(s). Assets or streams are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof.
         /// </summary>
-        /// <param name="assetName"></param>
-        /// <param name="rescan"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> Unsubscribe(string assetName, bool rescan)
-        {
-            return _Client.Execute<string>("unsubscribe", 0, assetName, rescan);
-        }
-
+        /// <param name="assetNames"></param>
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> UnsubscribeAsync(string[] assetNames)
+        {
+            return _Client.ExecuteAsync<string>("unsubscribe", 0, new object[] { assetNames });
+        }
+
+        /// <summary>
+        /// Instructs the node to stop tracking one or more asset(s) or stream(s). Assets or streams are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof.
+        /// </summary>
+        /// <param name="assetName"></param>
+        /// <returns></returns>
+        public JsonRpcResponse<string> Unsubscribe(string assetName)
+        {
+            return _Client.Execute<string>("unsubscribe", 0, assetName);
+        }
+
+        /// <summary>
+        /// Instructs the node to stop tracking one or more asset(s) or stream(s). Assets or streams are specified using a name, ref or creation/issuance txid, or for multiple items, an array thereof.
+        /// </summary>
+        /// <param name="assetNames"></param>
+        /// <returns></returns>
+        public JsonRpcResponse<string> Unsubscribe(string[] assetNames)
+        {
+            return _Client.Execute<string>("unsubscribe", 0, new object[] { assetNames });
+        }
+
         /// <summary>
         /// Lists transactions involving asset, passed as an asset name, ref or issuance txid, to which the node must be subscribed. Set verbose to true for additional information about each transaction. Use count and start to retrieve part of the list only, with negative start values (like the default) indicating the most recent items. Set local-ordering to true to order transactions by when first seen by this node, rather than their order in the chain.
         /// </summary>
         /// <param name="assetName"></param>
         /// <param name="verbose"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<List<ListAssetTransactionsResponse>>> ListAssetTransactions(string assetName, bool verbose)
-        {
-            return _Client.ExecuteAsync<List<ListAssetTransactionsResponse>>("listassettransactions", 0, assetName, verbose);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<List<ListAssetTransactionsResponse>>> ListAssetTransactions(string assetName, bool verbose)
+        {
+            return _Client.ExecuteAsync<List<ListAssetTransactionsResponse>>("listassettransactions", 0, assetName, verbose);
+        }
+
         /// <summary>
         /// Lists transactions involving asset, passed as an asset name, ref or issuance txid, to which the node must be subscribed. Set verbose to true for additional information about each transaction. Use count and start to retrieve part of the list only, with negative start values (like the default) indicating the most recent items. Set local-ordering to true to order transactions by when first seen by this node, rather than their order in the chain.
         /// </summary>
@@ -286,22 +326,22 @@
         /// <param name="count"></param>
         /// <param name="start"></param>
         /// <param name="localOrdering"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<List<ListAssetTransactionsResponse>>> ListAssetTransactions(string assetName, bool verbose, int count, int start, bool localOrdering)
-        {
-            return _Client.ExecuteAsync<List<ListAssetTransactionsResponse>>("listassettransactions", 0, assetName, verbose, count, start, localOrdering);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<List<ListAssetTransactionsResponse>>> ListAssetTransactions(string assetName, bool verbose, int count, int start, bool localOrdering)
+        {
+            return _Client.ExecuteAsync<List<ListAssetTransactionsResponse>>("listassettransactions", 0, assetName, verbose, count, start, localOrdering);
+        }
+
         /// <summary>
         /// Retrieves a specific transaction txid involving asset, passed as an asset name, ref or issuance txid, to which the node must be subscribed. Set verbose to true for additional information about the transaction.
         /// </summary>
         /// <param name="assetName"></param>
         /// <param name="txId"></param>
         /// <param name="verbose"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<ListAssetTransactionsResponse>> GetAssetTransactionAsync(string assetName, string txId, bool verbose = true)
-        {
-            return _Client.ExecuteAsync<ListAssetTransactionsResponse>("getassettransaction", 0, assetName, txId, verbose);
+        /// <returns></returns>
+        public Task<JsonRpcResponse<ListAssetTransactionsResponse>> GetAssetTransactionAsync(string assetName, string txId, bool verbose = true)
+        {
+            return _Client.ExecuteAsync<ListAssetTransactionsResponse>("getassettransaction", 0, assetName, txId, verbose);
         }

         /// <summary>
@@ -312,14 +352,14 @@
         /// <param name="amount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public Util.JsonRpcResponse<string> Send(string toAddress, string assetName, int amount, string comment = null, string commentTo = null)
-        {
-            var asset = new Dictionary<string, object>();
-            asset[assetName] = amount;
-            return _Client.Execute<string>("send", 0, toAddress, asset, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public Util.JsonRpcResponse<string> Send(string toAddress, string assetName, int amount, string comment = null, string commentTo = null)
+        {
+            var asset = new Dictionary<string, object>();
+            asset[assetName] = amount;
+            return _Client.Execute<string>("send", 0, toAddress, asset, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// Sends one or more assets to address, returning the txid. In Bitcoin Core, the amount field is the quantity of the bitcoin currency. For MultiChain, an {"asset":qty, ...} object can be used for amount, in which each asset is an asset name, ref or issuance txid, and each qty is the quantity of that asset to send (see native assets). Use "" as the asset inside this object to specify a quantity of the native blockchain currency. See also sendasset for sending a single asset and sendfrom to control the address whose funds are used.
         /// </summary>
@@ -328,14 +368,14 @@
         /// <param name="amount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendAsync(string toAddress, string assetName, int amount, string comment = null, string commentTo = null)
-        {
-            var asset = new Dictionary<string, object>();
-            asset[assetName] = amount;
-            return _Client.ExecuteAsync<string>("send", 0, toAddress, asset, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendAsync(string toAddress, string assetName, int amount, string comment = null, string commentTo = null)
+        {
+            var asset = new Dictionary<string, object>();
+            asset[assetName] = amount;
+            return _Client.ExecuteAsync<string>("send", 0, toAddress, asset, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// Sends qty of asset to address, returning the txid. The asset can be specified using its name, ref or issuance txid – see native assets for more information. See also sendassetfrom to control the address whose funds are used, send for sending multiple assets in one transaction, and sendfrom to combine both of these.
         /// </summary>
@@ -345,14 +385,14 @@
         /// <param name="nativeAmount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> SendAsset(string toAddress, string assetName, int amount, int nativeAmount = 0, string comment = null, string commentTo = null)
-        {
-            var asset = new Dictionary<string, object>();
-            asset[assetName] = amount;
-            return _Client.Execute<string>("sendasset", 0, toAddress, asset, amount, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> SendAsset(string toAddress, string assetName, int amount, int nativeAmount = 0, string comment = null, string commentTo = null)
+        {
+            var asset = new Dictionary<string, object>();
+            asset[assetName] = amount;
+            return _Client.Execute<string>("sendasset", 0, toAddress, asset, amount, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// Sends qty of asset to address, returning the txid. The asset can be specified using its name, ref or issuance txid – see native assets for more information. See also sendassetfrom to control the address whose funds are used, send for sending multiple assets in one transaction, and sendfrom to combine both of these.
         /// </summary>
@@ -362,14 +402,14 @@
         /// <param name="nativeAmount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendAssetAsync(string toAddress, string assetName, int amount, int nativeAmount = 0, string comment = null, string commentTo = null)
-        {
-            var asset = new Dictionary<string, object>();
-            asset[assetName] = amount;
-            return _Client.ExecuteAsync<string>("sendasset", 0, toAddress, asset, amount, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendAssetAsync(string toAddress, string assetName, int amount, int nativeAmount = 0, string comment = null, string commentTo = null)
+        {
+            var asset = new Dictionary<string, object>();
+            asset[assetName] = amount;
+            return _Client.ExecuteAsync<string>("sendasset", 0, toAddress, asset, amount, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// This works like sendasset, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address. See also sendfrom for sending multiple assets in one transaction.
         /// </summary>
@@ -380,12 +420,12 @@
         /// <param name="nativeAmount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendAssetFromAsync(string fromAddress, string toAddress, string assetName, decimal quantity, int nativeAmount = 0, string comment = null, string commentTo = null)
-        {
-            return _Client.ExecuteAsync<string>("sendassetfrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendAssetFromAsync(string fromAddress, string toAddress, string assetName, decimal quantity, int nativeAmount = 0, string comment = null, string commentTo = null)
+        {
+            return _Client.ExecuteAsync<string>("sendassetfrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// This works like sendasset, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address. See also sendfrom for sending multiple assets in one transaction.
         /// </summary>
@@ -396,12 +436,12 @@
         /// <param name="nativeAmount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> SendAssetFrom(string fromAddress, string toAddress, string assetName, decimal quantity, int nativeAmount = 0, string comment = null, string commentTo = null)
-        {
-            return _Client.Execute<string>("sendassetfrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> SendAssetFrom(string fromAddress, string toAddress, string assetName, decimal quantity, int nativeAmount = 0, string comment = null, string commentTo = null)
+        {
+            return _Client.Execute<string>("sendassetfrom", 0, fromAddress, toAddress, assetName, quantity, nativeAmount, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// This works like send, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address.
         /// </summary>
@@ -410,12 +450,12 @@
         /// <param name="amount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> SendFrom(string fromAddress, string toAddress, int amount, string comment = null, string commentTo = null)
-        {
-            return _Client.Execute<string>("sendfrom", 0, toAddress, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> SendFrom(string fromAddress, string toAddress, int amount, string comment = null, string commentTo = null)
+        {
+            return _Client.Execute<string>("sendfrom", 0, toAddress, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// This works like send, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address.
         /// </summary>
@@ -424,36 +464,36 @@
         /// <param name="amount"></param>
         /// <param name="comment"></param>
         /// <param name="commentTo"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendFromAsync(string fromAddress, string toAddress, int amount, string comment = null, string commentTo = null)
-        {
-            return _Client.ExecuteAsync<string>("sendfrom", 0, toAddress, comment ?? string.Empty, commentTo ?? string.Empty);
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendFromAsync(string fromAddress, string toAddress, int amount, string comment = null, string commentTo = null)
+        {
+            return _Client.ExecuteAsync<string>("sendfrom", 0, toAddress, comment ?? string.Empty, commentTo ?? string.Empty);
+        }
+
         /// <summary>
         /// This works like send, but with an additional data-only transaction output. To include raw data, pass a data-hex hexadecimal string. To publish the data to a stream, pass an object {"for":stream,"key":"...","data":"..."} where stream is a stream name, ref or creation txid, the key is in text form, and the data is hexadecimal.
         /// </summary>
         /// <param name="address"></param>
         /// <param name="amount"></param>
         /// <param name="dataHex"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> SendWithData(string address, decimal amount, byte[] dataHex)
-        {
-            return _Client.Execute<string>("sendwithdata", 0, address, amount, Util.Utility.FormatHex(dataHex));
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> SendWithData(string address, decimal amount, byte[] dataHex)
+        {
+            return _Client.Execute<string>("sendwithdata", 0, address, amount, Util.Utility.FormatHex(dataHex));
+        }
+
         /// <summary>
         /// This works like send, but with an additional data-only transaction output. To include raw data, pass a data-hex hexadecimal string. To publish the data to a stream, pass an object {"for":stream,"key":"...","data":"..."} where stream is a stream name, ref or creation txid, the key is in text form, and the data is hexadecimal.
         /// </summary>
         /// <param name="address"></param>
         /// <param name="amount"></param>
         /// <param name="dataHex"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendWithDataAsync(string address, decimal amount, byte[] dataHex)
-        {
-            return _Client.ExecuteAsync<string>("sendwithdata", 0, address, amount, Util.Utility.FormatHex(dataHex));
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendWithDataAsync(string address, decimal amount, byte[] dataHex)
+        {
+            return _Client.ExecuteAsync<string>("sendwithdata", 0, address, amount, Util.Utility.FormatHex(dataHex));
+        }
+
         /// <summary>
         /// This works like sendwithdata, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address.
         /// </summary>
@@ -461,12 +501,12 @@
         /// <param name="toAddress"></param>
         /// <param name="amount"></param>
         /// <param name="dataHex"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> SendWithDataFrom(string fromAddress, string toAddress, decimal amount, byte[] dataHex)
-        {
-            return _Client.Execute<string>("sendwithdatafrom", 0, fromAddress, toAddress, amount, Util.Utility.FormatHex(dataHex));
-        }
-
+        /// <returns></returns>
+        public JsonRpcResponse<string> SendWithDataFrom(string fromAddress, string toAddress, decimal amount, byte[] dataHex)
+        {
+            return _Client.Execute<string>("sendwithdatafrom", 0, fromAddress, toAddress, amount, Util.Utility.FormatHex(dataHex));
+        }
+
         /// <summary>
         /// This works like sendwithdata, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address.
         /// </summary>
@@ -474,25 +514,25 @@
         /// <param name="toAddress"></param>
         /// <param name="amount"></param>
         /// <param name="dataHex"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendWithDataFromAsync(string fromAddress, string toAddress, decimal amount, byte[] dataHex)
-        {
-            return _Client.ExecuteAsync<string>("sendwithdatafrom", 0, fromAddress, toAddress, amount, Util.Utility.FormatHex(dataHex));
-        }
-
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="fromAddress"></param>
-        /// <param name="toAddress"></param>
-        /// <param name="assetmovement"> { assetidentifier: "", quantity : 1}</param>
-        /// <param name="dataHex"></param>
-        /// <returns></returns>
-        public JsonRpcResponse<string> SendWithDataFrom(string fromAddress, string toAddress, Dictionary<string, int> assetmovement, byte[] dataHex)
-        {
-            return _Client.Execute<string>("sendwithdatafrom", 0, fromAddress, toAddress, assetmovement, Util.Utility.FormatHex(dataHex));
-        }
-
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendWithDataFromAsync(string fromAddress, string toAddress, decimal amount, byte[] dataHex)
+        {
+            return _Client.ExecuteAsync<string>("sendwithdatafrom", 0, fromAddress, toAddress, amount, Util.Utility.FormatHex(dataHex));
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="fromAddress"></param>
+        /// <param name="toAddress"></param>
+        /// <param name="assetmovement"> { assetidentifier: "", quantity : 1}</param>
+        /// <param name="dataHex"></param>
+        /// <returns></returns>
+        public JsonRpcResponse<string> SendWithDataFrom(string fromAddress, string toAddress, Dictionary<string, int> assetmovement, byte[] dataHex)
+        {
+            return _Client.Execute<string>("sendwithdatafrom", 0, fromAddress, toAddress, assetmovement, Util.Utility.FormatHex(dataHex));
+        }
+
         /// <summary>
         /// This works like sendwithdata, but with control over the from-address whose funds are used. Any change from the transaction is sent back to from-address.
         /// </summary>
@@ -500,11 +540,11 @@
         /// <param name="toAddress"></param>
         /// <param name="assetmovement"></param>
         /// <param name="dataHex"></param>
-        /// <returns></returns>
-        public Task<JsonRpcResponse<string>> SendWithDataFromAsync(string fromAddress, string toAddress, Dictionary<string,int> assetmovement, byte[] dataHex)
-        {
-            return _Client.ExecuteAsync<string>("sendwithdatafrom", 0, fromAddress, toAddress, assetmovement, Util.Utility.FormatHex(dataHex));
-        }
-
-    }
-}
+        /// <returns></returns>
+        public Task<JsonRpcResponse<string>> SendWithDataFromAsync(string fromAddress, string toAddress, Dictionary<string,int> assetmovement, byte[] dataHex)
+        {
+            return _Client.ExecuteAsync<string>("sendwithdatafrom", 0, fromAddress, toAddress, assetmovement, Util.Utility.FormatHex(dataHex));
+        }
+
+    }
+}


Add method changed to AddOrUpdate

Add method changed to AddOrUpdate

--- FurnitureFactory.Data.MongoDb/MongoDbDataImporter.cs
+++ FurnitureFactory.Data.MongoDb/MongoDbDataImporter.cs
@@ -3,6 +3,7 @@
     using System;
     using Logic;
     using System.Data.Entity;
+    using System.Data.Entity.Migrations;
     using System.Linq;
     using MongoModels;
     using Models;
@@ -42,7 +43,7 @@
                 {
                     Name = series.Name
                 };
-                this.Db.Set<Models.Series>().Add(seriesEntity);
+                this.Db.Set<Models.Series>().AddOrUpdate(x=>x.Name,seriesEntity);
             }

             this.Db.SaveChanges();
@@ -59,7 +60,7 @@
                     Name = room.Name
                 };

-                this.Db.Set<Models.Room>().Add(roomEntity);
+                this.Db.Set<Models.Room>().AddOrUpdate(x=>x.Name,roomEntity);
             }

             this.Db.SaveChanges();
@@ -76,7 +77,7 @@
                     Name = type.Name
                 };

-                this.Db.Set<Models.FurnitureType>().Add(typeEntity);
+                this.Db.Set<Models.FurnitureType>().AddOrUpdate(x=>x.Name,typeEntity);
             }

             this.Db.SaveChanges();
@@ -110,7 +111,7 @@

                 this.nextFreeCatalogNumber++;

-                this.Db.Set<Models.Product>().Add(productEntity);
+                this.Db.Set<Models.Product>().AddOrUpdate(x=>x.CatalogNumber,productEntity);
             }
             this.Db.SaveChanges();
         }


Add Xiph picture field conversion tests

Add Xiph picture field conversion tests

--- tests/fixtures/TagLib.Tests.TaggingFormats/XiphTest.cs
+++ tests/fixtures/TagLib.Tests.TaggingFormats/XiphTest.cs
@@ -498,6 +498,29 @@
 			TagTestWithSave (ref tag, delegate (Ogg.XiphComment t, string m) {
 				Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m);
 				Assert.AreEqual (0, t.Pictures.Length, "Value Cleared (Zero): " + m);
+			});
+
+			// Test that COVERART fields are parsed in Pictures property
+			string[] pictureStrings = new string[pictures.Length];
+			for (int i = 0; i < 6; ++i)
+				pictureStrings[i] = Convert.ToBase64String(pictures[i].Data.Data);
+			tag.SetField("COVERART", pictureStrings);
+
+			var parsedPictures = tag.Pictures;
+			Assert.IsTrue(!tag.IsEmpty, "Legacy Value Set (IsEmpty)");
+			Assert.AreEqual(6, parsedPictures.Length, "Legacy Value Set (Length)");
+
+			TagTestWithSave(ref tag, delegate (Ogg.XiphComment t, string m) {
+				// COVERART should be preserved
+				Assert.AreEqual(6, t.GetField("COVERART").Length, "Legacy Field Set (Length): " + m);
+			});
+
+			// Setting the pictures array should replace COVERART with METADATA_BLOCK_PICTURE
+			tag.Pictures = pictures;
+
+			TagTestWithSave(ref tag, delegate (Ogg.XiphComment t, string m) {
+				Assert.AreEqual(0, t.GetField("COVERART").Length, "Legacy Field Set (Length): " + m);
+				Assert.AreEqual(6, t.GetField("METADATA_BLOCK_PICTURE").Length, "Current Field Set (Length): " + m);
 			});
 		}


Mantis #2439 MemberwiseClone() also clones the "already backed up" flag, preventing prims created by drag-copying from being persisted. If such a prim is made the root prims of a link set, the entire set will not be persisted. Fixed now.

--- OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -1009,7 +1009,7 @@
             // that they don't happen, otherwise the deleted objects will reappear
             m_isDeleted = true;

-//            DetachFromBackup();
+            DetachFromBackup();

             foreach (SceneObjectPart part in m_parts.Values)
             {
@@ -1278,6 +1278,7 @@
         public SceneObjectGroup Copy(UUID cAgentID, UUID cGroupID, bool userExposed)
         {
             SceneObjectGroup dupe = (SceneObjectGroup) MemberwiseClone();
+            dupe.m_isBackedUp = false;
             dupe.m_parts = new Dictionary<UUID, SceneObjectPart>();
             dupe.m_parts.Clear();
             //dupe.OwnerID = AgentID;
@@ -1860,6 +1861,7 @@
             // The traffic caused is always going to be pretty minor, so it's not high priority
             //objectGroup.DeleteGroup();

+            AttachToBackup();
             HasGroupChanged = true;
             ScheduleGroupForFullUpdate();
         }


Ancestor to AncestorOrSelf

Ancestor to AncestorOrSelf

--- Gibe.DittoProcessors/Processors/AncestorAttribute.cs
+++ Gibe.DittoProcessors/Processors/AncestorAttribute.cs
@@ -35,7 +35,7 @@
 			{
 				return UmbracoWrapper().AncestorOrSelf(Context.Content, _maxDepth);
 			}
-			return UmbracoWrapper().Ancestor(Context.Content);
+			return UmbracoWrapper().AncestorOrSelf(Context.Content);
 		}
 	}
 }


Access permissions for network service on flat file log is now made with the full name of the user ("NT AUTHORITY\NetworkService)

--- PART/Source/Core/Installers/Utilities/Installation.cs
+++ PART/Source/Core/Installers/Utilities/Installation.cs
@@ -282,7 +282,7 @@
                 File.Create(fileName);
             }
             FileSecurity access = System.IO.File.GetAccessControl(fileName);
-            FileSystemAccessRule rule = new FileSystemAccessRule("NETWORK SERVICE", FileSystemRights.FullControl, AccessControlType.Allow);
+            FileSystemAccessRule rule = new FileSystemAccessRule(@"NT AUTHORITY\NetworkService", FileSystemRights.FullControl, AccessControlType.Allow);
             access.ResetAccessRule(rule);
             File.SetAccessControl(fileName, access);
         }


Implement known type types

Implement known type types

--- Packager/Models/PodMetadataModels/AudioPodMetadata.cs
+++ Packager/Models/PodMetadataModels/AudioPodMetadata.cs
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Xml.Linq;
+using Packager.Exceptions;
 using Packager.Factories;
 using RestSharp.Extensions;

@@ -22,6 +23,15 @@
         public string NoiseReduction { get; set; }
         public string FormatDuration { get; set; }

+        private static readonly Dictionary<string, string> KnownTapeTypes = new Dictionary<string, string>
+        {
+            {"i", "Type I"},
+            {"ii", "Type II"},
+            {"iii", "Type III"},
+            {"iv", "Type IV"},
+            {"unknown", "Unknown"}
+        };
+
         public override void ImportFromXml(XElement element, IImportableFactory factory)
         {
             base.ImportFromXml(element, factory);
@@ -39,24 +49,19 @@
             FormatDuration = factory.ToStringValue(element, "data/format_duration");
         }

-        private string ConvertTapeType(string value)
+        private static string ConvertTapeType(string value)
         {
             if (!value.HasValue())
             {
                 return value;
             }

-            if (value.StartsWith("type", StringComparison.OrdinalIgnoreCase))
+            if (!KnownTapeTypes.ContainsKey(value.ToLowerInvariant()))
             {
-                return value;
+                throw new PodMetadataException($"{value} does not correspond to a known tape type");
             }

-            if (value.Equals("unknown", StringComparison.OrdinalIgnoreCase))
-            {
-                return value;
-            }
-
-            return $"Type {value.Trim(' ')}";
+            return KnownTapeTypes[value.ToLowerInvariant()];
         }

         protected override List<AbstractDigitalFile> ImportFileProvenances(XElement element, string path,


Begin landing page version 2.0

Begin landing page version 2.0

--- Purchasing.Web/Controllers/Dev/JamesTestController.cs
+++ Purchasing.Web/Controllers/Dev/JamesTestController.cs
@@ -69,14 +69,8 @@
         public ActionResult Test(int id)
         {
             //TODO: Might be better to have a trigger in the database update the order to have the last acted upon date
-            var dt = DateTime.Now.AddDays(-id).Date;
-
-            var orderIds = (Repository.OfType<OrderTracking>().Queryable
-                .Where(a => a.Order.CreatedBy.Id == CurrentUser.Identity.Name)
-                .GroupBy(s => s.Order.Id).Select(g => new { id = g.Key, LastDateActedOn = g.Max(s => s.DateCreated) }).ToList().Where(xy => xy.LastDateActedOn <= dt)).Select(cx => cx.id).ToList();
-
-
-
+            var orderIds = GetListOfOrderIds(id);
+
             var results = Repository.OfType<Order>().Queryable.Where(a => orderIds.Contains(a.Id) && !a.OrderTrackings.Where(b => b.StatusCode.IsComplete).Any()).Distinct().ToList();
             //var results = Repository.OfType<Order>().Queryable.Where(a => a.CreatedBy.Id == CurrentUser.Identity.Name && !a.OrderTrackings.Where(b => !b.StatusCode.IsComplete && b.DateCreated >= dt).Any()).Distinct().ToList();

@@ -86,14 +80,40 @@
             return View(viewModel);
         }

+        private List<int> GetListOfOrderIds(int id)
+        {
+            var dt = DateTime.Now.AddDays(-id).Date;
+
+            var orderIds = (Repository.OfType<OrderTracking>().Queryable
+                .Where(a => a.Order.CreatedBy.Id == CurrentUser.Identity.Name)
+                .GroupBy(s => s.Order.Id).Select(g => new {id = g.Key, LastDateActedOn = g.Max(s => s.DateCreated)}).ToList().
+                Where(xy => xy.LastDateActedOn <= dt)).Select(cx => cx.id).ToList();
+            return orderIds;
+        }
+
         public ActionResult LandingPage()
         {
-            //var orders = Repository.OfType<OrderTracking>().Queryable.Where(a => a.User.Id == CurrentUser.Identity.Name);
-            //var q = Repository.OfType<OrderTracking>().Queryable.GroupBy(t => t.Order).Select(g => new { id = g.Key, uid = (from t2 in g select t2.DateCreated).Max() });
-            var result = from a in Repository.OfType<OrderTracking>().Queryable group a by a.Order into x select new { Order = x.Key, LastUpdate = x.Max(a => a.DateCreated) };
-            return null;
+            var landingPageViewModel = new LandingPageViewModel();
+            landingPageViewModel.YourOpenRequestCount = _orderAccessService.GetListofOrders(owned: true).Count();
+            landingPageViewModel.YourNotActedOnCount = GetListOfOrderIds(7).Count();
+            landingPageViewModel.OrdersPendingYourActionCount = _orderAccessService.GetListofOrders().Count();
+            return View(landingPageViewModel);
         }
+    }

+    public class LandingPageViewModel
+    {
+        public int YourOpenRequestCount { get; set; }
+        public int YourNotActedOnCount { get; set; }
+        public int OrdersPendingYourActionCount { get; set; }
+        public List<RequestedHistory> RequestedHistories { get; set; }
+    }
+
+    public class RequestedHistory
+    {
+        public string Name { get; set; }
+        public decimal PendingTotal { get; set; }
+        public decimal CompletedTotal { get; set; }
     }

     public class FilteredOrderListModel


Fixed wrong color-conversion for SteelSeries devices

--- RGB.NET.Devices.SteelSeries/Helper/ColorExtensions.cs
+++ RGB.NET.Devices.SteelSeries/Helper/ColorExtensions.cs
@@ -4,6 +4,6 @@
 {
     internal static class ColorExtensions
     {
-        internal static int[] ToIntArray(this Color color) => new int[] { color.GetR(), color.GetB(), color.GetG() };
+        internal static int[] ToIntArray(this Color color) => new int[] { color.GetR(), color.GetG(), color.GetB() };
     }
 }


Fix migration sql to be run in transaction block

--- RelistenApi/Migrations/05_AddSourceTrackPlaysIndex.cs
+++ RelistenApi/Migrations/05_AddSourceTrackPlaysIndex.cs
@@ -9,7 +9,7 @@
         {
             Execute(@"
                 CREATE INDEX IF NOT EXISTS idx_source_track_plays_id_btree ON source_track_plays(id);
-                CREATE INDEX CONCURRENTLY ON setlist_shows (artist_id);
+                CREATE INDEX IF NOT EXISTS idx_setlist_shows_artist_id ON setlist_shows (artist_id);
             ");
         }


XML report final

XML report final

--- RoutesSystem/Reports/ReportWriters/XmlReportWriter.cs
+++ RoutesSystem/Reports/ReportWriters/XmlReportWriter.cs
@@ -18,11 +18,7 @@
                 writer.WriteStartDocument();
                 writer.WriteComment("Report drivers visited routes");
                 writer.WriteStartElement("Routes");
-                    //writer.WriteStartElement("Route");
-                    //    writer.WriteAttributeString("Start","zzz");
-                    //    writer.WriteAttributeString("End","xxx");
-                    //writer.WriteEndElement();
-
+
                 var report = new XmlReport();
                 var inputData = report.GetVisitedRoutes();

@@ -33,7 +29,8 @@
                         writer.WriteStartElement("Route");
                         writer.WriteAttributeString("Start", item.StartTownName);
                         writer.WriteAttributeString("End", item.EndTownName);
-                        writer.WriteAttributeString("Date", detail.RouteDate.Date.Day.ToString());
+                        writer.WriteAttributeString("Driver", detail.DriverName);
+                        writer.WriteAttributeString("Date", detail.RouteDate.Date.ToString());
                         writer.WriteEndElement();
                     }
                 }


BTI-177 add more stats logs in StreamStatsActor - show detailed stats when fixtures are published

--- SS.Integration.Adapter/Actors/SportsProcessorActor.cs
+++ SS.Integration.Adapter/Actors/SportsProcessorActor.cs
@@ -104,21 +104,23 @@

             _logger.Info($"PublishedFixturesTotalCount={publishedFixturesTotalCount}");

-            var streamListenerStates = Enum.GetValues(typeof(StreamListenerState)).Cast<StreamListenerState>();
-            foreach (var state in streamListenerStates)
+            if (publishedFixturesTotalCount > 0)
             {
-                var publishedFixturesPerStateTotalCount = FixtureStatsPerSport.Count > 0
-                    ? FixtureStatsPerSport.Keys
+                var streamListenerStates = Enum.GetValues(typeof(StreamListenerState)).Cast<StreamListenerState>();
+                foreach (var state in streamListenerStates)
+                {
+                    var publishedFixturesPerStateCount = FixtureStatsPerSport.Keys
                         .Select(sport => FixtureStatsPerSport[sport].FixtureStateCount[state])
-                        .Sum()
-                    : 0;
-                _logger.Info($"PublishedFixturesTotalCount={publishedFixturesPerStateTotalCount} having StreamListenerState={state}");
+                        .Sum();
+                    _logger.Info(
+                        $"PublishedFixturesPerStateCount={publishedFixturesPerStateCount} having StreamListenerState={state}");
+                }
+
+                foreach (var sport in FixtureStatsPerSport.Keys)
+                foreach (var state in FixtureStatsPerSport[sport].FixtureStateCount.Keys)
+                    _logger.Info(
+                        $"PublishedFixturesPerStateForSportCount={FixtureStatsPerSport[sport].FixtureStateCount[state]} having StreamListenerState={state} for Sport={sport}");
             }
-
-            foreach (var sport in FixtureStatsPerSport.Keys)
-            foreach (var state in FixtureStatsPerSport[sport].FixtureStateCount.Keys)
-                _logger.Info(
-                    $"PublishedFixturesCount={FixtureStatsPerSport[sport].FixtureStateCount[state]} having StreamListenerState={state} for Sport={sport}");
         }

         private void NewStreamListenerActorMsgHandler(NewStreamListenerActorMsg msg)


fix TranslateInstanceValueProvider

fix TranslateInstanceValueProvider

--- Signum.Engine.Extensions/Templating/ValueProviders.cs
+++ Signum.Engine.Extensions/Templating/ValueProviders.cs
@@ -271,9 +271,12 @@
         public TranslateInstanceValueProvider(ParsedToken token, bool isExplicit, Action<bool, string> addError)
         {
             this.ParsedToken = token;
-            this.Route = token.QueryToken.GetPropertyRoute();
             this.IsExplicit = isExplicit;
-            this.EntityToken = DeterminEntityToken(token.QueryToken, addError);
+            if (token.QueryToken != null)
+            {
+                this.Route = token.QueryToken.GetPropertyRoute();
+                this.EntityToken = DeterminEntityToken(token.QueryToken, addError);
+            }
         }

         public override object GetValue(TemplateParameters p)


removed XPM thing

removed XPM thing

--- Site/Areas/Core/Views/Navigation/TopNavigation.cshtml
+++ Site/Areas/Core/Views/Navigation/TopNavigation.cshtml
@@ -7,8 +7,4 @@
             @item.LinkText

     }
-    @if (Configuration.IsStaging)
-    {
-
[XPM]

-    }


Ensure ProfileEvents GameObject is Correctly Named

--- Soomla/Assets/Plugins/Soomla/Profile/ProfileEvents.cs
+++ Soomla/Assets/Plugins/Soomla/Profile/ProfileEvents.cs
@@ -40,6 +40,7 @@
 				SoomlaUtils.LogDebug(TAG, "Initializing ProfileEvents (Awake)");

 				instance = this;
+                gameObject.name = "ProfileEvents";
 				GameObject.DontDestroyOnLoad(this.gameObject);
 				Initialize();
 				// now we initialize the event pusher


slightly improved corpse positioning for creeping mobs (#2554)

--- Source/ACE.Server/WorldObjects/Creature_Navigation.cs
+++ Source/ACE.Server/WorldObjects/Creature_Navigation.cs
@@ -331,10 +331,13 @@
             else
                 motion.MoveToParameters.MovementParameters &= ~MovementParams.CanRun;

-            // todo: use better movement system
-            // todo: set physics position
+            // todo: use physics MoveToManager
+            // todo: handle landblock updates
             if (setLoc)
+            {
                 Location = new Position(position);
+                PhysicsObj.SetPositionSimple(new Physics.Common.Position(position), true);
+            }

             EnqueueBroadcastMotion(motion);
         }


Make sure that events are inserted into the MSSQL database in the right order

--- Source/EventFlow.EventStores.MsSql/MssqlEventStore.cs
+++ Source/EventFlow.EventStores.MsSql/MssqlEventStore.cs
@@ -96,7 +96,8 @@
                     SELECT
                         BatchId, AggregateId, AggregateName, Data, Metadata, AggregateSequenceNumber
                     FROM
-                        @rows";
+                        @rows
+                    ORDER BY AggregateSequenceNumber ASC";

             IReadOnlyCollection<long> ids;
             try


Add documentation for people module.

Add documentation for people module.

--- Source/Lib/TraktApiSharp/Modules/TraktPeopleModule.cs
+++ Source/Lib/TraktApiSharp/Modules/TraktPeopleModule.cs
@@ -10,21 +10,55 @@
     using System.Linq;
     using System.Threading.Tasks;

+    ///
+    /// Provides access to data retrieving methods specific to people.
+    /// <para>
+    /// This module contains all methods of the "Trakt API Doc - People" section.
+    /// </para>
+    ///
     public class TraktPeopleModule : TraktBaseModule
     {
         internal TraktPeopleModule(TraktClient client) : base(client) { }

-        public async Task<TraktPerson> GetPersonAsync(string id, TraktExtendedOption extended = null)
+        ///
+        /// Gets a <see cref="TraktPerson" /> with the given Trakt-Id or -Slug.
+        /// <para>OAuth authorization NOT required.</para>
+        /// <para>
+        /// See "Trakt API Doc - People: Summary" for more information.
+        /// </para>
+        /// <para>See also <seealso cref="GetMultiplePersonsAsync(TraktMultipleObjectsQueryParams)" />.</para>
+        ///
+        /// <param name="personId">The person's Trakt-Id or -Slug. See also <seealso cref="TraktPersonIds" />.</param>
+        /// <param name="extendedOption">
+        /// The extended option, which determines how much data about the person should be queried.
+        /// See also <seealso cref="TraktExtendedOption" />.
+        /// </param>
+        /// <returns>A <see cref="TraktPerson" /> instance with the queried person's data.</returns>
+        /// <exception cref="Exceptions.TraktException">Thrown, if the request fails.</exception>
+        /// <exception cref="ArgumentException">Thrown, if the given personId is null, empty or contains spaces.</exception>
+        public async Task<TraktPerson> GetPersonAsync(string personId, TraktExtendedOption extendedOption = null)
         {
-            Validate(id);
+            Validate(personId);

             return await QueryAsync(new TraktPersonSummaryRequest(Client)
             {
-                Id = id,
-                ExtendedOption = extended
+                Id = personId,
+                ExtendedOption = extendedOption
             });
         }

+        ///
+        /// Gets multiple different <see cref="TraktPerson" />s at once with the given Trakt-Ids or -Slugs.
+        /// <para>OAuth authorization NOT required.</para>
+        /// <para>
+        /// See "Trakt API Doc - People: Summary" for more information.
+        /// </para>
+        /// <para>See also <seealso cref="GetPersonAsync(string, TraktExtendedOption)" />.</para>
+        ///
+        /// <param name="personsQueryParams">A list of person ids and optional extended options. See also <seealso cref="TraktMultipleObjectsQueryParams" />.</param>
+        /// <returns>A list of <see cref="TraktPerson" /> instances with the data of each queried person.</returns>
+        /// <exception cref="Exceptions.TraktException">Thrown, if one request fails.</exception>
+        /// <exception cref="ArgumentException">Thrown, if one of the given person ids is null, empty or contains spaces.</exception>
         public async Task<IEnumerable<TraktPerson>> GetMultiplePersonsAsync(TraktMultipleObjectsQueryParams personsQueryParams)
         {
             if (personsQueryParams == null || personsQueryParams.Count <= 0)
@@ -42,32 +76,62 @@
             return people.ToList();
         }

-        public async Task<TraktPersonMovieCredits> GetPersonMovieCreditsAsync(string id, TraktExtendedOption extended = null)
+        ///
+        /// Gets all movies where a person with the given Trakt-Id or -Slug is in the cast or crew.
+        /// <para>OAuth authorization NOT required.</para>
+        /// <para>
+        /// See "Trakt API Doc - People: Movies" for more information.
+        /// </para>
+        ///
+        /// <param name="personId">The Trakt-Id or -Slug of the person, for which the movies should be queried.</param>
+        /// <param name="extendedOption">
+        /// The extended option, which determines how much data about the movies should be queried.
+        /// See also <seealso cref="TraktExtendedOption" />.
+        /// </param>
+        /// <returns>A <see cref="TraktPersonMovieCredits" /> instance with the queried person's movie credits.</returns>
+        /// <exception cref="Exceptions.TraktException">Thrown, if the request fails.</exception>
+        /// <exception cref="ArgumentException">Thrown, if the given personId is null, empty or contains spaces.</exception>
+        public async Task<TraktPersonMovieCredits> GetPersonMovieCreditsAsync(string personId, TraktExtendedOption extendedOption = null)
         {
-            Validate(id);
+            Validate(personId);

             return await QueryAsync(new TraktPersonMovieCreditsRequest(Client)
             {
-                Id = id,
-                ExtendedOption = extended
+                Id = personId,
+                ExtendedOption = extendedOption
             });
         }

-        public async Task<TraktPersonShowCredits> GetPersonShowCreditsAsync(string id, TraktExtendedOption extended = null)
+        ///
+        /// Gets all shows where a person with the given Trakt-Id or -Slug is in the cast or crew.
+        /// <para>OAuth authorization NOT required.</para>
+        /// <para>
+        /// See "Trakt API Doc - People: Shows" for more information.
+        /// </para>
+        ///
+        /// <param name="personId">The Trakt-Id or -Slug of the person, for which the shows should be queried.</param>
+        /// <param name="extendedOption">
+        /// The extended option, which determines how much data about the shows should be queried.
+        /// See also <seealso cref="TraktExtendedOption" />.
+        /// </param>
+        /// <returns>A <see cref="TraktPersonShowCredits" /> instance with the queried person's show credits.</returns>
+        /// <exception cref="Exceptions.TraktException">Thrown, if the request fails.</exception>
+        /// <exception cref="ArgumentException">Thrown, if the given personId is null, empty or contains spaces.</exception>
+        public async Task<TraktPersonShowCredits> GetPersonShowCreditsAsync(string personId, TraktExtendedOption extendedOption = null)
         {
-            Validate(id);
+            Validate(personId);

             return await QueryAsync(new TraktPersonShowCreditsRequest(Client)
             {
-                Id = id,
-                ExtendedOption = extended
+                Id = personId,
+                ExtendedOption = extendedOption
             });
         }

-        private void Validate(string id)
+        private void Validate(string personId)
         {
-            if (string.IsNullOrEmpty(id) || id.ContainsSpace())
-                throw new ArgumentException("person id not valid", nameof(id));
+            if (string.IsNullOrEmpty(personId) || personId.ContainsSpace())
+                throw new ArgumentException("person id not valid", nameof(personId));
         }
     }
 }


OfflineSQLiteStore fixed Null Reference bug (#385)

* Update OfflineSQLiteStore.cs

Fixed Null Reference bug in UpsertAsync method

* Update OfflineSQLiteStore.cs

--- sdk/dotnet/src/Microsoft.Datasync.Client.SQLiteStore/OfflineSQLiteStore.cs
+++ sdk/dotnet/src/Microsoft.Datasync.Client.SQLiteStore/OfflineSQLiteStore.cs
@@ -213,7 +213,11 @@
                 {
                     throw new InvalidOperationException($"Column '{prop.Name}' is not defined on table '{tableName}'");
                 }
-                columns.Add(column);
+
+                if (column != null)
+                {
+                    columns.Add(column);
+                }
             }

             if (columns.Count == 0)


Updated InMemoryTestPersistence to reflect latest interface changes and implemented GetExistingBooks

--- InMemoryTestPersistence/PersistenceImplementation.cs
+++ InMemoryTestPersistence/PersistenceImplementation.cs
@@ -6,6 +6,7 @@
 using GlyssenEngine;
 using SIL.DblBundle.Text;
 using SIL.Extensions;
+using SIL.Scripture;

 namespace InMemoryTestPersistence
 {
@@ -20,10 +21,9 @@

 		public IEnumerable<ResourceReader<string>>  GetCustomReferenceTextsNotAlreadyLoaded()
 		{
-			foreach (var key in m_memoryCache.Keys.OfType<IReferenceTextProject>().Where(r => r.Type == ReferenceTextType.Custom && !ReferenceTextProxy.IsCustomReferenceTextIdentifierInListOfAvailable(r.Name)))
-			{
-				yield return new ResourceReader<string>(key.Name, new StringReader(m_memoryCache[key][ProjectResource.Metadata.ToString()]));
-			}
+			return m_memoryCache.Keys.OfType<IReferenceTextProject>()
+				.Where(r => r.Type == ReferenceTextType.Custom && !ReferenceTextProxy.IsCustomReferenceTextIdentifierInListOfAvailable(r.Name))
+				.Select(key => new ResourceReader<string>(key.Name, new StringReader(m_memoryCache[key][ProjectResource.Metadata.ToString()])));
 		}

 		public bool ProjectExistsHaving(string languageIsoCode, string metadataId, string name)
@@ -38,7 +38,7 @@

 		public bool BackupResourceExists(IProject project, ProjectResource resource)
 		{
-			return m_memoryCache.TryGetValue(project, out var resources) && resources.ContainsKey(resource.ToString() + kBackupExtSuffix);
+			return m_memoryCache.TryGetValue(project, out var resources) && resources.ContainsKey(resource + kBackupExtSuffix);
 		}

 		public bool BookResourceExists(IProject project, string bookId)
@@ -70,7 +70,15 @@

 		public IEnumerable<ResourceReader<string>> GetExistingBooks(IProject project)
 		{
-			throw new NotImplementedException();
+			if (m_memoryCache.TryGetValue(project, out var resources))
+			{
+				for (var i = 1; i <= BCVRef.LastBook; i++)
+				{
+					var bookCode = BCVRef.NumberToBookCode(i);
+					if (resources.TryGetValue(kBookPrefix + bookCode, out var bookContents))
+						yield return new ResourceReader<string>(bookCode, new StringReader(bookContents));
+				}
+			}
 		}

 		public bool TryInstallFonts(IUserProject project, string fontFamily, IFontRepository fontRepository)
@@ -138,7 +146,10 @@
 			throw new NotImplementedException();
 		}

-		public int MaxBaseRecordingNameLength { get; }
+		public int GetMaxProjectNameLength(string languageIsoCode)
+		{
+			throw new NotImplementedException();
+		}

 		public void ForgetCustomReferenceTexts()
 		{


Remove double action.

Remove double action.

TriggerLightShaderChanged already does the necessary render engine
actions.

--- Database/ChangeDatabase.cs
+++ Database/ChangeDatabase.cs
@@ -188,8 +188,6 @@
 					{
 						lgsh.Gamma = Gamma;
 						TriggerLightShaderChanged(lgsh, tup.Item2);
-						m_render_engine.ReCreateSimpleEmissionShader(tup.Item2, lgsh);
-						tup.Item2.Tag();
 					}

 				}


commented out startup module

commented out startup module

--- TransferWindowPlanner/TWP.cs
+++ TransferWindowPlanner/TWP.cs
@@ -349,46 +349,46 @@

-#if DEBUG
-    //This will kick us into the save called default and set the first vessel active
-    [KSPAddon(KSPAddon.Startup.MainMenu, false)]
-    public class Debug_AutoLoadPersistentSaveOnStartup : MonoBehaviour
-    {
-        //use this variable for first run to avoid the issue with when this is true and multiple addons use it
-        public static bool first = true;
-        public void Start()
-        {
-            //only do it on the first entry to the menu
-            if (first)
-            {
-                first = false;
-                HighLogic.SaveFolder = "default";
-                Game game = GamePersistence.LoadGame("persistent", HighLogic.SaveFolder, true, false);
-
-                if (game != null && game.flightState != null && game.compatible)
-                {
-                    HighLogic.CurrentGame = game;
-                    HighLogic.LoadScene(GameScenes.SPACECENTER);
-                    return;
-                    Int32 FirstVessel;
-                    Boolean blnFoundVessel = false;
-                    for (FirstVessel = 0; FirstVessel < game.flightState.protoVessels.Count; FirstVessel++)
-                    {
-                        if (game.flightState.protoVessels[FirstVessel].vesselType != VesselType.SpaceObject &&
-                            game.flightState.protoVessels[FirstVessel].vesselType != VesselType.Unknown)
-                        {
-                            blnFoundVessel = true;
-                            break;
-                        }
-                    }
-                    if (!blnFoundVessel)
-                        FirstVessel = 0;
-                    FlightDriver.StartAndFocusVessel(game, FirstVessel);
-                }
-
-                //CheatOptions.InfiniteFuel = true;
-            }
-        }
-    }
-#endif
+//#if DEBUG
+//    //This will kick us into the save called default and set the first vessel active
+//    [KSPAddon(KSPAddon.Startup.MainMenu, false)]
+//    public class Debug_AutoLoadPersistentSaveOnStartup : MonoBehaviour
+//    {
+//        //use this variable for first run to avoid the issue with when this is true and multiple addons use it
+//        public static bool first = true;
+//        public void Start()
+//        {
+//            //only do it on the first entry to the menu
+//            if (first)
+//            {
+//                first = false;
+//                HighLogic.SaveFolder = "default";
+//                Game game = GamePersistence.LoadGame("persistent", HighLogic.SaveFolder, true, false);
+
+//                if (game != null && game.flightState != null && game.compatible)
+//                {
+//                    HighLogic.CurrentGame = game;
+//                    HighLogic.LoadScene(GameScenes.SPACECENTER);
+//                    return;
+//                    Int32 FirstVessel;
+//                    Boolean blnFoundVessel = false;
+//                    for (FirstVessel = 0; FirstVessel < game.flightState.protoVessels.Count; FirstVessel++)
+//                    {
+//                        if (game.flightState.protoVessels[FirstVessel].vesselType != VesselType.SpaceObject &&
+//                            game.flightState.protoVessels[FirstVessel].vesselType != VesselType.Unknown)
+//                        {
+//                            blnFoundVessel = true;
+//                            break;
+//                        }
+//                    }
+//                    if (!blnFoundVessel)
+//                        FirstVessel = 0;
+//                    FlightDriver.StartAndFocusVessel(game, FirstVessel);
+//                }
+
+//                //CheatOptions.InfiniteFuel = true;
+//            }
+//        }
+//    }
+//#endif
 }


Small clean-up, remove unused variable and debug print.

--- Database/ChangeDatabase.cs
+++ Database/ChangeDatabase.cs
@@ -625,9 +625,7 @@
 			foreach (var cqm in added)
 			{
 				var meshes = cqm.GetMeshes();
-				var count = meshes.Length;
 				var meshguid = cqm.Id();
-				//System.Diagnostics.Debug.WriteLine("ChangeQueueMesh {0} has {1} sub-meshes", meshguid, count);

 				var mesh_index = 0;


group

group

--- Tyvj/Views/Group/Show.cshtml
+++ Tyvj/Views/Group/Show.cshtml
@@ -49,7 +49,6 @@

加入团队

团队设置

成员审核

-


Creating ChromeDriver with timeout specified.

--- SpecFlowHelper/Integrations/Browsers/ChromeBrowser.cs
+++ SpecFlowHelper/Integrations/Browsers/ChromeBrowser.cs
@@ -1,4 +1,5 @@
-using OpenQA.Selenium;
+using System;
+using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 using OpenQA.Selenium.Remote;
 using TestSharp;
@@ -42,7 +43,7 @@
             options.AddUserProfilePreference("credentials_enable_service", false);
             options.AddUserProfilePreference("profile.password_manager_enabled", false);

-            return new ChromeDriver(driverFolder, options);
+            return new ChromeDriver(driverFolder, options, TimeSpan.FromMinutes(3));
         }

         public override void Kill()


Pro ASP.Net MVC 5 - SportsStore - Ch 09 - Added Remove Button To Cart Items

Added the final piece, the remove button, which lets items get removed from the
cart.

--- SportsStore/SportsStore.WebUI/Views/Cart/Index.cshtml
+++ SportsStore/SportsStore.WebUI/Views/Cart/Index.cshtml
@@ -4,8 +4,12 @@
     ViewBag.Title = "Sports Store: Your Cart";
 }

+
+

Your cart

-

+

             Quantity
@@ -21,6 +25,14 @@
             @line.Product.Name
             @line.Product.Price.ToString("c")
             @((line.Quantity * line.Product.Price).ToString("c"))
+
+            @using (Html.BeginForm("RemoveFromCart", "Cart")) {
+                @Html.Hidden("ProductId", line.Product.ProductID)
+                @Html.HiddenFor(x => x.ReturnUrl)
+                <input class="btn btn-sm btn-warning" type="submit" value="Remove" />
+            }
+
+

     }


cleanup

cleanup

--- SqlConsole.UnitTests/Visualizers/CsvFormatterTests.cs
+++ SqlConsole.UnitTests/Visualizers/CsvFormatterTests.cs
@@ -1,9 +1,6 @@
 using System;
-using System.Collections.Generic;
 using System.Data;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Net.Code.ADONet;
 using SqlConsole.Host;


Convert tabs to spaces.

Convert tabs to spaces.

--- Keen.NetStandard.Test/ProjectSettingsProviderTest.cs
+++ Keen.NetStandard.Test/ProjectSettingsProviderTest.cs
@@ -19,58 +19,58 @@
             Assert.DoesNotThrow(() => new ProjectSettingsProvider(null));
         }

-		[Test]
-		public void SettingsProviderEnv_VarsNotSet_Throws()
-		{
+        [Test]
+        public void SettingsProviderEnv_VarsNotSet_Throws()
+        {
             var ProjectId = Environment.GetEnvironmentVariable(KeenConstants.KeenProjectId);
-			var MasterKey = Environment.GetEnvironmentVariable(KeenConstants.KeenMasterKey);
-			var WriteKey = Environment.GetEnvironmentVariable(KeenConstants.KeenWriteKey);
-			var ReadKey = Environment.GetEnvironmentVariable(KeenConstants.KeenReadKey);
+            var MasterKey = Environment.GetEnvironmentVariable(KeenConstants.KeenMasterKey);
+            var WriteKey = Environment.GetEnvironmentVariable(KeenConstants.KeenWriteKey);
+            var ReadKey = Environment.GetEnvironmentVariable(KeenConstants.KeenReadKey);

-			try
-			{
-				Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, null);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, null);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, null);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, null);
+            try
+            {
+                Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, null);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, null);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, null);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, null);

-				var settings = new ProjectSettingsProviderEnv();
-				Assert.Throws<KeenException>(() => new KeenClient(settings));
-			}
-			finally
-			{
-				Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, ProjectId);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, MasterKey);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, WriteKey);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, ReadKey);
-			}
-		}
+                var settings = new ProjectSettingsProviderEnv();
+                Assert.Throws<KeenException>(() => new KeenClient(settings));
+            }
+            finally
+            {
+                Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, ProjectId);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, MasterKey);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, WriteKey);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, ReadKey);
+            }
+        }

-		[Test]
-		public void SettingsProviderEnv_VarsSet_Success()
-		{
-			var ProjectId = Environment.GetEnvironmentVariable(KeenConstants.KeenProjectId);
-			var MasterKey = Environment.GetEnvironmentVariable(KeenConstants.KeenMasterKey);
-			var WriteKey = Environment.GetEnvironmentVariable(KeenConstants.KeenWriteKey);
-			var ReadKey = Environment.GetEnvironmentVariable(KeenConstants.KeenReadKey);
+        [Test]
+        public void SettingsProviderEnv_VarsSet_Success()
+        {
+            var ProjectId = Environment.GetEnvironmentVariable(KeenConstants.KeenProjectId);
+            var MasterKey = Environment.GetEnvironmentVariable(KeenConstants.KeenMasterKey);
+            var WriteKey = Environment.GetEnvironmentVariable(KeenConstants.KeenWriteKey);
+            var ReadKey = Environment.GetEnvironmentVariable(KeenConstants.KeenReadKey);

-			try
-			{
-				Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, "X");
-				Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, "X");
-				Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, "X");
-				Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, "X");
+            try
+            {
+                Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, "X");
+                Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, "X");
+                Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, "X");
+                Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, "X");

-				var settings = new ProjectSettingsProviderEnv();
-				Assert.DoesNotThrow(() => new KeenClient(settings));
-			}
-			finally
-			{
-				Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, ProjectId);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, MasterKey);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, WriteKey);
-				Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, ReadKey);
-			}
-		}
+                var settings = new ProjectSettingsProviderEnv();
+                Assert.DoesNotThrow(() => new KeenClient(settings));
+            }
+            finally
+            {
+                Environment.SetEnvironmentVariable(KeenConstants.KeenProjectId, ProjectId);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenMasterKey, MasterKey);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenWriteKey, WriteKey);
+                Environment.SetEnvironmentVariable(KeenConstants.KeenReadKey, ReadKey);
+            }
+        }
     }
 }


Fixed a typo in comment

Fixed a typo in comment

--- Stratis.Bitcoin/Features/MemoryPool/MempoolOrphans.cs
+++ Stratis.Bitcoin/Features/MemoryPool/MempoolOrphans.cs
@@ -189,7 +189,7 @@
                 return false;
             }

-            // TODO: Related to the commented code below with regrads to RelayBehaviour
+            // TODO: Related to the commented code below with regards to RelayBehaviour
             //GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus());
             foreach (var txin in tx.Inputs)
             {


using

using

--- King.Mapper.MVC/Controllers/api/CompanyController.cs
+++ King.Mapper.MVC/Controllers/api/CompanyController.cs
@@ -4,7 +4,6 @@
     using King.Mapper.Generated.Sql;
     using King.Mapper.MVC.Models;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Configuration;
     using System.Data.SqlClient;
     using System.Threading.Tasks;


Remove username from repo URL

Remove username from repo URL

--- Kudu.FunctionalTests/GitRepositoryManagementTests.cs
+++ Kudu.FunctionalTests/GitRepositoryManagementTests.cs
@@ -577,7 +577,7 @@
         {
             string repositoryName = "NodeHelloWorldNoConfig";
             string appName = KuduUtils.GetRandomWebsiteName("NodeConfig");
-            string cloneUrl = "https://davidebbo@github.com/KuduApps/NodeHelloWorldNoConfig.git";
+            string cloneUrl = "https://github.com/KuduApps/NodeHelloWorldNoConfig.git";

             using (var repo = Git.Clone(repositoryName, cloneUrl))
             {


Use expression body

Use expression body

--- SurveyMonkey/RequestSettings/GetSurveyListSettings.cs
+++ SurveyMonkey/RequestSettings/GetSurveyListSettings.cs
@@ -24,6 +24,6 @@
         public DateTime? StartModifiedAt { get; set; }
         public DateTime? EndModifiedAt { get; set; }
         public string Title { get; set; }
-        internal string Include { get { return "response_count,date_created,date_modified,language,question_count,analyze_url,preview"; } }
+        internal string Include => "response_count,date_created,date_modified,language,question_count,analyze_url,preview";
     }
 }


Modify test to also work on the original site builder factory, as this feature (deployment script cache) we are testing (the specific asserts) are not relevant there.

--- Kudu.FunctionalTests/GitRepositoryManagementTests.cs
+++ Kudu.FunctionalTests/GitRepositoryManagementTests.cs
@@ -800,8 +800,12 @@
                     Assert.Equal(1, results.Count);
                     Assert.Equal(DeployStatus.Success, results[0].Status);

-                    var log1 = GetLog(appManager, results[0].Id);
-                    Assert.Contains("Using the following command to generate deployment script", log1);
+                    if (!KuduUtils.TestOriginalSiteBuilderFactory)
+                    {
+                        // Only relevant for new generator deployment logic
+                        var log1 = GetLog(appManager, results[0].Id);
+                        Assert.Contains("Using the following command to generate deployment script", log1);
+                    }

                     string id = results[0].Id;

@@ -821,10 +825,14 @@
                     Assert.Equal(DeployStatus.Success, results[0].Status);
                     Assert.Equal(DeployStatus.Success, results[1].Status);

-                    var log2 = GetLog(appManager, results[0].Id);
-                    var log3 = GetLog(appManager, results[1].Id);
-                    Assert.Contains("Using cached version of deployment script", log2);
-                    Assert.Contains("Using cached version of deployment script", log3);
+                    if (!KuduUtils.TestOriginalSiteBuilderFactory)
+                    {
+                        // Only relevant for new generator deployment logic
+                        var log2 = GetLog(appManager, results[0].Id);
+                        var log3 = GetLog(appManager, results[1].Id);
+                        Assert.Contains("Using cached version of deployment script", log2);
+                        Assert.Contains("Using cached version of deployment script", log3);
+                    }
                 });
             }
         }