 		private function configure_response( iq:IQ ):void
 		{
 			var event:RoomEvent = new RoomEvent( RoomEvent.CONFIGURE_ROOM_COMPLETE );
+			dispatchEvent( event );
+		}
+
+		/**
+		 * Helper to dispatch a property change event.
+		 * @param	name
+		 * @param	newValue
+		 * @param	oldValue
+		 */
+		private function dispatchChangeEvent( name:String, newValue:*, oldValue:* ):void
+		{
+			var event:PropertyChangeEvent = new PropertyChangeEvent( PropertyChangeEvent.CHANGE );
+			event.name = name;
+			event.newValue = newValue;
+			event.oldValue = oldValue;
 			dispatchEvent( event );
 		}
 

	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.AFFILIATIONS
	 */
	[Event( name="affiliations",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when an administration action failed.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.ADMIN_ERROR
	 * @see	org.igniterealtime.xiff.core.XMPPConnection.error
	 */
	[Event( name="adminError",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when the room requires a password and the user did not supply one (or
	 * the password provided is incorrect).
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.PASSWORD_ERROR
	 */
	[Event( name="passwordError",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when the room is members-only and the user is not on the member list.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.REGISTRATION_REQ_ERROR
	 */
	[Event( name="registrationReqError",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when the room is removed.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.ROOM_DESTROYED
	 */
	[Event( name="roomDestroyed",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched if the user attempted to join the room but was not allowed to do so because
	 * they are banned (i.e., has an affiliation of "outcast").
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.BANNED_ERROR
	 */
	[Event( name="bannedError",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched if the room has reached its maximum number of occupants.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.MAX_USERS_ERROR
	 */
	[Event( name="maxUsersError",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched if a user attempts to enter a room while it is "locked" (i.e., before the room
	 * creator provides an initial configuration and therefore before the room officially exists).
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.LOCKED_ERROR
	 */
	[Event( name="lockedError",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched whenever an occupant joins the room. The <code>RoomEvent</code> instance will
	 * contain an attribute <code>nickname</code> with the nickname of the occupant who joined.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.USER_JOIN
	 */
	[Event( name="userJoin",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched whenever an occpant leaves the room. The <code>RoomEvent</code> instance will
	 * contain an attribute <code>nickname</code> with the nickname of the occupant who left.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.USER_DEPARTURE
	 */
	[Event( name="userDeparture",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when a user is kicked from the room.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.USER_KICKED
	 */
	[Event( name="userKicked",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when a user is banned from the room.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.USER_BANNED
	 */
	[Event( name="userBanned",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when a user's presence changes.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.USER_PRESENCE_CHANGE
	 */
	[Event( name="userPresenceChange",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when the user's preferred nickname already exists in the room.	The
	 * <code>RoomEvent</code> will contain an attribute <code>nickname</code> with the nickname
	 * already existing in the room.
	 *
	 * @eventType org.igniterealtime.xiff.events.RoomEvent.NICK_CONFLICT
	 */
	[Event( name="nickConflict",type="org.igniterealtime.xiff.events.RoomEvent" )]
	/**
	 * Dispatched when a room configuration form is required.	This can occur during the
	 * creation of a room, or if a room configuration is requested.	The <code>RoomEvent</code>


			if ( isThisUser( aPresence.from.unescaped ))
			{
				var oldAffiliation:String = _affiliation;
				_affiliation = item.affiliation;
				if( _affiliation != oldAffiliation ) dispatchChangeEvent( "affiliation", _affiliation, oldAffiliation );

				var oldRole:String = _role;
				_role = item.role;
				if( _role != oldRole ) dispatchChangeEvent( "role", _role, oldRole );

				if ( !isActive && aPresence.type != Presence.TYPE_UNAVAILABLE )
				{
