*/
     void DeleteProperty( wxPGPropArg id );
 
+    /**
+        Removes and returns a property.
+
+        @param id
+            Pointer or name of a property.
+
+        @remarks Removed property cannot have any children.
+    */
+    wxPGProperty* RemoveProperty( wxPGPropArg id );
+
     /** Disables property. */
     bool DisableProperty( wxPGPropArg id ) { return EnableProperty(id,false); }
 
 
         Override this member function to add custom behavior on property
         deletion.
     */
-    virtual void DoDelete( wxPGProperty* item );
+    virtual void DoDelete( wxPGProperty* item, bool doDelete = true );
 
     wxSize DoFitColumns( bool allowGridResize = false );
 
 
     */
     static void RegisterAdditionalEditors();
 
+    /**
+        Removes and returns a property.
+
+        @param id
+            Pointer or name of a property.
+
+        @remarks Removed property cannot have any children.
+    */
+    wxPGProperty* RemoveProperty( wxPGPropArg id );
+
     /**
         Replaces property with id with newly created one. For example,
         this code replaces existing property named "Flags" with one that
 
         pgman->EnsureVisible(wxT("Cell Colour"));
     }
 
+    {
+        RT_START_TEST(RemoveProperty)
+
+        wxPGProperty* p;
+
+        wxPGProperty* origParent =
+            pgman->GetProperty(wxT("Window Styles"))->GetParent();
+
+        p = pgman->RemoveProperty(wxT("Window Styles"));
+        pgman->Refresh();
+        pgman->Update();
+
+        pgman->AppendIn(origParent, p);
+        pgman->Refresh();
+        pgman->Update();
+    }
+
     {
         RT_START_TEST(SetPropertyBackgroundColour)
         wxCommandEvent evt;
 
     if ( grid->GetState() == state )
         grid->DoSelectProperty(NULL, wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE);
 
-    state->DoDelete( p );
+    state->DoDelete( p, true );
 
     RefreshGrid(state);
 }
 
 // -----------------------------------------------------------------------
 
+wxPGProperty* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id )
+{
+    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
+
+    wxCHECK( !p->GetChildCount() || p->HasFlag(wxPG_PROP_AGGREGATE),
+             wxNullProperty);
+
+    wxPropertyGridPageState* state = p->GetParentState();
+    wxPropertyGrid* grid = state->GetGrid();
+
+    if ( grid->GetState() == state )
+    {
+        grid->DoSelectProperty(NULL,
+            wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE);
+    }
+
+    state->DoDelete( p, false );
+
+    // Mark the property as 'unattached'
+    p->m_parentState = NULL;
+    p->m_parent = NULL;
+
+    RefreshGrid(state);
+
+    return p;
+}
+
+// -----------------------------------------------------------------------
+
 wxPGProperty* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id, wxPGProperty* property )
 {
     wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
 
 
 // -----------------------------------------------------------------------
 
-void wxPropertyGridPageState::DoDelete( wxPGProperty* item )
+void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete )
 {
     wxCHECK_RET( item->GetParent(),
         wxT("this property was already deleted") );
     if ( item->GetBaseName().Len() ) m_dictName.erase(item->GetBaseName());
 
     // We can actually delete it now
-    delete item;
+    if ( doDelete )
+        delete item;
 
     m_itemsAdded = 1; // Not a logical assignment (but required nonetheless).