docs: private IQ receiveSessionInitiateAction(JingleSession session, Jingle inJingle) throws SmackException, InterruptedException {
  
          IQ response;
          boolean shouldAck = true;
  
          // According to XEP-166 when we get a session-initiate we need to check for:
          //      1. Initiator unknown
          //      2. Receiver redirection
          //      3. Does not support Jingle
          //      4. Does not support any <description> formats
          //      5. Does not support any <transport> formats
          // If all of the above are OK then we send an IQ type = result to ACK the session-initiate.
  
          // 1. Initiator unknown
          // TODO
  
          // 2. Receiver redirection
          // TODO
  
          // 3. Does not support Jingle
          // Handled by Smack's lower layer.
  
          // 4. Does not support any <description> formats
          // TODO
  
          // 5. Does not support any <transport> formats
          // TODO
  
          if (!shouldAck) {
  
              response = session.createJingleError(inJingle, JingleError.NEGOTIATION_ERROR);
  
          } else {
  
              // Create the Ack
              response = session.createAck(inJingle);
  
              session.setSessionState(JingleSessionStatePending.getInstance());
  
              // Now set up all of the initial content negotiators for the session.
              for (JingleContent jingleContent : inJingle.getContentsList()) {
                  // First create the content negotiator for this <content> section.
                  ContentNegotiator contentNeg = new ContentNegotiator(session, jingleContent.getCreator(), jingleContent
                          .getName());
  
                  // Get the media negotiator that goes with the <description> of this content.
                  JingleDescription jingleDescription = jingleContent.getDescription();
  
                  // Loop through each media manager looking for the ones that matches the incoming
                  // session-initiate <content> choices.
                  // (Set the first media manager as the default, so that in case things don't match we can still negotiate.)
                  JingleMediaManager chosenMediaManager = session.getMediaManagers().get(0);
                  for (JingleMediaManager mediaManager : session.getMediaManagers()) {
                      boolean matches = true;
                      for (PayloadType mediaPayloadType : mediaManager.getPayloads()) {
                          for (PayloadType descPayloadType2 : jingleDescription.getPayloadTypesList()) {
                              if (mediaPayloadType.getId() != descPayloadType2.getId()) {
                                  matches = false;
                              }
                          }
                          if (matches) {
                              chosenMediaManager = mediaManager;
                          }
                      }
                  }
  
                  // Create the media negotiator for this content description.
                  contentNeg.setMediaNegotiator(new MediaNegotiator(session, chosenMediaManager, jingleDescription
                          .getPayloadTypesList(), contentNeg));
  
                  // For each transport type in this content, try to find the corresponding transport manager.
                  // Then create a transport negotiator for that transport.
                  for (JingleTransport jingleTransport : jingleContent.getJingleTransportsList()) {
                      for (JingleMediaManager mediaManager : session.getMediaManagers()) {
  
                          JingleTransportManager transportManager = mediaManager.getTransportManager();
                          TransportResolver resolver = null;
                          try {
                              resolver = transportManager.getResolver(session);
                          } catch (XMPPException e) {
                              LOGGER.log(Level.WARNING, "exception", e);
                          }
  
                          if (resolver.getType().equals(TransportResolver.Type.rawupd)) {
                              contentNeg.setTransportNegotiator(new TransportNegotiator.RawUdp(session, resolver, contentNeg));
                          }
                          if (resolver.getType().equals(TransportResolver.Type.ice)) {
                              contentNeg.setTransportNegotiator(new TransportNegotiator.Ice(session, resolver, contentNeg));
                          }
                      }
                  }
  
                  // Add the content negotiator to the session.
                  session.addContentNegotiator(contentNeg);
              }
  
              // Now setup to track the media negotiators, so that we know when (if) to send a session-accept.
              session.setupListeners();
          }
  
          return response;
      }