+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
+
+guint
+tags_count(guint32 *tags)
+{
+guint count = 0;
+
+ DB( g_print("\n[tags] count\n") );
+
+ if( tags == NULL )
+ return 0;
+
+ while(*tags++ != 0 && count < 32)
+ count++;
+
+ return count;
+}
+
+
+guint32 *tags_clone(guint32 *tags)
+{
+guint32 *newtags = NULL;
+guint count;
+
+ count = tags_count(tags);
+ if(count > 0)
+ {
+ //1501962: we must also copy the final 0
+ newtags = g_memdup(tags, (count+1)*sizeof(guint32));
+ }
+
+ return newtags;
+}
+
+
+static gboolean
+tags_key_exists(guint32 *tags, guint32 key)
+{
+guint count = 0;
+ while(*tags != 0 && count < 32)
+ {
+ if( *tags == key )
+ return TRUE;
+ tags++;
+ count++;
+ }
+ return FALSE;
+}
+
+
+guint32 *
+tags_parse(const gchar *tagstring)
+{
+gchar **str_array;
+guint32 *tags = NULL;
+guint32 *ptags;
+guint count, i;
+Tag *tag;
+
+ DB( g_print("\n[tags] parse\n") );
+
+ if( tagstring )
+ {
+ str_array = g_strsplit (tagstring, " ", 0);
+ count = g_strv_length( str_array );
+ DB( g_print("- %d tags '%s'\n", count, tagstring) );
+ if( count > 0 )
+ {
+ tags = g_new0(guint32, count + 1);
+ ptags = tags;
+ for(i=0;i<count;i++)
+ {
+ //5.2.3 fixed empty tag
+ if( strlen(str_array[i]) == 0 )
+ continue;
+
+ DB( g_print("- %d search '%s'\n", i, str_array[i]) );
+ tag = da_tag_get_by_name(str_array[i]);
+ if(tag == NULL)
+ {
+ Tag *newtag = da_tag_malloc();
+
+ newtag->name = g_strdup(str_array[i]);
+ da_tag_append(newtag);
+ tag = da_tag_get_by_name(str_array[i]);
+ }
+ DB( g_print("- array add %d '%s'\n", tag->key, tag->name) );
+
+ //5.3 fixed duplicate tag in same tags
+ if( tags_key_exists(tags, tag->key) == FALSE )
+ *ptags++ = tag->key;
+ }
+ *ptags = 0;
+ }
+
+ g_strfreev (str_array);
+ }
+ return tags;
+}
+
+
+
+gchar *
+tags_tostring(guint32 *tags)
+{
+guint count, i;
+gchar **str_array, **tptr;
+gchar *tagstring;
+Tag *tag;