//[Test]
		// User should uncomment if they want to see the Performance Comparison
		public void Performance() 
		{
			// set the hashtable and SequencedHashMap to be the 
			IDictionary hashtable;
			IDictionary sequenced;
			IDictionary list;

			int numOfRuns = 1;

			int numOfEntries = Int16.MaxValue;

			long hashStart;
			long[] hashPopulateTicks = new long[numOfRuns];
			long[] hashItemTicks = new long[numOfRuns];

			long seqStart;
			long[] seqPopulateTicks = new long[numOfRuns];
			long[] seqItemTicks = new long[numOfRuns];

			long listStart;
			long[] listPopulateTicks = new long[numOfRuns];
			long[] listItemTicks = new long[numOfRuns];

			for (int runIndex = 0; runIndex < numOfRuns; runIndex++) 
			{
				object key;
				object value;
				hashtable = new Hashtable();
				sequenced = new SequencedHashMap();
				list = new System.Collections.Specialized.ListDictionary();

				hashStart = DateTime.Now.Ticks;

				for(int i = 0; i < numOfEntries; i++) 
				{
					hashtable.Add("test" + i, new object());
				}

				hashPopulateTicks[runIndex] = DateTime.Now.Ticks - hashStart;

				hashStart = DateTime.Now.Ticks;
				for(int i = 0; i < numOfEntries; i++) 
				{
					key = "test" + i;
					value = hashtable[key];
				}

				hashItemTicks[runIndex] = DateTime.Now.Ticks - hashStart;

				hashtable.Clear();

				seqStart = DateTime.Now.Ticks;

				for(int i = 0; i < numOfEntries; i++) 
				{
					sequenced.Add("test" + i, new object());
				}

				seqPopulateTicks[runIndex] = DateTime.Now.Ticks - seqStart;

				seqStart = DateTime.Now.Ticks;
				for(int i = 0; i < numOfEntries; i++) 
				{
					key = "test" + i;
					value = sequenced[key];
				}

				seqItemTicks[runIndex] = DateTime.Now.Ticks - seqStart;

				sequenced.Clear();

				listStart = DateTime.Now.Ticks;

				for(int i = 0; i < numOfEntries; i++) 
				{
					list.Add("test" + i, new object());
				}

				listPopulateTicks[runIndex] = DateTime.Now.Ticks - listStart;

				listStart = DateTime.Now.Ticks;
				for(int i = 0; i < numOfEntries; i++) 
				{
					key = "test" + i;
					value = list[key];
				}

				listItemTicks[runIndex] = DateTime.Now.Ticks - listStart;


				list.Clear();

			}
			
			for (int runIndex = 0; runIndex < numOfRuns; runIndex++) 
			{
				decimal seqPopulateOverhead = ( (decimal)seqPopulateTicks[runIndex] /(decimal)hashPopulateTicks[runIndex] );
				decimal seqItemOverhead = ( (decimal)seqItemTicks[runIndex] / (decimal)hashItemTicks[runIndex] );

				string errMessage = "SequenceHashMap vs Hashtable:";
				errMessage += "\n POPULATE:";
				errMessage += "\n\t seqPopulateTicks[" + runIndex + "] took " + seqPopulateTicks[runIndex] + " ticks.";
				errMessage += "\n\t hashPopulateTicks[" + runIndex + "] took " + hashPopulateTicks[runIndex] + " ticks.";
				errMessage += "\n\t for an overhead of " + seqPopulateOverhead .ToString() ;
				errMessage += "\n ITEM:";
				errMessage += "\n\t seqItemTicks[" + runIndex + "] took " + seqItemTicks[runIndex] + " ticks.";
				errMessage += "\n\t hashItemTicks[" + runIndex + "] took " + hashItemTicks[runIndex] + " ticks.";
				errMessage += "\n\t for an overhead of " + seqItemOverhead .ToString() ;
				
				System.Console.Out.WriteLine(errMessage);
				
				decimal listPopulateOverhead = ( (decimal)listPopulateTicks[runIndex] / (decimal)seqPopulateTicks[runIndex] );
				decimal listItemOverhead = ( (decimal)listItemTicks[runIndex] / (decimal)seqItemTicks[runIndex] );

				errMessage = "ListDictionary vs SequenceHashMap:";
				errMessage += "\n POPULATE:";
				errMessage += "\n\t listPopulateTicks[" + runIndex + "] took " + listPopulateTicks[runIndex] + " ticks.";
				errMessage += "\n\t seqPopulateTicks[" + runIndex + "] took " + seqPopulateTicks[runIndex] + " ticks.";
				errMessage += "\n\t for an overhead of " + listPopulateOverhead.ToString();
				errMessage += "\n ITEM:";
				errMessage += "\n\t listItemTicks[" + runIndex + "] took " + listItemTicks[runIndex] + " ticks.";
				errMessage += "\n\t seqItemTicks[" + runIndex + "] took " + seqItemTicks[runIndex] + " ticks.";
				errMessage += "\n\t for an overhead of " + listItemOverhead .ToString() ;
				
				System.Console.Out.WriteLine(errMessage);

			}
		}
        public virtual void DrawAnnotation(Graphics g, object tiffAnnotation, Hashtable markGroupsVisibleList, Bitmap bitmapImg, InterpolationMode CurrentInterpolationMode, ref Rectangle[] SelectedRectangles, System.Collections.Specialized.ListDictionary notesToSelectedRectangles)
        {
            if (notesToSelectedRectangles != null)
            {
                notesToSelectedRectangles.Clear();
            }
            TiffAnnotation annotation = tiffAnnotation as TiffAnnotation;

            if (annotation != null)
            {
                ArrayList figuresList = annotation.GetFigures(false);
                foreach (object figure in figuresList)
                {
                    TiffAnnotation.IBufferBitmap bb = figure as TiffAnnotation.IBufferBitmap;
                    if (bb != null && markGroupsVisibleList.ContainsKey(bb.Attributes.OiGroup) && ((bool)markGroupsVisibleList[bb.Attributes.OiGroup]))
                    {
                        switch (figure.GetType().Name)
                        {
                        case "ImageEmbedded":
                            TiffAnnotation.ImageEmbedded img = (TiffAnnotation.ImageEmbedded)figure;
                            g.DrawImage(img.Img, img.LrBounds.Location.X, img.LrBounds.Location.Y, img.LrBounds.Size.Width, img.LrBounds.Size.Height);
                            if (bb.Selected)
                            {
                                DrawSelectedRectangle(g, bb.Rect, ref SelectedRectangles);
                            }
                            break;

                        case "StraightLine":
                            TiffAnnotation.StraightLine line = (TiffAnnotation.StraightLine)figure;
                            if (line.LinePoints == null)
                            {
                                continue;
                            }
                            g.DrawLine(new Pen(new SolidBrush(line.RgbColor1), Convert.ToSingle(line.ULineSize)), line.LinePoints[0], line.LinePoints[1]);
                            break;

                        case "FreehandLine":
                            TiffAnnotation.FreehandLine fline = (TiffAnnotation.FreehandLine)figure;
                            if (fline.LinePoints == null)
                            {
                                continue;
                            }
                            for (int i = 0; i < fline.LinePoints.Length; i += 2)
                            {
                                if (i != 0)
                                {
                                    g.DrawLine(new Pen(new SolidBrush(fline.RgbColor1), Convert.ToSingle(fline.ULineSize)), fline.LinePoints[i - 1], fline.LinePoints[i]);
                                }
                                g.DrawLine(new Pen(new SolidBrush(fline.RgbColor1), Convert.ToSingle(fline.ULineSize)), fline.LinePoints[i], fline.LinePoints[i + 1]);
                            }
                            break;

                        case "HollowRectangle":
                        {
                            TiffAnnotation.HollowRectangle rect = (TiffAnnotation.HollowRectangle)figure;
                            Bitmap bitmapUp = bb.GetBitmap(bitmapImg, CurrentInterpolationMode);
                            g.DrawImage(bitmapUp, rect.LrBounds.X, rect.LrBounds.Y);
                            if (bb.Selected)
                            {
                                DrawSelectedRectangle(g, rect.LrBounds, ref SelectedRectangles);
                            }
                        }
                        break;

                        case "FilledRectangle":
                        {
                            TiffAnnotation.FilledRectangle frect = (TiffAnnotation.FilledRectangle)figure;
                            Bitmap bitmapUp = bb.GetBitmap(bitmapImg, CurrentInterpolationMode);
                            g.DrawImage(bitmapUp, frect.LrBounds.X, frect.LrBounds.Y);
                            if (bb.Selected)
                            {
                                DrawSelectedRectangle(g, frect.LrBounds, ref SelectedRectangles);
                            }
                        }
                        break;

                        case "TypedText":
                            TiffAnnotation.TypedText        tt = (TiffAnnotation.TypedText)figure;
                            StringFormat                    sf = new StringFormat();
                            System.Drawing.Drawing2D.Matrix mx = null;
                            Rectangle newRect = tt.LrBounds;
                            switch (tt.TextPrivateData.NCurrentOrientation)
                            {
                            case 900:
                                mx      = new System.Drawing.Drawing2D.Matrix();
                                newRect = new Rectangle(tt.LrBounds.X, tt.LrBounds.Y + tt.LrBounds.Height, tt.LrBounds.Height, tt.LrBounds.Width);
                                mx.RotateAt(270, new PointF(newRect.X, newRect.Y));
                                g.Transform = mx;
                                break;

                            case 1800:
                                mx      = new System.Drawing.Drawing2D.Matrix();
                                newRect = tt.LrBounds;
                                mx.RotateAt(180, new PointF(tt.LrBounds.Location.X + tt.LrBounds.Width / 2, tt.LrBounds.Location.Y + tt.LrBounds.Height / 2));
                                g.Transform = mx;
                                break;

                            case 2700:
                                mx      = new System.Drawing.Drawing2D.Matrix();
                                newRect = new Rectangle(tt.LrBounds.X + tt.LrBounds.Width, tt.LrBounds.Y, tt.LrBounds.Height, tt.LrBounds.Width);
                                mx.RotateAt(90, new PointF(newRect.X, newRect.Y));
                                g.Transform = mx;

                                break;
                            }

                            g.TextRenderingHint = tt.FontRenderingHint;
                            sf.Trimming         = StringTrimming.Word;
                            using (Font f = new Font(tt.LfFont.FontFamily, tt.LfFont.SizeInPoints, tt.LfFont.Style))
                                g.DrawString(tt.TextPrivateData.SzAnoText, f, new SolidBrush(tt.RgbColor1), newRect, sf);

                            g.ResetTransform();
                            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                            if (bb.Selected)
                            {
                                DrawSelectedRectangle(g, bb.Rect, ref SelectedRectangles);
                                Pen p = new Pen(Brushes.Black);
                                p.DashStyle = DashStyle.Dash;
                                g.DrawRectangle(p, new Rectangle(bb.Rect.X - 1, bb.Rect.Y - 1, bb.Rect.Width + 2, bb.Rect.Height + 2));
                            }
                            break;

                        case "TextStump":

                            TiffAnnotation.TextStump ts  = (TiffAnnotation.TextStump)figure;
                            StringFormat             sf3 = new StringFormat();
                            g.TextRenderingHint = ts.FontRenderingHint;

                            g.DrawString(ts.TextPrivateData.SzAnoText, ts.LfFont, new SolidBrush(ts.RgbColor1), ts.LrBounds, sf3);
                            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                            break;

                        case "TextFromFile":
                            TiffAnnotation.TextFromFile tf = (TiffAnnotation.TextFromFile)figure;
                            StringFormat sf2 = new StringFormat();
                            g.TextRenderingHint = tf.FontRenderingHint;

                            g.DrawString(tf.TextPrivateData.SzAnoText, tf.LfFont, new SolidBrush(tf.RgbColor1), tf.LrBounds, sf2);
                            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                            break;

                        case "AttachANote":
                            TiffAnnotation.AttachANote an = (TiffAnnotation.AttachANote)figure;
                            StringFormat sf1 = new StringFormat();

                            g.TextRenderingHint = an.FontRenderingHint;

                            g.FillRectangle(Brushes.Black, an.LrBounds.X + 2, an.LrBounds.Y + 2, an.LrBounds.Width, an.LrBounds.Height);
                            g.FillRectangle(new SolidBrush(an.RgbColor1), an.LrBounds);
                            g.DrawRectangle(Pens.Black, an.LrBounds.X, an.LrBounds.Y, an.LrBounds.Width, an.LrBounds.Height);

                            System.Drawing.Drawing2D.Matrix mx1 = null;
                            Rectangle newRect1 = an.LrBounds;
                            switch (an.TextPrivateData.NCurrentOrientation)
                            {
                            case 900:
                                mx1      = new System.Drawing.Drawing2D.Matrix();
                                newRect1 = new Rectangle(an.LrBounds.X, an.LrBounds.Y + an.LrBounds.Height, an.LrBounds.Height, an.LrBounds.Width);
                                mx1.RotateAt(270, new PointF(newRect1.X, newRect1.Y));
                                g.Transform = mx1;
                                break;

                            case 1800:
                                mx1      = new System.Drawing.Drawing2D.Matrix();
                                newRect1 = an.LrBounds;
                                mx1.RotateAt(180, new PointF(an.LrBounds.Location.X + an.LrBounds.Width / 2, an.LrBounds.Location.Y + an.LrBounds.Height / 2));
                                g.Transform = mx1;
                                break;

                            case 2700:
                                mx1      = new System.Drawing.Drawing2D.Matrix();
                                newRect1 = new Rectangle(an.LrBounds.X + an.LrBounds.Width, an.LrBounds.Y, an.LrBounds.Height, an.LrBounds.Width);
                                mx1.RotateAt(90, new PointF(newRect1.X, newRect1.Y));
                                g.Transform = mx1;

                                break;
                            }
                            g.DrawString(an.TextPrivateData.SzAnoText, new Font(an.LfFont.FontFamily, an.LfFont.SizeInPoints, an.LfFont.Style), new SolidBrush(an.RgbColor2), newRect1, sf1);
                            g.ResetTransform();
                            if (bb.Selected)
                            {
                                DrawSelectedRectangle(g, bb.Rect, ref SelectedRectangles);
                            }
                            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                            break;
                        }
                        if (notesToSelectedRectangles != null && SelectedRectangles != null && SelectedRectangles.Length > 0 && bb.Selected)
                        {
                            notesToSelectedRectangles.Add(bb, SelectedRectangles);
                        }
                    }
                }
            }
        }