 
 		return
 
+	genStackInfo = (reason, p) ->
+		stackInfo = []
+
+		trim = (str) -> str.replace /^\s+|\s+$/g
+
+		if isLongStackTrace and p[$promiseTrace]
+			push = (trace) ->
+				stackInfo.push trim trace
+
+			if p[$settlerTrace]
+				push p[$settlerTrace]
+
+			# Hope you guys could understand how the back trace works.
+			# We only have to iter through the tree from the bottom to root.
+			iter = (node) ->
+				return if not node
+				iter node._next
+				push node[$promiseTrace]
+				iter node._pre
+
+			iter p
+
+		stackStr = '\n' + stackInfo.join('\n')
+
+		clean = (stack, cleanPrev) ->
+			if cleanPrev
+				stack = stack.slice 0, stack.indexOf('\n' + $fromPrevious)
+
+			if typeof __filename == 'string'
+				stack.replace ///.+#{__filename}.+\n?///g, ''
+
+		return [(
+			if reason
+				if reason.stack
+					clean (trim reason.stack), true
+				else
+					reason
+			else
+				reason
+		), clean(stackStr)]
+
 	callHanler = (handler, value) ->
 		# 2.2.5
 		handler value

	@onUnhandledRejection: (reason, p) ->
		return if not isObject console

		stackInfo = []

		trim = (str) -> str.replace /^\s+|\s+$/g

		if isLongStackTrace and p[$promiseTrace]
			push = (trace) ->
				stackInfo.push trim trace

			if p[$settlerTrace]
				push p[$settlerTrace]

			# Hope you guys could understand how the back trace works.
			# We only have to iter through the tree from the bottom to root.
			iter = (node) ->
				return if not node
				iter node._next
				push node[$promiseTrace]
				iter node._pre

			iter p

		stackStr = '\n' + stackInfo.join('\n')

		clean = (stack) ->
			if typeof __filename == 'string'
				stack.replace ///.+#{__filename}.+\n?///g, ''

		console.error 'Unhandled Rejection:', (
			if reason
				if reason.stack
					clean trim reason.stack
				else
					reason
			else
				reason
		), clean(stackStr)

		return

	isLongStackTrace = false


	$tryCatchFn = null
	$tryErr = { e: null }
	$noop = {}
	$nil = undefined

	isObject = (obj) ->
		typeof obj == 'object'
