Improves XApiFormat

Improves XApiFormat

--- Assets/Format/XApiFormat.cs
+++ Assets/Format/XApiFormat.cs
@@ -1,9 +1,9 @@
-/*
+/*
  * Copyright 2016 e-UCM (http://www.e-ucm.es/)
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
- * This project has received funding from the European Union’s Horizon
+ * This project has received funding from the European Unionâ€™s Horizon
  * 2020 research and innovation programme under grant agreement No 644187.
  * You may obtain a copy of the License at
  *
@@ -15,29 +15,80 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-using UnityEngine;
 using System.Collections.Generic;
 using SimpleJSON;
+using System;

 public class XApiFormat : Tracker.ITraceFormatter
 {
-	string SCREEN = "screen";
-	string ZONE = "zone";
-	string CHOICE = "choice";
-	string VAR = "var";
-	public static string VOCAB_PREFIX = "http://purl.org/xapi/games/";
-	public static string VERB_PREFIX = VOCAB_PREFIX + "verbs/";
-	public static string EXT_PREFIX = VOCAB_PREFIX + "ext/";
-	private List<JSONNode> statements = new List<JSONNode> ();
+
+    private Dictionary<string, string> verbIds = new Dictionary<string, string>()
+    {
+        { Tracker.Verb.Initialized.ToString().ToLower(), "https://w3id.org/xapi/adb/verbs/initialized"},
+        { Tracker.Verb.Progressed.ToString().ToLower(), "http://adlnet.gov/expapi/verbs/progressed"},
+        { Tracker.Verb.Completed.ToString().ToLower(), "http://adlnet.gov/expapi/verbs/completed"},
+        { Tracker.Verb.Accessed.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/verbs/accessed"},
+        { Tracker.Verb.Skipped.ToString().ToLower(), "http://id.tincanapi.com/verb/skipped"},
+        { Tracker.Verb.Selected.ToString().ToLower(), "https://w3id.org/xapi/adb/verbs/selected"},
+        { Tracker.Verb.Unlocked.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/verbs/unlocked"},
+        { Tracker.Verb.Interacted.ToString().ToLower(), "http://adlnet.gov/expapi/verbs/interacted"},
+        { Tracker.Verb.Used.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/verbs/used"}
+    };
+
+    private Dictionary<string, string> objectIds = new Dictionary<string, string>()
+    {
+        // Completable
+        { CompletableTracker.Completable.Game.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/serious-game" },
+        { CompletableTracker.Completable.Session.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/session"},
+        { CompletableTracker.Completable.Level.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/level"},
+        { CompletableTracker.Completable.Quest.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/quest"},
+        { CompletableTracker.Completable.Stage.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/stage"},
+        { CompletableTracker.Completable.Combat.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/combat"},
+        { CompletableTracker.Completable.StoryNode.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/story-node"},
+        { CompletableTracker.Completable.Race.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/race"},
+        { CompletableTracker.Completable.Completable.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/completable"},
+
+        // Acceesible
+        { AccessibleTracker.Accessible.Screen.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/screen" },
+        { AccessibleTracker.Accessible.Area.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/area"},
+        { AccessibleTracker.Accessible.Zone.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/zone"},
+        { AccessibleTracker.Accessible.Cutscene.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/cutscene"},
+        { AccessibleTracker.Accessible.Accessible.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/accessible"},
+
+        // Alternative
+        { AlternativeTracker.Alternative.Question.ToString().ToLower(), "http://adlnet.gov/expapi/activities/question" },
+        { AlternativeTracker.Alternative.Menu.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/menu"},
+        { AlternativeTracker.Alternative.Dialog.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/dialog-tree"},
+        { AlternativeTracker.Alternative.Path.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/path"},
+        { AlternativeTracker.Alternative.Arena.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/arena"},
+        { AlternativeTracker.Alternative.Alternative.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/alternative"},
+
+        // GameObject
+        { GameObjectTracker.TrackedGameObject.Enemy.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/enemy" },
+        { GameObjectTracker.TrackedGameObject.Npc.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/non-player-character"},
+        { GameObjectTracker.TrackedGameObject.Item.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/item"},
+        { GameObjectTracker.TrackedGameObject.GameObject.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/activity-types/game-object"}
+    };
+
+    private Dictionary<string, string> extensionIds = new Dictionary<string, string>()
+    {
+        { Tracker.Extension.Health.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/extensions/health"},
+        { Tracker.Extension.Position.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/extensions/position"},
+        { Tracker.Extension.Progress.ToString().ToLower(), "https://w3id.org/xapi/seriousgames/extensions/progress"}
+    };
+
+    private List<JSONNode> statements = new List<JSONNode> ();
 	private string objectId;
 	private JSONNode actor;

-	public void StartData (JSONNode data)
+public void StartData (JSONNode data)
 	{
 		actor = data ["actor"];
-		objectId = data ["objectId"].ToString ();
+		objectId = data ["objectId"].ToString();
 		if (!objectId.EndsWith ("/")) {
+            objectId = objectId.Replace("\"", "");
 			objectId += "/";
+            UnityEngine.Debug.Log("objectId::: " + objectId);
 		}
 	}

@@ -69,59 +120,102 @@
 		statement.Add ("verb", CreateVerb (parts [1]));

-		statement.Add ("object", CreateActivity (parts));
-
-		if (parts.Length > 3) {
-			JSONNode extensions = JSONNode.Parse ("{}");
-			JSONNode extensionsChild = JSONNode.Parse ("{}");
-			extensionsChild.Add (EXT_PREFIX + "value", parts [3]);
-
-			extensions.Add ("extensions", extensionsChild);
-
-			statement.Add ("result", extensions);
-		}
-
-		return statement;
+		statement.Add ("object", CreateObject(parts));
+
+		if (parts.Length > 4) {
+            // Parse extensions
+
+            int extCount = parts.Length - 4;
+            if(extCount > 0 && extCount % 2 == 0)
+            {
+                // Extensions come in <key, value> pairs
+
+                JSONNode extensions = JSONNode.Parse("{}");
+                JSONNode extensionsChild = null;
+
+                for (int i = 4; i < parts.Length; i+= 2)
+                {
+                    string key = parts[i];
+                    string value = parts[i + 1];
+                    if (key.Equals("") || value.Equals(""))
+                    {
+                        continue;
+                    }
+                    if (key.Equals(Tracker.Extension.Score.ToString().ToLower()))
+                    {
+
+                        JSONNode score = JSONNode.Parse("{\"raw\":}");
+                        float valueResult = 0f;
+                        float.TryParse(value, out valueResult);
+                        score["raw"] = new JSONData(valueResult);
+                        extensions.Add("score", score);
+                    }
+                    else if (key.Equals(Tracker.Extension.Success.ToString().ToLower()))
+                    {
+                        bool valueResult = false;
+                        bool.TryParse(value, out valueResult);
+                        extensions["success"] = new JSONData(valueResult);
+                    }
+                    else if (key.Equals(Tracker.Extension.Completion.ToString().ToLower()))
+                    {
+                        bool valueResult = false;
+                        bool.TryParse(value, out valueResult);
+                        extensions["completion"] = new JSONData(valueResult);
+                    }
+                    else if (key.Equals(Tracker.Extension.Response.ToString().ToLower()))
+                    {
+                        extensions["response"] = value;
+                    }
+                    else
+                    {
+                        if(extensionsChild == null)
+                        {
+                            extensionsChild = JSONNode.Parse("{}");
+                            extensions.Add("extensions", extensionsChild);
+                        }
+
+                        string id = key;
+                        extensionIds.TryGetValue(key, out id);
+
+                        extensionsChild.Add(id, JSONNode.Parse(value));
+                    }
+                }
+                statement.Add("result", extensions);
+            }
+		}
+
+        return statement;
 	}

 	private JSONNode CreateVerb (string ev)
 	{

-		string id;
-		if (CHOICE.Equals (ev)) {
-			id = "choose";
-		} else if (SCREEN.Equals (ev)) {
-			id = "viewed";
-		} else if (ZONE.Equals (ev)) {
-			id = "entered";
-		} else if (VAR.Equals (ev)) {
-			id = "updated";
-		} else {
-			id = ev;
-		}
-
-		JSONNode verb = JSONNode.Parse ("{ id : }");
-		verb ["id"] = VERB_PREFIX + id;
+        string id = ev;
+        verbIds.TryGetValue(ev, out id);
+
+		JSONNode verb = JSONNode.Parse ("{id: }");
+		verb ["id"] = id;

 		return verb;
 	}

-	private JSONNode CreateActivity (string[] parts)
-	{
-		string ev = parts [1];
-		string id;
-		if (CHOICE.Equals (ev)) {
-			id = "choice";
-		} else if (SCREEN.Equals (ev)) {
-			id = "screen";
-		} else if (ZONE.Equals (ev)) {
-			id = "zone";
-		} else if (VAR.Equals (ev)) {
-			id = "variable";
-		} else {
-			id = ev;
-		}
-		return JSONNode.Parse ("{ id : " + objectId + id + "/" + parts [2] + "}");
+	private JSONNode CreateObject (string[] parts)
+	{
+		string type = parts [2];
+
+        string id = parts[3];
+        string typeKey = type;
+        objectIds.TryGetValue(type, out typeKey);
+
+        JSONNode obj = JSONNode.Parse("{id: }");
+        obj["id"] = objectId + id;
+
+        JSONNode definition = JSONNode.Parse("{type: }");
+        definition["type"] = typeKey;
+
+        obj.Add("definition", definition);
+
+        return obj;
 	}
 }


fixish again

fixish again

made it so it doesn't make multiple paths over other existing paths,
next working on multiple paths.

--- Assets/Scripts/randomMap.cs
+++ Assets/Scripts/randomMap.cs
@@ -64,7 +64,8 @@
 			//Debug.Log("number of Paths: " + rooms[i].numOfPaths);
 			int dividedCorner = numberofCorners / 2;

-			for (int l = 0; l < 3; l++) {
+			//number of paths
+			for (int l = 0; l < 4; l++) {

 				//get last path Direction if not in first room
 				if (i > 1) {
@@ -90,13 +91,14 @@
 						break;
 					}
 				}
-				for (int k = 0; k < 2; k++) {
+				//number of corners
+				for (int k = 0; k < 4; k++) {
 					randomSize = Random.Range (4, lengthofCorridors);
 					for (int j = 0; j < randomSize - 1; j++) {

 						if (j == 0 && i == 0 && k == 0)
 							platform = Room1;
-						else if (j == 0) {
+						else if (j == 0 && k == 0) {
 							if (mapIndex.LastIndexOf("Plane(Clone) (UnityEngine.Transform)") == -1)
 								platform = transform.GetChild(mapIndex.LastIndexOf("Plane (UnityEngine.Transform)") );//GetChild (transform.childCount - 1 - totalRoomNodeOffsets);
 							else


test commit

test commit

commit for testing guthub client

--- Assets/scripts/util/Int2.cs
+++ Assets/scripts/util/Int2.cs
@@ -1,6 +1,7 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+

 public class Int2
 {


[Core] Deferred TokenizedStrings should not store their Parsed value ever - since they might be used many times with other modules with different Macro values in their strings. If the parsed value was written back, the same value would be used for all instances of them

--- Bam.Core/TokenizedString.cs
+++ Bam.Core/TokenizedString.cs
@@ -382,8 +382,14 @@
                         }
                         else
                         {
+                            // temporarily remove the deferred expansion flag to get a result - but don't commit this back as the parsed string
+                            // or it may not be useful in multiple scenarios, e.g. if a Tool has a deferred expansion string, with the Module using the Tool
+                            // defining one of the macros, then each Module may have a unique value for that macro - if the Tool had the value written back
+                            // as the parsed string, then the string will be considered expanded, and the same value will be used for all Modules
                             tokenString.Flags &= ~EFlags.DeferredExpansion;
-                            tokenString.ParsedString = tokenString.Parse((this.ModuleWithMacros != null) ? this.ModuleWithMacros.Macros : null);
+                            var result = tokenString.Parse((this.ModuleWithMacros != null) ? this.ModuleWithMacros.Macros : null);
+                            tokenString.Flags |= EFlags.DeferredExpansion;
+                            return result;
                         }
                     }
                     return tokenString.ToString();


Add method to get item by index as a specific type

--- BencodeNET/Objects/BList.cs
+++ BencodeNET/Objects/BList.cs
@@ -106,6 +106,17 @@
         }

         /// <summary>
+        /// Gets the object at the specified index as <typeparamref name="T"/>.
+        /// </summary>
+        /// <typeparam name="T">The type to cast the object to.</typeparam>
+        /// <param name="index">The index in the list to get the object from.</param>
+        /// <returns>The object at the specified index as the specified type or null if the object is not of that type.</returns>
+        public T Get<T>(int index) where T : class, IBObject
+        {
+            return this[index] as T;
+        }
+
+        /// <summary>
         /// Assumes all elements are <see cref="BString"/> and returns
         /// an enumerable of their string representation.
         /// </summary>


bringing hydra pr237 to sdk

bringing hydra pr237 to sdk

--- libraries/src/SchedulerManagement/SchedulerClient.cs
+++ libraries/src/SchedulerManagement/SchedulerClient.cs
@@ -453,39 +453,25 @@
     /// </summary>
     public partial class JobGetHistoryParameters
     {
-        private int? _skip;
-
-        /// <summary>
-        /// By default the top 100 history entries will be returned in a call
-        /// to GET job history. A maximum of 1000 history entries can be
-        /// returned in any call.  To get history entries beyond 1000 entries
-        /// use $skip.
-        /// </summary>
-        public int? Skip
+        private int _skip;
+
+        /// <summary>
+        /// Specify the (0-based) index of the history list from which to begin
+        /// requesting entries.
+        /// </summary>
+        public int Skip
         {
             get { return this._skip; }
             set { this._skip = value; }
         }

-        private Microsoft.WindowsAzure.Scheduler.Models.JobState? _state;
-
-        /// <summary>
-        /// Filter the job history to have it only return job histories of a
-        /// particular state.
-        /// </summary>
-        public Microsoft.WindowsAzure.Scheduler.Models.JobState? State
-        {
-            get { return this._state; }
-            set { this._state = value; }
-        }
-
-        private int? _top;
-
-        /// <summary>
-        /// To receive more or less than the default number of entries in a
-        /// call then use the $top OData operation.
-        /// </summary>
-        public int? Top
+        private int _top;
+
+        /// <summary>
+        /// Specify the number of history entries to request, in the of range
+        /// [1..100].
+        /// </summary>
+        public int Top
         {
             get { return this._top; }
             set { this._top = value; }
@@ -539,10 +525,27 @@
             return this.GetEnumerator();
         }

+        /// <summary>
+        /// A job history entry.
+        /// </summary>
         public partial class JobHistoryEntry
         {
+            private JobHistoryActionName _actionName;
+
+            /// <summary>
+            /// The action of this execution, MainAction or ErrorAction.
+            /// </summary>
+            public JobHistoryActionName ActionName
+            {
+                get { return this._actionName; }
+                set { this._actionName = value; }
+            }
+
             private DateTime _endTime;

+            /// <summary>
+            /// The time the execution attempt concluded.
+            /// </summary>
             public DateTime EndTime
             {
                 get { return this._endTime; }
@@ -551,6 +554,9 @@

             private string _id;

+            /// <summary>
+            /// The job id that this history entry is for.
+            /// </summary>
             public string Id
             {
                 get { return this._id; }
@@ -559,6 +565,9 @@

             private string _message;

+            /// <summary>
+            /// A description of the result of the execution attempt.
+            /// </summary>
             public string Message
             {
                 get { return this._message; }
@@ -567,14 +576,42 @@

             private int _recordNumber;

+            /// <summary>
+            /// The zero-based index of the history entry.
+            /// </summary>
             public int RecordNumber
             {
                 get { return this._recordNumber; }
                 set { this._recordNumber = value; }
+            }
+
+            private int _repeatCount;
+
+            /// <summary>
+            /// The occurrence count of this execution.
+            /// </summary>
+            public int RepeatCount
+            {
+                get { return this._repeatCount; }
+                set { this._repeatCount = value; }
+            }
+
+            private int _retryCount;
+
+            /// <summary>
+            /// The retry count of this occurrence.
+            /// </summary>
+            public int RetryCount
+            {
+                get { return this._retryCount; }
+                set { this._retryCount = value; }
             }

             private DateTime _startTime;

+            /// <summary>
+            /// The time the execution attempt began.
+            /// </summary>
             public DateTime StartTime
             {
                 get { return this._startTime; }
@@ -583,14 +620,31 @@

             private JobState _state;

+            /// <summary>
+            /// The state of the job: enabled, disabled, faulted, or completed.
+            /// </summary>
             public JobState State
             {
                 get { return this._state; }
                 set { this._state = value; }
+            }
+
+            private JobHistoryStatus _status;
+
+            /// <summary>
+            /// The status of this execution attempt, completed or failed.
+            /// </summary>
+            public JobHistoryStatus Status
+            {
+                get { return this._status; }
+                set { this._status = value; }
             }

             private DateTime _timestamp;

+            /// <summary>
+            /// The time the execution attempt began.
+            /// </summary>
             public DateTime Timestamp
             {
                 get { return this._timestamp; }
@@ -603,6 +657,32 @@
             public JobHistoryEntry()
             {
             }
+        }
+    }
+
+    /// <summary>
+    /// Parameters supplied to the Get Job History With Filter operation.
+    /// </summary>
+    public partial class JobGetHistoryWithFilterParameters : JobGetHistoryParameters
+    {
+        private JobHistoryStatus _status;
+
+        /// <summary>
+        /// Filter the job history to have it only return job execution
+        /// attempts having a particular Status, 'completed' or 'failed'.
+        /// </summary>
+        public JobHistoryStatus Status
+        {
+            get { return this._status; }
+            set { this._status = value; }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the JobGetHistoryWithFilterParameters
+        /// class.
+        /// </summary>
+        public JobGetHistoryWithFilterParameters()
+        {
         }
     }

@@ -628,6 +708,38 @@
         public JobGetResponse()
         {
         }
+    }
+
+    /// <summary>
+    /// The action of this execution, MainAction or ErrorAction.
+    /// </summary>
+    public enum JobHistoryActionName
+    {
+        /// <summary>
+        /// An execution attempt of the primary action.
+        /// </summary>
+        MainAction = 0,
+
+        /// <summary>
+        /// An execution attempt of the error action.
+        /// </summary>
+        ErrorAction = 1,
+    }
+
+    /// <summary>
+    /// The status of this execution attempt, completed or failed.
+    /// </summary>
+    public enum JobHistoryStatus
+    {
+        /// <summary>
+        /// A completed execution attempt.
+        /// </summary>
+        Completed = 0,
+
+        /// <summary>
+        /// A failed execution attempt.
+        /// </summary>
+        Failed = 1,
     }

     /// <summary>
@@ -1198,6 +1310,25 @@
         }
     }

+    public partial class PatchJobCollectionJobsUpdateStateParameters
+    {
+        private Patchable<JobState> _state;
+
+        public Patchable<JobState> State
+        {
+            get { return this._state; }
+            set { this._state = value; }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the
+        /// PatchJobCollectionJobsUpdateStateParameters class.
+        /// </summary>
+        public PatchJobCollectionJobsUpdateStateParameters()
+        {
+        }
+    }
+
     /// <summary>
     /// Retry Policy for the job action.
     /// </summary>
@@ -1445,6 +1576,94 @@
         }

         /// <summary>
+        /// Parse enum values for type JobHistoryActionName.
+        /// </summary>
+        /// <param name='value'>
+        /// The value to parse.
+        /// </param>
+        /// <returns>
+        /// The enum value.
+        /// </returns>
+        internal static JobHistoryActionName ParseJobHistoryActionName(string value)
+        {
+            if (value == "MainAction")
+            {
+                return JobHistoryActionName.MainAction;
+            }
+            if (value == "ErrorAction")
+            {
+                return JobHistoryActionName.ErrorAction;
+            }
+            throw new ArgumentOutOfRangeException("value");
+        }
+
+        /// <summary>
+        /// Convert an enum of type JobHistoryActionName to a string.
+        /// </summary>
+        /// <param name='value'>
+        /// The value to convert to a string.
+        /// </param>
+        /// <returns>
+        /// The enum value as a string.
+        /// </returns>
+        internal static string JobHistoryActionNameToString(JobHistoryActionName value)
+        {
+            if (value == JobHistoryActionName.MainAction)
+            {
+                return "MainAction";
+            }
+            if (value == JobHistoryActionName.ErrorAction)
+            {
+                return "ErrorAction";
+            }
+            throw new ArgumentOutOfRangeException("value");
+        }
+
+        /// <summary>
+        /// Parse enum values for type JobHistoryStatus.
+        /// </summary>
+        /// <param name='value'>
+        /// The value to parse.
+        /// </param>
+        /// <returns>
+        /// The enum value.
+        /// </returns>
+        internal static JobHistoryStatus ParseJobHistoryStatus(string value)
+        {
+            if (value == "completed")
+            {
+                return JobHistoryStatus.Completed;
+            }
+            if (value == "failed")
+            {
+                return JobHistoryStatus.Failed;
+            }
+            throw new ArgumentOutOfRangeException("value");
+        }
+
+        /// <summary>
+        /// Convert an enum of type JobHistoryStatus to a string.
+        /// </summary>
+        /// <param name='value'>
+        /// The value to convert to a string.
+        /// </param>
+        /// <returns>
+        /// The enum value as a string.
+        /// </returns>
+        internal static string JobHistoryStatusToString(JobHistoryStatus value)
+        {
+            if (value == JobHistoryStatus.Completed)
+            {
+                return "completed";
+            }
+            if (value == JobHistoryStatus.Failed)
+            {
+                return "failed";
+            }
+            throw new ArgumentOutOfRangeException("value");
+        }
+
+        /// <summary>
         /// Parse enum values for type JobRecurrenceFrequency.
         /// </summary>
         /// <param name='value'>
@@ -1795,6 +2014,23 @@
         Task<JobGetHistoryResponse> GetHistoryAsync(string jobId, JobGetHistoryParameters parameters, CancellationToken cancellationToken);

         /// <summary>
+        /// Job history tracks the updates and executions of a job.
+        /// </summary>
+        /// <param name='jobId'>
+        /// Id of the job to get the history of.
+        /// </param>
+        /// <param name='parameters'>
+        /// Parameters supplied to the Get Job History With Filter operation.
+        /// </param>
+        /// <param name='cancellationToken'>
+        /// Cancellation token.
+        /// </param>
+        /// <returns>
+        /// The Get Job History operation response.
+        /// </returns>
+        Task<JobGetHistoryResponse> GetHistoryWithFilterAsync(string jobId, JobGetHistoryWithFilterParameters parameters, CancellationToken cancellationToken);
+
+        /// <summary>
         /// Fetch all jobs in a job collection.
         /// </summary>
         /// <param name='parameters'>
@@ -1823,7 +2059,7 @@
         /// <returns>
         /// The Update Jobs State operation response.
         /// </returns>
-        Task<JobCollectionJobsUpdateStateResponse> UpdateJobCollectionStateAsync(JobCollectionJobsUpdateStateParameters parameters, CancellationToken cancellationToken);
+        Task<JobCollectionJobsUpdateStateResponse> UpdateJobCollectionStateAsync(PatchJobCollectionJobsUpdateStateParameters parameters, CancellationToken cancellationToken);

         /// <summary>
         /// Jobs can be updated through a simple PATCH operation to a job's
@@ -2115,6 +2351,60 @@
         }

         /// <summary>
+        /// Job history tracks the updates and executions of a job.
+        /// </summary>
+        /// <param name='operations'>
+        /// Reference to the Microsoft.WindowsAzure.Scheduler.IJobOperations.
+        /// </param>
+        /// <param name='jobId'>
+        /// Id of the job to get the history of.
+        /// </param>
+        /// <param name='parameters'>
+        /// Parameters supplied to the Get Job History With Filter operation.
+        /// </param>
+        /// <returns>
+        /// The Get Job History operation response.
+        /// </returns>
+        public static JobGetHistoryResponse GetHistoryWithFilter(this IJobOperations operations, string jobId, JobGetHistoryWithFilterParameters parameters)
+        {
+            try
+            {
+                return operations.GetHistoryWithFilterAsync(jobId, parameters).Result;
+            }
+            catch (AggregateException ex)
+            {
+                if (ex.InnerExceptions.Count > 1)
+                {
+                    throw;
+                }
+                else
+                {
+                    throw ex.InnerException;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Job history tracks the updates and executions of a job.
+        /// </summary>
+        /// <param name='operations'>
+        /// Reference to the Microsoft.WindowsAzure.Scheduler.IJobOperations.
+        /// </param>
+        /// <param name='jobId'>
+        /// Id of the job to get the history of.
+        /// </param>
+        /// <param name='parameters'>
+        /// Parameters supplied to the Get Job History With Filter operation.
+        /// </param>
+        /// <returns>
+        /// The Get Job History operation response.
+        /// </returns>
+        public static Task<JobGetHistoryResponse> GetHistoryWithFilterAsync(this IJobOperations operations, string jobId, JobGetHistoryWithFilterParameters parameters)
+        {
+            return operations.GetHistoryWithFilterAsync(jobId, parameters, CancellationToken.None);
+        }
+
+        /// <summary>
         /// Fetch all jobs in a job collection.
         /// </summary>
         /// <param name='operations'>
@@ -2177,7 +2467,7 @@
         /// <returns>
         /// The Update Jobs State operation response.
         /// </returns>
-        public static JobCollectionJobsUpdateStateResponse UpdateJobCollectionState(this IJobOperations operations, JobCollectionJobsUpdateStateParameters parameters)
+        public static JobCollectionJobsUpdateStateResponse UpdateJobCollectionState(this IJobOperations operations, PatchJobCollectionJobsUpdateStateParameters parameters)
         {
             try
             {
@@ -2211,7 +2501,7 @@
         /// <returns>
         /// The Update Jobs State operation response.
         /// </returns>
-        public static Task<JobCollectionJobsUpdateStateResponse> UpdateJobCollectionStateAsync(this IJobOperations operations, JobCollectionJobsUpdateStateParameters parameters)
+        public static Task<JobCollectionJobsUpdateStateResponse> UpdateJobCollectionStateAsync(this IJobOperations operations, PatchJobCollectionJobsUpdateStateParameters parameters)
         {
             return operations.UpdateJobCollectionStateAsync(parameters, CancellationToken.None);
         }
@@ -4585,19 +4875,7 @@
             }

             // Construct URL
-            string url = this.Client.BaseUri + this.Client.Credentials.SubscriptionId + "/cloudservices/" + this.Client.CloudServiceName + "/resources/scheduler/~/JobCollections/" + this.Client.JobCollectionName + "/jobs/" + jobId + "/history?api-version=2013-10-31_Preview";
-            if (parameters.State != null)
-            {
-                url = url + "&state=" + Uri.EscapeUriString(SchedulerClient.JobStateToString(parameters.State.Value));
-            }
-            if (parameters.Skip != null)
-            {
-                url = url + "&$skip=" + Uri.EscapeUriString(parameters.Skip.Value.ToString());
-            }
-            if (parameters.Top != null)
-            {
-                url = url + "&$top=" + Uri.EscapeUriString(parameters.Top.Value.ToString());
-            }
+            string url = this.Client.BaseUri + this.Client.Credentials.SubscriptionId + "/cloudservices/" + this.Client.CloudServiceName + "/resources/scheduler/~/JobCollections/" + this.Client.JobCollectionName + "/jobs/" + jobId + "/history?api-version=2013-10-31_Preview&$skip=" + parameters.Skip + "&$top=" + parameters.Top;

             // Create HTTP transport objects
             HttpRequestMessage httpRequest = null;
@@ -4708,6 +4986,240 @@
                             {
                                 string messageInstance = (string)messageValue;
                                 jobHistoryEntryInstance.Message = messageInstance;
+                            }
+
+                            JToken statusValue = jobHistoryValue["status"];
+                            if (statusValue != null)
+                            {
+                                JobHistoryStatus statusInstance = SchedulerClient.ParseJobHistoryStatus((string)statusValue);
+                                jobHistoryEntryInstance.Status = statusInstance;
+                            }
+
+                            JToken actionNameValue = jobHistoryValue["actionName"];
+                            if (actionNameValue != null)
+                            {
+                                JobHistoryActionName actionNameInstance = SchedulerClient.ParseJobHistoryActionName((string)actionNameValue);
+                                jobHistoryEntryInstance.ActionName = actionNameInstance;
+                            }
+
+                            JToken repeatCountValue = jobHistoryValue["repeatCount"];
+                            if (repeatCountValue != null)
+                            {
+                                int repeatCountInstance = (int)repeatCountValue;
+                                jobHistoryEntryInstance.RepeatCount = repeatCountInstance;
+                            }
+
+                            JToken retryCountValue = jobHistoryValue["retryCount"];
+                            if (retryCountValue != null)
+                            {
+                                int retryCountInstance = (int)retryCountValue;
+                                jobHistoryEntryInstance.RetryCount = retryCountInstance;
+                            }
+                        }
+                    }
+
+                    if (shouldTrace)
+                    {
+                        Tracing.Exit(invocationId, result);
+                    }
+                    return result;
+                }
+                finally
+                {
+                    if (httpResponse != null)
+                    {
+                        httpResponse.Dispose();
+                    }
+                }
+            }
+            finally
+            {
+                if (httpRequest != null)
+                {
+                    httpRequest.Dispose();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Job history tracks the updates and executions of a job.
+        /// </summary>
+        /// <param name='jobId'>
+        /// Id of the job to get the history of.
+        /// </param>
+        /// <param name='parameters'>
+        /// Parameters supplied to the Get Job History With Filter operation.
+        /// </param>
+        /// <param name='cancellationToken'>
+        /// Cancellation token.
+        /// </param>
+        /// <returns>
+        /// The Get Job History operation response.
+        /// </returns>
+        public async Task<JobGetHistoryResponse> GetHistoryWithFilterAsync(string jobId, JobGetHistoryWithFilterParameters parameters, CancellationToken cancellationToken)
+        {
+            // Validate
+            if (jobId == null)
+            {
+                throw new ArgumentNullException("jobId");
+            }
+            if (parameters == null)
+            {
+                throw new ArgumentNullException("parameters");
+            }
+
+            // Tracing
+            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
+            string invocationId = null;
+            if (shouldTrace)
+            {
+                invocationId = Tracing.NextInvocationId.ToString();
+                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
+                tracingParameters.Add("jobId", jobId);
+                tracingParameters.Add("parameters", parameters);
+                Tracing.Enter(invocationId, this, "GetHistoryWithFilterAsync", tracingParameters);
+            }
+
+            // Construct URL
+            string url = this.Client.BaseUri + this.Client.Credentials.SubscriptionId + "/cloudservices/" + this.Client.CloudServiceName + "/resources/scheduler/~/JobCollections/" + this.Client.JobCollectionName + "/jobs/" + jobId + "/history?api-version=2013-10-31_Preview&$filter=status eq " + parameters.Status + "&$skip=" + parameters.Skip + "&$top=" + parameters.Top;
+
+            // Create HTTP transport objects
+            HttpRequestMessage httpRequest = null;
+            try
+            {
+                httpRequest = new HttpRequestMessage();
+                httpRequest.Method = HttpMethod.Get;
+                httpRequest.RequestUri = new Uri(url);
+
+                // Set Headers
+                httpRequest.Headers.Add("x-ms-version", "2013-03-01");
+
+                // Set Credentials
+                cancellationToken.ThrowIfCancellationRequested();
+                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);
+
+                // Send Request
+                HttpResponseMessage httpResponse = null;
+                try
+                {
+                    if (shouldTrace)
+                    {
+                        Tracing.SendRequest(invocationId, httpRequest);
+                    }
+                    cancellationToken.ThrowIfCancellationRequested();
+                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
+                    if (shouldTrace)
+                    {
+                        Tracing.ReceiveResponse(invocationId, httpResponse);
+                    }
+                    HttpStatusCode statusCode = httpResponse.StatusCode;
+                    if (statusCode != HttpStatusCode.OK)
+                    {
+                        cancellationToken.ThrowIfCancellationRequested();
+                        CloudException ex = CloudException.CreateFromJson(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false));
+                        if (shouldTrace)
+                        {
+                            Tracing.Error(invocationId, ex);
+                        }
+                        throw ex;
+                    }
+
+                    // Create Result
+                    JobGetHistoryResponse result = new JobGetHistoryResponse();
+                    result.StatusCode = statusCode;
+                    if (httpResponse.Headers.Contains("x-ms-request-id"))
+                    {
+                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
+                    }
+
+                    // Deserialize Response
+                    cancellationToken.ThrowIfCancellationRequested();
+                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
+                    JToken responseDoc = JToken.Parse(responseContent);
+
+                    JArray jobHistoryArray = (JArray)responseDoc;
+                    if (jobHistoryArray != null)
+                    {
+                        foreach (JToken jobHistoryValue in jobHistoryArray)
+                        {
+                            JobGetHistoryResponse.JobHistoryEntry jobHistoryEntryInstance = new JobGetHistoryResponse.JobHistoryEntry();
+                            result.JobHistory.Add(jobHistoryEntryInstance);
+
+                            JToken jobIdValue = jobHistoryValue["jobId"];
+                            if (jobIdValue != null)
+                            {
+                                string jobIdInstance = (string)jobIdValue;
+                                jobHistoryEntryInstance.Id = jobIdInstance;
+                            }
+
+                            JToken recordNumberValue = jobHistoryValue["recordNumber"];
+                            if (recordNumberValue != null)
+                            {
+                                int recordNumberInstance = (int)recordNumberValue;
+                                jobHistoryEntryInstance.RecordNumber = recordNumberInstance;
+                            }
+
+                            JToken timestampValue = jobHistoryValue["timestamp"];
+                            if (timestampValue != null)
+                            {
+                                DateTime timestampInstance = (DateTime)timestampValue;
+                                jobHistoryEntryInstance.Timestamp = timestampInstance;
+                            }
+
+                            JToken startTimeValue = jobHistoryValue["startTime"];
+                            if (startTimeValue != null)
+                            {
+                                DateTime startTimeInstance = (DateTime)startTimeValue;
+                                jobHistoryEntryInstance.StartTime = startTimeInstance;
+                            }
+
+                            JToken endTimeValue = jobHistoryValue["endTime"];
+                            if (endTimeValue != null)
+                            {
+                                DateTime endTimeInstance = (DateTime)endTimeValue;
+                                jobHistoryEntryInstance.EndTime = endTimeInstance;
+                            }
+
+                            JToken stateValue = jobHistoryValue["state"];
+                            if (stateValue != null)
+                            {
+                                JobState stateInstance = SchedulerClient.ParseJobState((string)stateValue);
+                                jobHistoryEntryInstance.State = stateInstance;
+                            }
+
+                            JToken messageValue = jobHistoryValue["message"];
+                            if (messageValue != null)
+                            {
+                                string messageInstance = (string)messageValue;
+                                jobHistoryEntryInstance.Message = messageInstance;
+                            }
+
+                            JToken statusValue = jobHistoryValue["status"];
+                            if (statusValue != null)
+                            {
+                                JobHistoryStatus statusInstance = SchedulerClient.ParseJobHistoryStatus((string)statusValue);
+                                jobHistoryEntryInstance.Status = statusInstance;
+                            }
+
+                            JToken actionNameValue = jobHistoryValue["actionName"];
+                            if (actionNameValue != null)
+                            {
+                                JobHistoryActionName actionNameInstance = SchedulerClient.ParseJobHistoryActionName((string)actionNameValue);
+                                jobHistoryEntryInstance.ActionName = actionNameInstance;
+                            }
+
+                            JToken repeatCountValue = jobHistoryValue["repeatCount"];
+                            if (repeatCountValue != null)
+                            {
+                                int repeatCountInstance = (int)repeatCountValue;
+                                jobHistoryEntryInstance.RepeatCount = repeatCountInstance;
+                            }
+
+                            JToken retryCountValue = jobHistoryValue["retryCount"];
+                            if (retryCountValue != null)
+                            {
+                                int retryCountInstance = (int)retryCountValue;
+                                jobHistoryEntryInstance.RetryCount = retryCountInstance;
                             }
                         }
                     }
@@ -5261,7 +5773,7 @@
         /// <returns>
         /// The Update Jobs State operation response.
         /// </returns>
-        public async Task<JobCollectionJobsUpdateStateResponse> UpdateJobCollectionStateAsync(JobCollectionJobsUpdateStateParameters parameters, CancellationToken cancellationToken)
+        public async Task<JobCollectionJobsUpdateStateResponse> UpdateJobCollectionStateAsync(PatchJobCollectionJobsUpdateStateParameters parameters, CancellationToken cancellationToken)
         {
             // Validate
             if (parameters == null)
@@ -5305,8 +5817,11 @@
                 JObject jobCollectionJobsUpdateStateParametersValue = new JObject();
                 requestDoc = jobCollectionJobsUpdateStateParametersValue;

-                JToken stateValue = SchedulerClient.JobStateToString(parameters.State);
-                jobCollectionJobsUpdateStateParametersValue["state"] = stateValue;
+                if (parameters.State.IsIncluded)
+                {
+                    JToken stateValue = SchedulerClient.JobStateToString(parameters.State);
+                    jobCollectionJobsUpdateStateParametersValue["state"] = stateValue;
+                }

                 requestContent = requestDoc.ToString(Formatting.Indented);
                 httpRequest.Content = new StringContent(requestContent, Encoding.UTF8);


Fix calculation of total contract rewards

--- Source/contractContainer.cs
+++ Source/contractContainer.cs
@@ -151,22 +151,22 @@
 			decPen = HighLogic.CurrentGame.Parameters.Career.RepLossDeclined;
 			decPenString = decPen.ToString("F0");

+			//Generate four layers of parameters
+			for (int i = 0; i < c.ParameterCount; i++)
+			{
+				ContractParameter param = c.GetParameter(i);
+
+				if (param == null)
+					continue;
+
+				addContractParam(param, 0);
+			}
+
 			totalFundsReward = rewards();
 			totalFundsPenalty = penalties();
 			totalRepReward = repRewards();
 			totalSciReward = sciRewards();
 			totalRepPenalty = repPenalties();
-
-			//Generate four layers of parameters
-			for (int i = 0; i < c.ParameterCount; i++)
-			{
-				ContractParameter param = c.GetParameter(i);
-
-				if (param == null)
-					continue;
-
-				addContractParam(param, 0);
-			}

 			CelestialBody t = getTargetBody();


implemented DecodeMultiple

implemented DecodeMultiple

git-svn-id: 98f681d7a2907ee2a41df434552134740bcc8829@80973 81fbe566-5dc4-48c1-bdea-7421811ca204

--- Source/lib/BarcodeReader.cs
+++ Source/lib/BarcodeReader.cs
@@ -9,6 +9,8 @@
 #endif

 using ZXing.Common;
+using ZXing.Multi;
+using ZXing.Multi.QrCode;

 namespace ZXing
 {
@@ -36,9 +38,9 @@
       private readonly IDictionary<DecodeHintType, object> hints;
 #if !SILVERLIGHT
 #if !UNITY
-      private Func<Bitmap, LuminanceSource> createLuminanceSource;
-#else
-      private Func<byte[], int, int, LuminanceSource> createLuminanceSource;
+      private readonly Func<Bitmap, LuminanceSource> createLuminanceSource;
+#else
+      private readonly Func<byte[], int, int, LuminanceSource> createLuminanceSource;
 #endif
 #else
       private readonly Func<WriteableBitmap, LuminanceSource> createLuminanceSource;
@@ -448,7 +450,75 @@
       public Result[] DecodeMultiple(WriteableBitmap barcodeBitmap)
 #endif
       {
-         throw new NotImplementedException();
+#if !UNITY
+         if (barcodeBitmap == null)
+            throw new ArgumentNullException("barcodeBitmap");
+#else
+         if (rawRGB == null)
+            throw new ArgumentNullException("rawRGB");
+#endif
+
+         var results = default(Result[]);
+#if !UNITY
+         var luminanceSource = CreateLuminanceSource(barcodeBitmap);
+#else
+         var luminanceSource = CreateLuminanceSource(rawRGB, width, height);
+#endif
+         var binarizer = CreateBinarizer(luminanceSource);
+         var binaryBitmap = new BinaryBitmap(binarizer);
+         var rotationCount = 0;
+         var rotationMaxCount = AutoRotate ? 4 : 1;
+         MultipleBarcodeReader multiReader = null;
+
+         var formats = PossibleFormats;
+         if (formats != null &&
+             formats.Count == 1 &&
+             formats.Contains(BarcodeFormat.QR_CODE))
+         {
+            multiReader = new QRCodeMultiReader();
+         }
+         else
+         {
+            multiReader = new GenericMultipleBarcodeReader(Reader);
+         }
+
+         for (; rotationCount < rotationMaxCount; rotationCount++)
+         {
+            results = multiReader.decodeMultiple(binaryBitmap, hints);
+
+            if (results != null ||
+                !luminanceSource.RotateSupported ||
+                !AutoRotate)
+               break;
+
+            binaryBitmap = new BinaryBitmap(CreateBinarizer(luminanceSource.rotateCounterClockwise()));
+         }
+
+         if (results != null)
+         {
+            foreach (var result in results)
+            {
+               if (result.ResultMetadata == null)
+               {
+                  result.putMetadata(ResultMetadataType.ORIENTATION, rotationCount*90);
+               }
+               else if (!result.ResultMetadata.ContainsKey(ResultMetadataType.ORIENTATION))
+               {
+                  result.ResultMetadata[ResultMetadataType.ORIENTATION] = rotationCount*90;
+               }
+               else
+               {
+                  // perhaps the core decoder rotates the image already (can happen if TryHarder is specified)
+                  result.ResultMetadata[ResultMetadataType.ORIENTATION] =
+                     ((int) (result.ResultMetadata[ResultMetadataType.ORIENTATION]) + rotationCount*90)%360;
+               }
+
+               if (ResultFound != null)
+                  ResultFound(result);
+            }
+         }
+
+         return results;
       }
    }
 }


Updated JSON Date Serailizer to use reader.Value in hopes of working

--- CarTracker/CarTracker.Web/Util/JsonDateEpochConverter.cs
+++ CarTracker/CarTracker.Web/Util/JsonDateEpochConverter.cs
@@ -17,7 +17,7 @@
         public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue,
             JsonSerializer serializer)
         {
-            long milliseconds = Convert.ToInt64(reader.ReadAsString());
+            long milliseconds = Convert.ToInt64(reader.Value.ToString());
             return DateTimeOffset.FromUnixTimeMilliseconds(milliseconds).DateTime;
         }
     }


Added URL encoding of sp data.

Added URL encoding of sp data.

--- ChalmersxTools/Controllers/PresentationToolController.cs
+++ ChalmersxTools/Controllers/PresentationToolController.cs
@@ -180,11 +180,11 @@
                     CourseOrg = session.CourseOrg,
                     CourseId = session.CourseId,
                     CourseRun = session.CourseRun,
-                    Name = Request.Form["name"].ToString(),
-                    LocationName = Request.Form["location"].ToString(),
+                    Name = Server.UrlEncode(Request.Form["name"].ToString()),
+                    LocationName = Server.UrlEncode(Request.Form["location"].ToString()),
                     LocationLat = Double.Parse(Request.Form["latitude"].ToString(), CultureInfo.InvariantCulture),
                     LocationLong = Double.Parse(Request.Form["longitude"].ToString(), CultureInfo.InvariantCulture),
-                    Presentation = Request.Form["presentation"].ToString()
+                    Presentation = Server.UrlEncode(Request.Form["presentation"].ToString())
                 });

                 dbContext.SaveChanges();
@@ -214,11 +214,11 @@
                      sp.CourseRun == session.CourseRun
                      select sp).SingleOrDefault();

-                existingStudentPresentation.Name = Request.Form["name"].ToString();
-                existingStudentPresentation.LocationName = Request.Form["location"].ToString();
+                existingStudentPresentation.Name = Server.UrlEncode(Request.Form["name"].ToString());
+                existingStudentPresentation.LocationName = Server.UrlEncode(Request.Form["location"].ToString());
                 existingStudentPresentation.LocationLat = Double.Parse(Request.Form["latitude"].ToString(), CultureInfo.InvariantCulture);
                 existingStudentPresentation.LocationLong = Double.Parse(Request.Form["longitude"].ToString(), CultureInfo.InvariantCulture);
-                existingStudentPresentation.Presentation = Request.Form["presentation"].ToString();
+                existingStudentPresentation.Presentation = Server.UrlEncode(Request.Form["presentation"].ToString());

                 dbContext.SaveChanges();
             }


IsCorsEnabled should be true in most cases where IsStandard is true (we default IsStandard to true) Default IsSecure = true - seems like a logical default

--- CefSharp/CefCustomScheme.cs
+++ CefSharp/CefCustomScheme.cs
@@ -83,7 +83,7 @@

         /// <summary>
         /// If true the scheme can be sent CORS requests.
-        /// This value should be true in most cases where IsStandard| is true.
+        /// This value should be true in most cases where IsStandard is true.
         /// </summary>
         public bool IsCorsEnabled { get; set; }

@@ -101,8 +101,8 @@
             IsStandard = true;
             IsLocal = false;
             IsDisplayIsolated = false;
-            IsSecure = false;
-            IsCorsEnabled = false;
+            IsSecure = true;
+            IsCorsEnabled = true;
         }

         /// <summary>


Make MimeType directly settable - think that's the last change required to make it flexible

--- CefSharp/ResourceHandler.cs
+++ CefSharp/ResourceHandler.cs
@@ -24,7 +24,7 @@
         /// Gets or sets the Mime Type.
         /// </summary>
         /// <value>The Mime Type.</value>
-        public string MimeType { get; private set; }
+        public string MimeType { get; set; }

         /// <summary>
         /// Gets or sets the resource stream.


Update ResourceHandler.cs

Update ResourceHandler.cs

Added override for passing in the file ext to correctly set the correct mime type

--- CefSharp/ResourceHandler.cs
+++ CefSharp/ResourceHandler.cs
@@ -1,21 +1,49 @@
-// Copyright © 2010-2014 The CefSharp Authors. All rights reserved.
+// Copyright © 2010-2014 The CefSharp Authors. All rights reserved.
 //
 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

+using System;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.IO;
 using System.Text;

 namespace CefSharp
 {
+    /// <summary>
+    /// Class ResourceHandler.
+    /// </summary>
     public class ResourceHandler
     {
-        public string MimeType { get; set; }
-        public Stream Stream { get; set; }
-        public int StatusCode { get; set; }
-        public string StatusText { get; set; }
-        public NameValueCollection Headers { get; set; }
-
+        /// <summary>
+        /// Gets or sets the type of MIME.
+        /// </summary>
+        /// <value>The type of MIME.</value>
+        public string MimeType { get; private set; }
+        /// <summary>
+        /// Gets or sets the resource stream.
+        /// </summary>
+        /// <value>The stream.</value>
+        public Stream Stream { get; private set; }
+        /// <summary>
+        /// Gets or sets the http status code.
+        /// </summary>
+        /// <value>The http status code.</value>
+        public int StatusCode { get; private set; }
+        /// <summary>
+        /// Gets or sets the status text.
+        /// </summary>
+        /// <value>The status text.</value>
+        public string StatusText { get; private set; }
+        /// <summary>
+        /// Gets or sets the headers.
+        /// </summary>
+        /// <value>The headers.</value>
+        public NameValueCollection Headers { get; private set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ResourceHandler"/> class.
+        /// </summary>
         public ResourceHandler()
         {
             StatusCode = 200;
@@ -23,14 +51,644 @@
             MimeType = "text/html";
         }

+        /// <summary>
+        /// Initializes a new instance of the <see cref="ResourceHandler"/> class.
+        /// </summary>
+        /// <param name="mimeType">Type of MIME.</param>
+        public ResourceHandler(string mimeType)
+        {
+            StatusCode = 200;
+            StatusText = "OK";
+            MimeType = mimeType;
+        }
+
+        /// <summary>
+        /// Gets the resource from the file.
+        /// </summary>
+        /// <param name="fileName">Location of the file.</param>
+        /// <returns>ResourceHandler.</returns>
         public static ResourceHandler FromFileName(string fileName)
         {
             return new ResourceHandler { Stream = File.OpenRead(fileName) };
         }

+        /// <summary>
+        /// Gets the resource from the file.
+        /// </summary>
+        /// <param name="fileName">Location of the file.</param>
+        /// <param name="fileExtension">The file extension.</param>
+        /// <returns>ResourceHandler.</returns>
+        public static ResourceHandler FromFileName(string fileName, string fileExtension)
+        {
+            return new ResourceHandler(GetMimeType(fileExtension)) { Stream = File.OpenRead(fileName) };
+        }
+
+        /// <summary>
+        /// Gets the resource from the string.
+        /// </summary>
+        /// <param name="text">The text.</param>
+        /// <returns>ResourceHandler.</returns>
         public static ResourceHandler FromString(string text)
         {
             return new ResourceHandler { Stream = new MemoryStream(Encoding.UTF8.GetBytes(text)) };
+        }
+
+        /// <summary>
+        /// Gets the resource from the string.
+        /// </summary>
+        /// <param name="text">The text.</param>
+        /// <param name="fileExtension">The file extension.</param>
+        /// <returns>ResourceHandler.</returns>
+        public static ResourceHandler FromString(string text, string fileExtension)
+        {
+            return new ResourceHandler(GetMimeType(fileExtension)) { Stream = new MemoryStream(Encoding.UTF8.GetBytes(text)) };
+        }
+
+        private static readonly IDictionary<string, string> Mappings = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
+        {
+
+        // Combination of values from Windows 7 Registry and  C:\Windows\System32\inetsrv\config\applicationHost.config
+        {".323", "text/h323"},
+        {".3g2", "video/3gpp2"},
+        {".3gp", "video/3gpp"},
+        {".3gp2", "video/3gpp2"},
+        {".3gpp", "video/3gpp"},
+        {".7z", "application/x-7z-compressed"},
+        {".aa", "audio/audible"},
+        {".AAC", "audio/aac"},
+        {".aaf", "application/octet-stream"},
+        {".aax", "audio/vnd.audible.aax"},
+        {".ac3", "audio/ac3"},
+        {".aca", "application/octet-stream"},
+        {".accda", "application/msaccess.addin"},
+        {".accdb", "application/msaccess"},
+        {".accdc", "application/msaccess.cab"},
+        {".accde", "application/msaccess"},
+        {".accdr", "application/msaccess.runtime"},
+        {".accdt", "application/msaccess"},
+        {".accdw", "application/msaccess.webapplication"},
+        {".accft", "application/msaccess.ftemplate"},
+        {".acx", "application/internet-property-stream"},
+        {".AddIn", "text/xml"},
+        {".ade", "application/msaccess"},
+        {".adobebridge", "application/x-bridge-url"},
+        {".adp", "application/msaccess"},
+        {".ADT", "audio/vnd.dlna.adts"},
+        {".ADTS", "audio/aac"},
+        {".afm", "application/octet-stream"},
+        {".ai", "application/postscript"},
+        {".aif", "audio/x-aiff"},
+        {".aifc", "audio/aiff"},
+        {".aiff", "audio/aiff"},
+        {".air", "application/vnd.adobe.air-application-installer-package+zip"},
+        {".amc", "application/x-mpeg"},
+        {".application", "application/x-ms-application"},
+        {".art", "image/x-jg"},
+        {".asa", "application/xml"},
+        {".asax", "application/xml"},
+        {".ascx", "application/xml"},
+        {".asd", "application/octet-stream"},
+        {".asf", "video/x-ms-asf"},
+        {".ashx", "application/xml"},
+        {".asi", "application/octet-stream"},
+        {".asm", "text/plain"},
+        {".asmx", "application/xml"},
+        {".aspx", "application/xml"},
+        {".asr", "video/x-ms-asf"},
+        {".asx", "video/x-ms-asf"},
+        {".atom", "application/atom+xml"},
+        {".au", "audio/basic"},
+        {".avi", "video/x-msvideo"},
+        {".axs", "application/olescript"},
+        {".bas", "text/plain"},
+        {".bcpio", "application/x-bcpio"},
+        {".bin", "application/octet-stream"},
+        {".bmp", "image/bmp"},
+        {".c", "text/plain"},
+        {".cab", "application/octet-stream"},
+        {".caf", "audio/x-caf"},
+        {".calx", "application/vnd.ms-office.calx"},
+        {".cat", "application/vnd.ms-pki.seccat"},
+        {".cc", "text/plain"},
+        {".cd", "text/plain"},
+        {".cdda", "audio/aiff"},
+        {".cdf", "application/x-cdf"},
+        {".cer", "application/x-x509-ca-cert"},
+        {".chm", "application/octet-stream"},
+        {".class", "application/x-java-applet"},
+        {".clp", "application/x-msclip"},
+        {".cmx", "image/x-cmx"},
+        {".cnf", "text/plain"},
+        {".cod", "image/cis-cod"},
+        {".config", "application/xml"},
+        {".contact", "text/x-ms-contact"},
+        {".coverage", "application/xml"},
+        {".cpio", "application/x-cpio"},
+        {".cpp", "text/plain"},
+        {".crd", "application/x-mscardfile"},
+        {".crl", "application/pkix-crl"},
+        {".crt", "application/x-x509-ca-cert"},
+        {".cs", "text/plain"},
+        {".csdproj", "text/plain"},
+        {".csh", "application/x-csh"},
+        {".csproj", "text/plain"},
+        {".css", "text/css"},
+        {".csv", "text/csv"},
+        {".cur", "application/octet-stream"},
+        {".cxx", "text/plain"},
+        {".dat", "application/octet-stream"},
+        {".datasource", "application/xml"},
+        {".dbproj", "text/plain"},
+        {".dcr", "application/x-director"},
+        {".def", "text/plain"},
+        {".deploy", "application/octet-stream"},
+        {".der", "application/x-x509-ca-cert"},
+        {".dgml", "application/xml"},
+        {".dib", "image/bmp"},
+        {".dif", "video/x-dv"},
+        {".dir", "application/x-director"},
+        {".disco", "text/xml"},
+        {".dll", "application/x-msdownload"},
+        {".dll.config", "text/xml"},
+        {".dlm", "text/dlm"},
+        {".doc", "application/msword"},
+        {".docm", "application/vnd.ms-word.document.macroEnabled.12"},
+        {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
+        {".dot", "application/msword"},
+        {".dotm", "application/vnd.ms-word.template.macroEnabled.12"},
+        {".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
+        {".dsp", "application/octet-stream"},
+        {".dsw", "text/plain"},
+        {".dtd", "text/xml"},
+        {".dtsConfig", "text/xml"},
+        {".dv", "video/x-dv"},
+        {".dvi", "application/x-dvi"},
+        {".dwf", "drawing/x-dwf"},
+        {".dwp", "application/octet-stream"},
+        {".dxr", "application/x-director"},
+        {".eml", "message/rfc822"},
+        {".emz", "application/octet-stream"},
+        {".eot", "application/octet-stream"},
+        {".eps", "application/postscript"},
+        {".etl", "application/etl"},
+        {".etx", "text/x-setext"},
+        {".evy", "application/envoy"},
+        {".exe", "application/octet-stream"},
+        {".exe.config", "text/xml"},
+        {".fdf", "application/vnd.fdf"},
+        {".fif", "application/fractals"},
+        {".filters", "Application/xml"},
+        {".fla", "application/octet-stream"},
+        {".flr", "x-world/x-vrml"},
+        {".flv", "video/x-flv"},
+        {".fsscript", "application/fsharp-script"},
+        {".fsx", "application/fsharp-script"},
+        {".generictest", "application/xml"},
+        {".gif", "image/gif"},
+        {".group", "text/x-ms-group"},
+        {".gsm", "audio/x-gsm"},
+        {".gtar", "application/x-gtar"},
+        {".gz", "application/x-gzip"},
+        {".h", "text/plain"},
+        {".hdf", "application/x-hdf"},
+        {".hdml", "text/x-hdml"},
+        {".hhc", "application/x-oleobject"},
+        {".hhk", "application/octet-stream"},
+        {".hhp", "application/octet-stream"},
+        {".hlp", "application/winhlp"},
+        {".hpp", "text/plain"},
+        {".hqx", "application/mac-binhex40"},
+        {".hta", "application/hta"},
+        {".htc", "text/x-component"},
+        {".htm", "text/html"},
+        {".html", "text/html"},
+        {".htt", "text/webviewhtml"},
+        {".hxa", "application/xml"},
+        {".hxc", "application/xml"},
+        {".hxd", "application/octet-stream"},
+        {".hxe", "application/xml"},
+        {".hxf", "application/xml"},
+        {".hxh", "application/octet-stream"},
+        {".hxi", "application/octet-stream"},
+        {".hxk", "application/xml"},
+        {".hxq", "application/octet-stream"},
+        {".hxr", "application/octet-stream"},
+        {".hxs", "application/octet-stream"},
+        {".hxt", "text/html"},
+        {".hxv", "application/xml"},
+        {".hxw", "application/octet-stream"},
+        {".hxx", "text/plain"},
+        {".i", "text/plain"},
+        {".ico", "image/x-icon"},
+        {".ics", "application/octet-stream"},
+        {".idl", "text/plain"},
+        {".ief", "image/ief"},
+        {".iii", "application/x-iphone"},
+        {".inc", "text/plain"},
+        {".inf", "application/octet-stream"},
+        {".inl", "text/plain"},
+        {".ins", "application/x-internet-signup"},
+        {".ipa", "application/x-itunes-ipa"},
+        {".ipg", "application/x-itunes-ipg"},
+        {".ipproj", "text/plain"},
+        {".ipsw", "application/x-itunes-ipsw"},
+        {".iqy", "text/x-ms-iqy"},
+        {".isp", "application/x-internet-signup"},
+        {".ite", "application/x-itunes-ite"},
+        {".itlp", "application/x-itunes-itlp"},
+        {".itms", "application/x-itunes-itms"},
+        {".itpc", "application/x-itunes-itpc"},
+        {".IVF", "video/x-ivf"},
+        {".jar", "application/java-archive"},
+        {".java", "application/octet-stream"},
+        {".jck", "application/liquidmotion"},
+        {".jcz", "application/liquidmotion"},
+        {".jfif", "image/pjpeg"},
+        {".jnlp", "application/x-java-jnlp-file"},
+        {".jpb", "application/octet-stream"},
+        {".jpe", "image/jpeg"},
+        {".jpeg", "image/jpeg"},
+        {".jpg", "image/jpeg"},
+        {".js", "application/x-javascript"},
+        {".json", "application/json"},
+        {".jsx", "text/jscript"},
+        {".jsxbin", "text/plain"},
+        {".latex", "application/x-latex"},
+        {".library-ms", "application/windows-library+xml"},
+        {".lit", "application/x-ms-reader"},
+        {".loadtest", "application/xml"},
+        {".lpk", "application/octet-stream"},
+        {".lsf", "video/x-la-asf"},
+        {".lst", "text/plain"},
+        {".lsx", "video/x-la-asf"},
+        {".lzh", "application/octet-stream"},
+        {".m13", "application/x-msmediaview"},
+        {".m14", "application/x-msmediaview"},
+        {".m1v", "video/mpeg"},
+        {".m2t", "video/vnd.dlna.mpeg-tts"},
+        {".m2ts", "video/vnd.dlna.mpeg-tts"},
+        {".m2v", "video/mpeg"},
+        {".m3u", "audio/x-mpegurl"},
+        {".m3u8", "audio/x-mpegurl"},
+        {".m4a", "audio/m4a"},
+        {".m4b", "audio/m4b"},
+        {".m4p", "audio/m4p"},
+        {".m4r", "audio/x-m4r"},
+        {".m4v", "video/x-m4v"},
+        {".mac", "image/x-macpaint"},
+        {".mak", "text/plain"},
+        {".man", "application/x-troff-man"},
+        {".manifest", "application/x-ms-manifest"},
+        {".map", "text/plain"},
+        {".master", "application/xml"},
+        {".mda", "application/msaccess"},
+        {".mdb", "application/x-msaccess"},
+        {".mde", "application/msaccess"},
+        {".mdp", "application/octet-stream"},
+        {".me", "application/x-troff-me"},
+        {".mfp", "application/x-shockwave-flash"},
+        {".mht", "message/rfc822"},
+        {".mhtml", "message/rfc822"},
+        {".mid", "audio/mid"},
+        {".midi", "audio/mid"},
+        {".mix", "application/octet-stream"},
+        {".mk", "text/plain"},
+        {".mmf", "application/x-smaf"},
+        {".mno", "text/xml"},
+        {".mny", "application/x-msmoney"},
+        {".mod", "video/mpeg"},
+        {".mov", "video/quicktime"},
+        {".movie", "video/x-sgi-movie"},
+        {".mp2", "video/mpeg"},
+        {".mp2v", "video/mpeg"},
+        {".mp3", "audio/mpeg"},
+        {".mp4", "video/mp4"},
+        {".mp4v", "video/mp4"},
+        {".mpa", "video/mpeg"},
+        {".mpe", "video/mpeg"},
+        {".mpeg", "video/mpeg"},
+        {".mpf", "application/vnd.ms-mediapackage"},
+        {".mpg", "video/mpeg"},
+        {".mpp", "application/vnd.ms-project"},
+        {".mpv2", "video/mpeg"},
+        {".mqv", "video/quicktime"},
+        {".ms", "application/x-troff-ms"},
+        {".msi", "application/octet-stream"},
+        {".mso", "application/octet-stream"},
+        {".mts", "video/vnd.dlna.mpeg-tts"},
+        {".mtx", "application/xml"},
+        {".mvb", "application/x-msmediaview"},
+        {".mvc", "application/x-miva-compiled"},
+        {".mxp", "application/x-mmxp"},
+        {".nc", "application/x-netcdf"},
+        {".nsc", "video/x-ms-asf"},
+        {".nws", "message/rfc822"},
+        {".ocx", "application/octet-stream"},
+        {".oda", "application/oda"},
+        {".odc", "text/x-ms-odc"},
+        {".odh", "text/plain"},
+        {".odl", "text/plain"},
+        {".odp", "application/vnd.oasis.opendocument.presentation"},
+        {".ods", "application/oleobject"},
+        {".odt", "application/vnd.oasis.opendocument.text"},
+        {".one", "application/onenote"},
+        {".onea", "application/onenote"},
+        {".onepkg", "application/onenote"},
+        {".onetmp", "application/onenote"},
+        {".onetoc", "application/onenote"},
+        {".onetoc2", "application/onenote"},
+        {".orderedtest", "application/xml"},
+        {".osdx", "application/opensearchdescription+xml"},
+        {".p10", "application/pkcs10"},
+        {".p12", "application/x-pkcs12"},
+        {".p7b", "application/x-pkcs7-certificates"},
+        {".p7c", "application/pkcs7-mime"},
+        {".p7m", "application/pkcs7-mime"},
+        {".p7r", "application/x-pkcs7-certreqresp"},
+        {".p7s", "application/pkcs7-signature"},
+        {".pbm", "image/x-portable-bitmap"},
+        {".pcast", "application/x-podcast"},
+        {".pct", "image/pict"},
+        {".pcx", "application/octet-stream"},
+        {".pcz", "application/octet-stream"},
+        {".pdf", "application/pdf"},
+        {".pfb", "application/octet-stream"},
+        {".pfm", "application/octet-stream"},
+        {".pfx", "application/x-pkcs12"},
+        {".pgm", "image/x-portable-graymap"},
+        {".pic", "image/pict"},
+        {".pict", "image/pict"},
+        {".pkgdef", "text/plain"},
+        {".pkgundef", "text/plain"},
+        {".pko", "application/vnd.ms-pki.pko"},
+        {".pls", "audio/scpls"},
+        {".pma", "application/x-perfmon"},
+        {".pmc", "application/x-perfmon"},
+        {".pml", "application/x-perfmon"},
+        {".pmr", "application/x-perfmon"},
+        {".pmw", "application/x-perfmon"},
+        {".png", "image/png"},
+        {".pnm", "image/x-portable-anymap"},
+        {".pnt", "image/x-macpaint"},
+        {".pntg", "image/x-macpaint"},
+        {".pnz", "image/png"},
+        {".pot", "application/vnd.ms-powerpoint"},
+        {".potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"},
+        {".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},
+        {".ppa", "application/vnd.ms-powerpoint"},
+        {".ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"},
+        {".ppm", "image/x-portable-pixmap"},
+        {".pps", "application/vnd.ms-powerpoint"},
+        {".ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
+        {".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
+        {".ppt", "application/vnd.ms-powerpoint"},
+        {".pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
+        {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
+        {".prf", "application/pics-rules"},
+        {".prm", "application/octet-stream"},
+        {".prx", "application/octet-stream"},
+        {".ps", "application/postscript"},
+        {".psc1", "application/PowerShell"},
+        {".psd", "application/octet-stream"},
+        {".psess", "application/xml"},
+        {".psm", "application/octet-stream"},
+        {".psp", "application/octet-stream"},
+        {".pub", "application/x-mspublisher"},
+        {".pwz", "application/vnd.ms-powerpoint"},
+        {".qht", "text/x-html-insertion"},
+        {".qhtm", "text/x-html-insertion"},
+        {".qt", "video/quicktime"},
+        {".qti", "image/x-quicktime"},
+        {".qtif", "image/x-quicktime"},
+        {".qtl", "application/x-quicktimeplayer"},
+        {".qxd", "application/octet-stream"},
+        {".ra", "audio/x-pn-realaudio"},
+        {".ram", "audio/x-pn-realaudio"},
+        {".rar", "application/octet-stream"},
+        {".ras", "image/x-cmu-raster"},
+        {".rat", "application/rat-file"},
+        {".rc", "text/plain"},
+        {".rc2", "text/plain"},
+        {".rct", "text/plain"},
+        {".rdlc", "application/xml"},
+        {".resx", "application/xml"},
+        {".rf", "image/vnd.rn-realflash"},
+        {".rgb", "image/x-rgb"},
+        {".rgs", "text/plain"},
+        {".rm", "application/vnd.rn-realmedia"},
+        {".rmi", "audio/mid"},
+        {".rmp", "application/vnd.rn-rn_music_package"},
+        {".roff", "application/x-troff"},
+        {".rpm", "audio/x-pn-realaudio-plugin"},
+        {".rqy", "text/x-ms-rqy"},
+        {".rtf", "application/rtf"},
+        {".rtx", "text/richtext"},
+        {".ruleset", "application/xml"},
+        {".s", "text/plain"},
+        {".safariextz", "application/x-safari-safariextz"},
+        {".scd", "application/x-msschedule"},
+        {".sct", "text/scriptlet"},
+        {".sd2", "audio/x-sd2"},
+        {".sdp", "application/sdp"},
+        {".sea", "application/octet-stream"},
+        {".searchConnector-ms", "application/windows-search-connector+xml"},
+        {".setpay", "application/set-payment-initiation"},
+        {".setreg", "application/set-registration-initiation"},
+        {".settings", "application/xml"},
+        {".sgimb", "application/x-sgimb"},
+        {".sgml", "text/sgml"},
+        {".sh", "application/x-sh"},
+        {".shar", "application/x-shar"},
+        {".shtml", "text/html"},
+        {".sit", "application/x-stuffit"},
+        {".sitemap", "application/xml"},
+        {".skin", "application/xml"},
+        {".sldm", "application/vnd.ms-powerpoint.slide.macroEnabled.12"},
+        {".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"},
+        {".slk", "application/vnd.ms-excel"},
+        {".sln", "text/plain"},
+        {".slupkg-ms", "application/x-ms-license"},
+        {".smd", "audio/x-smd"},
+        {".smi", "application/octet-stream"},
+        {".smx", "audio/x-smd"},
+        {".smz", "audio/x-smd"},
+        {".snd", "audio/basic"},
+        {".snippet", "application/xml"},
+        {".snp", "application/octet-stream"},
+        {".sol", "text/plain"},
+        {".sor", "text/plain"},
+        {".spc", "application/x-pkcs7-certificates"},
+        {".spl", "application/futuresplash"},
+        {".src", "application/x-wais-source"},
+        {".srf", "text/plain"},
+        {".SSISDeploymentManifest", "text/xml"},
+        {".ssm", "application/streamingmedia"},
+        {".sst", "application/vnd.ms-pki.certstore"},
+        {".stl", "application/vnd.ms-pki.stl"},
+        {".sv4cpio", "application/x-sv4cpio"},
+        {".sv4crc", "application/x-sv4crc"},
+        {".svc", "application/xml"},
+        {".swf", "application/x-shockwave-flash"},
+        {".t", "application/x-troff"},
+        {".tar", "application/x-tar"},
+        {".tcl", "application/x-tcl"},
+        {".testrunconfig", "application/xml"},
+        {".testsettings", "application/xml"},
+        {".tex", "application/x-tex"},
+        {".texi", "application/x-texinfo"},
+        {".texinfo", "application/x-texinfo"},
+        {".tgz", "application/x-compressed"},
+        {".thmx", "application/vnd.ms-officetheme"},
+        {".thn", "application/octet-stream"},
+        {".tif", "image/tiff"},
+        {".tiff", "image/tiff"},
+        {".tlh", "text/plain"},
+        {".tli", "text/plain"},
+        {".toc", "application/octet-stream"},
+        {".tr", "application/x-troff"},
+        {".trm", "application/x-msterminal"},
+        {".trx", "application/xml"},
+        {".ts", "video/vnd.dlna.mpeg-tts"},
+        {".tsv", "text/tab-separated-values"},
+        {".ttf", "application/octet-stream"},
+        {".tts", "video/vnd.dlna.mpeg-tts"},
+        {".txt", "text/plain"},
+        {".u32", "application/octet-stream"},
+        {".uls", "text/iuls"},
+        {".user", "text/plain"},
+        {".ustar", "application/x-ustar"},
+        {".vb", "text/plain"},
+        {".vbdproj", "text/plain"},
+        {".vbk", "video/mpeg"},
+        {".vbproj", "text/plain"},
+        {".vbs", "text/vbscript"},
+        {".vcf", "text/x-vcard"},
+        {".vcproj", "Application/xml"},
+        {".vcs", "text/plain"},
+        {".vcxproj", "Application/xml"},
+        {".vddproj", "text/plain"},
+        {".vdp", "text/plain"},
+        {".vdproj", "text/plain"},
+        {".vdx", "application/vnd.ms-visio.viewer"},
+        {".vml", "text/xml"},
+        {".vscontent", "application/xml"},
+        {".vsct", "text/xml"},
+        {".vsd", "application/vnd.visio"},
+        {".vsi", "application/ms-vsi"},
+        {".vsix", "application/vsix"},
+        {".vsixlangpack", "text/xml"},
+        {".vsixmanifest", "text/xml"},
+        {".vsmdi", "application/xml"},
+        {".vspscc", "text/plain"},
+        {".vss", "application/vnd.visio"},
+        {".vsscc", "text/plain"},
+        {".vssettings", "text/xml"},
+        {".vssscc", "text/plain"},
+        {".vst", "application/vnd.visio"},
+        {".vstemplate", "text/xml"},
+        {".vsto", "application/x-ms-vsto"},
+        {".vsw", "application/vnd.visio"},
+        {".vsx", "application/vnd.visio"},
+        {".vtx", "application/vnd.visio"},
+        {".wav", "audio/wav"},
+        {".wave", "audio/wav"},
+        {".wax", "audio/x-ms-wax"},
+        {".wbk", "application/msword"},
+        {".wbmp", "image/vnd.wap.wbmp"},
+        {".wcm", "application/vnd.ms-works"},
+        {".wdb", "application/vnd.ms-works"},
+        {".wdp", "image/vnd.ms-photo"},
+        {".webarchive", "application/x-safari-webarchive"},
+        {".webtest", "application/xml"},
+        {".wiq", "application/xml"},
+        {".wiz", "application/msword"},
+        {".wks", "application/vnd.ms-works"},
+        {".WLMP", "application/wlmoviemaker"},
+        {".wlpginstall", "application/x-wlpg-detect"},
+        {".wlpginstall3", "application/x-wlpg3-detect"},
+        {".wm", "video/x-ms-wm"},
+        {".wma", "audio/x-ms-wma"},
+        {".wmd", "application/x-ms-wmd"},
+        {".wmf", "application/x-msmetafile"},
+        {".wml", "text/vnd.wap.wml"},
+        {".wmlc", "application/vnd.wap.wmlc"},
+        {".wmls", "text/vnd.wap.wmlscript"},
+        {".wmlsc", "application/vnd.wap.wmlscriptc"},
+        {".wmp", "video/x-ms-wmp"},
+        {".wmv", "video/x-ms-wmv"},
+        {".wmx", "video/x-ms-wmx"},
+        {".wmz", "application/x-ms-wmz"},
+        {".wpl", "application/vnd.ms-wpl"},
+        {".wps", "application/vnd.ms-works"},
+        {".wri", "application/x-mswrite"},
+        {".wrl", "x-world/x-vrml"},
+        {".wrz", "x-world/x-vrml"},
+        {".wsc", "text/scriptlet"},
+        {".wsdl", "text/xml"},
+        {".wvx", "video/x-ms-wvx"},
+        {".x", "application/directx"},
+        {".xaf", "x-world/x-vrml"},
+        {".xaml", "application/xaml+xml"},
+        {".xap", "application/x-silverlight-app"},
+        {".xbap", "application/x-ms-xbap"},
+        {".xbm", "image/x-xbitmap"},
+        {".xdr", "text/plain"},
+        {".xht", "application/xhtml+xml"},
+        {".xhtml", "application/xhtml+xml"},
+        {".xla", "application/vnd.ms-excel"},
+        {".xlam", "application/vnd.ms-excel.addin.macroEnabled.12"},
+        {".xlc", "application/vnd.ms-excel"},
+        {".xld", "application/vnd.ms-excel"},
+        {".xlk", "application/vnd.ms-excel"},
+        {".xll", "application/vnd.ms-excel"},
+        {".xlm", "application/vnd.ms-excel"},
+        {".xls", "application/vnd.ms-excel"},
+        {".xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
+        {".xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"},
+        {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
+        {".xlt", "application/vnd.ms-excel"},
+        {".xltm", "application/vnd.ms-excel.template.macroEnabled.12"},
+        {".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
+        {".xlw", "application/vnd.ms-excel"},
+        {".xml", "text/xml"},
+        {".xmta", "application/xml"},
+        {".xof", "x-world/x-vrml"},
+        {".XOML", "text/plain"},
+        {".xpm", "image/x-xpixmap"},
+        {".xps", "application/vnd.ms-xpsdocument"},
+        {".xrm-ms", "text/xml"},
+        {".xsc", "application/xml"},
+        {".xsd", "text/xml"},
+        {".xsf", "text/xml"},
+        {".xsl", "text/xml"},
+        {".xslt", "text/xml"},
+        {".xsn", "application/octet-stream"},
+        {".xss", "application/xml"},
+        {".xtp", "application/octet-stream"},
+        {".xwd", "image/x-xwindowdump"},
+        {".z", "application/x-compress"},
+        {".zip", "application/x-zip-compressed"},
+
+        };
+
+        /// <summary>
+        /// Gets the MIME type of the content.
+        /// </summary>
+        /// <param name="extension">The extension.</param>
+        /// <returns>System.String.</returns>
+        /// <exception cref="System.ArgumentNullException">extension</exception>
+        public static string GetMimeType(string extension)
+        {
+            if (extension == null)
+            {
+                throw new ArgumentNullException("extension");
+            }
+            if (!extension.StartsWith("."))
+            {
+                extension = "." + extension;
+            }
+            string mime;
+            return Mappings.TryGetValue(extension, out mime) ? mime : "application/octet-stream";
         }
     }
 }


Added method IsLogged()

Added method IsLogged()

--- ChatroServer/src/ChatHub.cs
+++ ChatroServer/src/ChatHub.cs
@@ -101,5 +101,9 @@
     {
         Success,
         Failure
+        private bool IsLogged()
+        {
+            return ConnectionIdsUsers.Keys.Any(s => s == this.Context.ConnectionId);
+        }
     }
 }


* Made Windows 7 integration safer

 * Made Windows 7 integration safer

git-svn-id: e2945e6dc2723cb01f425b5a7c3c201ce5019a89@557 080cfd25-d5d9-4c59-82ea-70d02a200d8b

--- Clients/WinForms/Program.cs
+++ Clients/WinForms/Program.cs
@@ -84,11 +84,18 @@
 						IconReference = new IconReference (exe, 0)
 					};
 				}
-
+
 				serverCategory.AddJumpListItems (links);

 				jl.AddCustomCategories (serverCategory);
-				jl.Refresh ();
+
+				try
+				{
+					jl.Refresh ();
+				}
+				catch (UnauthorizedAccessException)
+				{
+				}
 			}

 			if (args.Length > 0)


Add missing ;

Add missing ;


Update GiveRoleCommand.cs

Update GiveRoleCommand.cs

- Fixed a bug where it would remove all of the user's roles even if they entered an invalid role.
- Added some comments to clarify a loop :)

--- Commands/GiveRoleCommand.cs
+++ Commands/GiveRoleCommand.cs
@@ -29,15 +29,6 @@
                 return;
             }

-
-            foreach (IRole r in guildUser.Roles)
-            {
-                if (r.Name != "@everyone" && r.Position < Context.Guild.Roles.FirstOrDefault (x => x.Name == "BotMyst").Position)
-                {
-                    await guildUser.RemoveRoleAsync (r);
-                }
-            }
-
             try
             {
                 await guildUser.AddRoleAsync (role);
@@ -54,7 +45,17 @@
                 }
                 return;
             }
-
+
+            // Removes all of the user's roles that are below the "BotMyst" role,
+            // because you are only allowed to have one color at a time.
+            foreach (IRole r in guildUser.Roles)
+            {
+                if (r.Name != "@everyone" && r.Position < Context.Guild.Roles.FirstOrDefault (x => x.Name == "BotMyst").Position)
+                {
+                    await guildUser.RemoveRoleAsync (r);
+                }
+            }
+
             EmbedBuilder eb = new EmbedBuilder ();
             eb.WithColor (Color.Green);
             eb.WithTitle ("Success");
@@ -103,4 +104,4 @@
             await ReplyAsync (string.Empty, false, eb);
         }
     }
-}+}


Update to stub class

Update to stub class

--- main/Smartsheet/Api/DiscussionAttachmentResources.cs
+++ main/Smartsheet/Api/DiscussionAttachmentResources.cs
@@ -18,7 +18,7 @@

 using System.Collections.Generic;

-namespace Smartsheet.Api.Internal
+namespace Smartsheet.Api
 {
 	using Attachment = Api.Models.Attachment;


Remove extra callbacks (smooths out the progress bar)

--- uSync8.BackOffice/SyncHandlers/SyncHandlerBase.cs
+++ uSync8.BackOffice/SyncHandlers/SyncHandlerBase.cs
@@ -222,7 +222,7 @@
             // bulk save ..
             if (flags.HasFlag(SerializerFlags.DoNotSave) && updates.Any())
             {
-                callback?.Invoke($"Saving {updates.Count()} changes", 1, 1);
+                // callback?.Invoke($"Saving {updates.Count()} changes", 1, 1);
                 serializer.Save(updates.Select(x => x.Value));
             }

@@ -242,7 +242,7 @@
                 actions.RemoveAll(x => x.Change == ChangeType.Clean);
             }

-            callback?.Invoke("", 1, 1);
+            // callback?.Invoke("", 1, 1);

             return actions;
         }
@@ -407,7 +407,7 @@
                 actions.AddRange(ExportAll(item.Value.Id, folder, config, callback));
             }

-            callback?.Invoke("Done", 1, 1);
+            // callback?.Invoke("Done", 1, 1);
             return actions;
         }


Fixes #6041. Multi-steps in construction graph visible in examine menu. (#6043)

--- Content.Server/Construction/ConstructionSystem.Guided.cs
+++ Content.Server/Construction/ConstructionSystem.Guided.cs
@@ -95,7 +95,9 @@
                     preventStepExamine |= condition.DoExamine(args);
                 }

-                if (preventStepExamine) return;
+                if (!preventStepExamine && component.StepIndex < edge.Steps.Count)
+                    edge.Steps[component.StepIndex].DoExamine(args);
+                return;
             }
         }


log external provider claims on failure

log external provider claims on failure

--- source/Core/Endpoints/AuthenticationController.cs
+++ source/Core/Endpoints/AuthenticationController.cs
@@ -352,7 +352,8 @@
             var externalIdentity = ExternalIdentity.FromClaims(user.Claims);
             if (externalIdentity == null)
             {
-                Logger.Error("no subject or unique identifier claims from external identity provider");
+                var claims = user.Claims.Select(x => new { x.Type, x.Value });
+                Logger.ErrorFormat("no subject or unique identifier claims from external identity provider. Claims provided:\r\n{0}", LogSerializer.Serialize(claims));
                 return await RenderLoginPage(signInMessage, signInId, localizationService.GetMessage(MessageIds.NoMatchingExternalAccount));
             }


Fixed telemetry properties.

Fixed telemetry properties.

--- source/Server.Azure/ApplicationInsightsMonitor.cs
+++ source/Server.Azure/ApplicationInsightsMonitor.cs
@@ -37,7 +37,7 @@
             where TTelemetry: ITelemetry, ISupportProperties
         {
             telemetry.Context.Session.Id = session?.GetSessionId();
-            telemetry.Context.Properties.Add("Web App", _webAppName);
+            telemetry.Properties.Add("Web App", _webAppName);
             if (extras == null)
                 return;


Add PublicAPI attributes to constructors

--- Corale.Colore/Core/Color.cs
+++ Corale.Colore/Core/Color.cs
@@ -104,6 +104,7 @@
         /// color value in the format <c>0xAABBGGRR</c>.
         /// </summary>
         /// <param name="value">Value to create the color from.</param>
+        [PublicAPI]
         public Color(uint value)
         {
             _value = value;
@@ -118,6 +119,7 @@
         /// <param name="green">The green component.</param>
         /// <param name="blue">The blue component.</param>
         /// <param name="alpha">The alpha component (<c>0</c> = fully opaque).</param>
+        [PublicAPI]
         public Color(byte red, byte green, byte blue, byte alpha = 0)
             : this(red + ((uint)green << 8) + ((uint)blue << 16) + ((uint)alpha << 24))
         {
@@ -135,6 +137,7 @@
         /// <remarks>
         /// Each parameter value must be between <c>0.0f</c> and <c>1.0f</c> (inclusive).
         /// </remarks>
+        [PublicAPI]
         public Color(float red, float green, float blue, float alpha = 0.0f)
             : this((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255), (byte)(alpha * 255))
         {
@@ -151,6 +154,7 @@
         /// <remarks>
         /// Each parameter value must be between <c>0.0</c> and <c>1.0</c> (inclusive).
         /// </remarks>
+        [PublicAPI]
         public Color(double red, double green, double blue, double alpha = 0.0)
             : this((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255), (byte)(alpha * 255))
         {


SWICLI - guard against searching for type null

--- Swicli.Library/PrologCLR.cs
+++ Swicli.Library/PrologCLR.cs
@@ -625,7 +625,19 @@
             }
             try
             {
-                mi = c.GetMethod(fn, BindingFlagsALL, null, CallingConventions.Any, paramz, null);
+                bool hasNull = false;
+                foreach (var s in paramz)
+                {
+                    if (s == null)
+                    {
+                        hasNull = true;
+                        break;
+                    }
+                }
+                if (!hasNull)
+                {
+                    mi = c.GetMethod(fn, BindingFlagsALL, null, CallingConventions.Any, paramz, null);
+                }
                 if (mi != null)
                 {
                     return mi;


Some class types I missed (including some old(?) hockey types)

--- RocketLeagueReplayParser/NetworkStream/ActorState.cs
+++ RocketLeagueReplayParser/NetworkStream/ActorState.cs
@@ -40,15 +40,19 @@
         public static ClassNetCache ObjectNameToClassNetCache(string objectName, string[] objectIdToName, IEnumerable<ClassNetCache> classNetCache)
         {
             // TODO: Make these manual conversions less messy
-            if (objectName == "GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype") return classNetCache.Where(x=> objectIdToName[x.ObjectIndex] == "TAGame.GRI_TA").Single();
+            if (objectName == "Archetypes.Ball.Ball_Basketball") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Ball_TA").Single();
+            if (objectName == "Archetypes.Ball.Ball_Puck") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Ball_TA").Single();
+            if (objectName == "Archetypes.Ball.CubeBall") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Ball_TA").Single();
+            if (objectName == "Archetypes.GameEvent.GameEvent_Basketball") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_Soccar_TA").Single();
+            if (objectName == "Archetypes.GameEvent.GameEvent_BasketballPrivate") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_SoccarPrivate_TA").Single();
+            if (objectName == "Archetypes.GameEvent.GameEvent_BasketballSplitscreen") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_SoccarSplitscreen_TA").Single();
+            if (objectName == "Archetypes.GameEvent.GameEvent_HockeyPrivate") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_SoccarPrivate_TA").Single();
+            if (objectName == "Archetypes.GameEvent.GameEvent_HockeySplitscreen") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_SoccarSplitscreen_TA").Single();
+            if (objectName == "Archetypes.GameEvent.GameEvent_Season:CarArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Car_Season_TA").Single();
+            if (objectName == "GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GRI_TA").Single();
+            if (objectName == "Gameinfo_Hockey.GameInfo.Gameinfo_Hockey:GameReplicationInfoArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GRI_TA").Single();
             if (objectName == "GameInfo_Season.GameInfo.GameInfo_Season:GameReplicationInfoArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GRI_TA").Single();
-            if (objectName == "Archetypes.GameEvent.GameEvent_Season:CarArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Car_Season_TA").Single();
-            if (objectName == "Archetypes.Ball.CubeBall") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Ball_TA").Single();
-            if (objectName == "Archetypes.Ball.Ball_Puck") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Ball_TA").Single();
-            if (objectName == "Archetypes.Ball.Ball_Basketball") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.Ball_TA").Single();
-            if (objectName == "Archetypes.GameEvent.GameEvent_Basketball") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_Soccar_TA").Single();
-            if (objectName == "GameInfo_Basketball.GameInfo.GameInfo_Basketball:GameReplicationInfoArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GRI_TA").Single();
-            if (objectName == "Archetypes.GameEvent.GameEvent_BasketballSplitscreen") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GameEvent_SoccarSplitscreen_TA").Single();
+            if (objectName == "GameInfo_Soccar.GameInfo.GameInfo_Soccar:GameReplicationInfoArchetype") return classNetCache.Where(x => objectIdToName[x.ObjectIndex] == "TAGame.GRI_TA").Single();

             var name = Regex.Replace(objectName, @"_\d+", "")
                 .Split('.').Last()


Added optional IV parameter to FairPlay signaling generation helpers.

--- Cpix/DrmSignalingHelpers.cs
+++ Cpix/DrmSignalingHelpers.cs
@@ -99,14 +99,20 @@
 			return $"#EXT-X-KEY:{GenerateWidevineHlsAttributes(keyId)}";
 		}

-		public static string GenerateFairPlayHlsMasterPlaylistSignaling(Guid keyId)
-		{
-			return $"#EXT-X-SESSION-KEY:{GenerateFairPlayHlsAttributes(keyId)}";
-		}
-
-		public static string GenerateFairPlayHlsMediaPlaylistSignaling(Guid keyId)
-		{
-			return $"#EXT-X-KEY:{GenerateFairPlayHlsAttributes(keyId)}";
+		public static string GenerateFairPlayHlsMasterPlaylistSignaling(Guid keyId, byte[] iv = null)
+		{
+			if (iv != null && iv.Length != 16)
+				throw new ArgumentException("IV must be exactly 16 bytes.");
+
+			return $"#EXT-X-SESSION-KEY:{GenerateFairPlayHlsAttributes(keyId, iv)}";
+		}
+
+		public static string GenerateFairPlayHlsMediaPlaylistSignaling(Guid keyId, byte[] iv = null)
+		{
+			if (iv != null && iv.Length != 16)
+				throw new ArgumentException("IV must be exactly 16 bytes.");
+
+			return $"#EXT-X-KEY:{GenerateFairPlayHlsAttributes(keyId, iv)}";
 		}

 		public static byte[] GeneratePlayReadyPsshBox(Guid keyId, string playReadyLaUrl = null)
@@ -233,9 +239,11 @@
 			return widevineAttributes;
 		}

-		private static string GenerateFairPlayHlsAttributes(Guid keyId)
-		{
-			return $"METHOD=SAMPLE-AES,URI=\"skd://{keyId}\",KEYFORMAT=\"com.apple.streamingkeydelivery\",KEYFORMATVERSIONS=\"1\"";
+		private static string GenerateFairPlayHlsAttributes(Guid keyId, byte[] iv = null)
+		{
+			return $"METHOD=SAMPLE-AES,URI=\"skd://{keyId}" +
+				(iv == null ? "" : $":{ByteArrayToHexString(iv)}") +
+				"\",KEYFORMAT=\"com.apple.streamingkeydelivery\",KEYFORMATVERSIONS=\"1\"";
 		}

 		private static string ByteArrayToHexString(byte[] bytes)


Updated version number

Updated version number

--- Server/AjaxControlToolkit/Properties/AssemblyInfo.cs
+++ Server/AjaxControlToolkit/Properties/AssemblyInfo.cs
@@ -37,10 +37,10 @@
 [assembly: SecurityRules(SecurityRuleSet.Level1)]
 [assembly: System.Web.Script.AjaxFrameworkAssembly]
 [assembly: AssemblyVersion("4.1.40412")]
-[assembly: AssemblyFileVersion("4.1.40412.1")]
+[assembly: AssemblyFileVersion("4.1.40412.2")]
 #else
 [assembly: AssemblyVersion("3.5.40412")]
-[assembly: AssemblyFileVersion("3.5.40412.1")]
+[assembly: AssemblyFileVersion("3.5.40412.2")]
 #endif
 [assembly: NeutralResourcesLanguage("en-US")]