/// <summary>
        /// Returns a new JavaScriptValue for the specified handle querying for the handle's value type.
        /// </summary>
        /// <remarks>
        /// Use the valueType parameter carefully. If the resulting type does not match the handle type unexpected issues may occur.
        /// </remarks>
        /// <returns>The JavaScript Value that represents the handle</returns>
        public JsValue CreateValue(JavaScriptValueSafeHandle valueHandle, JsValueType?valueType = null)
        {
            if (valueHandle == JavaScriptValueSafeHandle.Invalid)
            {
                return(null);
            }

            return(m_valuePool.GetOrAdd(valueHandle, () =>
            {
                if (valueType.HasValue == false)
                {
                    valueType = m_engine.JsGetValueType(valueHandle);
                }

                JsValue result;
                switch (valueType.Value)
                {
                case JsValueType.Array:
                    result = new JsArray(m_engine, Context, valueHandle);
                    break;

                case JsValueType.ArrayBuffer:
                    result = new JsArrayBuffer(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Boolean:
                    result = new JsBoolean(m_engine, Context, valueHandle);
                    break;

                case JsValueType.DataView:
                    result = new JsDataView(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Error:
                    result = new JsError(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Function:
                    result = new JsFunction(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Null:
                    result = new JsNull(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Number:
                    result = new JsNumber(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Object:
                    result = new JsObject(m_engine, Context, valueHandle);
                    break;

                case JsValueType.String:
                    result = new JsString(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Symbol:
                    result = new JsSymbol(m_engine, Context, valueHandle);
                    break;

                case JsValueType.TypedArray:
                    result = new JsTypedArray(m_engine, Context, valueHandle);
                    break;

                case JsValueType.Undefined:
                    result = new JsUndefined(m_engine, Context, valueHandle);
                    break;

                default:
                    throw new NotImplementedException($"Error Creating JavaScript Value: The JavaScript Value Type '{valueType}' is unknown, invalid, or has not been implemented.");
                }

                result.BeforeCollect += JsValueBeforeCollectCallback;

                return result;
            }));
        }
 /// <summary>
 /// Sets the runtime of the current context to an exception state.
 /// </summary>
 /// <param name="error"></param>
 public void SetException(JsError error)
 {
     m_context.Engine.JsSetException(error.Handle);
 }