diff --git a/lib/native/mac/libjnportaudio.jnilib b/lib/native/mac/libjnportaudio.jnilib
index 04b39ad9cf52a521d95b15239944539d7df3d081..69126c0e42a705980369a0d137c257cc6b2f048a 100644
Binary files a/lib/native/mac/libjnportaudio.jnilib and b/lib/native/mac/libjnportaudio.jnilib differ
diff --git a/src/native/build.xml b/src/native/build.xml
index 9eb716062c3c37694dfc7484049fd64bf7615f3c..bf2906d11ff85cd72ba89c863d1b2bc35756f8a9 100644
--- a/src/native/build.xml
+++ b/src/native/build.xml
@@ -409,8 +409,6 @@
       <compilerarg value="x86_64" if="is.running.macos" />
       <compilerarg value="-arch" if="is.running.macos" />
       <compilerarg value="i386" if="is.running.macos" />
-      <compilerarg value="-arch" if="is.running.macos" />
-      <compilerarg value="ppc" if="is.running.macos" />
       <compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" if="is.running.macos" />
 
       <linkerarg value="-o" location="end" if="is.running.macos" />
@@ -420,8 +418,6 @@
       <linkerarg value="x86_64" if="is.running.macos" />
       <linkerarg value="-arch" if="is.running.macos" />
       <linkerarg value="i386" if="is.running.macos" />
-      <linkerarg value="-arch" if="is.running.macos" />
-      <linkerarg value="ppc" if="is.running.macos" />
       <linkerarg value="-framework" location="end" if="is.running.macos" />
       <linkerarg value="AudioToolbox" location="end" if="is.running.macos" />
       <linkerarg value="-framework" location="end" if="is.running.macos" />
@@ -495,8 +491,6 @@
       <compilerarg value="x86_64" if="is.running.macos" />
       <compilerarg value="-arch" if="is.running.macos" />
       <compilerarg value="i386" if="is.running.macos" />
-      <compilerarg value="-arch" if="is.running.macos" />
-      <compilerarg value="ppc" if="is.running.macos" />
       <compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" if="is.running.macos" />
 
       <linkerarg value="-o" location="end" if="is.running.macos" />
@@ -506,8 +500,6 @@
       <linkerarg value="x86_64" if="is.running.macos" />
       <linkerarg value="-arch" if="is.running.macos" />
       <linkerarg value="i386" if="is.running.macos" />
-      <linkerarg value="-arch" if="is.running.macos" />
-      <linkerarg value="ppc" if="is.running.macos" />
       <linkerarg value="-lspeex" location="end" if="is.running.macos" />
       <linkerarg value="-lspeexdsp" location="end" if="is.running.macos" />
 
diff --git a/src/native/portaudio/README b/src/native/portaudio/README
index 12b2ed77dc9e7abe01ab91db52d2a36ecbd621bb..bb9aa066a60c7c6e2c39bf81e895f7e5dbcd1434 100644
--- a/src/native/portaudio/README
+++ b/src/native/portaudio/README
@@ -1,7 +1,7 @@
 1. portaudio
 
     Get portaudio-hotplug branch and apply the portaudio-hotplug-os patch:
-    $ svn co https://www.portaudio.com/repos/portaudio/branches/hotplug
+    $ svn co https://subversion.assembla.com/svn/portaudio/portaudio/branches/hotplug/
     $ patch -p0 < portaudio-hotplug-os.patch
     $ autoreconf -i (OS X and Linux only)
 
@@ -27,7 +27,7 @@
 
     - Mac OS X
     $ export MACOSX_DEPLOYMENT_TARGET=10.4
-    $ export CC="gcc -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4"
+    $ export CC="gcc -arch i386 -arch x86_64 -mmacosx-version-min=10.4"
     $ export CPP="gcc -E"
     $ ./configure --disable-shared --enable-static --with-pic && make
 
diff --git a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c
index 3b274638a9a1b256f734d2ed62662c53543fad7e..133c91a54262f19149655708d4446f1786ad3807 100644
--- a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c
+++ b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c
@@ -910,6 +910,62 @@ Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getNameBytes
     return nameBytes;
 }
 
+JNIEXPORT jbyteArray JNICALL
+Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getTransportTypeBytes
+    (JNIEnv *env, jclass clazz, jlong deviceInfo)
+{
+    jbyteArray typeBytes = NULL;
+    if(((PaDeviceInfo *) (intptr_t) deviceInfo)->structVersion >= 3)
+    {
+        const char *type
+            = ((PaDeviceInfo *) (intptr_t) deviceInfo)->transportType;
+
+        if(type != NULL)
+        {
+            size_t typeLength = strlen(type);
+
+            typeBytes = (*env)->NewByteArray(env, typeLength);
+            if (typeBytes && typeLength)
+            {
+                (*env)->SetByteArrayRegion(
+                        env,
+                        typeBytes, 0, typeLength,
+                        (jbyte *) type);
+            }
+        }
+    }
+
+    return typeBytes;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getDeviceUIDBytes
+    (JNIEnv *env, jclass clazz, jlong deviceInfo)
+{
+    jbyteArray uidBytes = NULL;
+    if(((PaDeviceInfo *) (intptr_t) deviceInfo)->structVersion >= 3)
+    {
+        const char *uid
+            = ((PaDeviceInfo *) (intptr_t) deviceInfo)->deviceUID;
+
+        if (uid)
+        {
+            size_t uidLength = strlen(uid);
+
+            uidBytes = (*env)->NewByteArray(env, uidLength);
+            if (uidBytes && uidLength)
+            {
+                (*env)->SetByteArrayRegion(
+                        env,
+                        uidBytes, 0, uidLength,
+                        (jbyte *) uid);
+            }
+        }
+    }
+
+    return uidBytes;
+}
+
 JNIEXPORT jint JNICALL
 Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaHostApiInfo_1getDefaultInputDevice
     (JNIEnv *env, jclass clazz, jlong hostApi)
diff --git a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h
index 61a771bc5bf8b090c097123b0b99a2cd59c5771b..7af57761c3a2694ef3669422f7f14b447ea06395 100644
--- a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h
+++ b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h
@@ -229,6 +229,22 @@ JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaDevice
 JNIEXPORT jbyteArray JNICALL Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getNameBytes
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     net_java_sip_communicator_impl_neomedia_portaudio_PortAudio
+ * Method:    PaDeviceInfo_getTransportTypeBytes
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getTransportTypeBytes
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     net_java_sip_communicator_impl_neomedia_portaudio_PortAudio
+ * Method:    PaDeviceInfo_getDeviceUIDBytes
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getDeviceUIDBytes
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_jitsi_impl_neomedia_portaudio_PortAudio
  * Method:    PaHostApiInfo_getDefaultInputDevice
diff --git a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java
index e9a08476fa023f1b2605b4307ab99bb9f54641cb..2f3212fc4fe37ca5c855e86068067504bddd4ced 100644
--- a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java
+++ b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java
@@ -615,6 +615,73 @@ public static native double PaDeviceInfo_getDefaultSampleRate(
      */
     private static native byte[] PaDeviceInfo_getNameBytes(long deviceInfo);
 
+    /**
+     * Tranpsort type for the device: BuiltIn, USB, BLuetooth, etc.
+     * @param deviceInfo device info pointer.
+     * @return The transport type identifier.
+     */
+    public static native byte[] PaDeviceInfo_getTransportTypeBytes(
+            long deviceInfo);
+
+    /**
+     * Tranpsort type for the device: BuiltIn, USB, BLuetooth, etc.
+     * @param deviceInfo device info pointer.
+     * @return The transport type identifier.
+     */
+    public static String PaDeviceInfo_getTransportType(long deviceInfo)
+    {
+        byte[] typeBytes = PaDeviceInfo_getTransportTypeBytes(deviceInfo);
+        if(typeBytes == null)
+        {
+            return null;
+        }
+
+        Charset defaultCharset = Charset.defaultCharset();
+        String charsetName
+            = (defaultCharset == null) ? "UTF-8" : defaultCharset.name();
+        try
+        {
+            return new String(typeBytes, charsetName);
+        }
+        catch (UnsupportedEncodingException ueex)
+        {
+            return new String(typeBytes);
+        }
+    }
+
+    /**
+     * Device UID for the device (persistent across boots).
+     * @param deviceInfo device info pointer.
+     * @return The device UID.
+     */
+    public static native byte[] PaDeviceInfo_getDeviceUIDBytes(long deviceInfo);
+
+    /**
+     * Device UID for the device (persistent across boots).
+     * @param deviceInfo device info pointer.
+     * @return The device UID.
+     */
+    public static String PaDeviceInfo_getDeviceUID(long deviceInfo)
+    {
+        byte[] uidBytes = PaDeviceInfo_getDeviceUIDBytes(deviceInfo);
+        if(uidBytes == null)
+        {
+            return null;
+        }
+
+        Charset defaultCharset = Charset.defaultCharset();
+        String charsetName
+            = (defaultCharset == null) ? "UTF-8" : defaultCharset.name();
+        try
+        {
+            return new String(uidBytes, charsetName);
+        }
+        catch (UnsupportedEncodingException ueex)
+        {
+            return new String(uidBytes);
+        }
+    }
+
     /**
      * The default input device for this host API.
      * @param hostApiInfo pointer to host api info structure.
diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
index bfd1ac9312d00e0d2253b2bae94c531186649823..6a173915ee54fc7075e9324d63de7f366ac6e253 100644
--- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
@@ -508,7 +508,7 @@ public List<MediaDevice> getDevices(
             MediaType mediaType,
             MediaUseCase useCase)
     {
-        List<CaptureDeviceInfo> cdis;
+        List<? extends CaptureDeviceInfo> cdis;
         List<MediaDeviceImpl> privateDevices;
 
         if (MediaType.VIDEO.equals(mediaType))
@@ -528,8 +528,7 @@ public List<MediaDevice> getDevices(
             privateDevices = audioDevices;
             break;
         case VIDEO:
-            cdis
-                = getDeviceConfiguration().getAvailableVideoCaptureDevices(
+            cdis = getDeviceConfiguration().getAvailableVideoCaptureDevices(
                         useCase);
             privateDevices = videoDevices;
             break;
@@ -555,7 +554,8 @@ public List<MediaDevice> getDevices(
 
                 while (deviceIter.hasNext())
                 {
-                    Iterator<CaptureDeviceInfo> cdiIter = cdis.iterator();
+                    Iterator<? extends CaptureDeviceInfo> cdiIter
+                        = cdis.iterator();
                     CaptureDeviceInfo captureDeviceInfo
                         = deviceIter.next().getCaptureDeviceInfo();
                     boolean deviceIsFound = false;
diff --git a/src/org/jitsi/impl/neomedia/device/AudioSystem.java b/src/org/jitsi/impl/neomedia/device/AudioSystem.java
index 70d1bfd5f34b9509055500c0f326c58d56b6953d..b828ab6ec0e8e0da75869af9008dfa6efea83a73 100644
--- a/src/org/jitsi/impl/neomedia/device/AudioSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/AudioSystem.java
@@ -112,9 +112,9 @@ protected AudioSystem(String locatorProtocol, int features)
      *
      * @return The list of a kind of devices: cpature, notify or playback.
      */
-    public List<CaptureDeviceInfo> getDevices(int index)
+    public List<ExtendedCaptureDeviceInfo> getDevices(int index)
     {
-        return this.devices[index].getDevices(getLocatorProtocol());
+        return this.devices[index].getDevices();
     }
 
     /**
@@ -127,9 +127,11 @@ public List<CaptureDeviceInfo> getDevices(int index)
      * @return The selected device for a specific kind: cpature, notify or
      * playback.
      */
-    public CaptureDeviceInfo getDevice(int index)
+    public ExtendedCaptureDeviceInfo getDevice(int index)
     {
-        return this.devices[index].getDevice(getLocatorProtocol());
+        return this.devices[index].getDevice(
+                getLocatorProtocol(),
+                getDevices(index));
     }
 
     /**
@@ -139,7 +141,7 @@ public CaptureDeviceInfo getDevice(int index)
      * notify or playback.
      */
     protected void setCaptureDevices(
-            List<CaptureDeviceInfo> activeCaptureDevices)
+            List<ExtendedCaptureDeviceInfo> activeCaptureDevices)
     {
         this.devices[CAPTURE_INDEX].setActiveDevices(activeCaptureDevices);
     }
@@ -153,9 +155,16 @@ protected void setCaptureDevices(
      * @param save Flag set to true in order to save this choice in the
      * configuration. False otherwise.
      */
-    public void setDevice(int index, CaptureDeviceInfo device, boolean save)
+    public void setDevice(
+            int index,
+            ExtendedCaptureDeviceInfo device,
+            boolean save)
     {
-        this.devices[index].setDevice(getLocatorProtocol(), device, save);
+        this.devices[index].setDevice(
+                getLocatorProtocol(),
+                device,
+                save,
+                getDevices(index));
     }
 
     /**
@@ -164,7 +173,7 @@ public void setDevice(int index, CaptureDeviceInfo device, boolean save)
      * @param activePlaybackDevices The list of the active devices.
      */
     protected void setPlaybackDevices(
-            List<CaptureDeviceInfo> activePlaybackDevices)
+            List<ExtendedCaptureDeviceInfo> activePlaybackDevices)
     {
         this.devices[PLAYBACK_INDEX].setActiveDevices(activePlaybackDevices);
         // The active notify device list is a copy of the playback one.
@@ -225,34 +234,23 @@ protected void postInitialize()
      */
     protected void postInitializeSpecificDevices(int index)
     {
-        // If there is a selected device, checks if it is part of the current
-        // active devices.
-        if (this.devices[index].getDevice(getLocatorProtocol()) != null)
-        {
-            List<CaptureDeviceInfo> devices = this.devices[index].getDevices(
-                    getLocatorProtocol());
-
-            if ((devices == null)
-                    || !devices.contains(this.devices[index].getDevice(
-                            getLocatorProtocol())))
-            {
-                // The selected device is not part of the active devices, then
-                // set it to null (but not saved).
-                this.devices[index].setDevice(
-                        getLocatorProtocol(),
-                        null,
-                        false);
-            }
-        }
-        else
-        {
-            /*
-             * If the device is null, it means that a device is to be
-             * used as the default. The default in question may have
-             * changed.
-             */
-            this.devices[index].setDevice(getLocatorProtocol(), null, false);
-        }
+        // Gets all current active devies.
+        List<ExtendedCaptureDeviceInfo> activeDevices = this.getDevices(index);
+        // Gets the default device.
+        ExtendedCaptureDeviceInfo selectedActiveDevice
+            = this.devices[index].getDevice(
+                    getLocatorProtocol(),
+                    activeDevices);
+        // Sets the default device as selected (this function will only fire a
+        // property change if the device has changed from previous
+        // configuration).
+        // This "set" part is important because only the fire property event
+        // provides a way to get hot plugged devices working during a call.
+        this.devices[index].setDevice(
+                    getLocatorProtocol(),
+                    selectedActiveDevice,
+                    false,
+                    activeDevices);
     }
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/device/CaptureDevices.java b/src/org/jitsi/impl/neomedia/device/CaptureDevices.java
index 05dee0e657720655793690b1bbc8836997316eee..3638784c76da9c95306599d29c6eb8e31320aad4 100644
--- a/src/org/jitsi/impl/neomedia/device/CaptureDevices.java
+++ b/src/org/jitsi/impl/neomedia/device/CaptureDevices.java
@@ -25,14 +25,14 @@ public class CaptureDevices
     extends Devices
 {
     /**
-     * The flag nuber if the capture device is null.
+     * The property of the capture devices.
      */
-    protected static final int FLAG_DEVICE_IS_NULL = 1;
+    public static final String PROP_DEVICE = "captureDevice";
 
     /**
-     * The property of the capture devices.
+     * The list of active (actually plugged-in) capture devices.
      */
-    public static final String PROP_DEVICE = "captureDevice";
+    private List<ExtendedCaptureDeviceInfo> activeCaptureDevices = null;
 
     /**
      * Initializes the capture device list managment.
@@ -47,43 +47,34 @@ public CaptureDevices(AudioSystem audioSystem)
     /**
      * Returns the list of the active devices.
      *
-     * @param locator The string representation of the locator.
-     *
      * @return The list of the active devices.
      */
-    public List<CaptureDeviceInfo> getDevices(String locator)
+    public List<ExtendedCaptureDeviceInfo> getDevices()
     {
-        MediaServiceImpl mediaServiceImpl
-            = NeomediaServiceUtils.getMediaServiceImpl();
-        DeviceConfiguration deviceConfiguration = (mediaServiceImpl == null)
-                ? null
-                : mediaServiceImpl.getDeviceConfiguration();
-        List<CaptureDeviceInfo> deviceList;
+        Format[] formats;
+        Format format = new AudioFormat(AudioFormat.LINEAR, -1, 16, -1);
+        List<ExtendedCaptureDeviceInfo> devices = null;
 
-        if (deviceConfiguration == null)
+        if(this.activeCaptureDevices != null)
         {
-            /*
-             * XXX The initialization of MediaServiceImpl is very complex so it
-             * is wise to not reference it at the early stage of its
-             * initialization. The same goes for DeviceConfiguration. If for
-             * some reason one of the two is not available at this time, just
-             * fall back go something that makes sense.
-             */
-            @SuppressWarnings("unchecked")
-            Vector<CaptureDeviceInfo> audioCaptureDeviceInfos
-                = CaptureDeviceManager.getDeviceList(
-                        new AudioFormat(AudioFormat.LINEAR, -1, 16, -1));
+            devices = new ArrayList<ExtendedCaptureDeviceInfo>(
+                    this.activeCaptureDevices.size());
 
-            deviceList = audioCaptureDeviceInfos;
-        }
-        else
-        {
-            deviceList = deviceConfiguration.getAvailableAudioCaptureDevices();
+            for(ExtendedCaptureDeviceInfo device: this.activeCaptureDevices)
+            {
+                formats = device.getFormats();
+                for(int i = 0; i < formats.length; ++i)
+                {
+                    if(formats[i].matches(format))
+                    {
+                        devices.add(device);
+                        i = formats.length;
+                    }
+                }
+            }
         }
 
-        return DeviceSystem.filterDeviceListByLocatorProtocol(
-                deviceList,
-                locator);
+        return devices;
     }
 
     /**
@@ -91,7 +82,7 @@ public List<CaptureDeviceInfo> getDevices(String locator)
      *
      * @param activeDevices The list of the active devices.
      */
-    public void setActiveDevices(List<CaptureDeviceInfo> activeDevices)
+    public void setActiveDevices(List<ExtendedCaptureDeviceInfo> activeDevices)
     {
         if(activeDevices != null)
         {
@@ -114,16 +105,10 @@ public void setActiveDevices(List<CaptureDeviceInfo> activeDevices)
                 }
             }
         }
-    }
 
-    /**
-     * Returns the flag nuber if the capture device is null.
-     *
-     * @return The flag nuber if the capture device is null.
-     */
-    protected int getFlagDeviceIsNull()
-    {
-        return FLAG_DEVICE_IS_NULL;
+        this.activeCaptureDevices = (activeDevices == null)
+                ? null
+                : new ArrayList<ExtendedCaptureDeviceInfo>(activeDevices);
     }
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
index 1c8ba4d31a1850eaf5b105dc54addc8205dfae32..5affd454f3938ee20ab83ac6f235344e37acaf24 100644
--- a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
+++ b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java
@@ -395,7 +395,7 @@ private CaptureDeviceInfo extractConfiguredVideoCaptureDevice(Format format)
      * @return the CaptureDeviceInfo of a device that we could use for audio
      *         capture.
      */
-    public CaptureDeviceInfo getAudioCaptureDevice()
+    public ExtendedCaptureDeviceInfo getAudioCaptureDevice()
     {
         AudioSystem audioSystem = getAudioSystem();
 
@@ -414,14 +414,9 @@ public CaptureDeviceInfo getAudioCaptureDevice()
      *         capture devices available through this
      *         <tt>DeviceConfiguration</tt>
      */
-    public List<CaptureDeviceInfo> getAvailableAudioCaptureDevices()
+    public List<ExtendedCaptureDeviceInfo> getAvailableAudioCaptureDevices()
     {
-        @SuppressWarnings("unchecked")
-        Vector<CaptureDeviceInfo> audioCaptureDevices
-            = CaptureDeviceManager.getDeviceList(
-                    new AudioFormat(AudioFormat.LINEAR, -1, 16, -1));
-
-        return audioCaptureDevices;
+        return audioSystem.getDevices(AudioSystem.CAPTURE_INDEX);
     }
 
     public AudioSystem getAudioSystem()
@@ -445,7 +440,7 @@ public AudioSystem[] getAvailableAudioSystems()
                 if (!NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(
                         audioSystem.getLocatorProtocol()))
                 {
-                    List<CaptureDeviceInfo> captureDevices
+                    List<ExtendedCaptureDeviceInfo> captureDevices
                         = audioSystem.getDevices(AudioSystem.CAPTURE_INDEX);
 
                     if ((captureDevices == null)
@@ -459,14 +454,14 @@ public AudioSystem[] getAvailableAudioSystems()
                         }
                         else
                         {
-                            List<CaptureDeviceInfo> notifyDevices
+                            List<ExtendedCaptureDeviceInfo> notifyDevices
                                 = audioSystem.getDevices(
                                         AudioSystem.NOTIFY_INDEX);
 
                             if ((notifyDevices == null)
                                     || (notifyDevices.size() <= 0))
                             {
-                                List<CaptureDeviceInfo> playbackDevices
+                                List<ExtendedCaptureDeviceInfo> playbackDevices
                                     = audioSystem.getDevices(
                                         AudioSystem.PLAYBACK_INDEX);
     
diff --git a/src/org/jitsi/impl/neomedia/device/Devices.java b/src/org/jitsi/impl/neomedia/device/Devices.java
index bc34943b2f092a924220ee84c8cd0979d27a791c..a92411eeba6fd84b5811f2c966d2589b15d435e7 100644
--- a/src/org/jitsi/impl/neomedia/device/Devices.java
+++ b/src/org/jitsi/impl/neomedia/device/Devices.java
@@ -25,19 +25,14 @@ public abstract class Devices
     /**
      * The selected active device.
      */
-    protected CaptureDeviceInfo device = null;
+    protected ExtendedCaptureDeviceInfo device = null;
 
     /**
-     * The list of device names saved by the congifuration service and
+     * The list of device ID/names saved by the congifuration service and
      * previously saved given user preference order.
      */
     protected List<String> devicePreferences = new ArrayList<String>();
 
-    /**
-     * The flags that can save if the FLAG_DEVICE_IS_NULL state is set.
-     */
-    private int flags;
-
     /**
      * The audio system managing this device list.
      */
@@ -57,103 +52,74 @@ public Devices(AudioSystem audioSystem)
      * Gets the selected active device.
      *
      * @param locator The string representation of the locator.
+     * @param activeDevices The list of the active devices.
      *
      * @return The selected active device.
      */
-    public CaptureDeviceInfo getDevice(String locator)
+    public ExtendedCaptureDeviceInfo getDevice(
+            String locator,
+            List<ExtendedCaptureDeviceInfo> activeDevices)
     {
-        List<CaptureDeviceInfo> devices = getDevices(locator);
-
-        // Reinit the selected device if this one is no more in the active list.
-        if (this.device != null)
+        if (activeDevices != null)
         {
-            if ((devices == null) || !devices.contains(this.device))
+            String property = getPropDevice();
+            loadDevicePreferences(locator, property);
+            renameOldFashionedIdentifier(activeDevices);
+
+            // Search if an active device is a new one (is not stored in the
+            // preferences yet). If true, then active this device and set it as
+            // default device (only for USB devices since the user has
+            // deliberately plugged-in the device).
+            for(ExtendedCaptureDeviceInfo activeDevice : activeDevices)
             {
-                setDevice(locator, null, false);
+                if(!devicePreferences.contains(activeDevice.getIdentifier()))
+                {
+                    // Adds the device in the preference list (to the end of the
+                    // list, but the save device will push it to the top of
+                    // active devices).
+                    this.saveDevice(
+                            locator,
+                            property,
+                            activeDevice,
+                            activeDevices,
+                            activeDevice.isSameTransportType("USB"));
+                }
             }
-        }
-
-        CaptureDeviceInfo device = this.device;
 
-        // If the device is null and the device is not desactivated, then try to
-        // find the user preferred one between the active devices.
-        if ((device == null) && ((flags & getFlagDeviceIsNull()) == 0))
-        {
-            if ((devices != null) && (devices.size() > 0))
+            // Search if an active device match one of the previsouly configured
+            // in the preferences.
+            for(int i = 0; i < devicePreferences.size(); ++i)
             {
-                device = loadDevice(locator, getPropDevice(), devices);
-                if (device == null)
-                    device = devices.get(0);
+                for(ExtendedCaptureDeviceInfo activeDevice : activeDevices)
+                {
+                    // If we have found the "preferred" device among active
+                    // device.
+                    if(devicePreferences.get(i).equals(
+                                activeDevice.getIdentifier()))
+                    {
+                        return activeDevice;
+                    }
+                    // If the "none" device is the "preferred" device among
+                    // "active" device.
+                    else if(devicePreferences.get(i).equals(
+                                NoneAudioSystem.LOCATOR_PROTOCOL))
+                    {
+                        return null;
+                    }
+                }
             }
         }
-        return device;
+
+        // Else if nothing was found, then returns null.
+        return null;
     }
 
     /**
      * Returns the list of the active devices.
      *
-     * @param locator The string representation of the locator.
-     *
      * @return The list of the active devices.
      */
-    public abstract List<CaptureDeviceInfo> getDevices(String locator);
-
-    /**
-     * Loads the user's preference with respect to a <tt>CaptureDeviceInfo</tt>
-     * among a specific list of <tt>CaptureDeviceInfo</tt>s from the
-     * <tt>ConfigurationService</tt>.
-     *
-     * @param locator The string representation of the locator.
-     * @param property the name of the <tt>ConfigurationService</tt> property
-     * which specifies the user's preference with respect to a
-     * <tt>CaptureDeviceInfo</tt> among the specified list of
-     * <tt>CaptureDeviceInfo</tt>s 
-     * @param devices the list of <tt>CaptureDeviceInfo</tt>s which are valid
-     * selections for the user's preference
-     * @return a <tt>CaptureDeviceInfo</tt> among the specified <tt>devices</tt>
-     * which represents the user's preference stored in the
-     * <tt>ConfigurationService</tt>
-     */
-    private CaptureDeviceInfo loadDevice(
-            String locator,
-            String property,
-            List<CaptureDeviceInfo> devices)
-    {
-        loadDevicePreferences(locator, property);
-
-        // Search if an active device is a new one (is not stored in the
-        // preferences yet). If true, then active this device and set it as
-        // default device.
-        for(CaptureDeviceInfo device : devices)
-        {
-            if(!devicePreferences.contains(device.getName()))
-            {
-                // Adds the device in the preference list (to the end of the
-                // list, but the save device will push it to the top of active
-                // devices).
-                devicePreferences.add(device.getName());
-                this.saveDevice(locator, property, device, false);
-            }
-        }
-        // Search if an active device match one of the previsouly configured in
-        // the preferences.
-        for(int i = 0; i < devicePreferences.size(); ++i)
-        {
-            for(CaptureDeviceInfo device : devices)
-                if (devicePreferences.get(i).equals(device.getName()))
-                    return device;
-        }
-
-        // If no active devices matches a configured one, then gets the first
-        // active device available.
-        if(devices.size() > 0)
-        {
-            return devices.get(0);
-        }
-
-        // Else if nothing was found, then returns null.
-        return null;
-    }
+    public abstract List<ExtendedCaptureDeviceInfo> getDevices();
 
     /**
      * Loads device name ordered with user's preference from the
@@ -177,20 +143,18 @@ private void loadDevicePreferences(String locator, String property)
                     + property
                     + "_list";
 
-            String deviceNamesString = cfg.getString(new_property);
+            String deviceIdentifiersString = cfg.getString(new_property);
 
-            if (deviceNamesString != null
-                    && !NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(
-                        deviceNamesString))
+            if (deviceIdentifiersString != null)
             {
                 devicePreferences.clear();
                 // We must parce the string in order to load the device list.
-                String[] deviceNames = deviceNamesString
-                    .substring(2, deviceNamesString.length() - 2)
+                String[] deviceIdentifiers = deviceIdentifiersString
+                    .substring(2, deviceIdentifiersString.length() - 2)
                     .split("\", \"");
-                for(int i = 0; i < deviceNames.length; ++i)
+                for(int i = 0; i < deviceIdentifiers.length; ++i)
                 {
-                    devicePreferences.add(deviceNames[i]);
+                    devicePreferences.add(deviceIdentifiers[i]);
                 }
             }
             // Else, use the old property to load the last preferred device.
@@ -204,14 +168,14 @@ private void loadDevicePreferences(String locator, String property)
                         + "."
                         + property;
 
-                deviceNamesString = cfg.getString(old_property);
+                deviceIdentifiersString = cfg.getString(old_property);
 
-                if (deviceNamesString != null
+                if (deviceIdentifiersString != null
                         && !NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(
-                            deviceNamesString))
+                            deviceIdentifiersString))
                 {
                     devicePreferences.clear();
-                    devicePreferences.add(deviceNamesString);
+                    devicePreferences.add(deviceIdentifiersString);
                 }
             }
         }
@@ -224,15 +188,16 @@ private void loadDevicePreferences(String locator, String property)
      * @param property the name of the <tt>ConfigurationService</tt> property
      * into which the user's preference with respect to the specified
      * <tt>CaptureDeviceInfo</tt> is to be saved
-     * @param device the <tt>CaptureDeviceInfo</tt> selected by the user.
-     * @param isNull <tt>true</tt> if the user's preference with respect to the
-     * specified <tt>device</tt> is <tt>null</tt>; otherwise, <tt>false</tt>
+     * @param selectedDevice The device selected by the user.
+     * @param activeDevices The list of the active devices.
+     * @param isSelected True if the device is the selected one.
      */
     private void saveDevice(
             String locator,
             String property,
-            CaptureDeviceInfo device,
-            boolean isNull)
+            ExtendedCaptureDeviceInfo device,
+            List<ExtendedCaptureDeviceInfo> activeDevices,
+            boolean isSelected)
     {
         ConfigurationService cfg = LibJitsi.getConfigurationService();
 
@@ -243,62 +208,41 @@ private void saveDevice(
                     + "." + locator
                     + "." + property
                     + "_list";
-            if(device == null)
+
+            String selectedDeviceIdentifier = NoneAudioSystem.LOCATOR_PROTOCOL;
+            if(device != null)
             {
-                if(isNull)
-                {
-                    cfg.setProperty(property, NoneAudioSystem.LOCATOR_PROTOCOL);
-                }
-                else
-                {
-                    cfg.removeProperty(property);
-                }
+                selectedDeviceIdentifier = device.getIdentifier();
+            }
+
+            // Sorts the user preferences to put the selected device on top.
+            devicePreferences.remove(selectedDeviceIdentifier);
+            if(isSelected)
+            {
+                int firstActiveIndex = getFirstActiveIndexFromDevicePreferences(
+                        locator,
+                        activeDevices);
+                devicePreferences.add(
+                        firstActiveIndex,
+                        selectedDeviceIdentifier);
             }
             else
             {
-                // Sorts the user preferences to put the selected device on top.
-                ArrayList resultList
-                    = new ArrayList<String>(devicePreferences.size() + 1);
-                List<CaptureDeviceInfo> devices = getDevices(locator);
-                boolean firstActiveFound = false;
-                for(int i = 0; i < devicePreferences.size(); ++i)
-                {
-                    // Checks if this element is an active device.
-                    for(int j = 0; !firstActiveFound && j < devices.size(); ++j)
-                    {
-                        if(devicePreferences.get(i).equals(
-                                    devices.get(j).getName()))
-                        {
-                            // The first active device is found, then place the
-                            // selected device at the previous place.
-                            resultList.add(device.getName());
-                            firstActiveFound = true;
-                        }
-                    }
-
-                    // Checks that we do not add dupplicate of the selected
-                    // device>
-                    if(!devicePreferences.get(i).equals(device.getName()))
-                    {
-                        resultList.add(devicePreferences.get(i));
-                    }
-                }
-                // Updates the preferences list with the ew one computed.
-                devicePreferences = resultList;
+                devicePreferences.add(selectedDeviceIdentifier);
+            }
 
-                // Saves the user preferences.
-                StringBuffer value = new StringBuffer("[\"");
-                if(devicePreferences.size() > 0)
+            // Saves the user preferences.
+            StringBuffer value = new StringBuffer("[\"");
+            if(devicePreferences.size() > 0)
+            {
+                value.append(devicePreferences.get(0));
+                for(int i = 1; i < devicePreferences.size(); ++i)
                 {
-                    value.append(devicePreferences.get(0));
-                    for(int i = 1; i < devicePreferences.size(); ++i)
-                    {
-                        value.append("\", \"" + devicePreferences.get(i));
-                    }
+                    value.append("\", \"" + devicePreferences.get(i));
                 }
-                value.append("\"]");
-                cfg.setProperty(property, value.toString());
             }
+            value.append("\"]");
+            cfg.setProperty(property, value.toString());
         }
     }
 
@@ -309,41 +253,33 @@ private void saveDevice(
      * @param device The selected active device.
      * @param save Flag set to true in order to save this choice in the
      * configuration. False otherwise.
+     * @param activeDevices The list of the active devices.
      */
     public void setDevice(
             String locator,
-            CaptureDeviceInfo device,
-            boolean save)
+            ExtendedCaptureDeviceInfo device,
+            boolean save,
+            List<ExtendedCaptureDeviceInfo> activeDevices)
     {
         // Checks if there is a change.
-        if ((this.device != device) || (device == null))
+        if ((device == null) || !device.equals(this.device))
         {
-            CaptureDeviceInfo oldValue = this.device;
-            this.device = device;
+            ExtendedCaptureDeviceInfo oldValue = this.device;
 
             // Saves the new selected device in top of the user preferences.
             if (save)
             {
-                boolean isNull = (this.device == null);
-
-                if (isNull)
-                    flags |= getFlagDeviceIsNull();
-                else
-                    flags &= ~getFlagDeviceIsNull();
-
-                saveDevice(locator, getPropDevice(), this.device, isNull);
+                saveDevice(
+                        locator,
+                        getPropDevice(),
+                        device,
+                        activeDevices,
+                        true);
             }
+            this.device = device;
 
-            CaptureDeviceInfo newValue = getDevice(locator);
-
-            if (oldValue != newValue)
-            {
-                if(this.audioSystem != null)
-                {
-                    this.audioSystem
-                        .propertyChange(getPropDevice(), oldValue, newValue);
-                }
-            }
+            this.audioSystem
+                .propertyChange(getPropDevice(), oldValue, this.device);
         }
     }
 
@@ -353,19 +289,101 @@ public void setDevice(
      * @param activeDevices The list of the active devices.
      */
     public abstract void setActiveDevices(
-            List<CaptureDeviceInfo> activeDevices);
+            List<ExtendedCaptureDeviceInfo> activeDevices);
 
     /**
-     * Returns the flag nuber if the capture device is null.
+     * Returns the property of the capture devices.
      *
-     * @return The flag nuber if the capture device is null.
+     * @return The property of the capture devices.
      */
-    protected abstract int getFlagDeviceIsNull();
+    protected abstract String getPropDevice();
 
     /**
-     * Returns the property of the capture devices.
+     * Returns the index of the first active device from the device preference
+     * list.
      *
-     * @return The property of the capture devices.
+     * @param locator The string representation of the locator.
+     * @param activeDevices The list of the active devices.
+     *
+     * @return The index of the first active device from the device preference
+     * list. Or the size of the device preference list if all devices are
+     * inactive.
      */
-    protected abstract String getPropDevice();
+    private int getFirstActiveIndexFromDevicePreferences(
+            String locator,
+            List<ExtendedCaptureDeviceInfo> activeDevices)
+    {
+        int i;
+        int j;
+        // Searches for the first active device.
+        for(i = 0; i < devicePreferences.size(); ++i)
+        {
+            // Checks if this element is an active device.
+            for(j = 0; j < activeDevices.size(); ++j)
+            {
+                if(devicePreferences.get(i).equals(
+                            activeDevices.get(j).getIdentifier())
+                        || devicePreferences.get(i).equals(
+                            NoneAudioSystem.LOCATOR_PROTOCOL))
+                {
+                    // The first active device is found.
+                    return i;
+                }
+            }
+        }
+        // There is no active devices, then returns the size of the device
+        // peference list.
+        return devicePreferences.size();
+    }
+
+    /**
+     * Renames the old fashioned identifier (name only), into new fashioned one
+     * (UID, or name + transport type).
+     *
+     * @param activeDevices The list of the active devices.
+     */
+    public void renameOldFashionedIdentifier(
+            List<ExtendedCaptureDeviceInfo> activeDevices)
+    {
+        String name;
+        String id;
+        int nameIndex;
+        int idIndex;
+        // Renames the old fashioned device identifier for all active devices.
+        for(int i = 0; i < activeDevices.size(); ++i)
+        {
+            name = activeDevices.get(i).getName();
+            id = activeDevices.get(i).getIdentifier();
+            // We can only switch to the new fashioned notation, only if the OS
+            // api give us a unique identifier (different from the device name).
+            if(!name.equals(id))
+            {
+                do
+                {
+                    nameIndex = devicePreferences.indexOf(
+                            activeDevices.get(i).getName());
+                    idIndex = devicePreferences.indexOf(
+                            activeDevices.get(i).getIdentifier());
+                    // If there is one old fashioned identifier.
+                    if(nameIndex != -1)
+                    {
+                        // If the correspondant new fashioned identifier does
+                        // not exists, then renames the old one into the new
+                        // one.
+                        if(idIndex == -1)
+                        {
+                            devicePreferences.set(nameIndex,
+                                    activeDevices.get(i).getIdentifier());
+                        }
+                        // Else removes the dupplicate.
+                        else
+                        {
+                            devicePreferences.remove(nameIndex);
+                        }
+                    }
+                }
+                while(nameIndex != -1);
+            }
+        }
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/device/ExtendedCaptureDeviceInfo.java b/src/org/jitsi/impl/neomedia/device/ExtendedCaptureDeviceInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..87ca6059264fdf53142f43d8a8dbd9132daa3e95
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/device/ExtendedCaptureDeviceInfo.java
@@ -0,0 +1,147 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.device;
+
+import java.util.*;
+
+import javax.media.*;
+
+/**
+ * Adds some important information (i.e. device type, UID.) to FMJ
+ * CaptureDeviceInfo.
+ *
+ * @author Vincent Lucas
+ */
+public class ExtendedCaptureDeviceInfo
+    extends CaptureDeviceInfo
+{
+    /**
+     * The device UID (unique identifier).
+     */
+    private String UID = null;
+
+    /**
+     * The device transport type.
+     */
+    private String transportType = null;
+
+    /**
+     * Constructs a CaptureDeviceInfo object with the specified name, media
+     * locator, and array of Format objects.
+     *
+     * @param captureDeiceInfo the device info.
+     * @param uid The device UID (unique identifier).
+     * @param transportType The device transport type.
+     */
+    public ExtendedCaptureDeviceInfo(
+            CaptureDeviceInfo captureDeviceInfo,
+            String UID,
+            String transportType)
+    {
+        this(
+                captureDeviceInfo.getName(),
+                captureDeviceInfo.getLocator(),
+                captureDeviceInfo.getFormats(),
+                UID,
+                transportType);
+    }
+
+    /**
+     * Constructs a CaptureDeviceInfo object with the specified name, media
+     * locator, and array of Format objects.
+     *
+     * @param name A String that contains the name of the device.
+     * @param locator The MediaLocator that uniquely specifies the device.
+     * @param formats An array of the output formats supported by the device.
+     * @param uid The device UID (unique identifier).
+     * @param transportType The device transport type.
+     */
+    public ExtendedCaptureDeviceInfo(
+            String name,
+            MediaLocator locator,
+            Format[] formats,
+            String UID,
+            String transportType)
+    {
+        super(name, locator, formats);
+
+        this.UID = UID;
+        this.transportType = transportType;
+    }
+
+    /**
+     * Returns the device UID (unique identifier).
+     *
+     * @return The device UID (unique identifier).
+     */
+    public String getUID()
+    {
+        return this.UID;
+    }
+
+    /**
+     * Returns the device transport type.
+     *
+     * @return The device transport type.
+     */
+    public String getTransportType()
+    {
+        return this.transportType;
+    }
+
+    /**
+     * Returns if the transport type matches the one given in parameter.
+     *
+     * The transport type to compare with.
+     *
+     * @return True if the transport type matches the one given in parameter.
+     * False otherwise.
+     */
+    public boolean isSameTransportType(String transportType)
+    {
+        if(this.transportType == null)
+        {
+            return (transportType == null);
+        }
+        return this.transportType.equals(transportType);
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if(obj != null
+                && obj instanceof ExtendedCaptureDeviceInfo)
+        {
+            return this.getIdentifier().equals(
+                    ((ExtendedCaptureDeviceInfo) obj).getIdentifier());
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return this.getIdentifier().hashCode();
+    }
+
+    /**
+     * Returns the device identifier used to save and load device preferences.
+     * It is composed by the system UID if not null. Otherwise returns the
+     * device name and (if not null) the transport type.
+     *
+     * @return The device identifer.
+     */
+    public String getIdentifier()
+    {
+        String id = this.UID;
+        if(this.UID == null)
+        {
+            id = this.name;
+        }
+        return id;
+    }
+}
diff --git a/src/org/jitsi/impl/neomedia/device/NotifyDevices.java b/src/org/jitsi/impl/neomedia/device/NotifyDevices.java
index ff76b22acc25ef5c704b25f567de056ad56c1347..43512c97b2cde3e03aba34ce3eb02481591d1d2c 100644
--- a/src/org/jitsi/impl/neomedia/device/NotifyDevices.java
+++ b/src/org/jitsi/impl/neomedia/device/NotifyDevices.java
@@ -20,11 +20,6 @@
 public class NotifyDevices
     extends PlaybackDevices
 {
-    /**
-     * The flag nuber if the notify device is null.
-     */
-    protected static final int FLAG_DEVICE_IS_NULL = 2;
-
     /**
      * The property of the notify devices.
      */
@@ -40,16 +35,6 @@ public NotifyDevices(AudioSystem audioSystem)
         super(audioSystem);
     }
 
-    /**
-     * Returns the flag nuber if the capture device is null.
-     *
-     * @return The flag nuber if the capture device is null.
-     */
-    protected int getFlagDeviceIsNull()
-    {
-        return FLAG_DEVICE_IS_NULL;
-    }
-
     /**
      * Returns the property of the capture devices.
      *
diff --git a/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java b/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java
index c2ba74231c934b636f628c48d2de43a2bc4abb83..05d892ce42796ce491e97effdaee479402cfb4cc 100644
--- a/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java
+++ b/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java
@@ -20,11 +20,6 @@
 public class PlaybackDevices
     extends Devices
 {
-    /**
-     * The flag nuber if the playback device is null.
-     */
-    protected static final int FLAG_DEVICE_IS_NULL = 4;
-
     /**
      * The property of the playback devices.
      */
@@ -33,7 +28,7 @@ public class PlaybackDevices
     /**
      * The list of active (actually plugged-in) playback devices.
      */
-    private List<CaptureDeviceInfo> activePlaybackDevices = null;
+    private List<ExtendedCaptureDeviceInfo> activePlaybackDevices = null;
 
     /**
      * Initializes the playback device list managment.
@@ -48,18 +43,14 @@ public PlaybackDevices(AudioSystem audioSystem)
     /**
      * Returns the list of the active devices.
      *
-     * @param locator The string representation of the locator.
-     *
      * @return The list of the active devices.
      */
-    public List<CaptureDeviceInfo> getDevices(String locator)
+    public List<ExtendedCaptureDeviceInfo> getDevices()
     {
-        List<CaptureDeviceInfo> activePlaybackDevices
-            = this.activePlaybackDevices;
-
-        return (activePlaybackDevices == null)
+        return (this.activePlaybackDevices == null)
                 ? null
-                : new ArrayList<CaptureDeviceInfo>(activePlaybackDevices);
+                : new ArrayList<ExtendedCaptureDeviceInfo>(
+                        this.activePlaybackDevices);
     }
 
     /**
@@ -67,21 +58,11 @@ public List<CaptureDeviceInfo> getDevices(String locator)
      *
      * @param activeDevices The list of the active devices.
      */
-    public void setActiveDevices(List<CaptureDeviceInfo> activeDevices)
+    public void setActiveDevices(List<ExtendedCaptureDeviceInfo> activeDevices)
     {
         this.activePlaybackDevices = (activeDevices == null)
                 ? null
-                : new ArrayList<CaptureDeviceInfo>(activeDevices);
-    }
-
-    /**
-     * Returns the flag nuber if the capture device is null.
-     *
-     * @return The flag nuber if the capture device is null.
-     */
-    protected int getFlagDeviceIsNull()
-    {
-        return FLAG_DEVICE_IS_NULL;
+                : new ArrayList<ExtendedCaptureDeviceInfo>(activeDevices);
     }
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java b/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java
index 09b8c170282510eff7a205facb740b04cd3028b3..32a142000d74fd9a1a7bcebfc094b726afe0ea85 100644
--- a/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java
@@ -100,10 +100,10 @@ protected void doInitialize()
         long sampleFormat = PortAudio.getPaSampleFormat(sampleSizeInBits);
         int defaultInputDeviceIndex = PortAudio.Pa_GetDefaultInputDevice();
         int defaultOutputDeviceIndex = PortAudio.Pa_GetDefaultOutputDevice();
-        List<CaptureDeviceInfo> captureDevices
-            = new LinkedList<CaptureDeviceInfo>();
-        List<CaptureDeviceInfo> playbackDevices
-            = new LinkedList<CaptureDeviceInfo>();
+        List<ExtendedCaptureDeviceInfo> captureDevices
+            = new LinkedList<ExtendedCaptureDeviceInfo>();
+        List<ExtendedCaptureDeviceInfo> playbackDevices
+            = new LinkedList<ExtendedCaptureDeviceInfo>();
 
         for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
         {
@@ -117,30 +117,52 @@ protected void doInitialize()
                 = PortAudio.PaDeviceInfo_getMaxInputChannels(deviceInfo);
             int maxOutputChannels
                 = PortAudio.PaDeviceInfo_getMaxOutputChannels(deviceInfo);
+            String transportType
+                = PortAudio.PaDeviceInfo_getTransportType(deviceInfo);
+            String deviceUID
+                = PortAudio.PaDeviceInfo_getDeviceUID(deviceInfo);
 
-            CaptureDeviceInfo cdi
-                = new CaptureDeviceInfo(
-                        name,
-                        new MediaLocator(LOCATOR_PROTOCOL + ":#" + deviceIndex),
-                        new Format[]
-                        {
-                            new AudioFormat(
-                                    AudioFormat.LINEAR,
-                                    (maxInputChannels > 0)
-                                        ? getSupportedSampleRate(
-                                                true,
-                                                deviceIndex,
-                                                channels,
-                                                sampleFormat)
-                                        : PortAudio.DEFAULT_SAMPLE_RATE,
-                                    sampleSizeInBits,
-                                    channels,
-                                    AudioFormat.LITTLE_ENDIAN,
-                                    AudioFormat.SIGNED,
-                                    Format.NOT_SPECIFIED /* frameSizeInBits */,
-                                    Format.NOT_SPECIFIED /* frameRate */,
-                                    Format.byteArray)
-                        });
+            ExtendedCaptureDeviceInfo cdi = null;
+            List<ExtendedCaptureDeviceInfo> devices = getDevices(CAPTURE_INDEX);
+            boolean found = false;
+            // Search if the device is already initiated. If yes used it,
+            // otherwise a call currently using this device will fail.
+            for(int i = 0; devices !=null && i < devices.size() && !found; ++i)
+            {
+                if(devices.get(i).getUID().equals(deviceUID))
+                {
+                    cdi = devices.get(i);
+                    found = true;
+                }
+            }
+            // If not found, then we must initialized this new device.
+            if(!found)
+            {
+                cdi = new ExtendedCaptureDeviceInfo(
+                    name,
+                    new MediaLocator(LOCATOR_PROTOCOL + ":#" + deviceIndex),
+                    new Format[]
+                    {
+                        new AudioFormat(
+                                AudioFormat.LINEAR,
+                                (maxInputChannels > 0)
+                                    ? getSupportedSampleRate(
+                                            true,
+                                            deviceIndex,
+                                            channels,
+                                            sampleFormat)
+                                    : PortAudio.DEFAULT_SAMPLE_RATE,
+                                sampleSizeInBits,
+                                channels,
+                                AudioFormat.LITTLE_ENDIAN,
+                                AudioFormat.SIGNED,
+                                Format.NOT_SPECIFIED /* frameSizeInBits */,
+                                Format.NOT_SPECIFIED /* frameRate */,
+                                Format.byteArray)
+                    },
+                    deviceUID,
+                    transportType);
+            }
 
             if (maxInputChannels > 0)
             {
diff --git a/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java b/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java
index 3c76ee51f067e0bd7c6250fa48296bf7fdee6f92..c91ba16c5831fd1282350a7e3ef4d02acaa4f77e 100644
--- a/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java
+++ b/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java
@@ -264,8 +264,8 @@ protected synchronized void doInitialize()
     {
         long context = getContext();
 
-        final List<CaptureDeviceInfo> captureDevices
-            = new LinkedList<CaptureDeviceInfo>();
+        final List<ExtendedCaptureDeviceInfo> captureDevices
+            = new LinkedList<ExtendedCaptureDeviceInfo>();
         final List<Format> captureDeviceFormats = new LinkedList<Format>();
         PA.source_info_cb_t sourceInfoListCallback
             = new PA.source_info_cb_t()
@@ -290,8 +290,8 @@ public void callback(long c, long i, int eol)
                 }
             };
 
-        final List<CaptureDeviceInfo> playbackDevices
-            = new LinkedList<CaptureDeviceInfo>();
+        final List<ExtendedCaptureDeviceInfo> playbackDevices
+            = new LinkedList<ExtendedCaptureDeviceInfo>();
         final List<Format> playbackDeviceFormats = new LinkedList<Format>();
         PA.sink_info_cb_t sinkInfoListCallback
             = new PA.sink_info_cb_t()
@@ -364,19 +364,23 @@ public void callback(long c, long i, int eol)
         {
             captureDevices.add(
                     0,
-                    new CaptureDeviceInfo(
+                    new ExtendedCaptureDeviceInfo(
                             NULL_DEV_CAPTURE_DEVICE_INFO_NAME,
                             new MediaLocator(LOCATOR_PROTOCOL + ":"),
                             captureDeviceFormats.toArray(
-                                    new Format[captureDeviceFormats.size()])));
+                                    new Format[captureDeviceFormats.size()]),
+                            null,
+                            null));
         }
         if (!playbackDevices.isEmpty())
         {
             playbackDevices.add(
                     0,
-                    new CaptureDeviceInfo(
+                    new ExtendedCaptureDeviceInfo(
                             NULL_DEV_CAPTURE_DEVICE_INFO_NAME,
                             new MediaLocator(LOCATOR_PROTOCOL + ":"),
+                            null,
+                            null,
                             null));
         }
 
@@ -447,7 +451,7 @@ public void signalMainloop(boolean waitForAccept)
     private void sinkInfoListCallback(
             long context,
             long sinkInfo,
-            List<CaptureDeviceInfo> deviceList,
+            List<ExtendedCaptureDeviceInfo> deviceList,
             List<Format> formatList)
     {
         int sampleSpecFormat = PA.sink_info_get_sample_spec_format(sinkInfo);
@@ -461,19 +465,21 @@ private void sinkInfoListCallback(
         if (description == null)
             description = name;
         deviceList.add(
-                new CaptureDeviceInfo(
+                new ExtendedCaptureDeviceInfo(
                         description,
                         new MediaLocator(
                                 LOCATOR_PROTOCOL
                                     + ":"
                                     + name),
+                        null,
+                        null,
                         null));
     }
 
     private void sourceInfoListCallback(
             long context,
             long sourceInfo,
-            List<CaptureDeviceInfo> deviceList,
+            List<ExtendedCaptureDeviceInfo> deviceList,
             List<Format> formatList)
     {
         int monitorOfSink = PA.source_info_get_monitor_of_sink(sourceInfo);
@@ -524,14 +530,16 @@ private void sourceInfoListCallback(
             if (description == null)
                 description = name;
             deviceList.add(
-                    new CaptureDeviceInfo(
+                    new ExtendedCaptureDeviceInfo(
                             description,
                             new MediaLocator(
                                     LOCATOR_PROTOCOL
                                         + ":"
                                         + name),
                             sourceInfoFormatList.toArray(
-                                    new Format[sourceInfoFormatList.size()])));
+                                    new Format[sourceInfoFormatList.size()]),
+                            null,
+                            null));
         }
     }