/// <summary>
        /// Redraws element when it necessary.
        /// </summary>
        /// <param name="sender">Element to redraw.</param>
        /// <param name="e">Event args.</param>
        private void _ElementRedrawRequired(object sender, EventArgs e)
        {
            IGanttItemElement element = sender as IGanttItemElement;

            Debug.Assert(element != null);

            GanttItemElementDrawingVisual visual = null;

            if (_mapElementToVisual.TryGetValue(element, out visual))
            {
                visual.RedrawRequired = true;
            }

            InvalidateVisual();
        }
        /// <summary>
        /// Creates collection of visual from colection of gantt items.
        /// </summary>
        /// <param name="ganttItems">Gantt items collection.</param>
        private void _CreateVisuals(ICollection <IGanttItem> ganttItems)
        {
            Debug.Assert(ganttItems != null);

            foreach (IGanttItem ganttItem in ganttItems)
            {
                foreach (IGanttItemElement element in ganttItem.GanttItemElements)
                {
                    GanttItemElementDrawingVisual visual = new GanttItemElementDrawingVisual(element);

                    // Add visual to children collection.
                    _children.Add(visual);

                    // Add key-value pair to dictionary.
                    _mapElementToVisual.Add(element, visual);
                    element.RedrawRequired += new EventHandler(_ElementRedrawRequired);
                }
            }
        }
        /// <summary>
        /// Method determines what object is located under point.
        /// </summary>
        /// <param name="pt">Input point for test.</param>
        /// <returns>Returns IGanttItemElement instance if gantt item element presentation is under point.
        /// Returns null if nor gantt item nor gantt item element is found under point.</returns>
        public object HitTest(Point pt)
        {
            // Find object under necessary point using Visual tree helper.
            HitTestResult foundObject = VisualTreeHelper.HitTest(this, pt);

            if (foundObject == null)
            {
                return(null);
            }

            GanttItemElementDrawingVisual foundVisual = foundObject.VisualHit as GanttItemElementDrawingVisual;

            // If found object is not GanttItemElementDrawingVisual - return null.
            if (foundVisual == null)
            {
                return(null);
            }

            // If IGanttItemElement was found - return it.
            return(foundVisual.GanttItemElement);
        }
        /// <summary>
        /// Adds one "row" of visual elements to necessary gantt item.
        /// </summary>
        /// <param name="ganttItem">Gantt item.</param>
        private void _AddVisualsForGanttItem(IGanttItem ganttItem)
        {
            // Define next Gantt item in collection to insert new visuals before it's visuals.
            int indexOfNextGanttItem = _ganttItems.IndexOf(ganttItem) + 1;

            if (indexOfNextGanttItem == _ganttItems.Count) // If new item was added to the end of collection.
            {
                // Add new visuals to the end of collection.
                foreach (IGanttItemElement element in ganttItem.GanttItemElements)
                {
                    GanttItemElementDrawingVisual newVisual = new GanttItemElementDrawingVisual(element);
                    newVisual.RedrawRequired = true;
                    _mapElementToVisual.Add(element, newVisual); // Add pair to dictionary.
                    _children.Add(newVisual);
                    element.RedrawRequired += new EventHandler(_ElementRedrawRequired);
                }
            }
            else
            {
                Debug.Assert(false);
                // TODO : Add code to insert visual to necessary position later if necessary
            }
        }
        /// <summary>
        /// Handler of DragOver event: defines element under drag cursor and initiates Update Layout to highlight it.
        /// </summary>
        /// <param name="sender">Container.</param>
        /// <param name="e">Drag event args.</param>
        private void _DragOver(object sender, DragEventArgs e)
        {
            // Mark previous dragged over element as needed to be redrawn.
            if (_draggedOverVisual != null)
                _draggedOverVisual.RedrawRequired = true;

            // Find object under necessary point using Visual tree helper.
            HitTestResult foundObject = VisualTreeHelper.HitTest(this, e.GetPosition(this));

            // If there is an element under drag cursor.
            if (foundObject != null)
            {
                // Set element under drag cursor.
                _draggedOverVisual = foundObject.VisualHit as GanttItemElementDrawingVisual;

                if (_draggedOverVisual != null)
                {
                    // Mark dragged over element as needed to be redrawn.
                    _draggedOverVisual.RedrawRequired = true;

                    // Store dragged data.
                    _draggedData = e.Data;
                }
            }
            // No elements under drug cursor found.
            else
            {
                _draggedOverVisual = null;
            }

            // Update layout.
            InvalidateVisual();
        }
        /// <summary>
        /// Creates collection of visual from colection of gantt items.
        /// </summary>
        /// <param name="ganttItems">Gantt items collection.</param>
        private void _CreateVisuals(ICollection<IGanttItem> ganttItems)
        {
            Debug.Assert(ganttItems != null);

            foreach (IGanttItem ganttItem in ganttItems)
            {
                foreach (IGanttItemElement element in ganttItem.GanttItemElements)
                {
                    GanttItemElementDrawingVisual visual = new GanttItemElementDrawingVisual(element);

                    // Add visual to children collection.
                    _children.Add(visual);

                    // Add key-value pair to dictionary.
                    _mapElementToVisual.Add(element, visual);
                    element.RedrawRequired += new EventHandler(_ElementRedrawRequired);
                }
            }
        }
        /// <summary>
        /// Adds one "row" of visual elements to necessary gantt item.
        /// </summary>
        /// <param name="ganttItem">Gantt item.</param>
        private void _AddVisualsForGanttItem(IGanttItem ganttItem)
        {
            // Define next Gantt item in collection to insert new visuals before it's visuals.
            int indexOfNextGanttItem = _ganttItems.IndexOf(ganttItem) + 1;

            if (indexOfNextGanttItem == _ganttItems.Count) // If new item was added to the end of collection.
            {
                // Add new visuals to the end of collection.
                foreach (IGanttItemElement element in ganttItem.GanttItemElements)
                {
                    GanttItemElementDrawingVisual newVisual = new GanttItemElementDrawingVisual(element);
                    newVisual.RedrawRequired = true;
                    _mapElementToVisual.Add(element, newVisual); // Add pair to dictionary.
                    _children.Add(newVisual);
                    element.RedrawRequired += new EventHandler(_ElementRedrawRequired);
                }
            }
            else
            {
                Debug.Assert(false);
                // TODO : Add code to insert visual to necessary position later if necessary
            }
        }
        /// <summary>
        /// Updates layout after Drag'n'drop finished.
        /// </summary>
        public void DropGanttItemElements()
        {
            // If there is an element under drag cursor.
            if (_draggedOverVisual != null)
            {
                // Mark dragged over element as needed to be redrawn.
                _draggedOverVisual.RedrawRequired = true;

                // Clear dragged over element.
                _draggedOverVisual = null;

                // Update layout.
                InvalidateVisual();
            }
        }