Update nSelectionMark and nFocusedItem when inserting/deleting/sorting
items.
SortItems: If sorting less than 2 items, do nothing.

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 436a342..b5fb2ce 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -1479,18 +1479,17 @@
 
 /**
 * DESCRIPTION:
-* shifts all selection indexs starting with the indesx specified
-* in the direction specified.
+* Updates the various indices after an item has been inserted or deleted.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
-* [I] INT : amount and direction of shift
+* [I] INT : Direction of shift, +1 or -1.
 *
 * RETURN:
 * None
 */
-static VOID LISTVIEW_ShiftSelections(HWND hwnd, INT nItem, INT direction)
+static VOID LISTVIEW_ShiftIndices(HWND hwnd, INT nItem, INT direction)
 {
   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
   LISTVIEW_SELECTION selection,*checkselection;
@@ -1516,6 +1515,33 @@
         checkselection->upper += direction;
     index ++;
   }
+
+  /* Note that the following will fail if direction != +1 and -1 */
+  if (infoPtr->nSelectionMark > nItem)
+      infoPtr->nSelectionMark += direction;
+  else if (infoPtr->nSelectionMark == nItem)
+  {
+    if (direction > 0)
+      infoPtr->nSelectionMark += direction;
+    else if (infoPtr->nSelectionMark >= GETITEMCOUNT(infoPtr))
+      infoPtr->nSelectionMark = GETITEMCOUNT(infoPtr) - 1;
+  }
+
+  if (infoPtr->nFocusedItem > nItem)
+    infoPtr->nFocusedItem += direction;
+  else if (infoPtr->nFocusedItem == nItem)
+  {
+    if (direction > 0)
+      infoPtr->nFocusedItem += direction;
+    else
+    {
+      if (infoPtr->nFocusedItem >= GETITEMCOUNT(infoPtr))
+        infoPtr->nFocusedItem = GETITEMCOUNT(infoPtr) - 1;
+      if (infoPtr->nFocusedItem >= 0)
+        LISTVIEW_SetItemFocus(hwnd, infoPtr->nFocusedItem);
+    }
+  }
+  /* But we are not supposed to modify nHotItem! */
 }
 
 
@@ -3776,7 +3802,11 @@
   HDPA hdpaSubItems;
 
   TRACE("(hwnd=%x,)\n", hwnd);
+
   LISTVIEW_RemoveAllSelections(hwnd);
+  infoPtr->nSelectionMark=-1;
+  infoPtr->nFocusedItem=-1;
+  /* But we are supposed to leave nHotItem as is! */
 
   if (lStyle & LVS_OWNERDATA)
   {
@@ -3959,8 +3989,6 @@
   item.stateMask = LVIS_SELECTED;
   LISTVIEW_SetItemState(hwnd,nItem,&item);
 
-  LISTVIEW_ShiftSelections(hwnd,nItem,-1);
-
   if (lStyle & LVS_OWNERDATA)
   {
     infoPtr->hdpaItems->nItemCount --;
@@ -4010,6 +4038,8 @@
       bResult = DPA_Destroy(hdpaSubItems);
     }
 
+    LISTVIEW_ShiftIndices(hwnd,nItem,-1);
+
     /* align items (set position of each item) */
     if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
     {
@@ -4023,16 +4053,6 @@
       }
     }
 
-    /* If this item had focus change focus to next or previous item */
-    if (GETITEMCOUNT(infoPtr) > 0)
-    {
-       int sItem = nItem < GETITEMCOUNT(infoPtr) ? nItem : nItem - 1;
-       if (infoPtr->nFocusedItem == nItem)
-	   LISTVIEW_SetItemFocus(hwnd, sItem);
-    }
-    else
-	  infoPtr->nFocusedItem = -1;
-
     LISTVIEW_UpdateScroll(hwnd);
 
     /* refresh client area */
@@ -6481,7 +6501,7 @@
 	      }
               if (nItem != -1)
               {
-                LISTVIEW_ShiftSelections(hwnd,nItem,1);
+                LISTVIEW_ShiftIndices(hwnd,nItem,1);
 
                 /* manage item focus */
                 if (lpLVItem->mask & LVIF_STATE)
@@ -7396,9 +7416,9 @@
     LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
     int nCount, i;
     UINT lStyle = GetWindowLongA(hwnd, GWL_STYLE);
-    HDPA *hdpaSubItems=NULL;
+    HDPA hdpaSubItems=NULL;
     LISTVIEW_ITEM *pLVItem=NULL;
-
+    LPVOID selectionMarkItem;
 
     if (lStyle & LVS_OWNERDATA)
       return FALSE;
@@ -7408,17 +7428,19 @@
    
     nCount = GETITEMCOUNT(infoPtr);
     /* if there are 0 or 1 items, there is no need to sort */
-    if (nCount > 1)
-    {
-	infoPtr->pfnCompare = (PFNLVCOMPARE)lParam;
-	infoPtr->lParamSort = (LPARAM)wParam;
-	
-        DPA_Sort(infoPtr->hdpaItems, LISTVIEW_CallBackCompare, hwnd);
-    }
+    if (nCount < 2)
+        return TRUE;
 
-    /* Adjust selections so that they are the way they should be after
-       the sort (otherwise, the list items move around, but whatever
-       is at the item's previous original position will be selected instead) */
+    infoPtr->pfnCompare = (PFNLVCOMPARE)lParam;
+    infoPtr->lParamSort = (LPARAM)wParam;
+    DPA_Sort(infoPtr->hdpaItems, LISTVIEW_CallBackCompare, hwnd);
+
+    /* Adjust selections and indices so that they are the way they should 
+     * be after the sort (otherwise, the list items move around, but 
+     * whatever is at the item's previous original position will be 
+     * selected instead)
+     */
+    selectionMarkItem=(infoPtr->nSelectionMark>=0)?DPA_GetPtr(infoPtr->hdpaItems, infoPtr->nSelectionMark):NULL;
     for (i=0; i < nCount; i++)
     {
        hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, i);
@@ -7428,7 +7450,12 @@
           LISTVIEW_AddSelectionRange(hwnd, i, i);
        else
           LISTVIEW_RemoveSelectionRange(hwnd, i, i);
+       if (pLVItem->state & LVIS_FOCUSED)
+          infoPtr->nFocusedItem=i;
     }
+    if (selectionMarkItem != NULL)
+       infoPtr->nSelectionMark = DPA_GetPtrIndex(infoPtr->hdpaItems, selectionMarkItem);
+    /* I believe nHotItem should be left alone, see LISTVIEW_ShiftIndices */
 
     /* align the items */
     LISTVIEW_AlignTop(hwnd);