diff --git a/lib/fmj.jar b/lib/fmj.jar
index 2c9c69913dc13e1413f788cdfd4d035f96d9ce22..63ccd7b1e1574e9bca3db4a3ae58e4873c1689e0 100644
Binary files a/lib/fmj.jar and b/lib/fmj.jar differ
diff --git a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
index 5b021583759b65688b3bca6e5a5a0c7e90fb3533..6a97530907c2e327243f739fba6b8a79e7170448 100644
--- a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
@@ -502,10 +502,6 @@ public void close()
             csrcEngine = null;
         }
 
-        if (rtpConnector != null)
-            rtpConnector.removeTargets();
-        rtpConnectorTarget = null;
-
         if (rtpManager != null)
         {
             if (logger.isInfoEnabled())
@@ -544,6 +540,15 @@ public void close()
             }
         }
 
+        /*
+         * XXX Call AbstractRTPConnector#removeTargets() after
+         * StreamRTPManager#dispose(). Otherwise, the latter will try to send an
+         * RTCP BYE and there will be no targets to send it to.
+         */
+        if (rtpConnector != null)
+            rtpConnector.removeTargets();
+        rtpConnectorTarget = null;
+
         if (deviceSession != null)
             deviceSession.close();
     }
diff --git a/src/org/jitsi/impl/neomedia/RTCPConnectorInputStream.java b/src/org/jitsi/impl/neomedia/RTCPConnectorInputStream.java
index 9eb4c917a04e1421627211ee4b5a2ed2bb100a95..e8f10495a30aabb2e26aab6973b3fc7580e14a21 100644
--- a/src/org/jitsi/impl/neomedia/RTCPConnectorInputStream.java
+++ b/src/org/jitsi/impl/neomedia/RTCPConnectorInputStream.java
@@ -23,7 +23,7 @@ public class RTCPConnectorInputStream
     /**
      * List of feedback listeners;
      */
-    private final List<RTCPFeedbackListener> rtcpFeedbackListeners
+    private final List<RTCPFeedbackListener> listeners
         = new ArrayList<RTCPFeedbackListener>();
 
     /**
@@ -45,8 +45,57 @@ public RTCPConnectorInputStream(DatagramSocket socket)
      */
     public void addRTCPFeedbackListener(RTCPFeedbackListener listener)
     {
-        if(!rtcpFeedbackListeners.contains(listener))
-            rtcpFeedbackListeners.add(listener);
+        if (listener == null)
+            throw new NullPointerException("listener");
+        if(!listeners.contains(listener))
+            listeners.add(listener);
+    }
+
+    /**
+     * Notifies a specific list of <tt>RTCPFeedbackListener</tt>s about a
+     * specific RTCP feedback message if such a message can be parsed out of a
+     * specific <tt>byte</tt> buffer.
+     *
+     * @param source the object to be reported as the source of the
+     * <tt>RTCPFeedbackEvent</tt> to be fired
+     * @param buffer the <tt>byte</tt> buffer which may specific an RTCP
+     * feedback message
+     * @param offset the offset in <tt>buffer</tt> at which the reading of bytes
+     * is to begin
+     * @param length the number of bytes in <tt>buffer</tt> to be read for the
+     * purposes of parsing an RTCP feedback message and firing an
+     * <tt>RTPCFeedbackEvent</tt>
+     * @param listeners the list of <tt>RTCPFeedbackListener</tt>s to be
+     * notified about the specified RTCP feedback message if such a message can
+     * be parsed out of the specified <tt>buffer</tt>
+     */
+    public static void fireRTCPFeedbackReceived(
+            Object source,
+            byte[] buffer, int offset, int length,
+            List<RTCPFeedbackListener> listeners)
+    {
+        /*
+         * RTCP feedback message size is minimum 12 bytes:
+         * Version/Padding/Feedback message type: 1 byte
+         * Payload type: 1 byte
+         * Length: 2 bytes
+         * SSRC of packet sender: 4 bytes
+         * SSRC of media source: 4 bytes
+         */
+        if ((length >= 12) && !listeners.isEmpty())
+        {
+            int pt = buffer[offset + 1] & 0xFF;
+
+            if ((pt == RTCPFeedbackEvent.PT_PS)
+                    || (pt == RTCPFeedbackEvent.PT_TL))
+            {
+                int fmt = buffer[offset] & 0x1F;
+                RTCPFeedbackEvent evt = new RTCPFeedbackEvent(source, fmt, pt);
+
+                for (RTCPFeedbackListener l : listeners)
+                    l.rtcpFeedbackReceived(evt);
+            }
+        }
     }
 
     /**
@@ -56,65 +105,31 @@ public void addRTCPFeedbackListener(RTCPFeedbackListener listener)
      */
     public void removeRTCPFeedbackListener(RTCPFeedbackListener listener)
     {
-        rtcpFeedbackListeners.remove(listener);
+        listeners.remove(listener);
     }
 
     /**
      * Copies the content of the most recently received packet into
      * <tt>inBuffer</tt>.
      *
-     * @param inBuffer the <tt>byte[]</tt> that we'd like to copy the content
-     * of the packet to.
+     * @param buffer the <tt>byte[]</tt> that we'd like to copy the content of
+     * the packet to.
      * @param offset the position where we are supposed to start writing in
-     * <tt>inBuffer</tt>.
+     * <tt>buffer</tt>.
      * @param length the number of <tt>byte</tt>s available for writing in
-     * <tt>inBuffer</tt>.
+     * <tt>buffer</tt>.
      *
      * @return the number of bytes read
      *
      * @throws IOException if <tt>length</tt> is less than the size of the
      * packet.
      */
-    public int read(byte[] inBuffer, int offset, int length)
+    public int read(byte[] buffer, int offset, int length)
         throws IOException
     {
-        if (ioError)
-            return -1;
-
-        int pktLength = pkt.getLength();
-
-        if (length < pktLength)
-            throw
-                new IOException("Input buffer not big enough for " + pktLength);
-
-        /* check if RTCP feedback message */
-
-        /* Feedback message size is minimum 12 bytes:
-         * Version/Padding/Feedback message type: 1 byte
-         * Payload type: 1 byte
-         * Length: 2 bytes
-         * SSRC of packet sender: 4 bytes
-         * SSRC of media source: 4 bytes
-         */
-        if(pktLength >= 12)
-        {
-            byte data[] = pkt.getBuffer();
-            int fmt = 0;
-            int pt = 0;
-
-            /* get FMT field (last 5 bits of first byte) */
-            fmt = (data[0] & 0x1F);
-            pt |= (data[1] & 0xFF);
-
-            RTCPFeedbackEvent evt = new RTCPFeedbackEvent(this, fmt, pt);
-
-            /* notify feedback listeners */
-            for(RTCPFeedbackListener l : rtcpFeedbackListeners)
-                l.feedbackReceived(evt);
-        }
+        int pktLength = super.read(buffer, offset, length);
 
-        System.arraycopy(
-                pkt.getBuffer(), pkt.getOffset(), inBuffer, offset, pktLength);
+        fireRTCPFeedbackReceived(this, buffer, offset, pktLength, listeners);
 
         return pktLength;
     }
diff --git a/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java b/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java
index e03c383d27f01114d3c9875f5b26bd7148dff6ab..fc1b29694d866804ec457e42314da4a80342e3ec 100755
--- a/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java
+++ b/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java
@@ -248,11 +248,15 @@ public int read(byte[] buffer, int offset, int length)
         int pktLength = pkt.getLength();
 
         if (length < pktLength)
-            throw
-                new IOException("Input buffer not big enough for " + pktLength);
+        {
+            throw new IOException(
+                    "Input buffer not big enough for " + pktLength);
+        }
 
         System.arraycopy(
-                pkt.getBuffer(), pkt.getOffset(), buffer, offset, pktLength);
+                pkt.getBuffer(), pkt.getOffset(),
+                buffer, offset,
+                pktLength);
 
         return pktLength;
     }
diff --git a/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java b/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java
index 54f7a299b91afb077981487ccdcc03a26ee64519..0a73313ad2c2bedb7a54456160acce3227d5739e 100755
--- a/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java
+++ b/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java
@@ -16,6 +16,7 @@
 
 import org.jitsi.service.libjitsi.*;
 import org.jitsi.service.packetlogging.*;
+import org.jitsi.util.*;
 
 /**
  * @author Bing SU (nova.su@gmail.com)
@@ -24,6 +25,12 @@
 public abstract class RTPConnectorOutputStream
     implements OutputDataStream
 {
+    /**
+     * The <tt>Logger</tt> used by the <tt>RTPConnectorOutputStream</tt> class
+     * and its instances for logging output.
+     */
+    private static final Logger logger
+        = Logger.getLogger(RTPConnectorOutputStream.class);
 
     /**
      * The maximum number of packets to be sent to be kept in the queue of
@@ -307,6 +314,15 @@ public void setMaxPacketsPerMillis(int maxPackets, long perMillis)
      */
     public int write(byte[] buffer, int offset, int length)
     {
+        /*
+         * While calling write without targets can be carried out without a
+         * problem, such a situation may be a symptom of a problem. For example,
+         * it was discovered during testing that RTCP was seemingly-endlessly
+         * sent after hanging up a call.
+         */
+        if (logger.isDebugEnabled() && targets.isEmpty())
+            logger.debug("Write called without targets!", new Throwable());
+
         RawPacket packet = createRawPacket(buffer, offset, length);
 
         /*
@@ -333,8 +349,8 @@ public int write(byte[] buffer, int offset, int length)
     public void setPriority(int priority)
     {
         // currently no priority is set
-//        if(maxPacketsPerMillisPolicy != null &&
-//            maxPacketsPerMillisPolicy.sendThread != null)
+//        if ((maxPacketsPerMillisPolicy != null)
+//                && (maxPacketsPerMillisPolicy.sendThread != null))
 //            maxPacketsPerMillisPolicy.sendThread.setPriority(priority);
     }
 
diff --git a/src/org/jitsi/impl/neomedia/codec/video/h264/JNIEncoder.java b/src/org/jitsi/impl/neomedia/codec/video/h264/JNIEncoder.java
index ab1f160f7c9ac4c3d40a969fd155ad66eb468ce8..4062191fb88861795b40d5300d7724b6e91af9f2 100644
--- a/src/org/jitsi/impl/neomedia/codec/video/h264/JNIEncoder.java
+++ b/src/org/jitsi/impl/neomedia/codec/video/h264/JNIEncoder.java
@@ -238,16 +238,19 @@ public synchronized void close()
     }
 
     /**
-     * Event fired when RTCP feedback message is received.
+     * Notifies this <tt>RTCPFeedbackListener</tt> that an RTCP feedback message
+     * has been received
      *
-     * @param event <tt>RTCPFeedbackEvent</tt>
+     * @param event an <tt>RTCPFeedbackEvent</tt> which specifies the details of
+     * the notification event such as the feedback message type and the payload
+     * type
      */
-    public void feedbackReceived(RTCPFeedbackEvent event)
+    public void rtcpFeedbackReceived(RTCPFeedbackEvent event)
     {
         /*
-         * If RTCP message is a Picture Loss Indication (PLI) or a
-         * Full Intra-frame Request (FIR) the encoder will force the next frame
-         * to be a keyframe.
+         * If RTCP message is a Picture Loss Indication (PLI) or a Full
+         * Intra-frame Request (FIR) the encoder will force the next frame to be
+         * a keyframe.
          */
         if (event.getPayloadType() == RTCPFeedbackEvent.PT_PS)
         {
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java
index e8b1b0899aa53e4557bea13e37a91a133a529106..26f05e62dbe3bb58fec8da240fd91c1ddfc4ddac 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java
@@ -21,7 +21,8 @@ public class JAWTRendererVideoComponent
     extends Canvas
 {
     /**
-     * Serial version UID.
+     * The serial version UID of the <tt>JAWTRendererVideoComponent</tt> class
+     * defined to silence a serialization compile-time warning.
      */
     private static final long serialVersionUID = 0L;
 
diff --git a/src/org/jitsi/impl/neomedia/transform/ControlTransformInputStream.java b/src/org/jitsi/impl/neomedia/transform/ControlTransformInputStream.java
index db4a4ffc4ca85dfc8685a6dcef069d55710cd615..7b651e01b36d53913b2cb851b627aea4a780dc7f 100644
--- a/src/org/jitsi/impl/neomedia/transform/ControlTransformInputStream.java
+++ b/src/org/jitsi/impl/neomedia/transform/ControlTransformInputStream.java
@@ -10,6 +10,7 @@
 import java.net.*;
 import java.util.*;
 
+import org.jitsi.impl.neomedia.*;
 import org.jitsi.service.neomedia.event.*;
 
 /**
@@ -67,60 +68,27 @@ public void removeRTCPFeedbackListener(RTCPFeedbackListener listener)
      * Copies the content of the most recently received packet into
      * <tt>inBuffer</tt>.
      *
-     * @param inBuffer the <tt>byte[]</tt> that we'd like to copy the content
-     * of the packet to.
+     * @param buffer the <tt>byte[]</tt> that we'd like to copy the content of
+     * the packet to.
      * @param offset the position where we are supposed to start writing in
-     * <tt>inBuffer</tt>.
+     * <tt>buffer</tt>.
      * @param length the number of <tt>byte</tt>s available for writing in
-     * <tt>inBuffer</tt>.
+     * <tt>buffer</tt>.
      *
      * @return the number of bytes read
      *
      * @throws IOException if <tt>length</tt> is less than the size of the
      * packet.
      */
-    public int read(byte[] inBuffer, int offset, int length)
+    public int read(byte[] buffer, int offset, int length)
         throws IOException
     {
-        if (ioError)
-            return -1;
-
-        int pktLength = pkt.getLength();
-
-        if (length < pktLength)
-            throw new IOException(
-                    "Input buffer not big enough for " + pktLength);
-
-        /* check if RTCP feedback message */
-
-        /* Feedback message size is minimum 12 bytes:
-         * Version/Padding/Feedback message type: 1 byte
-         * Payload type: 1 byte
-         * Length: 2 bytes
-         * SSRC of packet sender: 4 bytes
-         * SSRC of media source: 4 bytes
-         */
-        if ((pktLength >= 12) && !listeners.isEmpty())
-        {
-            byte data[] = pkt.getBuffer();
-            int fmt = 0;
-            int pt = 0;
-
-            /* get FMT field (last 5 bits of first byte) */
-            fmt = (data[0] & 0x1F);
-            pt |= (data[1] & 0xFF);
-
-            RTCPFeedbackEvent evt = new RTCPFeedbackEvent(this, fmt, pt);
-
-            /* notify feedback listeners */
-            for(RTCPFeedbackListener l : listeners)
-                l.feedbackReceived(evt);
-        }
+        int pktLength = super.read(buffer, offset, length);
 
-        System.arraycopy(
-                pkt.getBuffer(), pkt.getOffset(),
-                inBuffer, offset,
-                pktLength);
+        RTCPConnectorInputStream.fireRTCPFeedbackReceived(
+                this,
+                buffer, offset, pktLength,
+                listeners);
 
         return pktLength;
     }
diff --git a/src/org/jitsi/service/neomedia/event/RTCPFeedbackEvent.java b/src/org/jitsi/service/neomedia/event/RTCPFeedbackEvent.java
index 346f2e3a33edd568d610c1fa8d57b4c8d1640762..e0d1e15a6d00274a3a83ca8762d15306d826fcdc 100644
--- a/src/org/jitsi/service/neomedia/event/RTCPFeedbackEvent.java
+++ b/src/org/jitsi/service/neomedia/event/RTCPFeedbackEvent.java
@@ -45,12 +45,12 @@ public class RTCPFeedbackEvent
     /**
      * Feedback message type.
      */
-    private int feedbackMessageType = 0;
+    private final int feedbackMessageType;
 
     /**
      * Payload type.
      */
-    private int payloadType = 0;
+    private final int payloadType;
 
     /**
      * Constructor.
diff --git a/src/org/jitsi/service/neomedia/event/RTCPFeedbackListener.java b/src/org/jitsi/service/neomedia/event/RTCPFeedbackListener.java
index 7f1577b56546b8400efd383ecc88fb6b319b6280..7b7269768f10387f6067f34cddc559408d25858f 100644
--- a/src/org/jitsi/service/neomedia/event/RTCPFeedbackListener.java
+++ b/src/org/jitsi/service/neomedia/event/RTCPFeedbackListener.java
@@ -7,19 +7,21 @@
 package org.jitsi.service.neomedia.event;
 
 /**
- * <tt>RTCPFeedbackListener</tt> is used by codec to be notified
- * by RTCP feedback event such as PLI (Picture Loss Indication) or
- * FIR (Full Intra-frame Request).
+ * Represents a listener of RTCP feedback messages such as PLI (Picture Loss
+ * Indication) or FIR (Full Intra-frame Request).
  *
  * @author Sebastien Vincent
  */
 public interface RTCPFeedbackListener
 {
     /**
-     * Event fired when RTCP feedback message is received.
+     * Notifies this <tt>RTCPFeedbackListener</tt> that an RTCP feedback message
+     * has been received
      *
-     * @param event <tt>RTCPFeedbackEvent</tt>
+     * @param event an <tt>RTCPFeedbackEvent</tt> which specifies the details of
+     * the notification event such as the feedback message type and the payload
+     * type
      */
-    public void feedbackReceived(RTCPFeedbackEvent event);
+    public void rtcpFeedbackReceived(RTCPFeedbackEvent event);
 }