Adding a null-check to 'RestClient.EncodeParameter'; optimizing relevant code.

--- RestSharp/RestClient.cs
+++ RestSharp/RestClient.cs
@@ -20,513 +20,509 @@
 using System.Net;
 using System.Reflection;
 using System.Security.Cryptography.X509Certificates;
-using System.Text;
 using RestSharp.Deserializers;
 using RestSharp.Extensions;

 namespace RestSharp
 {
-	/// <summary>
-	/// Client to translate RestRequests into Http requests and process response result
-	/// </summary>
-	public partial class RestClient : IRestClient
-	{
-		// silverlight friendly way to get current version
+    /// <summary>
+    /// Client to translate RestRequests into Http requests and process response result
+    /// </summary>
+    public partial class RestClient : IRestClient
+    {
+        // silverlight friendly way to get current version
 #if PocketPC
 		static readonly Version version = Assembly.GetExecutingAssembly().GetName().Version;
 #else
-		static readonly Version version = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version;
-#endif
-		public IHttpFactory HttpFactory = new SimpleFactory<Http>();
-
-		/// <summary>
-		/// Default constructor that registers default content handlers
-		/// </summary>
-		public RestClient()
-		{
+        static readonly Version version = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version;
+#endif
+        public IHttpFactory HttpFactory = new SimpleFactory<Http>();
+
+        /// <summary>
+        /// Default constructor that registers default content handlers
+        /// </summary>
+        public RestClient()
+        {
 #if WINDOWS_PHONE
 			UseSynchronizationContext = true;
 #endif
-			ContentHandlers = new Dictionary<string, IDeserializer>();
-			AcceptTypes = new List<string>();
-			DefaultParameters = new List<Parameter>();
-
-			// register default handlers
-			AddHandler("application/json", new JsonDeserializer());
-			AddHandler("application/xml", new XmlDeserializer());
-			AddHandler("text/json", new JsonDeserializer());
-			AddHandler("text/x-json", new JsonDeserializer());
-			AddHandler("text/javascript", new JsonDeserializer());
-			AddHandler("text/xml", new XmlDeserializer());
-			AddHandler("*", new XmlDeserializer());
-
-			FollowRedirects = true;
-		}
-
-		/// <summary>
-		/// Sets the BaseUrl property for requests made by this client instance
-		/// </summary>
-		/// <param name="baseUrl"></param>
-		public RestClient(string baseUrl)
-			: this()
-		{
-			BaseUrl = baseUrl;
-		}
-
-		private IDictionary<string, IDeserializer> ContentHandlers { get; set; }
-		private IList<string> AcceptTypes { get; set; }
-
-		/// <summary>
-		/// Parameters included with every request made with this instance of RestClient
-		/// If specified in both client and request, the request wins
-		/// </summary>
-		public IList<Parameter> DefaultParameters { get; private set; }
-
-		/// <summary>
-		/// Registers a content handler to process response content
-		/// </summary>
-		/// <param name="contentType">MIME content type of the response content</param>
-		/// <param name="deserializer">Deserializer to use to process content</param>
-		public void AddHandler(string contentType, IDeserializer deserializer)
-		{
-			ContentHandlers[contentType] = deserializer;
-			if (contentType != "*")
-			{
-				AcceptTypes.Add(contentType);
-				// add Accept header based on registered deserializers
-				var accepts = string.Join(", ", AcceptTypes.ToArray());
-				this.RemoveDefaultParameter("Accept");
-				this.AddDefaultParameter("Accept", accepts, ParameterType.HttpHeader);
-			}
-		}
-
-		/// <summary>
-		/// Remove a content handler for the specified MIME content type
-		/// </summary>
-		/// <param name="contentType">MIME content type to remove</param>
-		public void RemoveHandler(string contentType)
-		{
-			ContentHandlers.Remove(contentType);
-			AcceptTypes.Remove(contentType);
-			this.RemoveDefaultParameter("Accept");
-		}
-
-		/// <summary>
-		/// Remove all content handlers
-		/// </summary>
-		public void ClearHandlers()
-		{
-			ContentHandlers.Clear();
-			AcceptTypes.Clear();
-			this.RemoveDefaultParameter("Accept");
-		}
-
-		/// <summary>
-		/// Retrieve the handler for the specified MIME content type
-		/// </summary>
-		/// <param name="contentType">MIME content type to retrieve</param>
-		/// <returns>IDeserializer instance</returns>
-		IDeserializer GetHandler(string contentType)
-		{
-			if (string.IsNullOrEmpty(contentType) && ContentHandlers.ContainsKey("*"))
-			{
-				return ContentHandlers["*"];
-			}
-
-			var semicolonIndex = contentType.IndexOf(';');
-			if (semicolonIndex > -1) contentType = contentType.Substring(0, semicolonIndex);
-			IDeserializer handler = null;
-			if (ContentHandlers.ContainsKey(contentType))
-			{
-				handler = ContentHandlers[contentType];
-			}
-			else if (ContentHandlers.ContainsKey("*"))
-			{
-				handler = ContentHandlers["*"];
-			}
-
-			return handler;
-		}
-
-		/// <summary>
-		/// Maximum number of redirects to follow if FollowRedirects is true
-		/// </summary>
-		public int? MaxRedirects { get; set; }
+            ContentHandlers = new Dictionary<string, IDeserializer>();
+            AcceptTypes = new List<string>();
+            DefaultParameters = new List<Parameter>();
+
+            // register default handlers
+            AddHandler("application/json", new JsonDeserializer());
+            AddHandler("application/xml", new XmlDeserializer());
+            AddHandler("text/json", new JsonDeserializer());
+            AddHandler("text/x-json", new JsonDeserializer());
+            AddHandler("text/javascript", new JsonDeserializer());
+            AddHandler("text/xml", new XmlDeserializer());
+            AddHandler("*", new XmlDeserializer());
+
+            FollowRedirects = true;
+        }
+
+        /// <summary>
+        /// Sets the BaseUrl property for requests made by this client instance
+        /// </summary>
+        /// <param name="baseUrl"></param>
+        public RestClient(string baseUrl)
+            : this()
+        {
+            BaseUrl = baseUrl;
+        }
+
+        private IDictionary<string, IDeserializer> ContentHandlers { get; set; }
+        private IList<string> AcceptTypes { get; set; }
+
+        /// <summary>
+        /// Parameters included with every request made with this instance of RestClient
+        /// If specified in both client and request, the request wins
+        /// </summary>
+        public IList<Parameter> DefaultParameters { get; private set; }
+
+        /// <summary>
+        /// Registers a content handler to process response content
+        /// </summary>
+        /// <param name="contentType">MIME content type of the response content</param>
+        /// <param name="deserializer">Deserializer to use to process content</param>
+        public void AddHandler(string contentType, IDeserializer deserializer)
+        {
+            ContentHandlers[contentType] = deserializer;
+            if (contentType != "*")
+            {
+                AcceptTypes.Add(contentType);
+                // add Accept header based on registered deserializers
+                var accepts = string.Join(", ", AcceptTypes.ToArray());
+                this.RemoveDefaultParameter("Accept");
+                this.AddDefaultParameter("Accept", accepts, ParameterType.HttpHeader);
+            }
+        }
+
+        /// <summary>
+        /// Remove a content handler for the specified MIME content type
+        /// </summary>
+        /// <param name="contentType">MIME content type to remove</param>
+        public void RemoveHandler(string contentType)
+        {
+            ContentHandlers.Remove(contentType);
+            AcceptTypes.Remove(contentType);
+            this.RemoveDefaultParameter("Accept");
+        }
+
+        /// <summary>
+        /// Remove all content handlers
+        /// </summary>
+        public void ClearHandlers()
+        {
+            ContentHandlers.Clear();
+            AcceptTypes.Clear();
+            this.RemoveDefaultParameter("Accept");
+        }
+
+        /// <summary>
+        /// Retrieve the handler for the specified MIME content type
+        /// </summary>
+        /// <param name="contentType">MIME content type to retrieve</param>
+        /// <returns>IDeserializer instance</returns>
+        IDeserializer GetHandler(string contentType)
+        {
+            if (string.IsNullOrEmpty(contentType) && ContentHandlers.ContainsKey("*"))
+            {
+                return ContentHandlers["*"];
+            }
+
+            var semicolonIndex = contentType.IndexOf(';');
+            if (semicolonIndex > -1) contentType = contentType.Substring(0, semicolonIndex);
+            IDeserializer handler = null;
+            if (ContentHandlers.ContainsKey(contentType))
+            {
+                handler = ContentHandlers[contentType];
+            }
+            else if (ContentHandlers.ContainsKey("*"))
+            {
+                handler = ContentHandlers["*"];
+            }
+
+            return handler;
+        }
+
+        /// <summary>
+        /// Maximum number of redirects to follow if FollowRedirects is true
+        /// </summary>
+        public int? MaxRedirects { get; set; }

 #if FRAMEWORK
-		/// <summary>
-		/// X509CertificateCollection to be sent with request
-		/// </summary>
-		public X509CertificateCollection ClientCertificates { get; set; }
-
-		/// <summary>
-		/// Proxy to use for requests made by this client instance.
-		/// Passed on to underlying WebRequest if set.
-		/// </summary>
-		public IWebProxy Proxy { get; set; }
-#endif
-
-		/// <summary>
-		/// Default is true. Determine whether or not requests that result in
-		/// HTTP status codes of 3xx should follow returned redirect
-		/// </summary>
-		public bool FollowRedirects { get; set; }
-
-		/// <summary>
-		/// The CookieContainer used for requests made by this client instance
-		/// </summary>
+        /// <summary>
+        /// X509CertificateCollection to be sent with request
+        /// </summary>
+        public X509CertificateCollection ClientCertificates { get; set; }
+
+        /// <summary>
+        /// Proxy to use for requests made by this client instance.
+        /// Passed on to underlying WebRequest if set.
+        /// </summary>
+        public IWebProxy Proxy { get; set; }
+#endif
+
+        /// <summary>
+        /// Default is true. Determine whether or not requests that result in
+        /// HTTP status codes of 3xx should follow returned redirect
+        /// </summary>
+        public bool FollowRedirects { get; set; }
+
+        /// <summary>
+        /// The CookieContainer used for requests made by this client instance
+        /// </summary>
 #if !PocketPC
-		public CookieContainer CookieContainer { get; set; }
-#endif
-
-		/// <summary>
-		/// UserAgent to use for requests made by this client instance
-		/// </summary>
-		public string UserAgent { get; set; }
-
-		/// <summary>
-		/// Timeout in milliseconds to use for requests made by this client instance
-		/// </summary>
-		public int Timeout { get; set; }
-
-		/// <summary>
-		/// The number of milliseconds before the writing or reading times out.
-		/// </summary>
-		public int ReadWriteTimeout { get; set; }
-
-		/// <summary>
-		/// Whether to invoke async callbacks using the SynchronizationContext.Current captured when invoked
-		/// </summary>
-		public bool UseSynchronizationContext { get; set; }
-
-		/// <summary>
-		/// Authenticator to use for requests made by this client instance
-		/// </summary>
-		public IAuthenticator Authenticator { get; set; }
-
-		private string _baseUrl;
-		/// <summary>
-		/// Combined with Request.Resource to construct URL for request
-		/// Should include scheme and domain without trailing slash.
-		/// </summary>
-		/// <example>
-		/// client.BaseUrl = "http://example.com";
-		/// </example>
-		public virtual string BaseUrl
-		{
-			get
-			{
-				return _baseUrl;
-			}
-			set
-			{
-				_baseUrl = value;
-				if (_baseUrl != null && _baseUrl.EndsWith("/"))
-				{
-					_baseUrl = _baseUrl.Substring(0, _baseUrl.Length - 1);
-				}
-			}
-		}
-
-		public bool PreAuthenticate { get; set; }
-
-		private void AuthenticateIfNeeded(RestClient client, IRestRequest request)
-		{
-			if (Authenticator != null)
-			{
-				Authenticator.Authenticate(client, request);
-			}
-		}
-
-		/// <summary>
-		/// Assembles URL to call based on parameters, method and resource
-		/// </summary>
-		/// <param name="request">RestRequest to execute</param>
-		/// <returns>Assembled System.Uri</returns>
-		public Uri BuildUri(IRestRequest request)
-		{
-			var assembled = request.Resource;
-			var urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment);
-			foreach (var p in urlParms)
-			{
-				assembled = assembled.Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode());
-			}
-
-			if (!string.IsNullOrEmpty(assembled) && assembled.StartsWith("/"))
-			{
-				assembled = assembled.Substring(1);
-			}
-
-			if (!string.IsNullOrEmpty(BaseUrl))
-			{
-				if (string.IsNullOrEmpty(assembled))
-				{
-					assembled = BaseUrl;
-				}
-				else
-				{
-					assembled = string.Format("{0}/{1}", BaseUrl, assembled);
-				}
-			}
-
-			IEnumerable<Parameter> parameters = null;
-
-			if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH)
-			{
-				// build and attach querystring if this is a get-style request
-				parameters = request.Parameters.Where(p => p.Type == ParameterType.GetOrPost || p.Type == ParameterType.QueryString);
-			}
-			else
-			{
-				parameters = request.Parameters.Where(p => p.Type == ParameterType.QueryString);
-			}
-
-			// build and attach querystring
-			if (parameters != null && parameters.Any())
-			{
-				var data = EncodeParameters(parameters);
-				var separator = assembled.Contains("?") ? "&" : "?";
-				assembled = string.Format("{0}{1}{2}", assembled, separator, data);
-			}
-
-			return new Uri(assembled);
-		}
-
-		private static string EncodeParameters(IEnumerable<Parameter> parameters)
-		{
-			var querystring = new StringBuilder();
-			foreach (var p in parameters)
-			{
-				if (querystring.Length > 1)
-					querystring.Append("&");
-				querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), (p.Value.ToString()).UrlEncode());
-			}
-
-			return querystring.ToString();
-		}
-
-		private void ConfigureHttp(IRestRequest request, IHttp http)
-		{
-			http.AlwaysMultipartFormData = request.AlwaysMultipartFormData;
+        public CookieContainer CookieContainer { get; set; }
+#endif
+
+        /// <summary>
+        /// UserAgent to use for requests made by this client instance
+        /// </summary>
+        public string UserAgent { get; set; }
+
+        /// <summary>
+        /// Timeout in milliseconds to use for requests made by this client instance
+        /// </summary>
+        public int Timeout { get; set; }
+
+        /// <summary>
+        /// The number of milliseconds before the writing or reading times out.
+        /// </summary>
+        public int ReadWriteTimeout { get; set; }
+
+        /// <summary>
+        /// Whether to invoke async callbacks using the SynchronizationContext.Current captured when invoked
+        /// </summary>
+        public bool UseSynchronizationContext { get; set; }
+
+        /// <summary>
+        /// Authenticator to use for requests made by this client instance
+        /// </summary>
+        public IAuthenticator Authenticator { get; set; }
+
+        private string _baseUrl;
+        /// <summary>
+        /// Combined with Request.Resource to construct URL for request
+        /// Should include scheme and domain without trailing slash.
+        /// </summary>
+        /// <example>
+        /// client.BaseUrl = "http://example.com";
+        /// </example>
+        public virtual string BaseUrl
+        {
+            get
+            {
+                return _baseUrl;
+            }
+            set
+            {
+                _baseUrl = value;
+                if (_baseUrl != null && _baseUrl.EndsWith("/"))
+                {
+                    _baseUrl = _baseUrl.Substring(0, _baseUrl.Length - 1);
+                }
+            }
+        }
+
+        public bool PreAuthenticate { get; set; }
+
+        private void AuthenticateIfNeeded(RestClient client, IRestRequest request)
+        {
+            if (Authenticator != null)
+            {
+                Authenticator.Authenticate(client, request);
+            }
+        }
+
+        /// <summary>
+        /// Assembles URL to call based on parameters, method and resource
+        /// </summary>
+        /// <param name="request">RestRequest to execute</param>
+        /// <returns>Assembled System.Uri</returns>
+        public Uri BuildUri(IRestRequest request)
+        {
+            var assembled = request.Resource;
+            var urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment);
+            foreach (var p in urlParms)
+            {
+                assembled = assembled.Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode());
+            }
+
+            if (!string.IsNullOrEmpty(assembled) && assembled.StartsWith("/"))
+            {
+                assembled = assembled.Substring(1);
+            }
+
+            if (!string.IsNullOrEmpty(BaseUrl))
+            {
+                assembled = string.IsNullOrEmpty(assembled) ? this.BaseUrl : string.Format("{0}/{1}", this.BaseUrl, assembled);
+            }
+
+            IEnumerable<Parameter> parameters;
+
+            if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH)
+            {
+                // build and attach querystring if this is a get-style request
+                parameters = request.Parameters.Where(p => p.Type == ParameterType.GetOrPost || p.Type == ParameterType.QueryString).ToList();
+            }
+            else
+            {
+                parameters = request.Parameters.Where(p => p.Type == ParameterType.QueryString).ToList();
+            }
+
+            if (!parameters.Any())
+            {
+                return new Uri(assembled);
+            }
+
+            // build and attach querystring
+            var data = EncodeParameters(parameters);
+            var separator = assembled.Contains("?") ? "&" : "?";
+            assembled = string.Concat(assembled, separator, data);
+
+            return new Uri(assembled);
+        }
+
+        private static string EncodeParameters(IEnumerable<Parameter> parameters)
+        {
+            return string.Join("&", parameters.Select(EncodeParameter).ToArray());
+        }
+
+        private static string EncodeParameter(Parameter parameter)
+        {
+            if (parameter.Value == null)
+            {
+                return string.Concat(parameter.Name.UrlEncode(), "=");
+            }
+
+            return string.Concat(parameter.Name.UrlEncode(), "=", parameter.Value.ToString().UrlEncode());
+        }
+
+        private void ConfigureHttp(IRestRequest request, IHttp http)
+        {
+            http.AlwaysMultipartFormData = request.AlwaysMultipartFormData;
 #if !PocketPC
-			http.UseDefaultCredentials = request.UseDefaultCredentials;
-#endif
-			http.ResponseWriter = request.ResponseWriter;
+            http.UseDefaultCredentials = request.UseDefaultCredentials;
+#endif
+            http.ResponseWriter = request.ResponseWriter;
 #if !PocketPC
-			http.CookieContainer = CookieContainer;
-#endif
-			// move RestClient.DefaultParameters into Request.Parameters
-			foreach (var p in DefaultParameters)
-			{
-				if (request.Parameters.Any(p2 => p2.Name == p.Name && p2.Type == p.Type))
-				{
-					continue;
-				}
-
-				request.AddParameter(p);
-			}
-
-			// Add Accept header based on registered deserializers if none has been set by the caller.
+            http.CookieContainer = CookieContainer;
+#endif
+            // move RestClient.DefaultParameters into Request.Parameters
+            foreach (var p in DefaultParameters)
+            {
+                if (request.Parameters.Any(p2 => p2.Name == p.Name && p2.Type == p.Type))
+                {
+                    continue;
+                }
+
+                request.AddParameter(p);
+            }
+
+            // Add Accept header based on registered deserializers if none has been set by the caller.
 #if PocketPC
 			if (request.Parameters.All(p2 => p2.Name.ToLower() != "accept"))
 #else
-			if (request.Parameters.All(p2 => p2.Name.ToLowerInvariant() != "accept"))
-#endif
-			{
-				var accepts = string.Join(", ", AcceptTypes.ToArray());
-				request.AddParameter("Accept", accepts, ParameterType.HttpHeader);
-			}
-
-			http.Url = BuildUri(request);
-			http.PreAuthenticate = PreAuthenticate;
-
-			var userAgent = UserAgent ?? http.UserAgent;
-			http.UserAgent = userAgent.HasValue() ? userAgent : "RestSharp/" + version;
-
-			var timeout = request.Timeout > 0 ? request.Timeout : Timeout;
-			if (timeout > 0)
-			{
-				http.Timeout = timeout;
-			}
-
-			var readWriteTimeout = request.ReadWriteTimeout > 0 ? request.ReadWriteTimeout : ReadWriteTimeout;
-			if (readWriteTimeout > 0)
-			{
-				http.ReadWriteTimeout = readWriteTimeout;
-			}
+            if (request.Parameters.All(p2 => p2.Name.ToLowerInvariant() != "accept"))
+#endif
+            {
+                var accepts = string.Join(", ", AcceptTypes.ToArray());
+                request.AddParameter("Accept", accepts, ParameterType.HttpHeader);
+            }
+
+            http.Url = BuildUri(request);
+            http.PreAuthenticate = PreAuthenticate;
+
+            var userAgent = UserAgent ?? http.UserAgent;
+            http.UserAgent = userAgent.HasValue() ? userAgent : "RestSharp/" + version;
+
+            var timeout = request.Timeout > 0 ? request.Timeout : Timeout;
+            if (timeout > 0)
+            {
+                http.Timeout = timeout;
+            }
+
+            var readWriteTimeout = request.ReadWriteTimeout > 0 ? request.ReadWriteTimeout : ReadWriteTimeout;
+            if (readWriteTimeout > 0)
+            {
+                http.ReadWriteTimeout = readWriteTimeout;
+            }

 #if !SILVERLIGHT
-			http.FollowRedirects = FollowRedirects;
+            http.FollowRedirects = FollowRedirects;
 #endif
 #if FRAMEWORK
-			if (ClientCertificates != null)
-			{
-				http.ClientCertificates = ClientCertificates;
-			}
-
-			http.MaxRedirects = MaxRedirects;
-#endif
-
-			if (request.Credentials != null)
-			{
-				http.Credentials = request.Credentials;
-			}
-
-			var headers = from p in request.Parameters
-						  where p.Type == ParameterType.HttpHeader
-						  select new HttpHeader
-						  {
-							  Name = p.Name,
-							  Value = p.Value.ToString()
-						  };
-
-			foreach (var header in headers)
-			{
-				http.Headers.Add(header);
-			}
-
-			var cookies = from p in request.Parameters
-						  where p.Type == ParameterType.Cookie
-						  select new HttpCookie
-						  {
-							  Name = p.Name,
-							  Value = p.Value.ToString()
-						  };
-
-			foreach (var cookie in cookies)
-			{
-				http.Cookies.Add(cookie);
-			}
-
-			var @params = from p in request.Parameters
-						  where p.Type == ParameterType.GetOrPost
-								&& p.Value != null
-						  select new HttpParameter
-						  {
-							  Name = p.Name,
-							  Value = p.Value.ToString()
-						  };
-
-			foreach (var parameter in @params)
-			{
-				http.Parameters.Add(parameter);
-			}
-
-			foreach (var file in request.Files)
-			{
-				http.Files.Add(new HttpFile { Name = file.Name, ContentType = file.ContentType, Writer = file.Writer, FileName = file.FileName, ContentLength = file.ContentLength });
-			}
-
-			var body = (from p in request.Parameters
-						where p.Type == ParameterType.RequestBody
-						select p).FirstOrDefault();
-
-			if (body != null)
-			{
-				object val = body.Value;
-				if (val is byte[])
-					http.RequestBodyBytes = (byte[])val;
-				else
-					http.RequestBody = body.Value.ToString();
-				http.RequestContentType = body.Name;
-			}
+            if (ClientCertificates != null)
+            {
+                http.ClientCertificates = ClientCertificates;
+            }
+
+            http.MaxRedirects = MaxRedirects;
+#endif
+
+            if (request.Credentials != null)
+            {
+                http.Credentials = request.Credentials;
+            }
+
+            var headers = from p in request.Parameters
+                          where p.Type == ParameterType.HttpHeader
+                          select new HttpHeader
+                          {
+                              Name = p.Name,
+                              Value = p.Value.ToString()
+                          };
+
+            foreach (var header in headers)
+            {
+                http.Headers.Add(header);
+            }
+
+            var cookies = from p in request.Parameters
+                          where p.Type == ParameterType.Cookie
+                          select new HttpCookie
+                          {
+                              Name = p.Name,
+                              Value = p.Value.ToString()
+                          };
+
+            foreach (var cookie in cookies)
+            {
+                http.Cookies.Add(cookie);
+            }
+
+            var @params = from p in request.Parameters
+                          where p.Type == ParameterType.GetOrPost
+                                && p.Value != null
+                          select new HttpParameter
+                          {
+                              Name = p.Name,
+                              Value = p.Value.ToString()
+                          };
+
+            foreach (var parameter in @params)
+            {
+                http.Parameters.Add(parameter);
+            }
+
+            foreach (var file in request.Files)
+            {
+                http.Files.Add(new HttpFile { Name = file.Name, ContentType = file.ContentType, Writer = file.Writer, FileName = file.FileName, ContentLength = file.ContentLength });
+            }
+
+            var body = (from p in request.Parameters
+                        where p.Type == ParameterType.RequestBody
+                        select p).FirstOrDefault();
+
+            if (body != null)
+            {
+                object val = body.Value;
+                if (val is byte[])
+                    http.RequestBodyBytes = (byte[])val;
+                else
+                    http.RequestBody = body.Value.ToString();
+                http.RequestContentType = body.Name;
+            }
 #if FRAMEWORK
-			ConfigureProxy(http);
-#endif
-		}
+            ConfigureProxy(http);
+#endif
+        }

 #if FRAMEWORK
-		private void ConfigureProxy(IHttp http)
-		{
-			if (Proxy != null)
-			{
-				http.Proxy = Proxy;
-			}
-		}
-#endif
-
-		private RestResponse ConvertToRestResponse(IRestRequest request, HttpResponse httpResponse)
-		{
-			var restResponse = new RestResponse();
-			restResponse.Content = httpResponse.Content;
-			restResponse.ContentEncoding = httpResponse.ContentEncoding;
-			restResponse.ContentLength = httpResponse.ContentLength;
-			restResponse.ContentType = httpResponse.ContentType;
-			restResponse.ErrorException = httpResponse.ErrorException;
-			restResponse.ErrorMessage = httpResponse.ErrorMessage;
-			restResponse.RawBytes = httpResponse.RawBytes;
-			restResponse.ResponseStatus = httpResponse.ResponseStatus;
-			restResponse.ResponseUri = httpResponse.ResponseUri;
-			restResponse.Server = httpResponse.Server;
-			restResponse.StatusCode = httpResponse.StatusCode;
-			restResponse.StatusDescription = httpResponse.StatusDescription;
-			restResponse.Request = request;
-
-			foreach (var header in httpResponse.Headers)
-			{
-				restResponse.Headers.Add(new Parameter { Name = header.Name, Value = header.Value, Type = ParameterType.HttpHeader });
-			}
-
-			foreach (var cookie in httpResponse.Cookies)
-			{
-				restResponse.Cookies.Add(new RestResponseCookie
-				{
-					Comment = cookie.Comment,
-					CommentUri = cookie.CommentUri,
-					Discard = cookie.Discard,
-					Domain = cookie.Domain,
-					Expired = cookie.Expired,
-					Expires = cookie.Expires,
-					HttpOnly = cookie.HttpOnly,
-					Name = cookie.Name,
-					Path = cookie.Path,
-					Port = cookie.Port,
-					Secure = cookie.Secure,
-					TimeStamp = cookie.TimeStamp,
-					Value = cookie.Value,
-					Version = cookie.Version
-				});
-			}
-
-			return restResponse;
-		}
-
-		private IRestResponse<T> Deserialize<T>(IRestRequest request, IRestResponse raw)
-		{
-			request.OnBeforeDeserialization(raw);
-
-			IRestResponse<T> response = new RestResponse<T>();
-			try
-			{
-				response = raw.toAsyncResponse<T>();
-				response.Request = request;
-
-				// Only attempt to deserialize if the request has not errored due
-				// to a transport or framework exception.  HTTP errors should attempt to
-				// be deserialized
-				if (response.ErrorException==null)
-				{
-					IDeserializer handler = GetHandler(raw.ContentType);
-					// Only continue if there is a handler defined else there is no way to deserialize the data.
-					// This can happen when a request returns for example a 404 page instead of the requested JSON/XML resource
-					if (handler != null)
-					{
-						handler.RootElement = request.RootElement;
-						handler.DateFormat = request.DateFormat;
-						handler.Namespace = request.XmlNamespace;
-
-						response.Data = handler.Deserialize<T>(raw);
-					}
-				}
-			}
-			catch (Exception ex)
-			{
-				response.ResponseStatus = ResponseStatus.Error;
-				response.ErrorMessage = ex.Message;
-				response.ErrorException = ex;
-			}
-
-			return response;
-		}
-	}
+        private void ConfigureProxy(IHttp http)
+        {
+            if (Proxy != null)
+            {
+                http.Proxy = Proxy;
+            }
+        }
+#endif
+
+        private RestResponse ConvertToRestResponse(IRestRequest request, HttpResponse httpResponse)
+        {
+            var restResponse = new RestResponse();
+            restResponse.Content = httpResponse.Content;
+            restResponse.ContentEncoding = httpResponse.ContentEncoding;
+            restResponse.ContentLength = httpResponse.ContentLength;
+            restResponse.ContentType = httpResponse.ContentType;
+            restResponse.ErrorException = httpResponse.ErrorException;
+            restResponse.ErrorMessage = httpResponse.ErrorMessage;
+            restResponse.RawBytes = httpResponse.RawBytes;
+            restResponse.ResponseStatus = httpResponse.ResponseStatus;
+            restResponse.ResponseUri = httpResponse.ResponseUri;
+            restResponse.Server = httpResponse.Server;
+            restResponse.StatusCode = httpResponse.StatusCode;
+            restResponse.StatusDescription = httpResponse.StatusDescription;
+            restResponse.Request = request;
+
+            foreach (var header in httpResponse.Headers)
+            {
+                restResponse.Headers.Add(new Parameter { Name = header.Name, Value = header.Value, Type = ParameterType.HttpHeader });
+            }
+
+            foreach (var cookie in httpResponse.Cookies)
+            {
+                restResponse.Cookies.Add(new RestResponseCookie
+                {
+                    Comment = cookie.Comment,
+                    CommentUri = cookie.CommentUri,
+                    Discard = cookie.Discard,
+                    Domain = cookie.Domain,
+                    Expired = cookie.Expired,
+                    Expires = cookie.Expires,
+                    HttpOnly = cookie.HttpOnly,
+                    Name = cookie.Name,
+                    Path = cookie.Path,
+                    Port = cookie.Port,
+                    Secure = cookie.Secure,
+                    TimeStamp = cookie.TimeStamp,
+                    Value = cookie.Value,
+                    Version = cookie.Version
+                });
+            }
+
+            return restResponse;
+        }
+
+        private IRestResponse<T> Deserialize<T>(IRestRequest request, IRestResponse raw)
+        {
+            request.OnBeforeDeserialization(raw);
+
+            IRestResponse<T> response = new RestResponse<T>();
+            try
+            {
+                response = raw.toAsyncResponse<T>();
+                response.Request = request;
+
+                // Only attempt to deserialize if the request has not errored due
+                // to a transport or framework exception.  HTTP errors should attempt to
+                // be deserialized
+                if (response.ErrorException == null)
+                {
+                    IDeserializer handler = GetHandler(raw.ContentType);
+                    // Only continue if there is a handler defined else there is no way to deserialize the data.
+                    // This can happen when a request returns for example a 404 page instead of the requested JSON/XML resource
+                    if (handler != null)
+                    {
+                        handler.RootElement = request.RootElement;
+                        handler.DateFormat = request.DateFormat;
+                        handler.Namespace = request.XmlNamespace;
+
+                        response.Data = handler.Deserialize<T>(raw);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                response.ResponseStatus = ResponseStatus.Error;
+                response.ErrorMessage = ex.Message;
+                response.ErrorException = ex;
+            }
+
+            return response;
+        }
+    }
 }


Better default version number

Better default version number

--- Admo/Properties/VersionInfo.cs
+++ Admo/Properties/VersionInfo.cs
@@ -1 +1 @@
-[assembly: System.Reflection.AssemblyVersion("1.0.123.456")] // Generated by build this file should not be checkedin
+[assembly: System.Reflection.AssemblyVersion("1.0.*")]


Dpn't use CO in PrintBanner().

Dpn't use CO in PrintBanner().

--- Alpheus.CommandLine/Program.cs
+++ Alpheus.CommandLine/Program.cs
@@ -111,8 +111,8 @@

         static void PrintBanner()
         {
-            CO.Console.WriteLine(figlet.ToAscii("Alpheus"), Color.PaleGreen);
-            CO.Console.WriteLine("v" + Assembly.GetExecutingAssembly().GetName().Version.ToString(), Color.PaleGreen);
+            //CO.Console.WriteLine(figlet.ToAscii("Alpheus"), Color.PaleGreen);
+            Console.WriteLine("v" + Assembly.GetExecutingAssembly().GetName().Version.ToString(), Color.PaleGreen);
         }

         static void PrintMessage(string format)


Insert should now update any auto generated fields of the inserted object.

--- Database.cs
+++ Database.cs
@@ -538,7 +538,7 @@
             DatabaseTable table = GetTable<T>();
             DBCommand cmd = GenerateSelectCommand(table, false, predicates);

-            List<T> entities = new List<T>();
+            var entities = new List<T>();
             using (DBDataReader reader = cmd.ExecuteReader()) {
                 T entity;
                 while ((entity = reader.ReadEntity<T>(table)) != null)
@@ -574,12 +574,12 @@
             return Select<T>(x => true);
         }

-        private static List<Object> SelectAll(DatabaseTable table)
-        {
-            DBCommand cmd = GenerateSelectCommand<Object>(table, false, x => true);
-
-            List<Object> entities = new List<Object>();
-            using (DBDataReader reader = cmd.ExecuteReader()) {
+        private static IEnumerable<object> SelectAll(DatabaseTable table)
+        {
+            var cmd = GenerateSelectCommand<Object>(table, false, x => true);
+
+            var entities = new List<Object>();
+            using (var reader = cmd.ExecuteReader()) {
                 Object entity;
                 while ((entity = reader.ReadEntity(table)) != null)
                     entities.Add(entity);
@@ -592,41 +592,51 @@
             where T0 : new()
             where T1 : new()
         {
-            return Select<T0, T1>(joinOn, (x, y) => true);
-        }
-
-        public static int Insert<T>(T entity)
-            where T : new()
-        {
-            return Insert(GetTable<T>(), entity);
-        }
-
-        private static int Insert(DatabaseTable table, Object entity)
+            return Select(joinOn, (x, y) => true);
+        }
+
+        public static void Insert<T>(T entity)
+            where T : new()
+        {
+            Insert(GetTable<T>(), entity);
+        }
+
+        private static void Insert(DatabaseTable table, Object entity)
         {
             if (table.SuperTable != null) {
                 Insert(table.SuperTable, entity);
                 var inherited = table.Columns.Where(x => !x.AutoIncrement
                     && table.SuperTable.Columns.Any(y => y.Name == x.Name))
-                    .Select(x => new Tuple<DatabaseColumn, DatabaseColumn>(
+                    .Select(x => Tuple.Create(
                         x, table.SuperTable.Columns.First(y => y.Name == x.Name)));
-                if (inherited.Count() > 0) {
-                    Object super = Database.SelectLast(table.SuperTable);
+
+                if (inherited.Any()) {
+                    var super = SelectLast(table.SuperTable);
                     foreach (var pair in inherited) {
                         pair.Item1.SetValue(entity, pair.Item2.GetValue(super));
                     }
                 }
             }

-            IEnumerable<DatabaseColumn> valid = table.Columns.Where(x => !x.AutoIncrement);
-
-            String columns = String.Join(",\n  ", valid.Select(x => x.Name));
-            String values = String.Join(",\n  ", valid.Select(x => FormatValue(x.GetValue(entity))));
-
-            StringBuilder builder = new StringBuilder();
-            builder.AppendFormat("INSERT INTO {0}\n(\n  {1}\n) VALUES (\n  {2}\n)",
+            var nonAuto = table.Columns.Where(x => !x.AutoIncrement).ToArray();
+
+            var columns = String.Join(",\n  ", nonAuto.Select(x => x.Name));
+            var values = String.Join(",\n  ", nonAuto.Select(x => FormatValue(x.GetValue(entity))));
+
+            var builder = new StringBuilder();
+            builder.AppendFormat("INSERT INTO {0}\n(\n  {1}\n) OUTPUT INSERTED.* VALUES (\n  {2}\n)",
                 table.Name, columns, values);
-
-            return ExecuteNonQuery(builder.ToString());
+
+            Object result;
+            using (var reader = new DBCommand(builder.ToString(), _sConnection).ExecuteReader())
+                result = reader.ReadEntity(table);
+
+            var auto = table.Columns.Where(x => x.AutoIncrement).ToArray();
+            if (auto.Length == 0) return;
+
+            foreach (var col in auto) {
+                col.SetValue(entity, col.GetValue(result));
+            }
         }

         public static int Update<T>(T entity)
@@ -671,7 +681,7 @@
         public static int Delete<T>(IEnumerable<T> entities)
             where T : new()
         {
-            if (entities.Count() == 0) return 0;
+            if (!entities.Any()) return 0;

             DatabaseTable table = GetTable<T>();
             DatabaseColumn primaryKey = table.Columns.First(x => x.PrimaryKey);


Added try → catch block for /GETUSERDATA

--- AfricasTalkingCS/AfricasTalkingGateway.cs
+++ AfricasTalkingCS/AfricasTalkingGateway.cs
@@ -41,9 +41,6 @@

         public dynamic SendMessage(string to, string message, string from = null, int bulkSmsMode = -1, Hashtable options =null)
         {
-
-
-
             try
             {
                 Hashtable data = new Hashtable
@@ -86,9 +83,6 @@
             {
                 throw new AfricasTalkingGatewayException(e);
             }
-
-           // throw new AfricasTalkingGatewayException(response);
-
         }

         public void UploadMediaFile(string url)
@@ -211,15 +205,17 @@
                 ["username"] = _username,
                 ["recipients"] = recipients
             };
-            var response = SendPostRequest(data, urlString);
-            if (_responseCode != (int) HttpStatusCode.Created) throw new AfricasTalkingGatewayException(response);
-            dynamic json = JObject.Parse(response);
-            if (json["responses"] != null)
-            {
-                return json["responses"];
-            }
-
-            throw new AfricasTalkingGatewayException(json["errorMessage"]);
+            try
+            {
+                var response = SendPostRequest(data, urlString);
+                if (_responseCode != (int)HttpStatusCode.Created) throw new AfricasTalkingGatewayException(response);
+                dynamic json = JObject.Parse(response);
+                return json;
+            }
+            catch (AfricasTalkingGatewayException e)
+            {
+                throw new AfricasTalkingGatewayException(e);
+            }
         }

         public dynamic GetUserData()
@@ -228,7 +224,7 @@
             var response = SendGetRequest(urlString);
             if (_responseCode != (int) HttpStatusCode.OK) throw new AfricasTalkingGatewayException(response);
             dynamic json = JObject.Parse(response);
-            return json["UserData"];
+            return json;
         }

         private string PaymentsUrl => PaymentsHost + "/mobile/checkout/request";


Fix description

Fix description

--- SOVND.Server/Channel.cs
+++ SOVND.Server/Channel.cs
@@ -17,7 +17,7 @@

         /// <summary>
         /// Gets the song at the top of the list
-        /// TODO Return an enum that counts down from the top of the list (write a sorting function and use C#'s sorting)
+        /// TODO Return enumeration that counts down from the top of the list (write a sorting function and use C#'s sorting)
         /// </summary>
         /// <returns></returns>
         public Song GetTopSong()


Refactor GetVS2017Configuration.cs

Refactor GetVS2017Configuration.cs

--- tools/GetVS2017Configuration.cs
+++ tools/GetVS2017Configuration.cs
@@ -7,6 +7,7 @@
 using System;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;

 namespace VisualStudioConfiguration
 {
@@ -182,94 +183,131 @@
     {
     }

+    public class VSInstance : Dictionary<string, object>
+    {
+        public string ToJSON() {
+             List<string> outStrings = new List<string>();
+             foreach (string key in this.Keys) {
+                 string line = '"' + key + "\": ";
+                 switch (this[key].GetType().Name) {
+                     case "String":
+                        string str = (String)this[key];
+                        if (str.IndexOf('{') == 0) line += str;
+                        else line += '"' + (String)this[key] + '"';
+                     break;
+
+                     case "String[]":
+                        line += "[\n    " + String.Join(",\n    ", (string[])this[key]) + "    \n    ]";
+                     break;
+
+                     case "Boolean":
+                        line += (Boolean)this[key] ? "true" : "false";
+                     break;
+
+                     default:
+                        line = null;
+                     break;
+                 }
+                 if (line != null) outStrings.Add(line);
+             }
+             return "{\n        " + String.Join(",\n        ", outStrings.ToArray()) + "\n    }";
+        }
+        public static string ToJSON(IEnumerable<VSInstance> insts){
+             List<string> outStrings = new List<string>();
+             foreach (VSInstance inst in insts) {
+                outStrings.Add(inst.ToJSON());
+             }
+             return "    [\n    " + String.Join(",\n    ", outStrings.ToArray()) + "    \n    ]";
+        }
+    }
+
     public static class Main
     {
-
-        public static void Echo(string tmplt, params Object[] args)
-        {
-            string str = (args.Length > 0) ? String.Format(tmplt, args) : tmplt;
-            Console.Write("    " + str + '\n');
-        }
-
         public static void Query()
         {
+            List<VSInstance> insts = QueryEx(null);
+            Console.Write(VSInstance.ToJSON(insts));
+        }
+
+
+        public static List<VSInstance> QueryEx(string[] args)
+        {
+            List<VSInstance> insts = new List<VSInstance>();
 			ISetupConfiguration query = new SetupConfiguration();
 			ISetupConfiguration2 query2 = (ISetupConfiguration2) query;
 			IEnumSetupInstances e = query2.EnumAllInstances();
 			ISetupInstance2[] rgelt = new ISetupInstance2[1];
 			int pceltFetched;
-            Echo("[");
             e.Next(1, rgelt, out pceltFetched);
 			while (pceltFetched > 0)
 			{
-                PrintInstance(rgelt[0]);
+                ISetupInstance2 raw = rgelt[0];
+                insts.Add(ParseInstance(raw));
                 e.Next(1, rgelt, out pceltFetched);
-				if (pceltFetched > 0)
-				    Echo(",");
 			}
-            Echo("]");
-        }
-
-        private static void PrintInstance(ISetupInstance2 setupInstance2)
+            return insts;
+        }
+
+        private static VSInstance ParseInstance(ISetupInstance2 setupInstance2)
         {
-            Echo("{");
+            VSInstance inst = new VSInstance();
             string[] prodParts = setupInstance2.GetProduct().GetId().Split('.');
             Array.Reverse(prodParts);
-            string prod = prodParts[0];
-            string instPath = setupInstance2.GetInstallationPath().Replace("\\", "\\\\");
-            string installationVersion = setupInstance2.GetInstallationVersion();
-            bool isComplete = setupInstance2.IsComplete();
-            bool isLaunchable = setupInstance2.IsLaunchable();
-            Echo("\"Product\": \"{0}\",", prod);
-            Echo("\"Version\": \"{0}\",", installationVersion);
-            Echo("\"InstallationPath\": \"{0}\",", instPath);
-            Echo("\"IsComplete\": \"{0}\",", isComplete ? "true" : "false");
-            Echo("\"IsLaunchable\": \"{0}\",", isLaunchable ? "true" : "false");
-            String cmd = (instPath + @"\\Common7\\Tools\\VsDevCmd.bat");
-            Echo("\"CmdPath\": \"{0}\",", cmd);
-
+            inst["Product"] = prodParts[0];
+            inst["Version"] = setupInstance2.GetInstallationVersion();
+            inst["InstallationPath"] = setupInstance2.GetInstallationPath().Replace("\\", "\\\\");
+            inst["IsComplete"] = setupInstance2.IsComplete();
+            inst["IsLaunchable"] = setupInstance2.IsLaunchable();
+            inst["CmdPath"] = (inst["InstallationPath"] + @"\\Common7\\Tools\\VsDevCmd.bat");
+
+            inst["Win8SDK"] = "";
+            inst["SDK10"] = "";
+            inst["VisualCppTools"] = "";
             List<string> packs = new List<String>();
-            string MSBuild = "false";
-            string VCTools = "false";
-            string Win8SDK = "0";
-            string sdk10Ver = "0";
             foreach (ISetupPackageReference package in setupInstance2.GetPackages())
             {
                 string id = package.GetId();
+
                 string ver = package.GetVersion();
                 string detail = "{\"id\": \"" + id + "\", \"version\":\"" + ver + "\"}";
-                packs.Add("    " + detail);
+                packs.Add("        " + detail);

                 if (id.Contains("Component.MSBuild")) {
-                    MSBuild = detail;
-                } else if (id.Contains("VC.Tools")) {
-                    VCTools = detail;
+                    inst["MSBuild"] = detail;
+                    inst["MSBuildVer"] = ver;
+                } else if (id.Contains("Microsoft.VisualCpp.Tools.Core")) {
+                    inst["VisualCppTools"] = ver;
+                    inst["VCTools"] = detail;
                 } else if (id.Contains("Microsoft.Windows.81SDK")) {
-                    if (Win8SDK.CompareTo(ver) > 0) continue;
-                    Win8SDK = ver;
+                    if (inst["Win8SDK"].ToString().CompareTo(ver) > 0) continue;
+                    inst["Win8SDK"] = ver;
                 } else if (id.Contains("Win10SDK_10")) {
-                    if (sdk10Ver.CompareTo(ver) > 0) continue;
-                    sdk10Ver = ver;
+                    if (inst["SDK10"].ToString().CompareTo(ver) > 0) continue;
+                    inst["SDK10"] = ver;
                 }
             }
             packs.Sort();
-            string[] sdk10Parts = sdk10Ver.Split('.');
+            inst["Packages"] = packs.ToArray();
+
+            string[] sdk10Parts = inst["SDK10"].ToString().Split('.');
             sdk10Parts[sdk10Parts.Length - 1] = "0";
-            Echo("\"MSBuild\": {0},", MSBuild);
-            if (MSBuild != "false") {
-                string MSBuildToolsPath = instPath + @"\\MSBuild\\15.0\\Bin\\";
-                Echo("\"MSBuildToolsPath\": \"{0}\",", MSBuildToolsPath);
-                Echo("\"MSBuildPath\": \"{0}\",", MSBuildToolsPath + "MSBuild.exe");
+            inst["SDK10"] = String.Join(".", sdk10Parts);
+            inst["SDK"] = inst["SDK10"].ToString() != "0" ? inst["SDK10"] : inst["SDK8"];
+            Regex trimmer = new Regex(@"\.\d+$");
+            if (inst.ContainsKey("MSBuild")) {
+                string ver = trimmer.Replace(trimmer.Replace((string)inst["MSBuildVer"], ""), "");
+                inst["MSBuildToolsPath"] = inst["InstallationPath"] + @"\\MSBuild\\" + ver + @"\\Bin\\";
+                inst["MSBuildPath"] = inst["MSBuildToolsPath"] + "MSBuild.exe";
             }
-            Echo("\"VCTools\": {0},", VCTools);
-            Echo("\"SDK8\": \"{0}\",", Win8SDK);
-            Echo("\"SDK10\": \"{0}\",", sdk10Ver);
-            Echo("\"SDK\": \"{0}\",", String.Join(".", sdk10Parts));
-            Echo("\"Packages\": [\n    {0}    \n    ]", String.Join(",\n    ", packs.ToArray()));
-            Echo("}");
-        }
-    }
-
+            if (inst.ContainsKey("VisualCppTools")) {
+                string ver = trimmer.Replace((string)inst["VisualCppTools"], "");
+                inst["VisualCppToolsX64"] = inst["InstallationPath"] + @"\\VC\\Tools\\MSVC\\" + ver + @"\\bin\\HostX64\\x64\\";
+                inst["VisualCppToolsX86"] = inst["InstallationPath"] + @"\\VC\\Tools\\MSVC\\" + ver + @"\\bin\\HostX86\\x86\\";
+            }
+
+            return inst;
+        }
+    }
 }

 public static class Program


GetRecordSet時に生成されるキャッシュをクリア

GetRecordSet時に生成されるキャッシュをクリア

PostSaveなのに古いRecordSetを見にいかないようにしています

--- Sdx/Scaffold/Manager.cs
+++ Sdx/Scaffold/Manager.cs
@@ -442,6 +442,7 @@

       if (PostSaveHookList != null)
       {
+        record.ClearRecordCache();
         PostSaveHookList.ForEach(action =>
         {
           action(record, values, conn, isNew);


Fix: Stackoverflow exception on write (#27)

--- NeoLua/LuaFile.cs
+++ NeoLua/LuaFile.cs
@@ -332,14 +332,6 @@

 		#region -- Write, Seek ------------------------------------------------------------

-		private void WriteValue(object v)
-		{
-			if (v == null)
-				return;
-			else
-				WriteValue((string)Lua.RtConvertValue(v, typeof(string)));
-		} // proc WriteValue
-
 		/// <summary></summary>
 		/// <param name="args"></param>
 		/// <returns></returns>
@@ -353,8 +345,12 @@
 				{
 					if (args != null || args.Length > 0)
 					{
-						for (int i = 0; i < args.Length; i++)
-							WriteValue(args[i]);
+						for (var i = 0; i < args.Length; i++)
+						{
+							var v = args[i];
+							if (v != null)
+								tw.Write((string)Lua.RtConvertValue(v, typeof(string)));
+						}

 						if (tr != null)
 							tr.DiscardBufferedData();


minor revisions related to #47 (still needs rework)

--- Net/HttpServer.cs
+++ Net/HttpServer.cs
@@ -285,29 +285,38 @@
             httpSer.Close(flush: true);
             // Dispose any resources held by the serialiser.
             httpSer.Dispose();
-            // We need to support HTTP pipelining for HTTP/1.1 compliance, and
-            // this is how we're going to do it. Pipelining involves the user
-            // agent sending multiple requests, one after the other, without
-            // waiting for a response. This means that, if a user agent is using
-            // pipelining, we'll still have data in our receive buffers after
-            // processing the first request.
-            if (ns.DataAvailable)
-            {
-                // The pipelined requests aren't specially formatted, it's just
-                // one HTTP request after another. This means we don't need to
-                // write any special code, and we can just call the method we're
-                // currently in again.
-                this.HttpRequestHandler(tclo);
-            }
-            else
-            {
-                // If there's no data remaining in our receive buffers, there
-                // are no more requests to process. This means that we can close
-                // the streams and connections.
-                ns.Close();
-                ns.Dispose();
-                tcl.Close();
-            }
+
+            // If we are to keep the connection alive, we should check for any
+            // further data the client has sent us. Clients may reuse connections
+            // to save negotiating a new TCP connection, which is comparatively
+            // costly.
+            //
+            // By implementing this, we support HTTP pipelining (where requests
+            // are sent one after the other in order to be processed and responded
+            // to one-by-one on the same connection.
+            if (httpSer.Connection == HttpConnection.KeepAlive)
+            {
+                // TODO: Implement better keep-alive support here (issue #47).
+                if (ns.DataAvailable)
+                {
+                    // The pipelined requests aren't specially formatted, it's just
+                    // one HTTP request after another. This means we don't need to
+                    // write any special code, and we can just call the method we're
+                    // currently in again.
+                    this.HttpRequestHandler(tclo);
+                }
+            }
+
+            // In the below code, we are assuming that the keep-alive scope above
+            // will block until the keep-alive timeout expires, which means we can
+            // just close the connection once we've exited from it.
+            //
+            // This also means we don't need to check to see whether we've been
+            // instructed to close the connection, as if we have the above expressions
+            // won't evaluate to true and we'll bypass the if-statement and end up here.
+            ns.Close();
+            ns.Dispose();
+            tcl.Close();
         }
         private void EmitMessage(MessageType msgType, IList<object> args, HttpResponse res)
         {


simplify

simplify

--- SizSelCsZzz/BySizzle.cs
+++ SizSelCsZzz/BySizzle.cs
@@ -34,16 +34,7 @@

             EnsureSizzleIsLoaded(scriptExecutor);

-            IEnumerable<object> scriptResult = null;
-
-            if (context is IWebElement)
-            {
-                scriptResult = (IEnumerable<object>)scriptExecutor.ExecuteScript("return Sizzle(" + _selector + ", arguments[0])", context);
-            }
-            else
-            {
-                scriptResult = (IEnumerable<object>)scriptExecutor.ExecuteScript("return Sizzle(" + _selector + ")");
-            }
+            IEnumerable<object> scriptResult = (IEnumerable<object>)scriptExecutor.ExecuteScript("return Sizzle(" + _selector + ", arguments[0])", context);

             var result = new ReadOnlyCollection<IWebElement>(scriptResult.Cast<IWebElement>().ToList());


Scan completed

Scan completed

--- Mac/Mac.cs
+++ Mac/Mac.cs
@@ -12,6 +12,7 @@
 		// Consts
 		const uint nFrame = 15; // n. of time slots in superframe
 		const uint symRate = 60; // symbol rate
+
 		const byte beaconFCF = Radio.FCF_BEACON | Radio.FCF_NSPID;  // FCF header: data-frame & no-SRCPAN
 		const byte beaconFCA = Radio.FCA_DST_SADDR | Radio.FCA_SRC_SADDR; // FCA header to use short-addresses
 		const byte cmdFCF = Radio.FCF_CMD | Radio.FCF_ACKRQ; // FCF header: CMD + Acq request
@@ -67,6 +68,10 @@
 				ArgumentException.throwIt(ArgumentException.ILLEGAL_VALUE);
 		}

+		public void stopScan() {
+			this.scanContinue = false;
+		}
+
 		public int onScanEvent(uint flags, byte[] data, uint len, uint info, long time) {
 			uint mode = radio.getRxMode();
 			if(mode == Radio.RXMODE_ED) {
@@ -118,10 +123,6 @@

 		}

-		static void stopScan() {
-
-		}
-
 		// private methods
 		private void trackBeacon() { // da definire, nei diagrammi è espresso anche come scanBeacon()


Fixed paging bug where WHERE is in the wrong place (thanks Mark Price)

--- Massive.cs
+++ Massive.cs
@@ -338,16 +338,15 @@
             var countSQL = string.Format("SELECT COUNT({0}) FROM {1}", PrimaryKeyField, TableName);
             if (String.IsNullOrEmpty(orderBy))
                 orderBy = PrimaryKeyField;
-            var sql = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {2}) AS Row, {0} FROM {3}) AS Paged ",columns,pageSize,orderBy,TableName);
+
+            if (!string.IsNullOrEmpty(where)) {
+                if (!where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase)) {
+                    where = "WHERE " + where;
+                }
+            }
+            var sql = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {2}) AS Row, {0} FROM {3} {4}) AS Paged ",columns,pageSize,orderBy,TableName, where);
             var pageStart = (currentPage -1) * pageSize;
             sql+= string.Format(" WHERE Row >={0} AND Row <={1}",pageStart, (pageStart + pageSize));
-            var pagedWhere = "";
-            if (!string.IsNullOrEmpty(where)) {
-                if (where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase)) {
-                    pagedWhere = Regex.Replace(where, "where ", "and ", RegexOptions.IgnoreCase);
-                }
-            }
-            sql += pagedWhere;
             countSQL += where;
             result.TotalRecords = Scalar(countSQL,args);
             result.TotalPages = result.TotalRecords / pageSize;


Add TODOs to the monitor tool

Add TODOs to the monitor tool

--- Monitor.cs
+++ Monitor.cs
@@ -9,8 +9,23 @@

 public class ManagedDBusTest
 {
-	public static void Main ()
+	public static void Main (string[] args)
 	{
+		//TODO: allow selection of bus
+		if (args.Length == 1) {
+			string arg = args[1];
+
+			switch (arg)
+			{
+				case "--system":
+					break;
+				case "--session":
+					break;
+				default:
+					break;
+			}
+		}
+
 		Connection conn = new Connection ();

 		ObjectPath opath = new ObjectPath ("/org/freedesktop/DBus");
@@ -46,6 +61,7 @@
 				//System.IO.MemoryStream ms = new System.IO.MemoryStream (msg.Body);
 				//System.IO.MemoryStream ms = msg.Body;

+				//TODO: this needs to be done more intelligently
 				foreach (DType dtype in msg.Signature.Data) {
 					if (dtype == DType.Invalid)
 						continue;


Tidied Cell class

Tidied Cell class

--- 2048/Cell.cs
+++ 2048/Cell.cs
@@ -1,41 +1,12 @@
 using System;
-using System.Diagnostics;

 namespace _2048
 {
     public class Cell
     {
-        private int _value;
+        public int Value { get; set; }

-        public int Value
-        {
-            get
-            {
-                return _value;
-            }
-            set
-            {
-                if (value == 2 && WasDoubled)
-                    Debugger.Break();
-                _value = value;
-            }
-        }
-
-        private bool _wasDoubled;
-
-        public bool WasDoubled
-        {
-            get
-            {
-                return _wasDoubled;
-            }
-            set
-            {
-                if (value == true && _value == 2)
-                    Debugger.Break();
-                _wasDoubled = value;
-            }
-        }
+        public bool WasDoubled { get; set; }

         public bool WasCreated { get; set; }
         public int X { get; set; }


fixed bug: we can't send RST if the TCB is in Listen state, since we don't have a destination address+port pair to send the RST segment to;

--- examples/TCP/TCP.cs
+++ examples/TCP/TCP.cs
@@ -284,7 +284,8 @@
       // all open connections
       for (int i = 0; i < max_conn; i++) {
         lock (tcbs[i]) {
-          if (tcbs[i].tcp_state() != TCP_State.Free) {
+          if ((tcbs[i].tcp_state() != TCP_State.Free) &&
+              (tcbs[i].tcp_state() != TCP_State.Listen)) {
             send_RST(tcbs[i].local_port, tcbs[i].remote_port, tcbs[i].remote_address);

             // Set all TCBs to Free (even those in Listen state), and release


make sure a user has a security stamp set when resetting their password, as this was not populated during the migration

--- src/mikeandwan.us/Controllers/AccountController.cs
+++ src/mikeandwan.us/Controllers/AccountController.cs
@@ -241,6 +241,13 @@
 			if(ModelState.IsValid)
 			{
 				var user = await _userMgr.FindByEmailAsync(model.Email);
+
+				// legacy users might not have the security stamp set.  if so, set it here, as a non-null security stamp is requilred for this to work
+				if(string.IsNullOrEmpty(user.SecurityStamp))
+				{
+					await _userMgr.UpdateSecurityStampAsync(user);
+				}
+
 				var code = await _userMgr.GeneratePasswordResetTokenAsync(user);
 				var callbackUrl = Url.Action("ResetPassword", "Account", new { user.Email, code }, Request.Scheme);


Minor usability change

Minor usability change

Opens explorer with file selected when done.

--- Program.cs
+++ Program.cs
@@ -5,7 +5,7 @@
 using System.Text;
 using System.Threading.Tasks;

-namespace ConsoleApplication15
+namespace EdhPartners
 {
     class Program
     {
@@ -42,7 +42,15 @@
             output.AppendLine("<body>");
             output.AppendLine("</html>");

-            File.WriteAllText("partners.html", output.ToString());
+            string filename = "partners.html";
+            if (File.Exists(filename)) File.Delete(filename);
+            File.WriteAllText(filename, output.ToString());
+            OpenExplorer(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filename));
+        }
+
+        public static void OpenExplorer(string filename)
+        {
+            System.Diagnostics.Process.Start("explorer.exe", "/select, \"" + filename + "\"");
         }

         public static IEnumerable<CommanderPair> GetCommanderPairs(IEnumerable<Commander> commanders)


Hide console window if -i enabled

Hide console window if -i enabled

--- Program.cs
+++ Program.cs
@@ -70,7 +70,11 @@
 				Application.Run(new MainForm(dir1, dir2, dirC));
 				return 0;
 			} else {
-				if (interactive || (dir2 == null)) {
+				interactive = interactive || dir2 == null;
+				if (interactive) {
+					IntPtr handle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
+					ShowWindow(handle, 0);
+
 					using (Form loading = new Loading("Select directory")) {
 						loading.Show();
 						if (dir2 == null) {
@@ -87,7 +91,7 @@
 					}
 				}

-				var rows = MainForm.generate(dir1, dir2, dirC, recursive, filenameOnly, true);
+				var rows = MainForm.generate(dir1, dir2, dirC, recursive, filenameOnly, !interactive);
 				string report = html ? MainForm.html(rows) : MainForm.report(rows);
 				if (execute) {
 					string dir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);


deleted timer

deleted timer

--- Program.cs
+++ Program.cs
@@ -18,7 +18,6 @@
         private const int Iterations = 100000;
         private static string endpoint = "http://localhost:1234/";
         private static readonly Counter counter = Metric.Counter("Inserts", Unit.Items);
-        private static readonly Counter writers = Metric.Counter("Writers", Unit.Threads);
         private static readonly Timer timer = Metric.Timer("Events", Unit.Events);

@@ -35,6 +34,7 @@
             Metric
                 .Config
                 .WithHttpEndpoint(endpoint)
+                .WithSystemCounters()
             ;

             Console.Clear();
@@ -58,7 +58,6 @@

                 Parallel.For(1, Iterations, x =>
                     {
-                        writers.Increment();
                         using (timer.NewContext())
                         {
                             var stream = storeEvents.OpenStream("default", x.ToString(), 0, int.MaxValue);
@@ -69,7 +68,6 @@
                             stream.CommitChanges(Guid.NewGuid());
                         }
                         counter.Decrement();
-                        writers.Decrement();
                     });

                 Console.WriteLine("Press any key to exit...");
@@ -87,7 +85,8 @@
         private static PersistenceWireup ConfigureMongo(Wireup wireup)
         {
             return wireup
-                .UsingMongoPersistence("Mongo", new DocumentObjectSerializer(), new MongoPersistenceOptions()
+                .UsingMongoPersistence("Mongo", new DocumentObjectSerializer(),
+                new MongoPersistenceOptions()
                 {
                     ServerSideOptimisticLoop = true
                 });


Delete Program.cs

Delete Program.cs

--- Program.cs
+++ Program.cs
@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace logowanie
-{
-    class Program
-    {
-        static void Main(string[] args)
-        {
-            login log = new login();
-            log.trylogin();
-        }
-    }
-}


A little refactoring. Added validator example.

--- Program.cs
+++ Program.cs
@@ -4,6 +4,15 @@

 // Main at bottom show how to call this kind of library. Just a prototype.

+// Ideas:
+// - Use the Wix Documenation compiler to generate classes like WixProduct from XSD: https://github.com/wixtoolset/wix3/blob/develop/src/tools/wix/Xsd/wix.xsd
+// - Add methods at end to compile/link.
+// - Implement a guid hash for ID's, so hashes stay same as long as filename stays same.
+// - Hash prefix.
+// - Make an example the inherits for WixProduct for customization, like WixIisProduct.
+// - Add a validate method to check each class against XSD to make sure it has all children filled in (generated code).
+
+
 namespace WixSharp
 {

@@ -12,32 +21,34 @@
         public static readonly WxGuid ProductGuid = new WxGuid();
     }

-    // My idea was that I could use this type to constrain which nodes can have specific types of children.
-    public interface IChildOf<T>
-    {
-    }
-
     public class WixTag
     {
+        // Or null.
+        public WixTag Parent { get; set; }
     }

     public class WixLeafTag : WixTag
     {
+        public WixLeafTag()
+        {
+
+        }
+
         // Leaf's can't have children. This type prevents you from call EmitChildren.
     }

     public class WixNodeTag : WixTag
     {
-        public WixNodeTag()
-        {
-            Children = new List<WixTag>();
-        }
-
-        public List<WixTag> Children { get; set; }
+        public WixNodeTag()
+        {
+            Custom = new List<WixRawXml>();
+        }
+
+        public List<WixRawXml> Custom { get; set; }

         public WixRawXml Add(WixRawXml raw)
         {
-            Children.Add(raw);
+            Custom.Add(raw);
             return raw;
         }
     }
@@ -45,13 +56,7 @@

     public class WixDoc : WixNodeTag
     {
-        public WixProduct Add(WixProduct product)
-        {
-            Children.Add(product);
-            return product;
-        }
-
-
+        public WixProduct  Product { get; set; }
     }

     public class WxGuid
@@ -60,10 +65,14 @@

     public class WixRawXml : WixTag
     {
+        public WixRawXml()
+        {
+        }
+
         public string InnerXml { get; set; }
     }

-    public class WixProduct : WixNodeTag, IChildOf<WixDoc>
+    public class WixProduct : WixNodeTag
     {
         // TBD: Need reasonable defaults.

@@ -79,19 +88,75 @@

         public string Version { get; set; }

-        public WixPackage Add(WixPackage wixPackage)
-        {
-            Children.Add(wixPackage);
-            return wixPackage;
-        }
-    }
-
-    public class WixPackage : WixLeafTag, IChildOf<WixProduct>
+
+        public WixPackage Package { get; set; }
+    }
+
+    public class WixPackage : WixLeafTag
     {
         public string Compressed { get; set; }
         public string InstallerVersion { get; set; }
-
-    }
+    }
+
+    // TBD: Generated code (from xsd)
+    public static class WixValidator
+    {
+        public static void Validate(this WixDoc doc)
+        {
+            var ctx = new ValidationContext(doc);
+            Validate( doc, ctx);
+
+            if (ctx.Errors.Count > 0)
+            {
+                throw new Exception( "One or more validation errors occurred.");
+            }
+
+        }
+
+        public struct ValidationError
+        {
+            public WixTag TagWithError { get; set; }
+            public WixTag ParentTagWithError { get; set; } // TBD: Could be a stack all the way to the top.
+            public string Message { get; set; }
+        }
+
+        private class ValidationContext
+        {
+            public WixDoc Root { get; private set; }
+            public WixNodeTag ParentTag { get; set; }
+            public List<ValidationError> Errors { get; set; }
+
+            public ValidationContext(WixDoc root)
+            {
+                Root = root;
+                ParentTag = null;
+                Errors = new List<ValidationError>();
+
+            }
+        }
+
+        // TBD: Simple example. This code will all be genreated.
+        private static void Validate(this WixDoc doc, ValidationContext ctx)
+        {
+            if (doc.Product == null)
+            {
+                ctx.Errors.Add(new ValidationError() {Message = "Missing product", TagWithError = doc, ParentTagWithError = doc.Parent});
+            }
+            // Drill down
+            Validate( doc.Product, ctx);
+        }
+
+        private static void Validate(this WixProduct product, ValidationContext ctx)
+        {
+            if (product.Id == null)
+            {
+                // Missing ID
+                ctx.Errors.Add(new ValidationError() { Message = "Missing product", TagWithError = product, ParentTagWithError = product.Parent });
+            }
+        }
+
+    }
+

     public static class WixEmitter
     {
@@ -104,7 +169,7 @@
             }
         }

-        public class EmitContext
+        private class EmitContext
         {
             public WixDoc Root { get; private set; }
             public WixNodeTag ParentTag { get; set; }
@@ -118,21 +183,24 @@
             }
         }

-        public static void Emit(this WixRawXml rawXml, EmitContext ctx)
+        private static void Emit(this WixRawXml rawXml, EmitContext ctx)
         {
             ctx.Writer.Write(rawXml.InnerXml);
         }

-        public static void Emit(this WixProduct product, EmitContext ctx)
+        private static void Emit(this WixProduct product, EmitContext ctx)
         {
             ctx.Writer.Write("<product >");

+            Emit(product.Package, ctx);
+
+            // This is a lame way to hang some other xml off a node.
             EmitSelfChildren(product, ctx);

             ctx.Writer.Write("</product >");
         }

-        public static void Emit(this WixPackage package, EmitContext ctx)
+        private static void Emit(this WixPackage package, EmitContext ctx)
         {
             ctx.Writer.Write("<package >");

@@ -142,7 +210,7 @@
             ctx.Writer.Write("</package >");
         }

-        public static void Emit(this WixDoc doc, EmitContext ctx)
+        private static void Emit(this WixDoc doc, EmitContext ctx)
         {
             ctx.Writer.Write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
             ctx.Writer.Write("<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">");
@@ -153,14 +221,14 @@
         }

-        public static void EmitSelfChildren(this WixNodeTag node, EmitContext ctx)
+        private static void EmitSelfChildren(this WixNodeTag node, EmitContext ctx)
         {
             var oldParent = ctx.ParentTag;
             ctx.ParentTag = node;

-            if (node.Children != null)
-            {
-                foreach (var child in node.Children)
+            if (node.Custom != null)
+            {
+                foreach (var child in node.Custom)
                 {
                     // Dynamic dispatch. Calls the correct Emit override in THIS class based on type.
                     Emit(((dynamic)child), ctx); // This can fail if you don't have an override for every time.
@@ -200,10 +268,13 @@
         private static void Main(string[] args)
         {
             var wix = new WixDoc();
-            var product = wix.Add(new WixProduct() {Id = Constants.ProductGuid, Language = "1033"}); // Yucky constructor.
-            var package = product.Add(new WixPackage() {});
-            product.Add(new WixRawXml() { InnerXml = @"<test />" });
-
+            wix.Product = new WixProduct() {Id = Constants.ProductGuid, Language = "1033"}; // Yucky constructor.
+            wix.Product.Package = new WixPackage() {};
+
+            // TBD. This may not be that useful. How do I guarantee correct order of output.
+            wix.Product.Custom.Add(new WixRawXml() { InnerXml = @"<test />" });
+
+            wix.Validate();
             wix.EmitFile(new FileInfo(@"c:\temp\test.wxs"));


Fix issue when folder already exist

Fix issue when folder already exist

--- Program.cs
+++ Program.cs
@@ -34,11 +34,13 @@

         static string CreateFolder(string path)
         {
-            string ret = "";
+            string ret = path;
+
             if (!Directory.Exists(path))
             {
                 ret = Directory.CreateDirectory(path).FullName;
-            };
+            }
+
             return ret;
         }


LinearlyIndependentSum.Exponentiate debugging

--- Program.cs
+++ Program.cs
@@ -1398,8 +1398,8 @@
                     ExtendedGCDInfo<Integer> GCDInfo = ExtendedGCD(Index, surd.Index);
                     Number product = Coefficient * surd.Coefficient * (Radicand.Exponentiate(
                         GCDInfo.BOverGCD.Magnitude()) * surd.Radicand.Exponentiate(
-                        GCDInfo.AOverGCD.Magnitude())).Exponentiate(One / ((Index * surd.Index) /
-                        GCDInfo.GCD).Numerator);
+                        GCDInfo.AOverGCD.Magnitude())).Exponentiate(GCDInfo.GCD /
+                        (Index * surd.Index));
                     Rational errorIntervalSize = Pi.LowEstimate / Index;
                     product.RefineArgumentErrorInterval(errorIntervalSize);
                     errorIntervalSize /= new Integer(4) * Pi.HighEstimate;
@@ -1870,11 +1870,16 @@
             }
             public override Number Exponentiate(Rational exponent)
             {
+                if (exponent == One)
+                    return this;
                 if (exponent.Numerator != One)
                     return Exponentiate<Number>(this, exponent.Numerator).Exponentiate(
                         One / exponent.Denominator);
                 Rational rationalFactor = RationalFactor();
-                return rationalFactor.Exponentiate(exponent) *
+                Number coefficientExponentiation = rationalFactor.Exponentiate(exponent);
+                if (coefficientExponentiation is Surd surd && surd.Coefficient == One)
+                    return new Surd(One, this, exponent.Denominator);
+                return coefficientExponentiation *
                     new Surd(One, this / rationalFactor, exponent.Denominator);
             }
             protected override int GetTypeIndex()


Minor renaming

Minor renaming

--- OpenKh.Kh2/Bar.cs
+++ OpenKh.Kh2/Bar.cs
@@ -13,7 +13,7 @@
         private const int HeaderSize = 0x10;
         private const int EntrySize = 0x10;

-        private static Dictionary<EntryType, int> _alignmentsByType = new Dictionary<EntryType, int>
+        private static Dictionary<EntryType, int> _alignments = new Dictionary<EntryType, int>
         {
             [EntryType.Vif] = 0x10,
             [EntryType.Tim2] = 0x80,
@@ -105,8 +105,8 @@
                 throw new InvalidDataException("Invalid header");

             int filesCount = reader.ReadInt32();
-            reader.ReadInt32(); // padding
-            reader.ReadInt32(); // padding
+            reader.ReadInt32(); // always zero
+            reader.ReadInt32(); // unknown

             return Enumerable.Range(0, filesCount)
                 .Select(x => new
@@ -219,7 +219,7 @@

         private static int Align(int offset, Entry entry)
         {
-            if (!_alignmentsByType.TryGetValue(entry.Type, out var alignment))
+            if (!_alignments.TryGetValue(entry.Type, out var alignment))
             {
                 var stream = entry.Stream;
                 var magicCode = stream.Length >= 4 ?


Enables "resume" option by storing last completed transaction.

Uses a custom git config key+value to store each transaction number as it is converted. Passing new "-r" command line switch (instead of "-t" switch) will cause load to start from transaction following the one found in the new config key+value.

--- Program.cs
+++ Program.cs
@@ -21,8 +21,11 @@
 		[Option("w", "workingDir", HelpText = "Working directory of [new] git repo.", Required = true)]
 		public string WorkingDir { get; set; }

-		[Option("t", "startingTran", HelpText = "AccuRev transaction to start from.", DefaultValue = 0)]
-		public int StartingTransaction { get; set; }
+		[Option("t", "startingTran", HelpText = "AccuRev transaction to start from.", DefaultValue = null)]
+		public int? StartingTransaction { get; set; }
+
+		[Option("r", "resume", HelpText = "Resume from last transaction completed.", DefaultValue = false)]
+		public bool Resume { get; set; }
 	}

 	class Program
@@ -43,10 +46,11 @@
 			var streamName = _options.StreamName;
 			var workingDir = _options.WorkingDir;
 			var startingTran = _options.StartingTransaction;
+			var resume = _options.Resume;

 			accurevLogin();
 			loadUsers();
-			loadDepotFromScratch(depotName, streamName, workingDir, startingTran);
+			loadDepotFromScratch(depotName, streamName, workingDir, startingTran, resume);
 		}

 		private static void accurevLogin()
@@ -70,19 +74,26 @@
 				_gitUsers.Add(new GitUser(parts[0], parts[1], parts[2]));
 		}

-		static void loadDepotFromScratch(string depotName, string streamName, string workingDir, int startingTransaction)
+		static void loadDepotFromScratch(string depotName, string streamName, string workingDir, int? startingTransaction, bool resume)
 		{
 			var xdoc = new XDocument();

 			var tempFile = string.Format("_{0}_{1}_.depot.hist.xml", depotName, streamName);
 			if (File.Exists(tempFile))
 			{
-				Console.Write("Existing history file found. Re-use it? [y|n] ");
+				if (resume)
+				{
+					xdoc = XDocument.Load(tempFile);
+				}
+				else
+				{
+					Console.Write("Existing history file found. Re-use it? [y|n] ");
 // ReSharper disable PossibleNullReferenceException
-				if (Console.ReadLine().ToUpper() == "Y")
+					if (Console.ReadLine().ToUpper() == "Y")
 // ReSharper restore PossibleNullReferenceException
-				{
-					xdoc = XDocument.Load(tempFile);
+					{
+						xdoc = XDocument.Load(tempFile);
+					}
 				}
 			}

@@ -97,6 +108,35 @@
 			var n = 0;
 // ReSharper disable PossibleNullReferenceException
 			var nodes = xdoc.Document.Descendants("transaction").Where(t => Int32.Parse(t.Attribute("id").Value) >= startingTransaction).OrderBy(t => Int32.Parse(t.Attribute("id").Value));
+			if (resume)
+			{
+				Console.WriteLine("Attempting to resume from last completed transaction.");
+				int lastTransaction;
+				var result = execGitRaw("config --get accurev2git.lasttran", workingDir);
+				if (!Int32.TryParse(result, out lastTransaction))
+					throw new ApplicationException("Cannot resume - no last transaction was found in git config key 'accurev2git.lasttran'.");
+
+				Console.WriteLine("Resuming from last completed transaction {0}.", lastTransaction);
+				Console.WriteLine("Retrieving history as of {0} for {1} depot, {2} stream, from AccuRev server...", lastTransaction, depotName, streamName);
+				var temp = execAccuRev(string.Format("hist -p \"{0}\" -s \"{0}{1}\" -k promote -t {2}-now -fx", depotName, (string.IsNullOrEmpty(streamName) ? "" : "_" + streamName), lastTransaction), workingDir);
+				File.WriteAllText(tempFile, temp);
+				xdoc = XDocument.Parse(temp);
+
+				nodes = xdoc.Document.Descendants("transaction").Where(t => Int32.Parse(t.Attribute("id").Value) > lastTransaction).OrderBy(t => Int32.Parse(t.Attribute("id").Value));
+				try
+				{
+					startingTransaction = nodes.Select(t => Int32.Parse(t.Attribute("id").Value)).First();
+				}
+				catch (Exception)
+				{
+					Console.WriteLine("No transactions found after last transaction of {0}.", lastTransaction);
+					return;
+				}
+			}
+			else
+			{
+				startingTransaction = startingTransaction ?? 0;
+			}
 			var nCount = nodes.Count();
 			if (startingTransaction == 0)
 			{
@@ -105,6 +145,8 @@
 				var defaultGitUser = _gitUsers.SingleOrDefault(u => u.Name.Equals(defaultGitUserName, StringComparison.OrdinalIgnoreCase));
 				if (defaultGitUser == null)
 					 throw new ApplicationException("Cannot initialize new repository without a DefaultGitUserName specified!");
+				if (Directory.Exists(Path.Combine(workingDir, ".git")))
+					throw new ApplicationException(string.Format("Cannot initialize new repository; repository already exists in '{0}'.", workingDir));
 				execGitRaw("init", workingDir);
 				File.WriteAllText(Path.Combine(workingDir, ".gitignore"), "#empty");
 				execGitRaw("add --all", workingDir);
@@ -147,6 +189,7 @@
 			execAccuRev(string.Format("pop -R -O -v \"{0}{1}\" -L . -t {2} .", depotName, (string.IsNullOrEmpty(streamName) ? "" : "_" + streamName), transactionId), workingDir);
 			execGitRaw("add --all", workingDir);
 			execGitCommit(string.Format("commit --date={0} --author={1} --file=\"{2}\"", unixDate, gitUser, commentFilePath), workingDir, unixDate.ToString(), gitUser);
+			execGitRaw(string.Format("config accurev2git.lasttran {0}", transactionId), workingDir);
 		}

 		static GitUser translateUser(string accurevUser)
@@ -191,7 +234,7 @@
 			return result;
 		}

-		static void execGitRaw(string arguments, string workingDir, bool ignoreErrors = false)
+		static string execGitRaw(string arguments, string workingDir, bool ignoreErrors = false)
 		{
 			var gitPath = ConfigurationManager.AppSettings["GitPath"];
 			var process = new Process
@@ -205,12 +248,13 @@
 			process.StartInfo.RedirectStandardError = true;
 			process.StartInfo.RedirectStandardOutput = true;
 			process.Start();
-			process.StandardOutput.ReadToEnd();
+			var output = process.StandardOutput.ReadToEnd();
 			if (!ignoreErrors && process.StandardError.EndOfStream == false)
 			{
 				var errors = process.StandardError.ReadToEnd();
 				throw new ApplicationException(string.Format("Git has returned an error: {0}", errors));
 			}
+			return output;
 		}

 		static void execGitCommit(string arguments, string workingDir, string commitDate, GitUser gitUser)


Update Svg.cs

Update Svg.cs

--- svg/Svg.Skia/Svg.cs
+++ svg/Svg.Skia/Svg.cs
@@ -1035,6 +1035,24 @@
                     //}
                 }

+                /*
+                if (svgUse.ClipPath != null)
+                {
+                    var svgClipPath = svgVisualElement.OwnerDocument.GetElementById<SvgClipPath>(svgUse.ClipPath.ToString());
+                    if (svgClipPath != null && svgClipPath.Children != null)
+                    {
+                        foreach (var child in svgClipPath.Children)
+                        {
+                            var skPath = new SKPath();
+                        }
+
+                        // TODO:
+
+                        Console.WriteLine($"clip-path: {svgClipPath}");
+                    }
+                }
+                */
+
                 if (svgVisualElement is SvgSymbol)
                 {
                     DrawSvgSymbol(skCanvas, skSize, svgVisualElement as SvgSymbol, disposable);


qrqwwrarsa

qrqwwrarsa

--- TP2ETU/TP2ETU/Pacman.cs
+++ TP2ETU/TP2ETU/Pacman.cs
@@ -66,9 +66,9 @@
     // A COMPLETER MÉTHODE MOVE
     public void Move(Direction direction,Grid grid)
     {
-
+
        pacmanUpdatefrequency--;
-
+
        if (pacmanUpdatefrequency<=0)
        {
         if (direction == Direction.North)
@@ -77,6 +77,7 @@
           {
             position.Y = position.Y - 1;
             pacmanSprite.Rotation = -90;
+
           }
           pacmanUpdatefrequency = PACMAN_UPDATE_FREQUENCY;
         }
@@ -86,7 +87,7 @@
           if (grid.GetGridElementAt(position.Y + 1, position.X) != PacmanElement.Mur)
           {
             position.Y = position.Y + 1;
-            pacmanSprite.Rotation = 90;
+            pacmanSprite.Rotation = 90;
           }
           pacmanUpdatefrequency = PACMAN_UPDATE_FREQUENCY;
         }
@@ -96,7 +97,7 @@
           if (grid.GetGridElementAt(position.Y, position.X + 1) != PacmanElement.Mur)
           {
             position.X = position.X + 1;
-            pacmanSprite.Rotation = 0;
+            pacmanSprite.Rotation = 0;
           }
           pacmanUpdatefrequency = PACMAN_UPDATE_FREQUENCY;
         }
@@ -108,7 +109,6 @@

             position.X = position.X - 1;
             pacmanSprite.Rotation = -180;
-
           }
           pacmanUpdatefrequency = PACMAN_UPDATE_FREQUENCY;
         }


Fix issues when editor log file cannot be opened because it's read only.

--- Assets/Plugins/Editor/FMOD/EditorUtils.cs
+++ Assets/Plugins/Editor/FMOD/EditorUtils.cs
@@ -258,7 +258,11 @@
             UnityEngine.Debug.Log("FMOD Studio: Creating editor system instance");
             RuntimeUtils.EnforceLibraryOrder();

-            CheckResult(FMOD.Debug.Initialize(FMOD.DEBUG_FLAGS.LOG, FMOD.DEBUG_MODE.FILE, null, "fmod_editor.log"));
+            FMOD.RESULT result = FMOD.Debug.Initialize(FMOD.DEBUG_FLAGS.LOG, FMOD.DEBUG_MODE.FILE, null, "fmod_editor.log");
+            if (result != FMOD.RESULT.OK)
+            {
+                UnityEngine.Debug.LogWarning("FMOD Studio: Cannot open fmod_editor.log. Logging will be disabled for importing and previewing");
+            }

             CheckResult(FMOD.Studio.System.create(out system));


Added ToString method to RoomManager to display counts of difficulty/room combos

--- Assets/Scripts/Environment/RoomManager.cs
+++ Assets/Scripts/Environment/RoomManager.cs
@@ -1,5 +1,6 @@
 using UnityEngine;
 using System.Collections.Generic;
+using System.Text;

 public class RoomManager : MonoBehaviour {

@@ -35,6 +36,8 @@
         }

         Difficulties.Sort(); //Sort the difficulties for ordered indexing later.
+
+        Debug.Log(this.ToString());
 	}

 	public GameObject GetRandomRoom() {
@@ -79,4 +82,18 @@

         return closestDifficulty;
     }
+
+    public override string ToString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        foreach (var difficulty in Difficulties)
+        {
+            var rooms = difficultyMap[difficulty];
+
+            sb.AppendLine(string.Format("Number of rooms with difficulty {0}: {1}", difficulty, rooms.Count));
+        }
+
+        return sb.ToString();
+    }
 }


Gave up on pause menu, time constraints for final presentation

--- Assets/Scripts/Player/PlayerController.cs
+++ Assets/Scripts/Player/PlayerController.cs
@@ -34,7 +34,6 @@
     private int beans;
     private bool invulnerable;
     private bool isFloating;
-	private bool paused = false;
     private GameObject bubble;
 	private bool inTornado;
 	private bool canMove;
@@ -314,13 +313,6 @@
 		//ESC key quits the application
 		if(Input.GetKey(KeyCode.Escape))
 		{
-			Time.timeScale = 0;
-			if (paused == true) {
-
-				Time.timeScale = 1;
-				paused = false;
-			}
-			paused = true;
 			Application.Quit ();
 		}
 	}


Hide HelenaCtrl when hit

Hide HelenaCtrl when hit

--- Assets/Scripts/Skill/Helena/HelenaCtrl.cs
+++ Assets/Scripts/Skill/Helena/HelenaCtrl.cs
@@ -31,20 +31,28 @@
     }

     void OnTriggerEnter2D(Collider2D collider) {
+      var target = collider.gameObject.GetComponent<IPhoton>();
+
+      if (target == null)
+        return;
+      if (TeamChecker.IsSameTeam(collider.gameObject, _skillUserObj))
+        return;
+      if (_hitRistrictor.ShouldRistrict(collider.gameObject))
+        return;
+
+      var marginTime = 0.1f;
+      Observable.Timer(TimeSpan.FromSeconds(marginTime))
+        .Where(_ => this != null)
+        .Subscribe(_ => {
+          gameObject.SetActive(false);
+        });
+
       if (PhotonNetwork.isMasterClient) {
-        var target = collider.gameObject.GetComponent<IPhoton>();
-
-        if (target == null)
-          return;
-        if (TeamChecker.IsSameTeam(collider.gameObject, _skillUserObj))
-          return;
-        if (_hitRistrictor.ShouldRistrict(collider.gameObject))
-          return;
-
         DamageCalculator.Calculate(_skillUserObj, _attackInfo);

         _synchronizer.SyncAttack(_skillUserViewID, target.PhotonView.viewID, DamageCalculator.Damage, DamageCalculator.IsCritical, HitEffectType.Helena);
         _synchronizer.SyncDebuff(target.PhotonView.viewID, DebuffType.Ice, _duration);
+
       }
     }


Added style group null check

Added style group null check

--- Test2d/Editor/Editor.cs
+++ Test2d/Editor/Editor.cs
@@ -875,6 +875,7 @@
         {
             return Container.CurrentLayer != null
                 && Container.CurrentLayer.IsVisible
+                && Container.CurrentStyleGroup != null
                 && Container.CurrentStyleGroup.CurrentStyle != null;
         }

@@ -882,6 +883,7 @@
         {
             return Container.CurrentLayer != null
                 && Container.CurrentLayer.IsVisible
+                && Container.CurrentStyleGroup != null
                 && Container.CurrentStyleGroup.CurrentStyle != null;
         }

@@ -889,6 +891,7 @@
         {
             return Container.CurrentLayer != null
                 && Container.CurrentLayer.IsVisible
+                && Container.CurrentStyleGroup != null
                 && Container.CurrentStyleGroup.CurrentStyle != null;
         }

@@ -896,6 +899,7 @@
         {
             return Container.CurrentLayer != null
                 && Container.CurrentLayer.IsVisible
+                && Container.CurrentStyleGroup != null
                 && Container.CurrentStyleGroup.CurrentStyle != null;
         }

@@ -903,6 +907,7 @@
         {
             return Container.CurrentLayer != null
                 && Container.CurrentLayer.IsVisible
+                && Container.CurrentStyleGroup != null
                 && Container.CurrentStyleGroup.CurrentStyle != null;
         }


Update tracked lock test

Update tracked lock test

--- Tests/ThreadingTests.cs
+++ Tests/ThreadingTests.cs
@@ -62,8 +62,8 @@
             Assert.IsTrue(l.TryEnter().Success);
             Assert.IsTrue(l.IsHeld);
             Locks.Dispose();
-            Assert.IsFalse(l.IsHeld);
-            Assert.IsTrue(l.IsDisposed);
+            Assert.IsTrue(l.IsHeld);
+            Assert.IsFalse(l.IsDisposed);
         }

         [Test]


Fix llSetParcelMusicURL.

Fix llSetParcelMusicURL.

--- Aurora/AuroraDotNetEngine/APIs/LSL_Api.cs
+++ Aurora/AuroraDotNetEngine/APIs/LSL_Api.cs
@@ -8645,7 +8645,7 @@
                 if (land == null)
                     return DateTime.Now;

-                if (!World.Permissions.CanEditParcel(m_host.UUID, land))
+                if (!World.Permissions.CanEditParcel(m_host.OwnerID, land))
                     return DateTime.Now;

                 land.SetMusicUrl(url);


reset button, fixed ships placement where cursor is

--- Battlezeppelins/Views/Shared/Game2.cshtml
+++ Battlezeppelins/Views/Shared/Game2.cshtml
@@ -4,8 +4,22 @@

-

-

+

+

+      @for(var y = 0; y < 10; y++){
+

+        @for(var x = 0; x < 10; x++){
+
+            <button type="button" id="@x,@y" class="btn btn-info" style="width:40px;height:40px;padding:0px"></button>
+
+        }
+

+      }
+

+

+
+

+

       @for(var y = 0; y < 10; y++){

         @for(var x = 0; x < 10; x++){
@@ -20,18 +34,23 @@

-

+

+        Continue
+        Reset
+

+

         <button type="button" class="btn btn-default" id="rotation1" value="Up">Up</button>
         <button type="button" class="btn btn-default" id="rotation2" value="Down">Down</button>
         <button type="button" class="btn btn-default" id="rotation3" value="Right">Right</button>
         <button type="button" class="btn btn-default" id="rotation4" value="Left">Left</button>

-

+

         @foreach (var item in Model.zeppelinType)
         {
-
@item.Name

+          var length = item.Length * 40 + "px";
+
@item.Name

         }

@@ -62,9 +81,34 @@
         @Html.Raw("      { \"ship\" : new Ship(" + @item.Length + ", \"" + @item.Name + "\") }, \n")
       }
     ];
-
     this.get = function(shipId) {
       return $.grep(this.list, function (e) { return e.ship.id == shipId; })[0].ship;
+    }
+    this.allSet = function(){
+      var set = false;
+      $.each(this.list, function (i, ship) {
+        if (typeof ship.ship.x === "undefined")
+          return set = false;
+        return set = true;
+      });
+      return set;
+    }
+    this.reset = function () {
+      $("#continue").attr("disabled", true);
+      $("#drag").empty();
+      $.each(this.list, function (i, ship) {
+        for (var i = 0; i < ship.ship.size; i++)
+          $("button[id^='" + ship.ship.x + "," + (i + parseInt(ship.ship.y)) + "']").text('');
+        ship.ship.x = "undefined";
+        ship.ship.y = "undefined";
+        $("#drag").append('
' + ship.ship.name + '
');
+        $("#drag div").draggable({
+          appendTo: "body",
+          cursorAt: { top: 0, left: 0 }
+        });
+      });
     }
   };
   var ships = new ShipList();
@@ -77,16 +121,20 @@

   $(function () {
     $("#drag div").draggable({
-      appendTo: "body"
+      appendTo: "body",
+      cursorAt: { top: 0, left: 0 }
     });
     $("#gameTable button").droppable({
+      tolerance: "pointer",
       drop: function (even, ui) {
         var xy = $(this).attr('id').split(',');
         var shipId = $(ui.draggable).attr("id");
         var ship = ships.get(shipId);
         ship.place(xy[0], xy[1]);
         ui.draggable.remove();
-        showShip(ship);
+        showShip(ship);
+        if (ships.allSet())
+          $("#continue").attr("disabled",false);
       }
     })
   });
@@ -96,6 +144,10 @@
       return;
     $("button[id^='rotation']").removeClass("btn-success");
     $(this).addClass("btn-success");
+  });
+
+  $(document).ready(function () {
+    $("#gameTable2").hide();
   });

   function pollGameMetadata() {


Replaced windows forms file chooser with Gtk

--- BizMachineGUI/BizMachineGUI/MainWindow.cs
+++ BizMachineGUI/BizMachineGUI/MainWindow.cs
@@ -32,11 +32,19 @@

 	protected void OpenFile (object sender, EventArgs e)
 	{
-		OpenFileDialog ofd = new OpenFileDialog ();
-		ofd.Filter = "BizMachine|*.biz";
-		DialogResult result = ofd.ShowDialog();
-		if (result == DialogResult.OK) {
-			Interpreter.Interpreter.ExecuteProgram (ofd.FileName);
+		FileChooserDialog fc = new Gtk.FileChooserDialog ("Choose the file to open",
+		                                                this,
+		                                                FileChooserAction.Open,
+		                                                "Cancel", ResponseType.Cancel,
+		                                                "Open", ResponseType.Accept
+		);
+
+		//fc.Filter = "*.biz";
+		if (fc.Run() == (int)ResponseType.Accept)
+		{
+			Interpreter.Interpreter.ExecuteProgram (fc.Filename);
 		}
+
+		fc.Destroy();
 	}
 }


Fixed proper acceleration visualisation.

--- Principia/Core.cs
+++ Principia/Core.cs
@@ -104,8 +104,8 @@
         activeVesselProperAcceleration = Vector3d.zero;
       }

-      properAccelerationVisualisation.SetPosition(0, activeVessel.GetWorldPos3D());
-      properAccelerationVisualisation.SetPosition(1, activeVessel.GetWorldPos3D() + activeVesselProperAcceleration * 100);
+      properAccelerationVisualisation.SetPosition(0, activeVessel.rootPart.rb.worldCenterOfMass);
+      properAccelerationVisualisation.SetPosition(1, activeVessel.rootPart.rb.worldCenterOfMass + activeVesselProperAcceleration * 100);

       if (simulate) {
 #if TRACE


Even more traces.

Even more traces.

--- Principia/Core.cs
+++ Principia/Core.cs
@@ -272,15 +272,9 @@
         Body kerbin;
         bodies.TryGetValue("Kerbin", out kerbin);
         CelestialBody minmus = FlightGlobals.Bodies[3];
-        GUILayout.TextArea("qKerbin: " + kerbin.q.x + ", "
-                                       + kerbin.q.y + ", "
-                                       + kerbin.q.z);
-        GUILayout.TextArea("vKerbin: " + kerbin.v.x + ", "
-                                       + kerbin.v.y + ", "
-                                       + kerbin.v.z);
-        GUILayout.TextArea("ωMinmus: " + minmus.angularVelocity.x + ", "
-                                       + minmus.angularVelocity.y + ", "
-                                       + minmus.angularVelocity.z);
+        GUILayout.TextArea("qKerbin: " + kerbin.q.ToVector().ToString("F5"));
+        GUILayout.TextArea("vKerbin: " + kerbin.v.ToVector().ToString("F5"));
+        GUILayout.TextArea("ωMinmus: " + minmus.angularVelocity.ToString("F5"));
       }
       GUILayout.TextArea("MapView.Draw3DLines: "
                          + MapView.Draw3DLines.ToString());
@@ -293,6 +287,12 @@
       GUILayout.TextArea("FlightGlobals.ActiveVessel.rootPart.rb.velocity: "
         + ((Vector3d)FlightGlobals.ActiveVessel.rootPart.rb.velocity)
                                                                .ToString("F5"));
+      GUILayout.TextArea("FlightGlobals.ActiveVessel.perturbation: "
+          + ((Vector3d)FlightGlobals.ActiveVessel.perturbation).ToString("F5"));
+      GUILayout.TextArea("FlightGlobals.ActiveVessel.geeForce: "
+                          + FlightGlobals.ActiveVessel.geeForce.ToString());
+      GUILayout.TextArea("FlightGlobals.ActiveVessel.geeForce_immediate: "
+                + FlightGlobals.ActiveVessel.geeForce_immediate.ToString());
       GUILayout.EndVertical();

       GUI.DragWindow(new Rect(left: 0f, top: 0f, width: 10000f, height: 20f));