/**
   * Selects an appropriate stream negotiator after examining the incoming file transfer request.
   *
   * @param request The related file transfer request.
   * @return The file transfer object that handles the transfer
   * @throws XMPPException If there are either no stream methods contained in the packet, or there
   *     is not an appropriate stream method.
   */
  public StreamNegotiator selectStreamNegotiator(FileTransferRequest request) throws XMPPException {
    final StreamInitiation si = request.getStreamInitiation();
    final FormField streamMethodField = getStreamMethodField(si.getFeatureNegotiationForm());

    if (streamMethodField == null) {
      final String errorMessage = "No stream methods contained in packet.";
      final XMPPError error = new XMPPError(XMPPError.Condition.bad_request, errorMessage);
      final IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(), IQ.Type.ERROR);
      iqPacket.setError(error);
      connection.sendPacket(iqPacket);
      throw new XMPPException(errorMessage, error);
    }

    // select the appropriate protocol

    StreamNegotiator selectedStreamNegotiator;
    try {
      selectedStreamNegotiator = getNegotiator(streamMethodField);
    } catch (final XMPPException e) {
      final IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(), IQ.Type.ERROR);
      iqPacket.setError(e.getXMPPError());
      connection.sendPacket(iqPacket);
      throw e;
    }

    // return the appropriate negotiator

    return selectedStreamNegotiator;
  }
  protected void rejectIncomingFileTransfer(FileTransferRequest request) {
    StreamInitiation initiation = request.getStreamInitiation();

    IQ rejection =
        FileTransferNegotiator.createIQ(
            initiation.getPacketID(), initiation.getFrom(), initiation.getTo(), IQ.Type.ERROR);
    rejection.setError(new XMPPError(XMPPError.Condition.no_acceptable));
    connection.sendPacket(rejection);
  }
    /**
     * Listens for file transfer packets.
     *
     * @param packet packet to be processed
     */
    public void processPacket(Packet packet) {
      if (!(packet instanceof StreamInitiation)) return;

      if (logger.isDebugEnabled()) logger.debug("Incoming Jabber file transfer request.");

      StreamInitiation streamInitiation = (StreamInitiation) packet;

      FileTransferRequest jabberRequest = new FileTransferRequest(manager, streamInitiation);

      // Create a global incoming file transfer request.
      IncomingFileTransferRequestJabberImpl incomingFileTransferRequest =
          new IncomingFileTransferRequestJabberImpl(
              jabberProvider, OperationSetFileTransferJabberImpl.this, jabberRequest);

      // Send a thumbnail request if a thumbnail is advertised in the
      // streamInitiation packet.
      org.jivesoftware.smackx.packet.StreamInitiation.File file = streamInitiation.getFile();

      boolean isThumbnailedFile = false;
      if (file instanceof FileElement) {
        ThumbnailElement thumbnailElement = ((FileElement) file).getThumbnailElement();

        if (thumbnailElement != null) {
          isThumbnailedFile = true;
          incomingFileTransferRequest.createThumbnailListeners(thumbnailElement.getCid());

          ThumbnailIQ thumbnailRequest =
              new ThumbnailIQ(
                  streamInitiation.getTo(),
                  streamInitiation.getFrom(),
                  thumbnailElement.getCid(),
                  IQ.Type.GET);

          if (logger.isDebugEnabled())
            logger.debug("Sending thumbnail request:" + thumbnailRequest.toXML());

          jabberProvider.getConnection().sendPacket(thumbnailRequest);
        }
      }

      if (!isThumbnailedFile) {
        // Create an event associated to this global request.
        FileTransferRequestEvent fileTransferRequestEvent =
            new FileTransferRequestEvent(
                OperationSetFileTransferJabberImpl.this, incomingFileTransferRequest, new Date());

        // Notify the global listener that a request has arrived.
        fireFileTransferRequest(fileTransferRequestEvent);
      }
    }
 /**
  * Reject a stream initiation request from a remote user.
  *
  * @param si The Stream Initiation request to reject.
  */
 public void rejectStream(final StreamInitiation si) {
   final XMPPError error = new XMPPError(XMPPError.Condition.forbidden, "Offer Declined");
   final IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(), IQ.Type.ERROR);
   iqPacket.setError(error);
   connection.sendPacket(iqPacket);
 }