class RelaySession extends MediaProxySession {

    /**
     * Creates a new Smart Session to provide connectivity between Host A and Host B.
     *
     * @param id        of the Session (Could be a Jingle session ID)
     * @param localhost The localhost IP that will listen for UDP packets
     * @param hostA     the hostname or IP of the point A of the Channel
     * @param portA     the port number point A of the Channel
     * @param hostB     the hostname or IP of the point B of the Channel
     * @param portB     the port number point B of the Channel
     * @param creator   the created name or description of the Channel
     * @param minPort   the minimal port number to be used by the proxy
     * @param maxPort   the maximun port number to be used by the proxy
     */
    public RelaySession(String id, String creator, String localhost, String hostA, int portA, String hostB, int portB,
                        int minPort, int maxPort) {
        super(id, creator, localhost, hostA, portA, hostB, portB, minPort, maxPort);
    }

    /**
     * Creates a new Smart Session to provide connectivity between Host A and Host B.
     *
     * @param id        of the Session (Could be a Jingle session ID)
     * @param localhost The localhost IP that will listen for UDP packets
     * @param hostA     the hostname or IP of the point A of the Channel
     * @param portA     the port number point A of the Channel
     * @param hostB     the hostname or IP of the point B of the Channel
     * @param portB     the port number point B of the Channel
     * @param creator   the created name or description of the Channel
     */
    public RelaySession(String id, String creator, String localhost, String hostA, int portA, String hostB, int portB) {
        super(id, creator, localhost, hostA, portA, hostB, portB, 10000, 20000);
    }

    @Override
    void createChannels() {<FILL_FUNCTION_BODY>}


    @Override
    void addChannelListeners() {
        super.addChannelListeners();
        // Add channel as listeners
        channelAtoB.addListener((DynamicAddressChannel) channelBtoA);
        channelAtoBControl.addListener((DynamicAddressChannel) channelBtoAControl);
        channelBtoA.addListener((DynamicAddressChannel) channelAtoB);
        channelBtoAControl.addListener((DynamicAddressChannel) channelAtoBControl);
    }
}

        channelAtoB = new DynamicAddressChannel(socketA, hostB, portB);
        channelAtoBControl = new DynamicAddressChannel(socketAControl, hostB, portB + 1);
        channelBtoA = new DynamicAddressChannel(socketB, hostA, portA);
        channelBtoAControl = new DynamicAddressChannel(socketBControl, hostA, portA + 1);
    
<methods>public void <init>(java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, int, int, int) ,public void addAgentListener(org.jivesoftware.openfire.mediaproxy.SessionListener) ,public void clearAgentListeners() ,public boolean datagramReceived(java.net.DatagramPacket) ,public void dispatchAgentStopped() ,public java.lang.String getCreator() ,public java.net.InetAddress getHostA() ,public java.net.InetAddress getHostB() ,public int getLocalPortA() ,public int getLocalPortB() ,public java.net.InetAddress getLocalhost() ,public java.lang.String getPass() ,public int getPortA() ,public int getPortB() ,public java.lang.String getSID() ,public long getTimestamp() ,public void removeAgentListener(org.jivesoftware.openfire.mediaproxy.SessionListener) ,public void run() ,public void sendFromPortA(java.lang.String, int) ,public void sendFromPortB(java.lang.String, int) ,public void setHostA(java.net.InetAddress) ,public void setHostB(java.net.InetAddress) ,public void setPortA(int) ,public void setPortB(int) ,public void stopAgent() <variables>private static final Logger Log,protected org.jivesoftware.openfire.mediaproxy.Channel channelAtoB,protected org.jivesoftware.openfire.mediaproxy.Channel channelAtoBControl,protected org.jivesoftware.openfire.mediaproxy.Channel channelBtoA,protected org.jivesoftware.openfire.mediaproxy.Channel channelBtoAControl,private java.lang.String creator,protected java.net.InetAddress hostA,protected java.net.InetAddress hostB,private java.lang.String id,private java.util.Timer idleTimer,private java.util.Timer lifeTimer,protected java.net.InetAddress localAddress,protected int localPortA,protected int localPortB,private int maxPort,private int minPort,private java.lang.String pass,protected int portA,protected int portB,private List<org.jivesoftware.openfire.mediaproxy.SessionListener> sessionListeners,protected java.net.DatagramSocket socketA,protected java.net.DatagramSocket socketAControl,protected java.net.DatagramSocket socketB,protected java.net.DatagramSocket socketBControl,protected java.lang.Thread threadAtoB,protected java.lang.Thread threadAtoBControl,protected java.lang.Thread threadBtoA,protected java.lang.Thread threadBtoAControl,private long timestamp