private void SortSelectedShapes(MoveShapesDirection moveDirection)
        {
            ShapeCollection selected = shapeTreeView.SelectedShapes;

              // return if any of the indices is already on the maximum.
              foreach (ShapeBase shape in selected)
              {
            if (moveDirection == MoveShapesDirection.Up)
            {
              if (shape.Parent.ChildCollection.FindIndex(i => i == shape) <= 0)
            return;
            }
            else
              if (shape.Parent.ChildCollection.FindIndex(i => i == shape) >= shape.Parent.ChildCollection.Count - 1)
            return;
              }

              // get all parents to share modified collections between their children.
              ShapeCollection parents = new ShapeCollection();
              foreach (ShapeBase shape in selected)
            if (!parents.Contains(shape.Parent))
              parents.Add(shape.Parent);

              EditorManager.Actions.StartGroup("Sort Shapes");
              foreach (ShapeBase parent in parents)
              {
            // create copy of the original collection before sorting
            ShapeCollection copyOfChildren = new ShapeCollection();
            copyOfChildren.AddRange(parent.ChildCollection);

            if (moveDirection == MoveShapesDirection.Up)
            {
              for (int i = 0; i < selected.Count; i++)
              {
            ShapeBase child = selected[i];
            if (child.Parent == parent)
            {
              int index = copyOfChildren.FindIndex(c => c == child);
              copyOfChildren.Remove(child);
              copyOfChildren.Insert(index - 1, child);
              EditorManager.Actions.Add(new SortShapeChildrenAction(parent, copyOfChildren));
            }
              }
            }
            else
              for (int i = selected.Count - 1; i > -1; i--)
              {
            ShapeBase child = selected[i];
            if (child.Parent == parent)
            {
              int index = copyOfChildren.FindIndex(c => c == child);
              copyOfChildren.Remove(child);
              copyOfChildren.Insert(index + 1, child);
              EditorManager.Actions.Add(new SortShapeChildrenAction(parent, copyOfChildren));
            }
              }
              }
              EditorManager.Actions.EndGroup();

              // recover selection
              ArrayList newSelection = new ArrayList();
              foreach (ShapeTreeNode node in shapeTreeView.Nodes)
              {
            if (selected.Contains(node.shape)) // root
              newSelection.Add(node);
            foreach (ShapeTreeNode subNode in shapeTreeView.GetChildNodes(node))
            {
              if (selected.Contains(subNode.shape)) // all children
            newSelection.Add(subNode);
            }
              }
              shapeTreeView.SelectedNodes = newSelection;
        }