/// <summary>
        /// Converts a <see cref="JObject" /> to a <see cref="PSObject" />
        /// </summary>
        /// <param name="jtoken">The <see cref="JObject" /></param>
        /// <returns></returns>
        internal static PSObject ToPsObject(this JToken jtoken)
        {
            if (jtoken == null)
            {
                return(null);
            }

            if (jtoken.Type != JTokenType.Object)
            {
                return(new PSObject(JTokenExtensions.ConvertPropertyValueForPsObject(propertyValue: jtoken)));
            }

            var jobject  = (JObject)jtoken;
            var psObject = new PSObject();

            psObject.TypeNames.Add(typeof(PSCustomObject).FullName);

            foreach (var property in jobject.Properties())
            {
                psObject.Properties.Add(new PSNoteProperty(
                                            name: property.Name,
                                            value: JTokenExtensions.ConvertPropertyValueForPsObject(propertyValue: property.Value)));
            }

            return(psObject);
        }
        /// <summary>
        /// Converts a property value for a <see cref="JObject" /> into an <see cref="object" /> that can be
        /// used as the value of a <see cref="PSNoteProperty" />.
        /// </summary>
        /// <param name="propertyValue">The <see cref="JToken" /> value.</param>
        /// <returns></returns>
        private static object ConvertPropertyValueForPsObject(JToken propertyValue)
        {
            if (propertyValue.Type == JTokenType.Object)
            {
                return(propertyValue.ToPsObject());
            }

            if (propertyValue.Type == JTokenType.Array)
            {
                var jArray = (JArray)propertyValue;

                var array = new object[jArray.Count];

                for (int i = 0; i < array.Length; ++i)
                {
                    array[i] = JTokenExtensions.ConvertPropertyValueForPsObject(jArray[i]);
                }

                return(array);
            }

            Type primitiveType;

            if (PrimitiveTypeMap.TryGetValue(propertyValue.Type, out primitiveType))
            {
                try
                {
                    return(propertyValue.ToObject(primitiveType));
                }
                catch (FormatException)
                {
                }
                catch (ArgumentException)
                {
                }
                catch (JsonException)
                {
                }
            }

            return(propertyValue.ToString());
        }