+ p_item->i_id = ++p_playlist->i_last_playlist_id;
+
+ p_item->p_parent = NULL;
+ p_item->i_children = -1;
+ p_item->pp_children = NULL;
+ p_item->i_flags = 0;
+
+ vlc_object_release( p_playlist );
+
+ return p_item;
+}
+
+/***************************************************************************
+ * Playlist item destruction
+ ***************************************************************************/
+
+/** Delete a playlist item and detach its input item */
+int playlist_ItemDelete( playlist_item_t *p_item )
+{
+ vlc_gc_decref( p_item->p_input );
+ free( p_item );
+ return VLC_SUCCESS;
+}
+
+/** Remove an input item when it appears from a root playlist item */
+static int DeleteFromInput( playlist_t *p_playlist, int i_input_id,
+ playlist_item_t *p_root, vlc_bool_t b_do_stop )
+{
+ int i;
+ for( i = 0 ; i< p_root->i_children ; i++ )
+ {
+ if( p_root->pp_children[i]->i_children == -1 &&
+ p_root->pp_children[i]->p_input->i_id == i_input_id )
+ {
+ DeleteInner( p_playlist, p_root->pp_children[i], b_do_stop );
+ return VLC_SUCCESS;
+ }
+ else if( p_root->pp_children[i]->i_children >= 0 )
+ {
+ int i_ret = DeleteFromInput( p_playlist, i_input_id,
+ p_root->pp_children[i], b_do_stop );
+ if( i_ret == VLC_SUCCESS ) return VLC_SUCCESS;
+ }
+ }
+ return VLC_EGENERIC;
+}
+
+/** Remove an input item from ONELEVEL and CATEGORY */
+int playlist_DeleteFromInput( playlist_t *p_playlist, int i_input_id,
+ vlc_bool_t b_locked )
+{
+ int i_ret1, i_ret2;
+ if( !b_locked ) PL_LOCK;
+ i_ret1 = DeleteFromInput( p_playlist, i_input_id,
+ p_playlist->p_root_category, VLC_TRUE );
+ i_ret2 = DeleteFromInput( p_playlist, i_input_id,
+ p_playlist->p_root_onelevel, VLC_TRUE );
+ if( !b_locked ) PL_UNLOCK;
+ return ( i_ret1 == VLC_SUCCESS || i_ret2 == VLC_SUCCESS ) ?
+ VLC_SUCCESS : VLC_ENOITEM;
+}
+
+void playlist_Clear( playlist_t * p_playlist, vlc_bool_t b_locked )
+{
+ if( !b_locked ) PL_LOCK;
+ playlist_NodeEmpty( p_playlist, p_playlist->p_root_category, VLC_TRUE );
+ playlist_NodeEmpty( p_playlist, p_playlist->p_root_onelevel, VLC_TRUE );
+ if( !b_locked ) PL_UNLOCK;
+}
+
+/** Remove a playlist item from the playlist, given its id
+ * This function is to be used only by the playlist */
+int playlist_DeleteFromItemId( playlist_t *p_playlist, int i_id )
+{
+ playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id,
+ VLC_TRUE );
+ if( !p_item ) return VLC_EGENERIC;
+ return DeleteInner( p_playlist, p_item, VLC_TRUE );
+}
+
+/***************************************************************************
+ * Playlist item addition
+ ***************************************************************************/
+/** Add an item to the playlist or the media library
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ * PLAYLIST_END the item will be added at the end of the playlist
+ * regardless of its size
+ * \param b_playlist TRUE for playlist, FALSE for media library
+ * \return The id of the playlist item
+ */
+int playlist_Add( playlist_t *p_playlist, const char *psz_uri,
+ const char *psz_name, int i_mode, int i_pos,
+ vlc_bool_t b_playlist, vlc_bool_t b_locked )
+{
+ return playlist_AddExt( p_playlist, psz_uri, psz_name,
+ i_mode, i_pos, -1, NULL, 0, b_playlist, b_locked );
+}