/// <summary>
        ///     Deletes the given element from priority queue.
        /// </summary>
        /// <param name="queueElement">Element to be deleted. </param>
        public void DeleteElement(QueueElement queueElement)
        {
            Trace.Indent();

            // Increase the timestamp to max possible value.
            IncreaseTimestamp(queueElement, DateTime.MaxValue);
            Trace.WriteLine("Whiteboard.BoardPriorityQueue.DeleteElement: Timestamp for element increased to MAX");

            // extract out max value (highest timestamp)
            Extract();
            Trace.WriteLine("Whiteboard.BoardPriorityQueue.DeleteElement: Element extracted out.");
            Trace.Unindent();
        }
        /// <summary>
        ///     Inserts the element in the priority queue.
        /// </summary>
        /// <param name="queueElement">Element to be inserted.</param>
        public void Insert(QueueElement queueElement)
        {
            Trace.Indent();
            // update the index of the queue element
            var lastIndex = GetSize();

            queueElement.Index = lastIndex;

            // adding the element in queue and placing it at right position.
            _queue.Add(queueElement);
            while (lastIndex != 0 && _queue[Parent(lastIndex)].Timestamp < _queue[lastIndex].Timestamp)
            {
                SwapElements(lastIndex, Parent(lastIndex));
                lastIndex = Parent(lastIndex);
            }

            Trace.WriteLine("Whiteboard.BoardPriorityQueue.Insert: Inserted the element successfully.");
            Trace.Unindent();
        }
        /// <summary>
        ///     Increases the timestamp of given queue element and place it at appropriate position in priority queue.
        /// </summary>
        /// <param name="queueElement">Element to be updated. </param>
        /// <param name="dateTime">The new date-time value. </param>
        public void IncreaseTimestamp(QueueElement queueElement, DateTime dateTime)
        {
            Trace.Indent();
            var index = queueElement.Index;

            // if index is out of range
            if (index < 0 || index >= GetSize())
            {
                Trace.WriteLine("Whiteboard.BoardPriorityQueue.IncreaseTimestamp: Index out of range.");
                throw new IndexOutOfRangeException("Element index in the queue. IncreaseTimestamp failed.");
            }

            // update timestamp and place the element at correct position.
            queueElement.Timestamp = dateTime;
            while (index != 0 && _queue[Parent(index)].Timestamp < _queue[index].Timestamp)
            {
                SwapElements(index, Parent(index));
                index = Parent(index);
            }

            Trace.WriteLine(
                "Whiteboard.BoardPriorityQueue.IncreaseTimestamp: Increased timestamp and moved to new suitable position.");
            Trace.Unindent();
        }
        /// <summary>
        ///     Updates local state on Fetch State from server.
        /// </summary>
        /// <param name="boardServerShape">BoardServerShape object having the whole update.</param>
        /// <returns>List of UXShape to notify client.</returns>
        private List <UXShape> UpdateStateOnFetch(BoardServerShape boardServerShape)
        {
            try
            {
                var            boardShapes = boardServerShape.ShapeUpdates;
                List <UXShape> uXShapes    = new();

                // Sorting boardShapes
                boardShapes.Sort(delegate(BoardShape boardShape1, BoardShape boardShape2)
                {
                    return(boardShape1.LastModifiedTime.CompareTo(boardShape2.LastModifiedTime));
                });

                // updating checkpoint number
                _checkpointsNumber = boardServerShape.CheckpointNumber;
                _clientCheckPointHandler.CheckpointNumber = _checkpointsNumber;

                // updating state
                for (var i = 0; i < boardShapes.Count; i++)
                {
                    var boardShapeId = boardShapes[i].Uid;

                    // insert in id to BoardShape map
                    if (_mapIdToBoardShape.ContainsKey(boardShapeId))
                    {
                        // if already there is some reference present, removing it
                        _mapIdToBoardShape.Remove(boardShapeId);
                        GC.Collect();
                    }

                    _mapIdToBoardShape.Add(boardShapeId, boardShapes[i]);

                    // insert in priority queue and id to QueueElement map
                    var queueElement = new QueueElement(boardShapeId, boardShapes[i].LastModifiedTime);
                    if (_mapIdToQueueElement.ContainsKey(boardShapeId))
                    {
                        // if already there is some reference present, removing it
                        var tempQueueElement = _mapIdToQueueElement[boardShapeId];
                        _priorityQueue.DeleteElement(tempQueueElement);
                        _mapIdToQueueElement.Remove(boardShapeId);
                        GC.Collect();
                    }

                    _mapIdToQueueElement.Add(boardShapeId, queueElement);
                    _priorityQueue.Insert(queueElement);

                    // converting BoardShape to UXShape and adding it in the list
                    uXShapes.Add(new UXShape(UXOperation.CREATE, boardShapes[i].MainShapeDefiner, boardShapeId,
                                             _checkpointsNumber, boardServerShape.OperationFlag));
                }

                return(uXShapes);
            }
            catch (Exception e)
            {
                Trace.WriteLine("ClientBoardStateManager.UpdateStateOnFetch: Exception occurred.");
                Trace.WriteLine(e.Message);
            }

            return(null);
        }