public bool TryFromObject(BaristaContext context, object obj, out JsValue value)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(context));
            }

            var valueFactory = (IBaristaValueFactory)context;

            //Well this is easy!
            if (obj == null)
            {
                value = valueFactory.Null;
                return(true);
            }

            switch (obj)
            {
            case Undefined undefinedValue:
                value = valueFactory.Undefined;
                return(true);

            case JsValue jsValue:
                value = jsValue;
                return(true);

            case JavaScriptValueSafeHandle jsValueSafeHandle:
                value = valueFactory.CreateValue(jsValueSafeHandle);
                return(true);

            case string stringValue:
                value = valueFactory.CreateString(stringValue);
                return(true);

            case double doubleValue:
            case float floatValue:
                value = valueFactory.CreateNumber((double)obj);
                return(true);

            case int intValue:
            case short shortValue:
            case ushort ushortValue:
            case byte byteValue:
            case sbyte sbyteValue:
                value = valueFactory.CreateNumber((int)obj);
                return(true);

            case uint uintValue:
                value = valueFactory.CreateNumber(uintValue);
                return(true);

            case long longValue:
                value = valueFactory.CreateNumber(longValue);
                return(true);

            case bool boolValue:
                value = boolValue ? valueFactory.True : valueFactory.False;
                return(true);

            case Array arrayValue:
                var arr = valueFactory.CreateArray((uint)arrayValue.LongLength);
                for (int i = 0; i < arrayValue.Length; i++)
                {
                    if (TryFromObject(context, arrayValue.GetValue(i), out JsValue currentValue))
                    {
                        arr[i] = currentValue;
                    }
                    else
                    {
                        value = null;
                        return(false);
                    }
                }
                value = arr;
                return(true);

            //Don't convert IEnumerators -- they'll be auto-created.
            //case IEnumerator enumeratorValue:
            //    value = valueFactory.CreateIterator(enumeratorValue);
            //    return true;
            case Delegate delegateValue:
                value = valueFactory.CreateFunction(delegateValue);
                return(true);

            case Exception exValue:
                value = valueFactory.CreateError(exValue.Message);
                return(true);

            case Task taskValue:
                value = valueFactory.CreatePromise(taskValue);
                return(true);

            case Type typeValue:
                if (m_typeConversionStrategy == null)
                {
                    value = null;
                    return(false);
                }
                var result = m_typeConversionStrategy.TryCreatePrototypeFunction(context, typeValue, out JsFunction fnValue);
                value = fnValue;
                return(result);
            }

            var objType = obj.GetType();

            if (objType.IsValueType)
            {
                if (m_jsonConverter == null)
                {
                    value = null;
                    return(false);
                }

                var jsonString = m_jsonConverter.Stringify(obj);
                value = context.JSON.Parse(valueFactory.CreateString(jsonString));
                return(true);
            }

            //We've run out of options, convert the non-primitive object.
            return(TryConvertFromNonPrimitiveObject(context, obj, out value));
        }