@Override
  public InputStream createIncomingStream(StreamInitiation initiation)
      throws XMPPException, InterruptedException {
    /*
     * SOCKS5 initiation listener must ignore next SOCKS5 Bytestream request with given session
     * ID
     */
    this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());

    Packet streamInitiation = initiateIncomingStream(this.connection, initiation);
    return negotiateIncomingStream(streamInitiation);
  }
  @Override
  public StreamInitiation parse(XmlPullParser parser, int initialDepth) throws Exception {
    boolean done = false;

    // si
    String id = parser.getAttributeValue("", "id");
    String mimeType = parser.getAttributeValue("", "mime-type");

    StreamInitiation initiation = new StreamInitiation();

    // file
    String name = null;
    String size = null;
    String hash = null;
    String date = null;
    String desc = null;
    boolean isRanged = false;

    // feature
    DataForm form = null;
    DataFormProvider dataFormProvider = new DataFormProvider();

    int eventType;
    String elementName;
    String namespace;
    while (!done) {
      eventType = parser.next();
      elementName = parser.getName();
      namespace = parser.getNamespace();
      if (eventType == XmlPullParser.START_TAG) {
        if (elementName.equals("file")) {
          name = parser.getAttributeValue("", "name");
          size = parser.getAttributeValue("", "size");
          hash = parser.getAttributeValue("", "hash");
          date = parser.getAttributeValue("", "date");
        } else if (elementName.equals("desc")) {
          desc = parser.nextText();
        } else if (elementName.equals("range")) {
          isRanged = true;
        } else if (elementName.equals("x") && namespace.equals("jabber:x:data")) {
          form = dataFormProvider.parse(parser);
        }
      } else if (eventType == XmlPullParser.END_TAG) {
        if (elementName.equals("si")) {
          done = true;
        } else if (elementName.equals("file")) {
          long fileSize = 0;
          if (size != null && size.trim().length() != 0) {
            try {
              fileSize = Long.parseLong(size);
            } catch (NumberFormatException e) {
              LOGGER.log(Level.SEVERE, "Failed to parse file size from " + fileSize, e);
            }
          }

          Date fileDate = new Date();
          if (date != null) {
            try {
              fileDate = XmppDateTime.parseDate(date);
            } catch (ParseException e) {
              // couldn't parse date, use current date-time
            }
          }

          File file = new File(name, fileSize);
          file.setHash(hash);
          file.setDate(fileDate);
          file.setDesc(desc);
          file.setRanged(isRanged);
          initiation.setFile(file);
        }
      }
    }

    initiation.setSessionID(id);
    initiation.setMimeType(mimeType);

    initiation.setFeatureNegotiationForm(form);

    return initiation;
  }