| "use strict"; | 
| module.exports = function(Promise, INTERNAL) { | 
| var util = require("./util"); | 
| var errorObj = util.errorObj; | 
| var isObject = util.isObject; | 
|   | 
| function tryConvertToPromise(obj, context) { | 
|     if (isObject(obj)) { | 
|         if (obj instanceof Promise) return obj; | 
|         var then = getThen(obj); | 
|         if (then === errorObj) { | 
|             if (context) context._pushContext(); | 
|             var ret = Promise.reject(then.e); | 
|             if (context) context._popContext(); | 
|             return ret; | 
|         } else if (typeof then === "function") { | 
|             if (isAnyBluebirdPromise(obj)) { | 
|                 var ret = new Promise(INTERNAL); | 
|                 obj._then( | 
|                     ret._fulfill, | 
|                     ret._reject, | 
|                     undefined, | 
|                     ret, | 
|                     null | 
|                 ); | 
|                 return ret; | 
|             } | 
|             return doThenable(obj, then, context); | 
|         } | 
|     } | 
|     return obj; | 
| } | 
|   | 
| function doGetThen(obj) { | 
|     return obj.then; | 
| } | 
|   | 
| function getThen(obj) { | 
|     try { | 
|         return doGetThen(obj); | 
|     } catch (e) { | 
|         errorObj.e = e; | 
|         return errorObj; | 
|     } | 
| } | 
|   | 
| var hasProp = {}.hasOwnProperty; | 
| function isAnyBluebirdPromise(obj) { | 
|     try { | 
|         return hasProp.call(obj, "_promise0"); | 
|     } catch (e) { | 
|         return false; | 
|     } | 
| } | 
|   | 
| function doThenable(x, then, context) { | 
|     var promise = new Promise(INTERNAL); | 
|     var ret = promise; | 
|     if (context) context._pushContext(); | 
|     promise._captureStackTrace(); | 
|     if (context) context._popContext(); | 
|     var synchronous = true; | 
|     var result = util.tryCatch(then).call(x, resolve, reject); | 
|     synchronous = false; | 
|   | 
|     if (promise && result === errorObj) { | 
|         promise._rejectCallback(result.e, true, true); | 
|         promise = null; | 
|     } | 
|   | 
|     function resolve(value) { | 
|         if (!promise) return; | 
|         promise._resolveCallback(value); | 
|         promise = null; | 
|     } | 
|   | 
|     function reject(reason) { | 
|         if (!promise) return; | 
|         promise._rejectCallback(reason, synchronous, true); | 
|         promise = null; | 
|     } | 
|     return ret; | 
| } | 
|   | 
| return tryConvertToPromise; | 
| }; |