public synchronized ProtocolOutputConverter newInstance(AMQProtocolSession session) {
      if (_methodRegistry == null) {

        _methodRegistry = MethodRegistry.getMethodRegistry(_protocolVersion);
      }
      return new ProtocolOutputConverterImpl(session, _methodRegistry);
    }
  public void methodReceived(AMQStateManager stateManager, ExchangeDeclareBody body, int channelId)
      throws AMQException {
    AMQProtocolSession session = stateManager.getProtocolSession();
    VirtualHost virtualHost = session.getVirtualHost();
    ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
    ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory();
    final AMQChannel channel = session.getChannel(channelId);
    if (channel == null) {
      throw body.getChannelNotFoundException(channelId);
    }

    final AMQShortString exchangeName = body.getExchange();
    if (_logger.isDebugEnabled()) {
      _logger.debug(
          "Request to declare exchange of type " + body.getType() + " with name " + exchangeName);
    }

    synchronized (exchangeRegistry) {
      Exchange exchange = exchangeRegistry.getExchange(exchangeName);

      if (exchange == null) {
        if (body.getPassive() && ((body.getType() == null) || body.getType().length() == 0)) {
          throw body.getChannelException(
              AMQConstant.NOT_FOUND, "Unknown exchange: " + exchangeName);
        } else if (exchangeName.startsWith("amq.")) {
          throw body.getConnectionException(
              AMQConstant.NOT_ALLOWED,
              "Attempt to declare exchange: "
                  + exchangeName
                  + " which begins with reserved prefix 'amq.'.");
        } else if (exchangeName.startsWith("qpid.")) {
          throw body.getConnectionException(
              AMQConstant.NOT_ALLOWED,
              "Attempt to declare exchange: "
                  + exchangeName
                  + " which begins with reserved prefix 'qpid.'.");
        } else {
          try {
            exchange =
                exchangeFactory.createExchange(
                    exchangeName == null ? null : exchangeName.intern(),
                    body.getType() == null ? null : body.getType().intern(),
                    body.getDurable(),
                    body.getAutoDelete(),
                    body.getTicket());
            exchangeRegistry.registerExchange(exchange);

            if (exchange.isDurable()) {
              virtualHost.getMessageStore().createExchange(exchange);
            }
          } catch (AMQUnknownExchangeType e) {
            throw body.getConnectionException(
                AMQConstant.COMMAND_INVALID, "Unknown exchange: " + exchangeName, e);
          }
        }
      } else if (!exchange.getTypeShortString().equals(body.getType())
          && !((body.getType() == null || body.getType().length() == 0) && body.getPassive())) {

        throw new AMQConnectionException(
            AMQConstant.NOT_ALLOWED,
            "Attempt to redeclare exchange: "
                + exchangeName
                + " of type "
                + exchange.getTypeShortString()
                + " to "
                + body.getType()
                + ".",
            body.getClazz(),
            body.getMethod(),
            body.getMajor(),
            body.getMinor(),
            null);
      }
    }
    if (!body.getNowait()) {
      MethodRegistry methodRegistry = session.getMethodRegistry();
      AMQMethodBody responseBody = methodRegistry.createExchangeDeclareOkBody();
      channel.sync();
      session.writeFrame(responseBody.generateFrame(channelId));
    }
  }