def then(self, success=None, failure=None):
        """
        This method takes two optional arguments.  The first argument
        is used if the "self promise" is fulfilled and the other is
        used if the "self promise" is rejected.  In either case, this
        method returns another promise that effectively represents
        the result of either the first of the second argument (in the
        case that the "self promise" is fulfilled or rejected,
        respectively).

        Each argument can be either:
          * None - Meaning no action is taken
          * A function - which will be called with either the value
            of the "self promise" or the reason for rejection of
            the "self promise".  The function may return:
            * A value - which will be used to fulfill the promise
              returned by this method.
            * A promise - which, when fulfilled or rejected, will
              cascade its value or reason to the promise returned
              by this method.
          * A value - which will be assigned as either the value
            or the reason for the promise returned by this method
            when the "self promise" is either fulfilled or rejected,
            respectively.
        """
        ret = Promise()

        def callAndFulfill(v):
            """
            A callback to be invoked if the "self promise"
            is fulfilled.
            """
            try:
                # From 3.2.1, don't call non-functions values
                if _isFunction(success):
                    newvalue = success(v)
                    if _isPromise(newvalue):
                        newvalue.then(lambda v: ret.fulfill(v),
                                      lambda r: ret.reject(r))
                    else:
                        ret.fulfill(newvalue)
                elif success!=None:
                    # From 3.2.6.4
                    ret.fulfill(v)
                else:
                    pass
            except Exception as e:
                ret.reject(e)

        def callAndReject(r):
            """
            A callback to be invoked if the "self promise"
            is rejected.
            """
            try:
                if _isFunction(failure):
                    newvalue = failure(r)
                    if _isPromise(newvalue):
                        newvalue.then(lambda v: ret.fulfill(v),
                                      lambda r: ret.reject(r))
                    else:
                        ret.fulfill(newvalue)
                elif failure!=None:
                    # From 3.2.6.5
                    ret.reject(r)
                else:
                    pass
            except Exception as e:
                ret.reject(e)
        
        if self._state==self.PENDING:
            """
            If this is still pending, then add callbacks to the
            existing promise that call either the success or
            rejected functions supplied and then fulfill the
            promise being returned by this method
            """
            if success!=None:
                self._callbacks.append(callAndFulfill)
            if failure!=None:
                self._errbacks.append(callAndReject)

        elif self._state==self.FULFILLED:
            """
            If this promise was already fulfilled, then
            we need to use the first argument to this method
            to determine the value to use in fulfilling the
            promise that we return from this method.
            """
            try:
                if _isFunction(success):
                    newvalue = success(self.value)
                    if _isPromise(newvalue):
                        newvalue.then(lambda v: ret.fulfill(v),
                                      lambda r: ret.reject(r))
                    else:
                        ret.fulfill(newvalue)
                elif success!=None:
                    # From 3.2.6.4
                    ret.fulfill(self.value)
                else:
                    pass
            except Exception as e:
                ret.reject(e)
        elif self._state==self.REJECTED:
            """
            If this promise was already rejected, then
            we need to use the second argument to this method
            to determine the value to use in fulfilling the
            promise that we return from this method.
            """
            try:
                if _isFunction(failure):
                    newvalue = failure(self.reason)
                    if _isPromise(newvalue):
                        newvalue.then(lambda v: ret.fulfill(v),
                                      lambda r: ret.reject(r))
                    else:
                        ret.fulfill(newvalue)
                elif failure!=None:
                    # From 3.2.6.5
                    ret.reject(self.reason)
                else:
                    pass
            except Exception as e:
                ret.reject(e)

        return ret