Index: kmail/kmmessagetag.h
===================================================================
--- kmail/kmmessagetag.h	(révision 838312)
+++ kmail/kmmessagetag.h	(copie de travail)
@@ -75,6 +75,29 @@
                   const QString &aIconName = "feed-subscribe",
                   const KShortcut &aShortcut = KShortcut() );
 
+    /** Constructor using a set of given parameters. The label will be auto generated.
+      @param aName Visible name for the tag
+      @param aPriority Priority of the tag. 0 is the highest. Used in defining
+            which tag to modify the appearance if the message has multiple
+            tags. Note that Important and Todo flags still dominate tags.
+      @param aTextColor Text color
+      @param aBackgroundColor Background color.
+      @param aTextFont Font of the text
+      @param aInToolbar Whether the toggle button appears in the toolbar
+      @param aIconName The name for the corresponding icon that will appear in
+              the menus and toolbar. The default value is an icon packaged with
+              akregator.
+      */
+    KMMessageTagDescription( const QString &aName,
+                  const int aPriority = -1,
+                  const QColor &aTextColor = QColor(),
+                  const QColor &aBackgroundColor = QColor(),
+                  const QFont &aTextFont = QFont(),
+                  const bool aInToolbar = false,
+                  const QString &aIconName = "feed-subscribe",
+                  const KShortcut &aShortcut = KShortcut() );
+
+
     /** Accessor functions */
     const QString label() const { return mLabel; }
     const QString name() const { return mName; }
Index: kmail/configuredialog.cpp
===================================================================
--- kmail/configuredialog.cpp	(révision 838312)
+++ kmail/configuredialog.cpp	(copie de travail)
@@ -2686,13 +2686,14 @@
 void AppearancePage::MessageTagTab::slotAddNewTag()
 {
   int tmp_priority = mMsgTagList->count();
-  QString tmp_label = KRandom::randomString( 10 );
-    //Very unlikely, but if the tag already exists, regenerate label
-  while ( kmkernel->msgTagMgr()->find( tmp_label ) )
-    tmp_label = KRandom::randomString( 10 );
 
-  KMMessageTagDescription *tmp_desc = new KMMessageTagDescription( tmp_label,
-                                             mTagAddLineEdit->text(),
+  // Ensure we won't have any duplicate tag
+  foreach(KMMessageTagDescription* d, *mMsgTagList) {
+    if(d->name() == mTagAddLineEdit->text())
+        return;
+  }
+
+  KMMessageTagDescription *tmp_desc = new KMMessageTagDescription( mTagAddLineEdit->text(),
                                              tmp_priority );
   mMsgTagDict->insert( tmp_desc->label() , tmp_desc );
   mMsgTagList->append( tmp_desc );
Index: kmail/kmmessagetag.cpp
===================================================================
--- kmail/kmmessagetag.cpp	(révision 838312)
+++ kmail/kmmessagetag.cpp	(copie de travail)
@@ -43,8 +43,12 @@
 #include <krandom.h>
 #ifdef Nepomuk_FOUND
 #include <nepomuk/resourcemanager.h>
+#include <nepomuk/resource.h>
+#include <nepomuk/tag.h>
 #endif
 
+#define TAGS_PREFIX QString("Tags/")
+
 //----------------------------KMMessageTagDescription------------------------------------
 KMMessageTagDescription::KMMessageTagDescription( const QString &aLabel, 
                              const QString &aName, 
@@ -69,6 +73,31 @@
   mEmpty = false;
 }
 
+KMMessageTagDescription::KMMessageTagDescription( const QString &aName, 
+                            const int aPriority, const QColor &aTextColor, 
+                            const QColor &aBackgroundColor, 
+                            const QFont &aTextFont, const bool aInToolbar, 
+                            const QString &aIconName, 
+                            const KShortcut &aShortcut ) {
+  #ifdef Nepomuk_FOUND
+  Nepomuk::Tag tag(aName);
+  mLabel = tag.resourceUri().toString();
+  #else
+  mLabel = KRandom::randomString( 10 );
+  while ( KMKernel::self()->msgTagMgr()->find( tmp_label ) )
+	  mLabel = KRandom::randomString( 10 );
+  #endif
+  mName = aName;
+  mPriority = aPriority;
+  mTextColor = aTextColor;
+  mBackgroundColor = aBackgroundColor;
+  mTextFont = aTextFont;
+  mInToolbar = aInToolbar;
+  mIconName = aIconName;
+  mShortcut = aShortcut;
+  mEmpty = false;
+}
+
 KMMessageTagDescription::KMMessageTagDescription( const KConfigGroup& aGroup ) 
             : mPriority( -1 ), mEmpty( false ) 
 {
@@ -102,12 +131,17 @@
 {
   mEmpty = true;
 
-  mLabel = group.readEntry( "Label", QString() );
-  if ( mLabel.isEmpty() )
-    return;
+  mLabel = group.name().remove(TAGS_PREFIX);
+
+  #ifdef Nepomuk_FOUND
+  QUrl tagUrl(mLabel);
+  Nepomuk::Tag tag(tagUrl);
+  mName = tag.genericLabel();
+  #else
   mName = group.readEntry( "Name", QString() );
   if ( mName.isEmpty() )
     return;
+  #endif
 
   mEmpty = false;
 
@@ -129,8 +163,14 @@
 
 void KMMessageTagDescription::writeConfig( KConfigGroup &group ) const 
 {
-  group.writeEntry( "Label", mLabel );
+  #ifdef Nepomuk_FOUND
+  QUrl tagUrl(mLabel);
+  Nepomuk::Tag tag(tagUrl);
+  tag.setLabel(mName);
+  #else
   group.writeEntry( "Name", mName );
+  #endif
+
   if ( mTextColor.isValid() ) 
     group.writeEntry( "text-color", mTextColor );
 
@@ -208,6 +248,7 @@
 
 void KMMessageTagMgr::createInitialTags() 
 {
+  #ifndef Nepomuk_FOUND
   //Some predefined structures for the very first initialization of tags
   static const struct { 
     QString name;
@@ -223,6 +264,7 @@
                                        TagNames[i].name, i, TagNames[i].color );
     addTag( tmp_ptr, false );
   }
+  #endif
 }
 
 void KMMessageTagMgr::addTag( KMMessageTagDescription *aDesc, bool emitChange )
@@ -244,30 +286,59 @@
 void KMMessageTagMgr::readConfig() 
 {
   KConfig *config = KMKernel::config();
-  int numTags = 0;
   QString grpName;
 
   clear();
 
-  KConfigGroup group( config, "General" );
-  numTags = group.readEntry( "messagetags", -1 );
+  QStringList tagGroups = config->groupList().filter(TAGS_PREFIX);
+  tagGroups.replaceInStrings(TAGS_PREFIX, "");
+  #ifdef Nepomuk_FOUND
+  QStringList nepomukTags;
+  if(tagGroups.empty()) { // This if is stupid, but without it I get an assert (dunno why). Looks like it's when I call contains on an empty list
+    foreach(const Nepomuk::Tag& tag, Nepomuk::Tag::allTags()) {
+      tagGroups.append(tag.resourceUri().toString());
+      nepomukTags.append(tag.resourceUri().toString());
+    }
+  } else {
+    foreach(const Nepomuk::Tag& tag, Nepomuk::Tag::allTags()) {
+      // If a tag was created outside KMail, add it to the config group
+      if(!tagGroups.contains(tag.resourceUri().toString())) {
+        KMMessageTagDescription* t = new KMMessageTagDescription(tag.resourceUri().toString(), tag.genericLabel());
+        addTag(t, false);
+        tagGroups.append(tag.resourceUri().toString());
+      }
+      nepomukTags.append(tag.resourceUri().toString());
+    }
+  }
 
-  if ( numTags < 0 ) {
+  // If we have some config related to a no more existing tag, do the cleanup
+  if(nepomukTags.empty()) { // Same stupid if to avoid the ASSERT
+    foreach(const QString& tag, tagGroups) {
+	  KConfigGroup g(config, TAGS_PREFIX+tag);
+	  g.deleteGroup();
+	}
+	tagGroups.clear();
+  } else {
+    foreach(const QString& tag, tagGroups) {
+      if(!nepomukTags.contains(tag)) {
+        KConfigGroup g(config, TAGS_PREFIX+tag);
+        g.deleteGroup();
+        tagGroups.removeOne(tag);
+      }
+    }
+  }
+  #endif
+
+  if ( tagGroups.size() == 0 ) {
     //Key doesn't exist, which probably means first run with the tag feature
     //Create some tags, put them into dictionary, set dirty
     createInitialTags(); 
   } else {
     //j used to handle priorities properly, in case a tag definition is missing
     int j = 0;
-    for ( int i=0; i < numTags; ++i ) {
-      grpName.sprintf( "MessageTag #%d", i );
-      if (! config->hasGroup( grpName ) ) {
-        //Something wrong, set dirty so the tag set is correctly written back
-        mDirty = true;
-        continue;
-      }
-      KConfigGroup group( config, grpName );
-      KMMessageTagDescription *tag = new KMMessageTagDescription( group );
+    foreach (const QString& tagGroup, tagGroups) {
+      KConfigGroup g( config, TAGS_PREFIX+tagGroup );
+      KMMessageTagDescription *tag = new KMMessageTagDescription( g );
       if ( tag->isEmpty() ) {
         delete tag;
       } else {
@@ -283,26 +354,35 @@
 {
   KConfig *config = KMKernel::config();
 
+  QStringList tagGroups = config->groupList().filter(TAGS_PREFIX);
+
   //first, delete all groups:
-  QStringList tagGroups 
-      = config->groupList().filter( QRegExp( "MessageTag #\\d+" ) );
   foreach ( const QString& group, tagGroups )
     config->deleteGroup( group );
 
+  #ifdef Nepomuk_FOUND
+  // Sync the changes back to Nepomuk
+  QStringList nepomukTags;
+  foreach(const Nepomuk::Tag& tag, Nepomuk::Tag::allTags()) {
+    nepomukTags.append(tag.resourceUri().toString());
+  }
+  foreach(KMMessageTagDescription* description, *mTagList) {
+    nepomukTags.removeOne(description->label());
+  }
+  // Now the strings left in the nepomukTags list have to be removed
+  foreach(const QString& uri, nepomukTags)
+    Nepomuk::ResourceManager::instance()->removeResource(uri);
+  #endif
   // Now, write out the new stuff:
   int i = 0;
   foreach ( KMMessageTagDescription *description, *mTagList ) {
     if ( ! description->isEmpty() ) {
-      QString grpName;
-      grpName.sprintf( "MessageTag #%d", i );
-      KConfigGroup group( config, grpName );
+      KConfigGroup group( config, TAGS_PREFIX+description->label() );
       description->writeConfig( group );
       ++i;
     }
   }
 
-  KConfigGroup group( config, "General" );
-  group.writeEntry( "messagetags", i );
   if (withSync) 
     config->sync();
   //mDirty = false;
