I have solved the problem (the problem itself seems to be Outlook 2007 bug) using a hack.
The following links helped me to create the hack (oops, not enough reputation to post more then 1 link):
The hack itself is show below:
using System;
using System.Text;
using System.Xml;
using System.IO;
using Microsoft.Office.Interop.Outlook;
namespace OutlookHack
{
public static class OutlookCategoryHelper
{
private const string CategoryListStorageItemIdentifier = "IPM.Configuration.CategoryList";
private const string CategoryListPropertySchemaName = @"http://schemas.microsoft.com/mapi/proptag/0x7C080102";
private const string CategoriesXmlElementNamespace = "CategoryList.xsd";
private const string XmlNamespaceAttribute = "xmlns";
private const string CategoryElement = "category";
private const string NameAttribute = "name";
public static void RenameCategory(string oldName, string newName, Application outlookApplication)
{
MAPIFolder calendarFolder = outlookApplication.Session.GetDefaultFolder(
OlDefaultFolders.olFolderCalendar);
StorageItem categoryListStorageItem = calendarFolder.GetStorage(
CategoryListStorageItemIdentifier, OlStorageIdentifierType.olIdentifyByMessageClass);
if (categoryListStorageItem != null)
{
PropertyAccessor categoryListPropertyAccessor = categoryListStorageItem.PropertyAccessor;
string schemaName = CategoryListPropertySchemaName;
try
{
// next statement raises Out of Memory error if property is too big
var xmlBytes = (byte[])categoryListPropertyAccessor.GetProperty(schemaName);
// the byte array has to be translated into a string and then the XML has to be parsed
var xmlReader = XmlReader.Create(new StringReader(Encoding.UTF8.GetString(xmlBytes)));
// xmlWriter will write new category list xml with renamed category
XmlWriterSettings settings = new XmlWriterSettings { Indent = true, IndentChars = ("\t") };
var stringWriter = new StringWriter();
var xmlWriter = XmlWriter.Create(stringWriter, settings);
xmlReader.Read(); // read xml declaration
xmlWriter.WriteNode(xmlReader, true);
xmlReader.Read(); // read categories
xmlWriter.WriteStartElement(xmlReader.Name, CategoriesXmlElementNamespace);
while (xmlReader.MoveToNextAttribute())
{
if (xmlReader.Name != XmlNamespaceAttribute) // skip namespace attr
{
xmlWriter.WriteAttributeString(xmlReader.Name, xmlReader.Value);
}
}
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element: // read category
xmlWriter.WriteStartElement(CategoryElement);
while (xmlReader.MoveToNextAttribute())
{
if ((xmlReader.Name == NameAttribute) && (xmlReader.Value == oldName))
{
xmlWriter.WriteAttributeString(NameAttribute, newName);
}
else
{
xmlWriter.WriteAttributeString(xmlReader.Name, xmlReader.Value);
}
}
xmlWriter.WriteEndElement();
break;
case XmlNodeType.EndElement: // categories ended
xmlWriter.WriteEndElement();
break;
}
}
xmlReader.Close();
xmlWriter.Close();
xmlBytes = Encoding.UTF8.GetBytes(stringWriter.ToString());
categoryListPropertyAccessor.SetProperty(schemaName, xmlBytes);
categoryListStorageItem.Save();
}
catch (OutOfMemoryException)
{
// if error is "out of memory error" then the XML blob was too big
}
}
}
}
}
This helper method must be called prior to category renaming, e.g.:
var session = Application.Session;
var categories = session.Categories;
var category1 = session.Categories[1];
//catefory1.Name is "Group1" before executing line below
OutlookCategoryHelper.RenameCategory(category1.Name, "TEST!!!", Application);
category1.Name = "TEST!!!";
Marshal.ReleaseComObject(category1);
Marshal.ReleaseComObject(categories);
Marshal.ReleaseComObject(session);