/**
   * Sends a message to a destination or manage subscriptions. If the the content type of the POST
   * is <code>application/x-www-form-urlencoded</code>, then the form parameters "destination",
   * "message" and "type" are used to pass a message or a subscription. If multiple messages or
   * subscriptions are passed in a single post, then additional parameters are shortened to "dN",
   * "mN" and "tN" where N is an index starting from 1. The type is either "send", "listen" or
   * "unlisten". For send types, the message is the text of the TextMessage, otherwise it is the ID
   * to be used for the subscription. If the content type is not <code>
   * application/x-www-form-urlencoded</code>, then the body of the post is sent as the message to a
   * destination that is derived from a query parameter, the URL or the default destination.
   *
   * @param request
   * @param response
   * @throws ServletException
   * @throws IOException
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    // lets turn the HTTP post into a JMS Message
    AjaxWebClient client = getAjaxWebClient(request);
    String messageIds = "";

    synchronized (client) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "POST client="
                + client
                + " session="
                + request.getSession().getId()
                + " clientId="
                + request.getParameter("clientId")
                + " info="
                + request.getPathInfo()
                + " contentType="
                + request.getContentType());
        // dump(request.getParameterMap());
      }

      int messages = 0;

      // loop until no more messages
      while (true) {
        // Get the message parameters. Multiple messages are encoded
        // with more compact parameter names.
        String destinationName =
            request.getParameter(messages == 0 ? "destination" : ("d" + messages));

        if (destinationName == null) {
          destinationName = request.getHeader("destination");
        }

        String message = request.getParameter(messages == 0 ? "message" : ("m" + messages));
        String type = request.getParameter(messages == 0 ? "type" : ("t" + messages));

        if (destinationName == null || message == null || type == null) {
          break;
        }

        try {
          Destination destination = getDestination(client, request, destinationName);

          if (LOG.isDebugEnabled()) {
            LOG.debug(
                messages
                    + " destination="
                    + destinationName
                    + " message="
                    + message
                    + " type="
                    + type);
            LOG.debug(destination + " is a " + destination.getClass().getName());
          }

          messages++;

          if ("listen".equals(type)) {
            AjaxListener listener = client.getListener();
            Map<MessageAvailableConsumer, String> consumerIdMap = client.getIdMap();
            Map<MessageAvailableConsumer, String> consumerDestinationNameMap =
                client.getDestinationNameMap();
            client.closeConsumer(destination); // drop any existing
            // consumer.
            MessageAvailableConsumer consumer =
                (MessageAvailableConsumer)
                    client.getConsumer(destination, request.getHeader(WebClient.selectorName));

            consumer.setAvailableListener(listener);
            consumerIdMap.put(consumer, message);
            consumerDestinationNameMap.put(consumer, destinationName);
            if (LOG.isDebugEnabled()) {
              LOG.debug("Subscribed: " + consumer + " to " + destination + " id=" + message);
            }
          } else if ("unlisten".equals(type)) {
            Map<MessageAvailableConsumer, String> consumerIdMap = client.getIdMap();
            Map<MessageAvailableConsumer, String> consumerDestinationNameMap =
                client.getDestinationNameMap();
            MessageAvailableConsumer consumer =
                (MessageAvailableConsumer)
                    client.getConsumer(destination, request.getHeader(WebClient.selectorName));

            consumer.setAvailableListener(null);
            consumerIdMap.remove(consumer);
            consumerDestinationNameMap.remove(consumer);
            client.closeConsumer(destination);
            if (LOG.isDebugEnabled()) {
              LOG.debug("Unsubscribed: " + consumer);
            }
          } else if ("send".equals(type)) {
            TextMessage text = client.getSession().createTextMessage(message);
            appendParametersToMessage(request, text);

            client.send(destination, text);
            messageIds += text.getJMSMessageID() + "\n";
            if (LOG.isDebugEnabled()) {
              LOG.debug("Sent " + message + " to " + destination);
            }
          } else {
            LOG.warn("unknown type " + type);
          }

        } catch (JMSException e) {
          LOG.warn("jms", e);
        }
      }
    }

    if ("true".equals(request.getParameter("poll"))) {
      try {
        // TODO return message IDs
        doMessages(client, request, response);
      } catch (JMSException e) {
        throw new ServletException("JMS problem: " + e, e);
      }
    } else {
      // handle simple POST of a message
      if (request.getContentLength() != 0
          && (request.getContentType() == null
              || !request
                  .getContentType()
                  .toLowerCase()
                  .startsWith("application/x-www-form-urlencoded"))) {
        try {
          Destination destination = getDestination(client, request);
          String body = getPostedMessageBody(request);
          TextMessage message = client.getSession().createTextMessage(body);
          appendParametersToMessage(request, message);

          client.send(destination, message);
          if (LOG.isDebugEnabled()) {
            LOG.debug("Sent to destination: " + destination + " body: " + body);
          }
          messageIds += message.getJMSMessageID() + "\n";
        } catch (JMSException e) {
          throw new ServletException(e);
        }
      }

      response.setContentType("text/plain");
      response.setHeader("Cache-Control", "no-cache");
      response.getWriter().print(messageIds);
    }
  }