public FileTransferHandler sendFile(final File aFile, final String aPeer) {
    // create a new FilePacketIO for this file transfer
    FilePacketIO theIO = FilePacketIO.createForRead(aFile, myPacketSize);
    // store it
    FileSender theFileSender = new FileSender(aPeer, theIO, this);
    mySendingFiles.put(theIO.getId(), theFileSender);
    notifyNewTransfer(theIO.getId());
    theFileSender.startAsync(myFileSenderService);

    return new FileTransferHandler(theIO.getId(), this);
  }
  @Override
  public void setFileTransferResponse(AcceptFileResponse aResponse)
      throws AsyncFileTransferException {
    if (!myPendingTransfers.containsKey(aResponse.getTransferId()))
      throw new AsyncFileTransferException(
          "No pending transfer with id '" + aResponse.getTransferId() + "'");

    PendingTransfer thePendingTransfer = myPendingTransfers.remove(aResponse.getTransferId());

    try {
      AbstractPeer theSender =
          getRoutingTable().getEntryForPeer(thePendingTransfer.getPeer()).getPeer();
      testReachable(thePendingTransfer.getPeer());

      if (aResponse.getResponse() == AcceptFileResponse.Response.REFUSED) {
        sendMessageAsyncTo(
            theSender, Command.TRANSFER_REFUSED.name() + ";" + thePendingTransfer.getUUId());
      } else if (aResponse.getResponse() == AcceptFileResponse.Response.ACCEPT) {
        FilePacketIO theIO =
            FilePacketIO.createForWrite(
                aResponse.getFile(),
                thePendingTransfer.getUUId(),
                thePendingTransfer.getPacketSize(),
                thePendingTransfer.getNrOfPackets());

        if (!myReceivingFiles.containsKey(thePendingTransfer.getUUId())) {
          myReceivingFiles.put(
              thePendingTransfer.getUUId(),
              new FileReceiver(
                  thePendingTransfer.getPeer(), theIO, AsyncFileTransferProtocol.this));
          notifyNewTransfer(thePendingTransfer.getUUId());
        }

        myReceivingFiles.get(thePendingTransfer.getUUId()).setTransferring(true);

        // send a message to the sender that it can start sending
        sendMessageAsyncTo(
            theSender, Command.RESUME_TRANSFER.name() + ";" + thePendingTransfer.getUUId());
      }
    } catch (Exception e) {
      throw new AsyncFileTransferException(
          "Peer '" + thePendingTransfer.getPeer() + "' is not known");
    }
  }
  @Override
  public String handleCommand(String aSessionId, String anInput) {

    try {
      if (anInput.startsWith(Command.ACCEPT_FILE.name())) {
        if (myHandler == null) return Response.ABORT_FILE_TRANSFER.name();
        String[] theParams = anInput.substring(Command.ACCEPT_FILE.name().length() + 1).split(";");

        String theFileName = theParams[0];
        String theUUId = theParams[1];
        int thePacketSize = Integer.parseInt(theParams[2]);
        int theNrOfPackets = Integer.parseInt(theParams[3]);
        String thePeerId = theParams[4];

        if (!myReceivingFiles.containsKey(theUUId)) {
          AcceptFileResponse theResponse =
              myHandler.acceptFile(thePeerId, theFileName, theUUId, this);

          if (theResponse.getResponse() == AcceptFileResponse.Response.PENDING) {
            PendingTransfer thePendingTransfer =
                new PendingTransfer(theFileName, theUUId, thePeerId, thePacketSize, theNrOfPackets);
            myPendingTransfers.put(theUUId, thePendingTransfer);
            return Response.TRANSFER_PENDING.name();
          } else if (theResponse.getResponse() == AcceptFileResponse.Response.ACCEPT) {
            FilePacketIO theIO =
                FilePacketIO.createForWrite(
                    theResponse.getFile(), theUUId, thePacketSize, theNrOfPackets);
            myReceivingFiles.put(
                theUUId, new FileReceiver(thePeerId, theIO, AsyncFileTransferProtocol.this));
            myReceivingFiles.get(theUUId).setTransferring(true);
            notifyNewTransfer(theUUId);
            return Response.FILE_ACCEPTED.name();
          } else if (theResponse.getResponse() == AcceptFileResponse.Response.REFUSED) {
            return Response.FILE_REFUSED.name();
          }
        } else {
          myReceivingFiles.get(theUUId).setTransferring(true);
          return Response.FILE_ACCEPTED.name();
        }
      } else if (anInput.startsWith(Command.ACCEPT_PACKET.name())) {
        if (myHandler == null) return Response.ABORT_FILE_TRANSFER.name();
        String thePack = anInput.substring(Command.ACCEPT_PACKET.name().length() + 1);
        FilePacket thePacket = myObjectPerister.getObject(thePack);

        if (isSimulateLostPacket()) {
          LOGGER.debug("Simulating lost packet '" + thePacket.getPacket() + "'");
          return Response.NOK.name();
        }

        if (!myReceivingFiles.containsKey(thePacket.getId())) {
          return Response.UNKNOWN_ID.name();
        }

        FileReceiver theIO = myReceivingFiles.get(thePacket.getId());
        theIO.writePacket(thePacket);

        myHandler.fileTransfer(
            theIO.getFile().getName(), thePacket.getId(), theIO.getPercentageComplete());

        LOGGER.debug("Packet accepted '" + thePacket.getPacket() + "'");
        return Response.PACKET_OK.name();
      } else if (anInput.startsWith(Command.END_FILE_TRANSFER.name())) {
        if (myHandler == null) return Response.ABORT_FILE_TRANSFER.name();
        String[] theParams =
            anInput.substring(Command.END_FILE_TRANSFER.name().length() + 1).split(";");

        String theUUId = theParams[0];
        FilePacketIO theIO = myReceivingFiles.get(theUUId).getIO();
        if (theIO.isComplete()) {
          myHandler.fileSaved(theIO.getFile());
          return Response.END_FILE_TRANSFER_OK.name();
        } else {
          StringBuilder theIncompletePackets = new StringBuilder();
          for (int i = 0; i < theIO.getWrittenPackets().length; i++) {
            if (!theIO.getWrittenPackets()[i]) {
              theIncompletePackets.append(i);
              theIncompletePackets.append(";");
            }
          }
          return theIncompletePackets.toString();
        }
      } else if (anInput.startsWith(Command.STOP_TRANSFER.name())) {
        String[] theParams =
            anInput.substring(Command.STOP_TRANSFER.name().length() + 1).split(";");
        String theUUId = theParams[0];
        if (!mySendingFiles.containsKey(theUUId)) return Response.UNKNOWN_ID.name();

        iFileIO theSender = mySendingFiles.get(theUUId);
        theSender.stop();
        return Response.OK.name();
      } else if (anInput.startsWith(Command.TRANSFER_REFUSED.name())) {
        String[] theParams =
            anInput.substring(Command.TRANSFER_REFUSED.name().length() + 1).split(";");
        String theUUId = theParams[0];
        if (!mySendingFiles.containsKey(theUUId)) return Response.UNKNOWN_ID.name();

        iFileIO theSender = mySendingFiles.get(theUUId);
        theSender.refuse();
      } else if (anInput.startsWith(Command.CANCEL_TRANSFER.name())) {
        String[] theParams =
            anInput.substring(Command.CANCEL_TRANSFER.name().length() + 1).split(";");
        String theUUId = theParams[0];
        if (!mySendingFiles.containsKey(theUUId)) return Response.UNKNOWN_ID.name();

        iFileIO theSender = mySendingFiles.get(theUUId);
        theSender.cancel();
        return Response.OK.name();
      } else if (anInput.startsWith(Command.TRANSFER_CANCELLED.name())) {
        String[] theParams =
            anInput.substring(Command.TRANSFER_CANCELLED.name().length() + 1).split(";");
        String theUUId = theParams[0];
        if (!myReceivingFiles.containsKey(theUUId)) return Response.UNKNOWN_ID.name();
        iFileIO theFileIo = myReceivingFiles.get(theUUId);
        // only when the transfer was not completed
        // otherwise an already completed tranfer would be removed and the user can not know that
        // the transfer was done successfully
        if (!theFileIo.isComplete()) {
          myReceivingFiles.remove(theUUId);
          notifyTransferRemoved(theUUId);
        }
      } else if (anInput.startsWith(Command.RESUME_TRANSFER.name())) {
        String[] theParams =
            anInput.substring(Command.RESUME_TRANSFER.name().length() + 1).split(";");
        String theUUId = theParams[0];
        if (!mySendingFiles.containsKey(theUUId)) return Response.UNKNOWN_ID.name();
        LOGGER.debug("Resuming file transfer for transfer '" + theUUId + "'");
        resume(theUUId);
        return Response.OK.name();
      } else if (anInput.startsWith(Command.TRANSFER_STOPPED.name())) {
        String[] theParams =
            anInput.substring(Command.TRANSFER_STOPPED.name().length() + 1).split(";");
        String theUUId = theParams[0];
        if (!myReceivingFiles.containsKey(theUUId)) return Response.UNKNOWN_ID.name();

        FileReceiver theReceiver = myReceivingFiles.get(theUUId);
        theReceiver.setTransferring(false);
      }

    } catch (Exception e) {
      LOGGER.error("Error occured in ayncfiletransferprotocol", e);
      return Response.NOK.name();
    }

    // TODO Auto-generated method stub
    return null;
  }