public void startFileTransfer() {
    if (fileTransfer.isReceiver()) {
      MsnslpMessage msnslpRequest = fileTransfer.getReqMessage().getSlpMessage();
      MsnslpResponse okSlpMessage = new MsnslpResponse();
      okSlpMessage.setTo(msnslpRequest.getFrom());
      okSlpMessage.setFrom(msnslpRequest.getTo());
      okSlpMessage.setVia(msnslpRequest.getVia());
      okSlpMessage.setCSeq(msnslpRequest.getCSeq() + 1);
      okSlpMessage.setCallId(msnslpRequest.getCallId());
      okSlpMessage.setMaxForwards(msnslpRequest.getMaxForwards());
      okSlpMessage.setContentType(msnslpRequest.getContentType());

      StringHolder body = new StringHolder();
      body.setProperty("SessionID", fileTransfer.getID());

      okSlpMessage.setBody(body.toString() + JmlConstants.LINE_SEPARATOR + "\0");

      int okSlpMessageLength = Charset.encodeAsByteArray(okSlpMessage.toString()).length;

      MsnP2PSlpMessage okMessage = new MsnP2PSlpMessage();
      okMessage.setSlpMessage(okSlpMessage);
      okMessage.setIdentifier(getNextIdentifier());
      okMessage.setTotalLength(okSlpMessageLength);
      okMessage.setCurrentLength(okSlpMessageLength);
      okMessage.setField7(NumberUtils.getIntRandom());
      okMessage.setFlag(MsnP2PMessage.FLAG_OLD_NONE);
      okMessage.setP2PDest(fileTransfer.getEmail().getEmailAddress());

      OutgoingMSG[] outgoingOkMessages =
          okMessage.toOutgoingMsg(fileTransfer.getSession().getMessenger().getActualMsnProtocol());
      for (OutgoingMSG outgoingOkMessage : outgoingOkMessages) {
        fileTransfer.getSession().sendSynchronousMessage(outgoingOkMessage);
      }
    } else {
      try {
        if (fileInput == null) {
          fileInput = new FileInputStream(fileTransfer.getFile());
          // increase identifier
          getNextIdentifier();
        }

        int remaining = (int) (fileTransfer.getFile().length() - fileOffset);

        int dataLength =
            remaining > MsnP2PDataMessage.MAX_DATA_LENGTH
                ? MsnP2PDataMessage.MAX_DATA_LENGTH
                : remaining;

        byte data[] = new byte[dataLength];
        fileInput.read(data);

        MsnP2PDataMessage dataMessage =
            new MsnP2PDataMessage(
                Integer.parseInt(fileTransfer.getID()),
                getLastIdentifier(),
                (int) fileOffset,
                (int) fileTransfer.getFileTotalSize(),
                data,
                fileTransfer.getEmail().getEmailAddress()) {
              protected void receivedResponse(MsnSession session, MsnIncomingMessage response) {
                try {
                  int remaining = (int) (fileTransfer.getFile().length() - fileOffset);

                  if (remaining == 0) {
                    fileTransfer.setState(MsnFileTransferState.COMPLETED);

                    ((AbstractMessenger) fileTransfer.getSession().getMessenger())
                        .fireFileTransferFinished(fileTransfer);
                    return;
                  }

                  if (fileTransfer.getState() == MsnFileTransferState.CANCELED) return;

                  binaryHeader.rewind();

                  int dataLength =
                      remaining > MsnP2PDataMessage.MAX_DATA_LENGTH
                          ? MsnP2PDataMessage.MAX_DATA_LENGTH
                          : remaining;

                  byte data[] = new byte[dataLength];
                  fileInput.read(data);

                  setCurrentLength(data.length);
                  parseP2PBody(ByteBuffer.wrap(data));

                  setOffset(fileOffset);

                  fileOffset += data.length;

                  fileTransfer.setTransferredSize(getOffset());
                  ((AbstractMessenger) fileTransfer.getSession().getMessenger())
                      .fireFileTransferProcess(fileTransfer);

                  OutgoingMSG[] outgoingMessages =
                      toOutgoingMsg(session.getMessenger().getActualMsnProtocol());
                  for (OutgoingMSG outgoingMessage : outgoingMessages) {
                    switchboard.send(outgoingMessage);
                  }
                } catch (IOException e) {
                  logger.info("Cannot send file", e);
                }
              }
            };
        dataMessage.setFlag(MsnP2PMessage.FLAG_OLD_DATA);
        fileOffset += data.length;

        fileTransfer.setTransferredSize(fileOffset);
        ((AbstractMessenger) fileTransfer.getSession().getMessenger())
            .fireFileTransferProcess(fileTransfer);

        OutgoingMSG[] outgoingDataMessages =
            dataMessage.toOutgoingMsg(
                fileTransfer.getSession().getMessenger().getActualMsnProtocol());
        for (OutgoingMSG outgoingDataMessage : outgoingDataMessages) {
          switchboard.send(outgoingDataMessage);
        }
      } catch (FileNotFoundException ex) {
        logger.error("Cannot open file", ex);
      } catch (IOException ex) {
        logger.error("Cannot read from file", ex);
      }
    }
  }
  public void sendDeny(MsnP2PSlpMessage msg) {
    MsnslpRequest msnslpRequest = (MsnslpRequest) msg.getSlpMessage();
    MsnslpResponse okSlpMessage = new MsnslpResponse();
    okSlpMessage.setStatusCode(405);
    okSlpMessage.setReasonPhrase("Not supported");
    okSlpMessage.setTo(msnslpRequest.getFrom());
    okSlpMessage.setFrom(msnslpRequest.getTo());
    okSlpMessage.setVia(msnslpRequest.getVia());
    okSlpMessage.setCSeq(msnslpRequest.getCSeq() + 1);
    okSlpMessage.setCallId(msnslpRequest.getCallId());
    okSlpMessage.setMaxForwards(msnslpRequest.getMaxForwards());
    okSlpMessage.setContentType(msnslpRequest.getContentType());

    StringHolder body = new StringHolder();
    body.setProperty("SessionID", fileTransfer.getID());
    okSlpMessage.setBody(body.toString() + JmlConstants.LINE_SEPARATOR + "\0");

    int okSlpMessageLength = Charset.encodeAsByteArray(okSlpMessage.toString()).length;

    MsnP2PSlpMessage okMessage = new MsnP2PSlpMessage();
    okMessage.setSlpMessage(okSlpMessage);
    okMessage.setIdentifier(getNextIdentifier());
    okMessage.setTotalLength(okSlpMessageLength);
    okMessage.setCurrentLength(okSlpMessageLength);
    okMessage.setField7(NumberUtils.getIntRandom());
    okMessage.setP2PDest(fileTransfer.getEmail().getEmailAddress());

    OutgoingMSG[] outgoingOkMessages =
        okMessage.toOutgoingMsg(fileTransfer.getSession().getMessenger().getActualMsnProtocol());
    for (OutgoingMSG outgoingOkMessage : outgoingOkMessages) {
      fileTransfer.getSession().sendSynchronousMessage(outgoingOkMessage);
    }
  }