/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

/*
 * This file is auto-generated by Qpid Gentools v.0.1 - do not modify.
 * Supported AMQP version:
  *   0-9
  *   0-91
  *   8-0
  */

package org.apache.qpid.framing;

import org.apache.qpid.QpidException;

public interface ClientMethodDispatcher
{

    public boolean dispatchBasicCancelOk(BasicCancelOkBody body, int channelId) throws QpidException;
    public boolean dispatchBasicConsumeOk(BasicConsumeOkBody body, int channelId) throws QpidException;
    public boolean dispatchBasicDeliver(BasicDeliverBody body, int channelId) throws QpidException;
    public boolean dispatchBasicGetEmpty(BasicGetEmptyBody body, int channelId) throws QpidException;
    public boolean dispatchBasicGetOk(BasicGetOkBody body, int channelId) throws QpidException;
    public boolean dispatchBasicQosOk(BasicQosOkBody body, int channelId) throws QpidException;
    public boolean dispatchBasicReturn(BasicReturnBody body, int channelId) throws QpidException;
    public boolean dispatchChannelClose(ChannelCloseBody body, int channelId) throws QpidException;
    public boolean dispatchChannelCloseOk(ChannelCloseOkBody body, int channelId) throws QpidException;
    public boolean dispatchChannelFlow(ChannelFlowBody body, int channelId) throws QpidException;
    public boolean dispatchChannelFlowOk(ChannelFlowOkBody body, int channelId) throws QpidException;
    public boolean dispatchChannelOpenOk(ChannelOpenOkBody body, int channelId) throws QpidException;
    public boolean dispatchConnectionClose(ConnectionCloseBody body, int channelId) throws QpidException;
    public boolean dispatchConnectionCloseOk(ConnectionCloseOkBody body, int channelId) throws QpidException;
    public boolean dispatchConnectionOpenOk(ConnectionOpenOkBody body, int channelId) throws QpidException;
    public boolean dispatchConnectionSecure(ConnectionSecureBody body, int channelId) throws QpidException;
    public boolean dispatchConnectionStart(ConnectionStartBody body, int channelId) throws QpidException;
    public boolean dispatchConnectionTune(ConnectionTuneBody body, int channelId) throws QpidException;
    public boolean dispatchExchangeBoundOk(ExchangeBoundOkBody body, int channelId) throws QpidException;
    public boolean dispatchExchangeDeclareOk(ExchangeDeclareOkBody body, int channelId) throws QpidException;
    public boolean dispatchExchangeDeleteOk(ExchangeDeleteOkBody body, int channelId) throws QpidException;
    public boolean dispatchQueueBindOk(QueueBindOkBody body, int channelId) throws QpidException;
    public boolean dispatchQueueDeclareOk(QueueDeclareOkBody body, int channelId) throws QpidException;
    public boolean dispatchQueueDeleteOk(QueueDeleteOkBody body, int channelId) throws QpidException;
    public boolean dispatchQueuePurgeOk(QueuePurgeOkBody body, int channelId) throws QpidException;
    public boolean dispatchTxCommitOk(TxCommitOkBody body, int channelId) throws QpidException;
    public boolean dispatchTxRollbackOk(TxRollbackOkBody body, int channelId) throws QpidException;
    public boolean dispatchTxSelectOk(TxSelectOkBody body, int channelId) throws QpidException;

    boolean dispatchConnectionRedirect(ConnectionRedirectBody connectionRedirectBody, int channelId) throws
                                                                                                     QpidException;
    boolean dispatchAccessRequestOk(AccessRequestOkBody accessRequestOkBody, int channelId) throws QpidException;

    boolean dispatchQueueUnbindOk(QueueUnbindOkBody queueUnbindOkBody, int channelId) throws QpidException;

    boolean dispatchBasicRecoverSyncOk(BasicRecoverSyncOkBody basicRecoverSyncOkBody, int channelId)
            throws QpidException;

    boolean dispatchChannelAlert(ChannelAlertBody channelAlertBody, int channelId) throws QpidException;

    boolean dispatchConfirmSelectOk(ConfirmSelectOkBody confirmSelectOkBody, int channelId) throws QpidException;
}
