function Promise.prototype._andThen(P,z,p,u)P._unhandledRejection=false if P._status==Promise.Status.Cancelled then local z=Promise.new(function() end)z:cancel()return z end return Promise._new(z,function(U,d,T)local D=U if p then D=createAdvancer(z,p,U,d)end local B=d if u then B=createAdvancer(z,u,U,d)end if P._status==Promise.Status.Started then table.insert(P._queuedResolve,D)table.insert(P._queuedReject,B)T(function()if P._status==Promise.Status.Started then table.remove(P._queuedResolve,table.find(P._queuedResolve,D))table.remove(P._queuedReject,table.find(P._queuedReject,B))end end)elseif P._status==Promise.Status.Resolved then D(unpack(P._values,1,P._valuesLength))elseif P._status==Promise.Status.Rejected then B(unpack(P._values,1,P._valuesLength))end end,P)end

function Promise.prototype:_andThen(traceback, successHandler, failureHandler)
	self._unhandledRejection = false

	-- If we are already cancelled, we return a cancelled Promise
	if self._status == Promise.Status.Cancelled then
		local promise = Promise.new(function() end)
		promise:cancel()

		return promise
	end

	-- Create a new promise to follow this part of the chain
	return Promise._new(traceback, function(resolve, reject, onCancel)
		-- Our default callbacks just pass values onto the next promise.
		-- This lets success and failure cascade correctly!

		local successCallback = resolve
		if successHandler then
			successCallback = createAdvancer(traceback, successHandler, resolve, reject)
		end

		local failureCallback = reject
		if failureHandler then
			failureCallback = createAdvancer(traceback, failureHandler, resolve, reject)
		end

		if self._status == Promise.Status.Started then
			-- If we haven't resolved yet, put ourselves into the queue
			table.insert(self._queuedResolve, successCallback)
			table.insert(self._queuedReject, failureCallback)

			onCancel(function()
				-- These are guaranteed to exist because the cancellation handler is guaranteed to only
				-- be called at most once
				if self._status == Promise.Status.Started then
					table.remove(self._queuedResolve, table.find(self._queuedResolve, successCallback))
					table.remove(self._queuedReject, table.find(self._queuedReject, failureCallback))
				end
			end)
		elseif self._status == Promise.Status.Resolved then
			-- This promise has already resolved! Trigger success immediately.
			successCallback(unpack(self._values, 1, self._valuesLength))
		elseif self._status == Promise.Status.Rejected then
			-- This promise died a terrible death! Trigger failure immediately.
			failureCallback(unpack(self._values, 1, self._valuesLength))
		end
	end, self)
end
