Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37850)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37851)
@@ -2933,5 +2933,5 @@
   <interface
     name="IInternalMachineControl" extends="$unknown"
-    uuid="31de448d-ef5e-4f79-9206-a8e830cbf9ea"
+    uuid="2087906d-bb92-43a0-8014-4cab009e4888"
     internal="yes"
     wsmap="suppress"
@@ -3224,9 +3224,11 @@
     <method name="deleteSnapshot">
       <desc>
-        Gets called by <link to="IConsole::deleteSnapshot"/> and
-        <link to="IConsole::deleteSnapshotAndAllChildren"/>.
+        Gets called by <link to="IConsole::deleteSnapshot"/>,
+        <link to="IConsole::deleteSnapshotAndAllChildren"/> and
+        <link to="IConsole::deleteSnapshotRange"/>.
         <result name="VBOX_E_INVALID_OBJECT_STATE">
           Snapshot has more than one child snapshot. Only possible if the
-          delete operation does not delete all children.
+          delete operation does not delete all children or the range does
+          not meet the linearity condition.
         </result>
       </desc>
@@ -3234,6 +3236,9 @@
         <desc>The console object that initiated this call.</desc>
       </param>
-      <param name="id" type="uuid" mod="string" dir="in">
-        <desc>UUID of the snapshot to delete.</desc>
+      <param name="startId" type="uuid" mod="string" dir="in">
+        <desc>UUID of the first snapshot to delete.</desc>
+      </param>
+      <param name="endId" type="uuid" mod="string" dir="in">
+        <desc>UUID of the last snapshot to delete.</desc>
       </param>
       <param name="deleteAllChildren" type="boolean" dir="in">
@@ -6244,5 +6249,5 @@
   <interface
     name="IConsole" extends="$unknown"
-    uuid="7fcaa74a-5d69-4c83-a357-404a60664e47"
+    uuid="1968b7d3-e3bf-4ceb-99e0-cb7c913317bb"
     wsmap="managed"
     >
@@ -6937,4 +6942,42 @@
       <param name="id" type="uuid" mod="string" dir="in">
         <desc>UUID of the snapshot to delete, including all its children.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
+      </param>
+    </method>
+
+    <method name="deleteSnapshotRange">
+      <desc>
+        Starts deleting the specified snapshot range. This is limited to
+        linear snapshot lists, which means there may not be any other child
+        snapshots other than the direct sequence between the start and end
+        snapshot. If the start and end snapshot point to the same snapshot this
+        method is completely equivalent to <link to="#deleteSnapshot"/>. See
+        <link to="ISnapshot" /> for an introduction to snapshots. The
+        conditions and many details are the same as with
+        <link to="#deleteSnapshot"/>.
+
+        This operation is generally faster than deleting snapshots one by one
+        and often also needs less extra disk space before freeing up disk space
+        by deleting the removed disk images corresponding to the snapshot.
+
+        <note>This API method is right now not implemented!</note>
+
+        <result name="VBOX_E_INVALID_VM_STATE">
+          The running virtual machine prevents deleting this snapshot. This
+          happens only in very specific situations, usually snapshots can be
+          deleted without trouble while a VM is running. The error message
+          text explains the reason for the failure.
+        </result>
+        <result name="E_NOTIMPL">
+          The method is not implemented yet.
+        </result>
+      </desc>
+      <param name="startId" type="uuid" mod="string" dir="in">
+        <desc>UUID of the first snapshot to delete.</desc>
+      </param>
+      <param name="endId" type="uuid" mod="string" dir="in">
+        <desc>UUID of the last snapshot to delete.</desc>
       </param>
       <param name="progress" type="IProgress" dir="return">
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 37850)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 37851)
@@ -157,4 +157,5 @@
     STDMETHOD(DeleteSnapshot)(IN_BSTR aId, IProgress **aProgress);
     STDMETHOD(DeleteSnapshotAndAllChildren)(IN_BSTR aId, IProgress **aProgress);
+    STDMETHOD(DeleteSnapshotRange)(IN_BSTR aStartId, IN_BSTR aEndId, IProgress **aProgress);
     STDMETHOD(RestoreSnapshot)(ISnapshot *aSnapshot, IProgress **aProgress);
     STDMETHOD(Teleport)(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress);
Index: /trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImpl.h	(revision 37850)
+++ /trunk/src/VBox/Main/include/MachineImpl.h	(revision 37851)
@@ -991,6 +991,6 @@
                                    BSTR *aStateFilePath);
     STDMETHOD(EndTakingSnapshot)(BOOL aSuccess);
-    STDMETHOD(DeleteSnapshot)(IConsole *aInitiator, IN_BSTR aId,
-                              BOOL fDeleteAllChildren,
+    STDMETHOD(DeleteSnapshot)(IConsole *aInitiator, IN_BSTR aStartId,
+                              IN_BSTR aEndID, BOOL fDeleteAllChildren,
                               MachineState_T *aMachineState, IProgress **aProgress);
     STDMETHOD(FinishOnlineMergeMedium)(IMediumAttachment *aMediumAttachment,
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 37850)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 37851)
@@ -3247,5 +3247,5 @@
 
     MachineState_T machineState = MachineState_Null;
-    HRESULT rc = mControl->DeleteSnapshot(this, aId, FALSE /* fDeleteAllChildren */, &machineState, aProgress);
+    HRESULT rc = mControl->DeleteSnapshot(this, aId, aId, FALSE /* fDeleteAllChildren */, &machineState, aProgress);
     if (FAILED(rc)) return rc;
 
@@ -3270,5 +3270,29 @@
 
     MachineState_T machineState = MachineState_Null;
-    HRESULT rc = mControl->DeleteSnapshot(this, aId, TRUE /* fDeleteAllChildren */, &machineState, aProgress);
+    HRESULT rc = mControl->DeleteSnapshot(this, aId, aId, TRUE /* fDeleteAllChildren */, &machineState, aProgress);
+    if (FAILED(rc)) return rc;
+
+    setMachineStateLocally(machineState);
+    return S_OK;
+}
+
+STDMETHODIMP Console::DeleteSnapshotRange(IN_BSTR aStartId, IN_BSTR aEndId, IProgress **aProgress)
+{
+    CheckComArgExpr(aStartId, Guid(aStartId).isEmpty() == false);
+    CheckComArgExpr(aEndId, Guid(aEndId).isEmpty() == false);
+    CheckComArgOutPointerValid(aProgress);
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (Global::IsTransient(mMachineState))
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
+                        Global::stringifyMachineState(mMachineState));
+
+    MachineState_T machineState = MachineState_Null;
+    HRESULT rc = mControl->DeleteSnapshot(this, aStartId, aEndId, FALSE /* fDeleteAllChildren */, &machineState, aProgress);
     if (FAILED(rc)) return rc;
 
Index: /trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/SnapshotImpl.cpp	(revision 37850)
+++ /trunk/src/VBox/Main/src-server/SnapshotImpl.cpp	(revision 37851)
@@ -2014,5 +2014,6 @@
  */
 STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator,
-                                            IN_BSTR aId,
+                                            IN_BSTR aStartId,
+                                            IN_BSTR aEndId,
                                             BOOL fDeleteAllChildren,
                                             MachineState_T *aMachineState,
@@ -2021,10 +2022,11 @@
     LogFlowThisFuncEnter();
 
-    Guid id(aId);
-    AssertReturn(aInitiator && !id.isEmpty(), E_INVALIDARG);
+    Guid startId(aStartId);
+    Guid endId(aEndId);
+    AssertReturn(aInitiator && !startId.isEmpty() && !endId.isEmpty(), E_INVALIDARG);
     AssertReturn(aMachineState && aProgress, E_POINTER);
 
-    /** @todo implement the "and all children" variant */
-    if (fDeleteAllChildren)
+    /** @todo implement the "and all children" and "range" variants */
+    if (fDeleteAllChildren || startId != endId)
         ReturnComNotImplemented();
 
@@ -2047,5 +2049,5 @@
 
     ComObjPtr<Snapshot> pSnapshot;
-    HRESULT rc = findSnapshotById(id, pSnapshot, true /* aSetError */);
+    HRESULT rc = findSnapshotById(startId, pSnapshot, true /* aSetError */);
     if (FAILED(rc)) return rc;
 
