=== modified file 'src/selection-chemistry.cpp'
--- src/selection-chemistry.cpp	2010-01-15 06:45:34 +0000
+++ src/selection-chemistry.cpp	2010-01-27 18:46:27 +0000
@@ -2856,6 +2856,7 @@
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     bool topmost = prefs->getBool("/options/maskobject/topmost", true);
     bool remove_original = prefs->getBool("/options/maskobject/remove", true);
+    bool enclose_in_group = prefs->getBool("/options/maskobject/encloseingroup", false);
 
     if (apply_to_layer) {
         // all selected items are used for mask, which is applied to a layer
@@ -2925,7 +2926,29 @@
         g_slist_free(mask_items_dup);
         mask_items_dup = NULL;
 
-        SP_OBJECT_REPR(i->data)->setAttribute(attributeName, g_strdup_printf("url(#%s)", mask_id));
+        Inkscape::XML::Node *current = SP_OBJECT_REPR(i->data);
+        
+        if (enclose_in_group) {
+            // enclose current node in group, and apply crop/mask on that
+            Inkscape::XML::Node *group = xml_doc->createElement("svg:g");
+            
+            Inkscape::XML::Node *spnew = current->duplicate(xml_doc);
+            gint position = current->position();
+            selection->remove(current);
+            current->parent()->appendChild(group);
+            sp_repr_unparent(current);
+            group->appendChild(spnew);
+            group->setPosition(position);
+            group->setAttribute(attributeName, g_strdup_printf("url(#%s)", mask_id));
+            // TODO add special mark to group so we can remove it in future
+            // if we need to unset clip/mask
+            selection->add(group);
+            Inkscape::GC::release(spnew); 
+            Inkscape::GC::release(group);
+        }
+        else {
+            current->setAttribute(attributeName, g_strdup_printf("url(#%s)", mask_id));
+        }
     }
 
     g_slist_free(mask_items);
@@ -2959,10 +2982,14 @@
 
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     bool remove_original = prefs->getBool("/options/maskobject/remove", true);
+    bool ungroup_masked = prefs->getBool("/options/maskobject/encloseingroup", false);
     sp_document_ensure_up_to_date(doc);
 
     gchar const *attributeName = apply_clip_path ? "clip-path" : "mask";
     std::map<SPObject*,SPItem*> referenced_objects;
+    
+    GSList *items_to_ungroup = NULL;
+    
     // SPObject* refers to a group containing the clipped path or mask itself,
     // whereas SPItem* refers to the item being clipped or masked
     for (GSList const *i = selection->itemList(); NULL != i; i = i->next) {
@@ -2984,6 +3011,19 @@
         }
 
         SP_OBJECT_REPR(i->data)->setAttribute(attributeName, "none");
+        
+        if (ungroup_masked) {
+                // if we had previously enclosed masked object in group,
+                // add it to list so we can ungroup it later
+                SPItem *item = reinterpret_cast<SPItem *>(i->data);
+                
+                // first check if this is enclosed group
+                // TODO also add check for special mark
+                if (!strcmp(SP_OBJECT_REPR(item)->name(), "svg:g")) {
+                    items_to_ungroup = g_slist_prepend(items_to_ungroup, item);
+                }
+                
+        }
     }
 
     // restore mask objects into a document
@@ -3024,6 +3064,17 @@
 
         g_slist_free(items_to_move);
     }
+    
+    // ungroup marked groups added when setting mask
+    for (GSList *i = items_to_ungroup ; NULL != i ; i = i->next) {
+        selection->remove(SP_GROUP(i->data));
+        GSList *children = NULL;
+        sp_item_group_ungroup(SP_GROUP(i->data), &children, false);
+        selection->addList(children);
+        g_slist_free(children);
+    }
+    
+    g_slist_free(items_to_ungroup);
 
     if (apply_clip_path)
         sp_document_done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path"));

=== modified file 'src/ui/dialog/inkscape-preferences.cpp'
--- src/ui/dialog/inkscape-preferences.cpp	2010-01-18 02:11:50 +0000
+++ src/ui/dialog/inkscape-preferences.cpp	2010-01-27 17:25:04 +0000
@@ -664,6 +664,9 @@
     _mask_mask_remove.init ( _("Remove clippath/mask object after applying"), "/options/maskobject/remove", true);
     _page_mask.add_line(true, "", _mask_mask_remove, "",
                         _("After applying, remove the object used as the clipping path or mask from the drawing"));
+    _mask_enclose_in_group.init ( _("Enclose masked objects in groups"), "/options/maskobject/encloseingroup", false);
+    _page_mask.add_line(true, "", _mask_enclose_in_group, "",
+                        _("Before applying clip/mask, enclose every object to be clipped/masked in group. When unsetting clip/mask, ungroup groups added by this feature."));
     this->AddPage(_page_mask, _("Clippaths and masks"), PREFS_PAGE_MASKS);
 }
 

=== modified file 'src/ui/dialog/inkscape-preferences.h'
--- src/ui/dialog/inkscape-preferences.h	2010-01-18 02:11:50 +0000
+++ src/ui/dialog/inkscape-preferences.h	2010-01-27 17:17:26 +0000
@@ -170,6 +170,7 @@
 
     PrefCheckButton _mask_mask_on_top;
     PrefCheckButton _mask_mask_remove;
+    PrefCheckButton _mask_enclose_in_group;
 
     PrefRadioButton _blur_quality_best, _blur_quality_better, _blur_quality_normal, _blur_quality_worse, _blur_quality_worst;
     PrefRadioButton _filter_quality_best, _filter_quality_better, _filter_quality_normal, _filter_quality_worse, _filter_quality_worst;

