Index: pjproject/trunk/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java
===================================================================
--- pjproject/trunk/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java	(revision 5968)
+++ pjproject/trunk/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java	(revision 5969)
@@ -98,11 +98,7 @@
 			pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD))
 	    {
-		// unfortunately, on Java too, the returned Media cannot be
-		// downcasted to AudioMedia 
-		Media m = getMedia(i);
-		AudioMedia am = AudioMedia.typecastFromMedia(m);
-
 		// connect ports
 		try {
+		    AudioMedia am = getAudioMedia(i);
 		    MyApp.ep.audDevManager().getCaptureDevMedia().
 							    startTransmit(am);
@@ -110,4 +106,6 @@
 				     getPlaybackDevMedia());
 		} catch (Exception e) {
+		    System.out.println("Failed connecting media ports" +
+				       e.getMessage());
 		    continue;
 		}
Index: pjproject/trunk/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- pjproject/trunk/pjsip-apps/src/swig/pjsua2.i	(revision 5968)
+++ pjproject/trunk/pjsip-apps/src/swig/pjsua2.i	(revision 5969)
@@ -106,13 +106,22 @@
 %template(SipMultipartPartVector)	std::vector<pj::SipMultipartPart>;
 %template(BuddyVector)			std::vector<pj::Buddy*>;
+%template(BuddyVector2)			std::vector<pj::Buddy>;
 %template(AudioMediaVector)		std::vector<pj::AudioMedia*>;
+%template(AudioMediaVector2)		std::vector<pj::AudioMedia>;
 %template(ToneDescVector)		std::vector<pj::ToneDesc>;
 %template(ToneDigitVector)		std::vector<pj::ToneDigit>;
 %template(ToneDigitMapVector)	        std::vector<pj::ToneDigitMapDigit>;
-%template(MediaFormatVector)		std::vector<pj::MediaFormat*>;
 %template(AudioDevInfoVector)		std::vector<pj::AudioDevInfo*>;
+%template(AudioDevInfoVector2)		std::vector<pj::AudioDevInfo>;
 %template(CodecInfoVector)		std::vector<pj::CodecInfo*>;
+%template(CodecInfoVector2)		std::vector<pj::CodecInfo>;
 %template(VideoDevInfoVector)		std::vector<pj::VideoDevInfo*>;
+%template(VideoDevInfoVector2)		std::vector<pj::VideoDevInfo>;
 %template(CodecFmtpVector)		std::vector<pj::CodecFmtp>;	
+%template(MediaFormatAudioVector)       std::vector<pj::MediaFormatAudio>;
+%template(MediaFormatVideoVector)       std::vector<pj::MediaFormatVideo>;
+%template(CallMediaInfoVector)          std::vector<pj::CallMediaInfo>;
+%template(RtcpFbCapVector)              std::vector<pj::RtcpFbCap>;
+%template(SslCertNameVector)            std::vector<pj::SslCertName>;
 
 %ignore pj::WindowHandle::display;
@@ -145,6 +154,4 @@
 %include "pjsua2/call.hpp"
 
-%template(CallMediaInfoVector)          std::vector<pj::CallMediaInfo>;
-
 %ignore pj::JsonDocument::allocElement;
 %ignore pj::JsonDocument::getPool;
Index: pjproject/trunk/pjsip/include/pjsua2/account.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/account.hpp	(revision 5968)
+++ pjproject/trunk/pjsip/include/pjsua2/account.hpp	(revision 5969)
@@ -1649,4 +1649,7 @@
      * and delete the corresponding account in the PJSUA-LIB.
      *
+     * Note that application must delete all Buddy instances belong to this
+     * account before shutting down the account.
+     *
      * If application implements a derived class, the derived class should
      * call this method in the beginning stage in its destructor, or
@@ -1760,4 +1763,7 @@
     
     /**
+     * Warning: deprecated, use enumBuddies2() instead. This function is not
+     * safe in multithreaded environment.
+     *
      * Enumerate all buddies of the account.
      *
@@ -1767,4 +1773,14 @@
 
     /**
+     * Enumerate all buddies of the account.
+     *
+     * @return			The buddy list.
+     */
+    BuddyVector2 enumBuddies2() const throw(Error);
+
+    /**
+     * Warning: deprecated, use findBuddy2 instead. This function is not
+     * safe in multithreaded environment.
+     *
      * Find a buddy in the buddy list with the specified URI. 
      *
@@ -1778,4 +1794,15 @@
     Buddy* findBuddy(string uri, FindBuddyMatch *buddy_match = NULL) const
 		    throw(Error);
+
+    /**
+     * Find a buddy in the buddy list with the specified URI. 
+     *
+     * Exception: if buddy is not found, PJ_ENOTFOUND will be thrown.
+     *
+     * @param uri		The buddy URI.
+     *
+     * @return			The pointer to buddy.
+     */
+    Buddy findBuddy2(string uri) const throw(Error);
 
 public:
Index: pjproject/trunk/pjsip/include/pjsua2/call.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5968)
+++ pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5969)
@@ -312,5 +312,5 @@
      * Default constructor initializes with empty or default values.
      */
-    CallSetting(pj_bool_t useDefaultValues = false);
+    CallSetting(bool useDefaultValues = false);
 
     /**
@@ -1010,5 +1010,5 @@
      * which are going to be used.
      */
-    vector<SrtpCrypto>		cryptos;
+    SrtpCryptoVector		cryptos;
 };
 
@@ -1236,4 +1236,7 @@
     
     /**
+     * Warning: deprecated, use getAudioMedia() instead. This function is not
+     * safe in multithreaded environment.
+     *
      * Get media for the specified media index.
      *
@@ -1243,4 +1246,14 @@
      */
     Media *getMedia(unsigned med_idx) const;
+
+    /**
+     * Get audio media for the specified media index. If the specified media
+     * index is not audio or invalid or inactive, exception will be thrown.
+     *
+     * @param med_idx       Media index.
+     *
+     * @return              The audio media.
+     */
+    AudioMedia getAudioMedia(unsigned med_idx) const throw(Error);
 
     /**
Index: pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5968)
+++ pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5969)
@@ -133,4 +133,7 @@
 };
 
+/** Array of SSL certificate type and name. */
+typedef std::vector<SslCertName> SslCertNameVector;
+
 /**
  * SSL certificate information.
@@ -156,5 +159,5 @@
 					 	 date/time use GMT	*/
 
-    vector<SslCertName> subjectAltName;     /**< Subject alternative
+    SslCertNameVector	subjectAltName;     /**< Subject alternative
 					 	 name extension		*/
 
@@ -1379,4 +1382,7 @@
 
     /**
+     * Warning: deprecated, use mediaEnumPorts2() instead. This function is
+     * not safe in multithreaded environment.
+     *
      * Enumerate all media port.
      *
@@ -1384,4 +1390,11 @@
      */
     const AudioMediaVector &mediaEnumPorts() const throw(Error);
+
+    /**
+     * Enumerate all audio media port.
+     *
+     * @return		The list of audio media port.
+     */
+    AudioMediaVector2 mediaEnumPorts2() const throw(Error);
 
     /**
@@ -1404,4 +1417,7 @@
 
     /**
+     * Warning: deprecated, use codecEnum2() instead. This function is not
+     * safe in multithreaded environment.
+     *
      * Enum all supported codecs in the system.
      *
@@ -1409,4 +1425,11 @@
      */
     const CodecInfoVector &codecEnum() throw(Error);
+
+    /**
+     * Enum all supported codecs in the system.
+     *
+     * @return		Array of codec info.
+     */
+    CodecInfoVector2 codecEnum2() const throw(Error);
 
     /**
@@ -1445,4 +1468,7 @@
 
     /**
+     * Warning: deprecated, use videoCodecEnum2() instead. This function is
+     * not safe in multithreaded environment.
+     *
      * Enum all supported video codecs in the system.
      *  
@@ -1450,4 +1476,11 @@
      */
     const CodecInfoVector &videoCodecEnum() throw(Error);
+
+    /**
+     * Enum all supported video codecs in the system.
+     *  
+     * @return		Array of video codec info.
+     */
+    CodecInfoVector2 videoCodecEnum2() const throw(Error);
 
     /**
Index: pjproject/trunk/pjsip/include/pjsua2/media.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/media.hpp	(revision 5968)
+++ pjproject/trunk/pjsip/include/pjsua2/media.hpp	(revision 5969)
@@ -214,5 +214,20 @@
 
 /**
- * Audio Media.
+ * Audio Media. This is a lite wrapper class for audio conference bridge port,
+ * i.e: this class only maintains one data member, conference slot ID, and 
+ * the methods are simply proxies for conference bridge operations.
+ *
+ * Application can create a derived class and use registerMediaPort2()/
+ * unregisterMediaPort() to register/unregister a media port to/from the
+ * conference bridge.
+ *
+ * The library will not keep a list of AudioMedia instances, so any
+ * AudioMedia (descendant) instances instantiated by application must be
+ * maintained and destroyed by the application itself.
+ *
+ * Note that any PJSUA2 APIs that return AudioMedia instance(s) such as
+ * Endpoint::mediaEnumPorts2() or Call::getAudioMedia() will just return
+ * generated copy. All AudioMedia methods should work normally on this
+ * generated copy instance.
  */
 class AudioMedia : public Media
@@ -321,4 +336,6 @@
 
     /**
+     * Warning: deprecated and will be removed in future release.
+     *
      * Typecast from base class Media. This is useful for application written
      * in language that does not support downcasting such as Python.
@@ -331,5 +348,11 @@
 
     /**
-     * Virtual Destructor
+     * Default Constructor. Normally application will not create AudioMedia
+     * object directly, but it may instantiate an AudioMedia derived class.
+     */
+    AudioMedia();
+
+    /**
+     * Virtual Destructor.
      */
     virtual ~AudioMedia();
@@ -343,17 +366,26 @@
 protected:
     /**
-     * Default Constructor.
-     */
-    AudioMedia();
-
-    /**
+     * Warning: deprecated and will be removed in future release, use
+     * registerMediaPort2() instead.
+     *
      * This method needs to be called by descendants of this class to register
      * the media port created to the conference bridge and Endpoint's
      * media list.
      *
-     * param port  the media port to be registered to the conference bridge.
+     * param port  The media port to be registered to the conference bridge.
      *
      */
     void registerMediaPort(MediaPort port) throw(Error);
+
+    /**
+     * This method needs to be called by descendants of this class to register
+     * the media port created to the conference bridge and Endpoint's
+     * media list.
+     *
+     * param port  The media port to be registered to the conference bridge.
+     * param pool  The memory pool.
+     *
+     */
+    void registerMediaPort2(MediaPort port, pj_pool_t *pool) throw(Error);
 
     /**
@@ -366,10 +398,21 @@
 
 private:
+    /* Memory pool for deprecated registerMediaPort() */
     pj_caching_pool 	 mediaCachingPool;
     pj_pool_t 		*mediaPool;
-};
+
+    friend class Endpoint;
+};
+
+/** 
+ * Warning: deprecated, use AudioMediaVector2 instead.
+ *
+ * Array of Audio Media.
+ */
+typedef std::vector<AudioMedia*> AudioMediaVector;
+
 
 /** Array of Audio Media */
-typedef std::vector<AudioMedia*> AudioMediaVector;
+typedef std::vector<AudioMedia> AudioMediaVector2;
 
 /**
@@ -465,4 +508,6 @@
 
     /**
+     * Warning: deprecated and will be removed in future release.
+     *
      * Typecast from base class AudioMedia. This is useful for application
      * written in language that does not support downcasting such as Python.
@@ -475,5 +520,6 @@
 
     /**
-     * Destructor.
+     * Destructor. This will unregister the player port from the conference
+     * bridge.
      */
     virtual ~AudioMediaPlayer();
@@ -546,8 +592,10 @@
     void createRecorder(const string &file_name,
 			unsigned enc_type=0,
-			pj_ssize_t max_size=0,
+			long max_size=0,
 			unsigned options=0) throw(Error);
 
     /**
+     * Warning: deprecated and will be removed in future release.
+     *
      * Typecast from base class AudioMedia. This is useful for application
      * written in language that does not support downcasting such as Python.
@@ -560,5 +608,6 @@
 
     /**
-     * Destructor.
+     * Destructor. This will unregister the recorder port from the conference
+     * bridge.
      */
     virtual ~AudioMediaRecorder();
@@ -635,10 +684,11 @@
 
     /**
-     * Destructor.
+     * Destructor. This will unregister the tone generator port from the
+     * conference bridge.
      */
     ~ToneGenerator();
 
     /**
-     * Create tone generator.
+     * Create tone generator and register the port to the conference bridge.
      */
     void createToneGenerator(unsigned clock_rate = 16000,
@@ -776,6 +826,13 @@
 };
 
+/** 
+ * Warning: deprecated, use AudioDevInfoVector2 instead.
+ *
+ * Array of audio device info.
+ */
+typedef std::vector<AudioDevInfo*> AudioDevInfoVector;
+
 /** Array of audio device info */
-typedef std::vector<AudioDevInfo*> AudioDevInfoVector;
+typedef std::vector<AudioDevInfo> AudioDevInfoVector2;
 
 /**
@@ -836,9 +893,20 @@
 
     /**
+     * Warning: deprecated, use enumDev2 instead. This function is not
+     * safe in multithreaded environment.
+     *
+     * Enum all audio devices installed in the system. This function is not
+     * safe in multithreaded environment.
+     *
+     * @return			The list of audio device info.
+     */
+    const AudioDevInfoVector &enumDev() throw(Error);
+
+    /**
      * Enum all audio devices installed in the system.
      *
      * @return			The list of audio device info.
      */
-    const AudioDevInfoVector &enumDev() throw(Error);
+    AudioDevInfoVector2 enumDev2() const throw(Error);
 
     /**
@@ -1417,5 +1485,5 @@
 public:
     /**
-     * Constructor
+     * Constructor.
      *
      * @param playdev		Playback device ID.
@@ -1425,5 +1493,5 @@
 
     /**
-     * Destructor
+     * Destructor.
      */
     virtual ~ExtraAudioDevice();
@@ -1432,10 +1500,12 @@
      * Open the audio device using format (e.g.: clock rate, bit per sample,
      * samples per frame) matched to the conference bridge's format, except
-     * the channel count, which will be set to one (mono channel).
+     * the channel count, which will be set to one (mono channel). This will
+     * also register the audio device port to conference bridge.
      */
     void open();
 
     /**
-     * Close the audio device.
+     * Close the audio device and unregister the audio device port from the
+     * conference bridge.
      */
     void close();
@@ -1766,6 +1836,13 @@
 };
 
+/** 
+ * Warning: deprecated, use VideoDevInfoVector2 instead.
+ *
+ * Array of video device info.
+ */
+typedef std::vector<VideoDevInfo*> VideoDevInfoVector;
+
 /** Array of video device info */
-typedef std::vector<VideoDevInfo*> VideoDevInfoVector;
+typedef std::vector<VideoDevInfo> VideoDevInfoVector2;
 
 /**
@@ -1813,4 +1890,7 @@
 
     /**
+     * Warning: deprecated, use enumDev2() instead. This function is not
+     * safe in multithreaded environment.
+     *
      * Enum all video devices installed in the system.
      *
@@ -1818,4 +1898,11 @@
      */
     const VideoDevInfoVector &enumDev() throw(Error);
+
+    /**
+     * Enum all video devices installed in the system.
+     *
+     * @return		The list of video device info
+     */
+    VideoDevInfoVector2 enumDev2() const throw(Error);
 
     /**
@@ -2056,6 +2143,13 @@
 };
 
+/** 
+ * Warning: deprecated, use CodecInfoVector2 instead.
+ *
+ * Array of codec info.
+ */
+typedef std::vector<CodecInfo*> CodecInfoVector;
+
 /** Array of codec info */
-typedef std::vector<CodecInfo*> CodecInfoVector;
+typedef std::vector<CodecInfo> CodecInfoVector2;
 
 /**
Index: pjproject/trunk/pjsip/include/pjsua2/presence.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/presence.hpp	(revision 5968)
+++ pjproject/trunk/pjsip/include/pjsua2/presence.hpp	(revision 5969)
@@ -169,5 +169,5 @@
      */
     PresenceStatus	 presStatus;
-    
+
 public:
     /** Import from pjsip structure */
@@ -189,5 +189,20 @@
 
 /**
- * Buddy.
+ * Buddy. This is a lite wrapper class for PJSUA-LIB buddy, i.e: this class
+ * only maintains one data member, PJSUA-LIB buddy ID, and the methods are
+ * simply proxies for PJSUA-LIB buddy operations.
+ *
+ * Application can use create() to register a buddy to PJSUA-LIB, and
+ * the destructor of the original instance (i.e: the instance that calls
+ * create()) will unregister and delete the buddy from PJSUA-LIB. Application
+ * must delete all Buddy instances belong to an account before shutting down
+ * the account (via Account::shutdown()).
+ *
+ * The library will not keep a list of Buddy instances, so any Buddy (or
+ * descendant) instances instantiated by application must be maintained
+ * and destroyed by the application itself. Any PJSUA2 APIs that return Buddy
+ * instance(s) such as Account::enumBuddies2() or Account::findBuddy2() will
+ * just return generated copy. All Buddy methods should work normally on this
+ * generated copy instance.
  */
 class Buddy
@@ -200,6 +215,9 @@
     
     /**
-     * Destructor. Note that if the Buddy instance is deleted, it will also
-     * delete the corresponding buddy in the PJSUA-LIB.
+     * Destructor. Note that if the Buddy original instance (i.e: the instance
+     * that calls Buddy::create()) is destroyed, it will also delete the
+     * corresponding buddy in the PJSUA-LIB. While the destructor of
+     * a generated copy (i.e: Buddy instance returned by PJSUA2 APIs such as
+     * Account::enumBuddies2() or Account::findBuddy2()) will do nothing.
      */
     virtual ~Buddy();
@@ -207,4 +225,8 @@
     /**
      * Create buddy and register the buddy to PJSUA-LIB.
+     *
+     * Note that application should maintain the Buddy original instance, i.e:
+     * the instance that calls this create() method as it is only the original
+     * instance destructor that will delete the underlying Buddy in PJSUA-LIB.
      *
      * @param acc		The account for this buddy.
@@ -298,15 +320,25 @@
       * Buddy ID.
       */
-     pjsua_buddy_id	 id;
-     
-     /**
-      * Account.
-      */
-     Account		*acc;
-};
-
+    pjsua_buddy_id	 id;
+
+private:
+    friend class Endpoint;
+    friend class Account;
+
+    /* Internal constructor/methods used by Endpoint and Account */
+    Buddy(pjsua_buddy_id buddy_id);
+    Buddy *getOriginalInstance();
+};
+
+
+/**
+ * Warning: deprecated, use BuddyVector2 instead.
+ *
+ * Array of buddies.
+ */
+typedef std::vector<Buddy*> BuddyVector;
 
 /** Array of buddies */
-typedef std::vector<Buddy*> BuddyVector;
+typedef std::vector<Buddy> BuddyVector2;
 
 
Index: pjproject/trunk/pjsip/src/pjsua2/account.cpp
===================================================================
--- pjproject/trunk/pjsip/src/pjsua2/account.cpp	(revision 5968)
+++ pjproject/trunk/pjsip/src/pjsua2/account.cpp	(revision 5969)
@@ -1029,4 +1029,18 @@
 }
 
+BuddyVector2 Account::enumBuddies2() const throw(Error)
+{
+    BuddyVector2 bv2;
+    pjsua_buddy_id ids[PJSUA_MAX_BUDDIES];
+    unsigned i, count = PJSUA_MAX_BUDDIES;
+
+    PJSUA2_CHECK_EXPR( pjsua_enum_buddies(ids, &count) );
+    for (i = 0; i < count; ++i) {
+	bv2.push_back(Buddy(ids[i]));
+    }
+
+    return bv2;
+}
+
 Buddy* Account::findBuddy(string uri, FindBuddyMatch *buddy_match) const
 		throw(Error)
@@ -1042,4 +1056,20 @@
     }
     PJSUA2_RAISE_ERROR(PJ_ENOTFOUND);
+}
+
+Buddy Account::findBuddy2(string uri) const throw(Error)
+{
+    pj_str_t pj_uri;
+    pjsua_buddy_id id;
+
+    pj_strset2(&pj_uri, (char*)uri.c_str());
+
+    id = pjsua_buddy_find(&pj_uri);
+    if (id == PJSUA_INVALID_ID) {
+	PJSUA2_RAISE_ERROR(PJ_ENOTFOUND);
+    }
+
+    Buddy buddy(id);
+    return buddy;
 }
 
Index: pjproject/trunk/pjsip/src/pjsua2/call.cpp
===================================================================
--- pjproject/trunk/pjsip/src/pjsua2/call.cpp	(revision 5968)
+++ pjproject/trunk/pjsip/src/pjsua2/call.cpp	(revision 5969)
@@ -228,5 +228,5 @@
 }
 
-CallSetting::CallSetting(pj_bool_t useDefaultValues)
+CallSetting::CallSetting(bool useDefaultValues)
 {
     if (useDefaultValues) {
@@ -522,4 +522,17 @@
 }
 
+AudioMedia Call::getAudioMedia(unsigned med_idx) const throw(Error)
+{
+    CallAudioMedia cam;
+    CallInfo ci = getInfo();
+
+    if (med_idx < ci.media.size() &&
+	ci.media[med_idx].type == PJMEDIA_TYPE_AUDIO)
+    {
+	cam.setPortId(ci.media[med_idx].audioConfSlot);
+    }
+    return cam;
+}
+
 pjsip_dialog_cap_status Call::remoteHasCap(int htype,
                                            const string &hname,
Index: pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5968)
+++ pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5969)
@@ -978,5 +978,6 @@
 void Endpoint::on_buddy_state(pjsua_buddy_id buddy_id)
 {
-    Buddy *buddy = (Buddy*)pjsua_buddy_get_user_data(buddy_id);
+    Buddy b(buddy_id);
+    Buddy *buddy = b.getOriginalInstance();
     if (!buddy || !buddy->isValid()) {
 	/* Ignored */
@@ -993,5 +994,6 @@
     PJ_UNUSED_ARG(sub);
 
-    Buddy *buddy = (Buddy*)pjsua_buddy_get_user_data(buddy_id);
+    Buddy b(buddy_id);
+    Buddy *buddy = b.getOriginalInstance();
     if (!buddy || !buddy->isValid()) {
 	/* Ignored */
@@ -2045,6 +2047,25 @@
 }
 
+AudioMediaVector2 Endpoint::mediaEnumPorts2() const throw(Error)
+{
+    AudioMediaVector2 amv2;
+    pjsua_conf_port_id ids[PJSUA_MAX_CONF_PORTS];
+    unsigned i, count = PJSUA_MAX_CONF_PORTS;
+
+    PJSUA2_CHECK_EXPR( pjsua_enum_conf_ports(ids, &count) );
+    for (i = 0; i < count; ++i) {
+	AudioMedia am;
+	am.id = ids[i];
+	amv2.push_back(am);
+    }
+
+    return amv2;
+}
+
 void Endpoint::mediaAdd(AudioMedia &media)
 {
+    /* mediaList serves mediaEnumPorts() only, once mediaEnumPorts()
+     * is removed, this function implementation should be no-op.
+     */
     pj_mutex_lock(mediaListMutex);
 
@@ -2060,4 +2081,7 @@
 void Endpoint::mediaRemove(AudioMedia &media)
 {
+    /* mediaList serves mediaEnumPorts() only, once mediaEnumPorts()
+     * is removed, this function implementation should be no-op.
+     */
     pj_mutex_lock(mediaListMutex);
     AudioMediaVector::iterator it = std::find(mediaList.begin(),
@@ -2067,5 +2091,4 @@
     if (it != mediaList.end())
 	mediaList.erase(it);
-
     pj_mutex_unlock(mediaListMutex);
 }
@@ -2073,13 +2096,10 @@
 bool Endpoint::mediaExists(const AudioMedia &media) const
 {
-    bool exists;
-
-    pj_mutex_lock(mediaListMutex);
-    AudioMediaVector::const_iterator it = std::find(mediaList.begin(),
-						    mediaList.end(),
-						    &media);
-    exists = (it != mediaList.end());
-    pj_mutex_unlock(mediaListMutex);
-    return exists;
+    pjsua_conf_port_id id = media.getPortId();
+    if (id == PJSUA_INVALID_ID || id >= (int)mediaMaxPorts())
+	return false;
+
+    pjsua_conf_port_info pi;
+    return (pjsua_conf_get_port_info(id, &pi) == PJ_SUCCESS);
 }
 
@@ -2108,4 +2128,19 @@
 }
 
+CodecInfoVector2 Endpoint::codecEnum2() const throw(Error)
+{
+    CodecInfoVector2 civ2;
+    pjsua_codec_info pj_codec[MAX_CODEC_NUM];
+    unsigned count = MAX_CODEC_NUM;
+
+    PJSUA2_CHECK_EXPR( pjsua_enum_codecs(pj_codec, &count) );
+    for (unsigned i = 0; i<count; ++i) {
+	CodecInfo codec_info;
+	codec_info.fromPj(pj_codec[i]);
+	civ2.push_back(codec_info);
+    }
+    return civ2;
+}
+
 void Endpoint::codecSetPriority(const string &codec_id,
 			        pj_uint8_t priority) throw(Error)
@@ -2169,4 +2204,21 @@
 #endif
     return videoCodecInfoList;
+}
+
+CodecInfoVector2 Endpoint::videoCodecEnum2() const throw(Error)
+{
+    CodecInfoVector2 civ2;
+#if PJSUA_HAS_VIDEO
+    pjsua_codec_info pj_codec[MAX_CODEC_NUM];
+    unsigned count = MAX_CODEC_NUM;
+
+    PJSUA2_CHECK_EXPR(pjsua_vid_enum_codecs(pj_codec, &count));
+    for (unsigned i = 0; i<count; ++i) {
+	CodecInfo codec_info;
+	codec_info.fromPj(pj_codec[i]);
+	civ2.push_back(codec_info);
+    }
+#endif
+    return civ2;
 }
 
Index: pjproject/trunk/pjsip/src/pjsua2/media.cpp
===================================================================
--- pjproject/trunk/pjsip/src/pjsua2/media.cpp	(revision 5968)
+++ pjproject/trunk/pjsip/src/pjsua2/media.cpp	(revision 5969)
@@ -158,4 +158,22 @@
 }
 
+void AudioMedia::registerMediaPort2(MediaPort port, pj_pool_t *pool)
+     throw(Error)
+{
+    /* Check if media already added to Conf bridge. */
+    pj_assert(!Endpoint::instance().mediaExists(*this));
+
+    if (port != NULL) {
+	pj_assert(id == PJSUA_INVALID_ID);
+	pj_assert(pool);
+
+	PJSUA2_CHECK_EXPR( pjsua_conf_add_port(pool,
+					       (pjmedia_port *)port,
+					       &id) );
+    }
+
+    Endpoint::instance().mediaAdd(*this);
+}
+
 void AudioMedia::unregisterMediaPort()
 {
@@ -176,5 +194,4 @@
 AudioMedia::~AudioMedia() 
 {
-    unregisterMediaPort();
 }
 
@@ -409,5 +426,5 @@
 void AudioMediaRecorder::createRecorder(const string &file_name,
 				        unsigned enc_type,
-				        pj_ssize_t max_size,
+				        long max_size,
 				        unsigned options)
 				        throw(Error)
@@ -481,5 +498,5 @@
     }
 
-    registerMediaPort(tonegen);
+    registerMediaPort2(tonegen, pool);
 }
 
@@ -746,4 +763,21 @@
     pj_leave_critical_section();
     return audioDevList;
+}
+
+AudioDevInfoVector2 AudDevManager::enumDev2() const throw(Error)
+{
+    pjmedia_aud_dev_info pj_info[MAX_DEV_COUNT];
+    unsigned count = MAX_DEV_COUNT;
+    AudioDevInfoVector2 adiv2;
+
+    PJSUA2_CHECK_EXPR( pjsua_enum_aud_devs(pj_info, &count) );
+
+    for (unsigned i = 0; i<count ;++i) {
+	AudioDevInfo di;
+	di.fromPj(pj_info[i]);
+	adiv2.push_back(di);
+    }
+
+    return adiv2;
 }
 
@@ -1427,4 +1461,22 @@
 }
 
+VideoDevInfoVector2 VidDevManager::enumDev2() const throw(Error)
+{
+    VideoDevInfoVector2 vdiv2;
+#if PJSUA_HAS_VIDEO
+    pjmedia_vid_dev_info pj_info[MAX_DEV_COUNT];
+    unsigned count = MAX_DEV_COUNT;
+
+    PJSUA2_CHECK_EXPR(pjsua_vid_enum_devs(pj_info, &count));
+
+    for (unsigned i = 0; i<count;++i) {
+	VideoDevInfo vdi;
+	vdi.fromPj(pj_info[i]);
+	vdiv2.push_back(vdi);
+    }
+#endif
+    return vdiv2;
+}
+
 int VidDevManager::lookupDev(const string &drv_name,
 			     const string &dev_name) const throw(Error)
Index: pjproject/trunk/pjsip/src/pjsua2/presence.cpp
===================================================================
--- pjproject/trunk/pjsip/src/pjsua2/presence.cpp	(revision 5968)
+++ pjproject/trunk/pjsip/src/pjsua2/presence.cpp	(revision 5969)
@@ -74,4 +74,9 @@
 
 //////////////////////////////////////////////////////////////////////////////
+typedef struct BuddyUserData
+{
+    Buddy	*self;
+    Account	*acc;
+} BuddyUserData;
 
 /*
@@ -83,4 +88,15 @@
 }
  
+Buddy::Buddy(pjsua_buddy_id buddy_id)
+: id(buddy_id)
+{
+}
+
+Buddy *Buddy::getOriginalInstance()
+{
+    BuddyUserData *bud = (BuddyUserData*)pjsua_buddy_get_user_data(id);
+    return (bud? bud->self : NULL);
+}
+
 /*
  * Destructor.
@@ -88,10 +104,18 @@
 Buddy::~Buddy()
 {
-    if (isValid()) {
+    if (isValid() && getOriginalInstance()==this) {
+	Account *acc = NULL;
+	BuddyUserData *bud = (BuddyUserData*)pjsua_buddy_get_user_data(id);
+	if (bud) {
+	    acc = bud->acc;
+	    delete bud;
+	}
+
 	pjsua_buddy_set_user_data(id, NULL);
 	pjsua_buddy_del(id);
 
 	/* Remove from account buddy list */
-	acc->removeBuddy(this);
+	if (acc)
+	    acc->removeBuddy(this);
     }
 }
@@ -108,11 +132,14 @@
 	PJSUA2_RAISE_ERROR3(PJ_EINVAL, "Buddy::create()", "Invalid account");
     
+    BuddyUserData *bud = new BuddyUserData();
+    bud->self = this;
+    bud->acc  = &account;
+
     pj_cfg.uri = str2Pj(cfg.uri);
     pj_cfg.subscribe = cfg.subscribe;
-    pj_cfg.user_data = (void*)this;
+    pj_cfg.user_data = (void*)bud;
     PJSUA2_CHECK_EXPR( pjsua_buddy_add(&pj_cfg, &id) );
     
-    acc = &account;
-    acc->addBuddy(this);
+    account.addBuddy(this);
 }
     
@@ -161,4 +188,11 @@
 {
     BuddyInfo bi = getInfo();
+    BuddyUserData *bud = (BuddyUserData*)pjsua_buddy_get_user_data(id);
+    Account *acc = bud? bud->acc : NULL;
+
+    if (!bud || !acc || !acc->isValid()) {
+	PJSUA2_RAISE_ERROR3(PJ_EINVAL, "sendInstantMessage()",
+			    "Invalid Buddy");
+    }
 
     pj_str_t to = str2Pj(bi.contact.empty()? bi.uri : bi.contact);
@@ -180,4 +214,11 @@
 {
     BuddyInfo bi = getInfo();
+    BuddyUserData *bud = (BuddyUserData*)pjsua_buddy_get_user_data(id);
+    Account *acc = bud? bud->acc : NULL;
+
+    if (!bud || !acc || !acc->isValid()) {
+	PJSUA2_RAISE_ERROR3(PJ_EINVAL, "sendInstantMessage()",
+			    "Invalid Buddy");
+    }
 
     pj_str_t to = str2Pj(bi.contact.empty()? bi.uri : bi.contact);
