docs: public synchronized boolean incrementPayment(Coin refundSize, byte[] signatureBytes)
              throws SignatureDecodeException, VerificationException, ValueOutOfRangeException,
              InsufficientMoneyException {
          stateMachine.checkState(State.READY);
          checkNotNull(refundSize);
          checkNotNull(signatureBytes);
          TransactionSignature signature = TransactionSignature.decodeFromBitcoin(signatureBytes, true, false);
          // We allow snapping to zero for the payment amount because it's treated specially later, but not less than
          // the dust level because that would prevent the transaction from being relayed/mined.
          final boolean fullyUsedUp = refundSize.equals(Coin.ZERO);
          Coin newValueToMe = getTotalValue().subtract(refundSize);
          if (newValueToMe.signum() < 0)
              throw new ValueOutOfRangeException("Attempt to refund more than the contract allows.");
          if (newValueToMe.compareTo(bestValueToMe) < 0)
              throw new ValueOutOfRangeException("Attempt to roll back payment on the channel.");
  
          SendRequest req = makeUnsignedChannelContract(newValueToMe);
  
          if (!fullyUsedUp && refundSize.isLessThan(req.tx.getOutput(0).getMinNonDustValue()))
              throw new ValueOutOfRangeException("Attempt to refund negative value or value too small to be accepted by the network");
  
          // Get the wallet's copy of the contract (ie with confidence information), if this is null, the wallet
          // was not connected to the peergroup when the contract was broadcast (which may cause issues down the road, and
          // disables our double-spend check next)
          Transaction walletContract = wallet.getTransaction(contract.getTxId());
          checkNotNull(walletContract, "Wallet did not contain multisig contract {} after state was marked READY", contract.getTxId());
  
          // Note that we check for DEAD state here, but this test is essentially useless in production because we will
          // miss most double-spends due to bloom filtering right now anyway. This will eventually fixed by network-wide
          // double-spend notifications, so we just wait instead of attempting to add all dependant outpoints to our bloom
          // filters (and probably missing lots of edge-cases).
          if (walletContract.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.DEAD) {
              close();
              throw new VerificationException("Multisig contract was double-spent");
          }
  
          Transaction.SigHash mode;
          // If the client doesn't want anything back, they shouldn't sign any outputs at all.
          if (fullyUsedUp)
              mode = Transaction.SigHash.NONE;
          else
              mode = Transaction.SigHash.SINGLE;
  
          if (signature.sigHashMode() != mode || !signature.anyoneCanPay())
              throw new VerificationException("New payment signature was not signed with the right SIGHASH flags.");
  
          // Now check the signature is correct.
          // Note that the client must sign with SIGHASH_{SINGLE/NONE} | SIGHASH_ANYONECANPAY to allow us to add additional
          // inputs (in case we need to add significant fee, or something...) and any outputs we want to pay to.
          Sha256Hash sighash = req.tx.hashForSignature(0, getSignedScript(), mode, true);
  
          if (!getClientKey().verify(sighash, signature))
              throw new VerificationException("Signature does not verify on tx\n" + req.tx);
          bestValueToMe = newValueToMe;
          bestValueSignature = signatureBytes;
          updateChannelInWallet();
          return !fullyUsedUp;
      }