/// <summary>
        /// Adds a polygon (list of poly point descriptor).
        /// </summary>
        /// <param name="points">The descriptor list for all polygon points of one polygon.</param>
        /// <param name="polygonIndex">Index of the polygon if this is a poly polygon. Default is <c>Int32.MaxValue</c></param>
        /// <param name="updateDirectly">if set to <c>true</c> the polygon lists will be updated in the shape properties directly;
        /// otherwise you have to call <see cref="WritePointsToPolygon"/> manually.
        /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
        /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update"/>function.
        /// Default is <c>true</c></param>
        /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c> </param>
        /// <returns><c>true</c> if the polygon points could be added</returns>
        virtual public bool AddPolygonPoints(List <PolyPointDescriptor> points, int polygonIndex = Int32.MaxValue, bool updateDirectly = true, bool geometry = false)
        {
            if (IsValid())
            {
                if (CachedPolyPointList != null && points != null)
                {
                    try
                    {
                        _updating = true;
                        if (polygonIndex < CachedPolyPointList.Count)
                        {
                            CachedPolyPointList.Insert(Math.Max(0, polygonIndex), points);
                        }
                        else
                        {
                            CachedPolyPointList.Add(points);
                        }

                        if (updateDirectly)
                        {
                            return(WritePointsToPolygon(geometry));
                        }
                        else
                        {
                            return(true);
                        }
                    }
                    finally { _updating = false; }
                }
            }
            return(false);
        }
        /// <summary>
        /// Updates a polygon (list of poly point descriptor).
        /// If the new list is <c>null</c>, the polygon will be removed from the list.
        /// </summary>
        /// <param name="points">The descriptor list for all polygon points of one polygon or <c>null</c> if it should be removed.</param>
        /// <param name="polygonIndex">Index of the polygon if this is a poly polygon. Default is 0</param>
        /// <param name="updateDirectly">if set to <c>true</c> the polygon lists will be updated in the shape properties directly;
        /// otherwise you have to call <see cref="WritePointsToPolygon" /> manually.
        /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
        /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update"/>function.
        /// Default is <c>true</c></param>
        /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c></param>
        /// <returns>
        ///   <c>true</c> if the polygon points could be added
        /// </returns>
        virtual public bool UpdatePolygonPoints(List <PolyPointDescriptor> points, int polygonIndex = 0, bool updateDirectly = true, bool geometry = false)
        {
            if (IsValid())
            {
                if (CachedPolyPointList != null)
                {
                    try
                    {
                        _updating = true;
                        if (polygonIndex < CachedPolyPointList.Count)
                        {
                            if (points != null)
                            {
                                CachedPolyPointList[polygonIndex] = points;
                            }
                            else
                            {
                                CachedPolyPointList.RemoveAt(polygonIndex);
                            }

                            if (updateDirectly)
                            {
                                return(WritePointsToPolygon(geometry));
                            }
                            else
                            {
                                return(true);
                            }
                        }
                    }
                    finally { _updating = false; }
                }
            }
            return(false);
        }
        /// <summary>
        /// Adds a poly point descriptor.
        /// </summary>
        /// <param name="ppd">The descriptor for a poly polygon point.</param>
        /// <param name="index">The index of the poly point to add to. A index &lt;= 0 will add the point as fist; an index &gt; the length of the list will add it as last. Default is <c>Int32.MaxValue</c></param>
        /// <param name="polygonIndex">Index of the polygon if this is a poly polygon.  Default is 0</param>
        /// <param name="updateDirectly">if set to <c>true</c> the point lists will be updated in the shape properties directly;
        /// otherwise you have to call <see cref="WritePointsToPolygon" /> manually.
        /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
        /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update" />function.
        /// Default is <c>true</c></param>
        /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c></param>
        /// <returns>
        ///   <c>true</c> if the point could be added
        /// </returns>
        virtual public bool AddPolyPointDescriptor(PolyPointDescriptor ppd, int index = Int32.MaxValue, int polygonIndex = 0, bool updateDirectly = true, bool geometry = false)
        {
            if (IsValid())
            {
                if (CachedPolyPointList != null)
                {
                    try
                    {
                        _updating = true;
                        if (CachedPolyPointList.Count > polygonIndex)
                        {
                            if (CachedPolyPointList[polygonIndex] == null)
                            {
                                CachedPolyPointList[polygonIndex] = new List <PolyPointDescriptor>();
                            }
                            if (index < CachedPolyPointList[polygonIndex].Count)
                            {
                                CachedPolyPointList[polygonIndex].Insert(Math.Max(index, 0), ppd);
                            }
                            else
                            {
                                CachedPolyPointList[polygonIndex].Add(ppd);
                            }
                        }
                        else
                        {
                            CachedPolyPointList.Add(
                                new List <PolyPointDescriptor>()
                            {
                                ppd
                            }
                                );
                        }

                        if (updateDirectly)
                        {
                            return(WritePointsToPolygon(geometry));
                        }
                        else
                        {
                            return(true);
                        }
                    }
                    finally { _updating = false; }
                }
            }
            return(false);
        }