private static IGraphic GeoShapeToGraphic(aim_dotnet.IGeometricShape geoShape, string shapeLabel)
        {
            if (geoShape.SpatialCoordinateCollection == null || geoShape.SpatialCoordinateCollection.Count == 0)
                return null;

            IGraphic graphic = null;
            if (geoShape is aim_dotnet.Circle)
            {
                // Ellipse
                var shapeCircle = geoShape as aim_dotnet.Circle;
                var centerPt = AsPointF(shapeCircle.Center);
                var radiusPt = AsPointF(shapeCircle.RadiusPoint);
                var radiusLength = Vector.Distance(centerPt, radiusPt);
                RoiGraphic roiGraphic = AimRoiGraphic.CreateEllipse();
                var boundableGraphic = roiGraphic.Subject as BoundableGraphic;
                if (boundableGraphic != null)
                {
                    roiGraphic.Suspend();
                    roiGraphic.Name = shapeLabel;
                    boundableGraphic.TopLeft = new PointF((float) (centerPt.X - radiusLength), (float) (centerPt.Y - radiusLength));
                    boundableGraphic.BottomRight = new PointF((float) (centerPt.X + radiusLength), (float) (centerPt.Y + radiusLength));
                    roiGraphic.Resume(true);
                }
                graphic = roiGraphic;
            }
            else if (geoShape is aim_dotnet.Ellipse)
            {
                // Ellipse
                var shapeEllipse = geoShape as aim_dotnet.Ellipse;
                var firstMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[0]);
                var secondMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[1]);
                var firstMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[2]);
                var secondMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[3]);
                RoiGraphic roiGraphic = AimRoiGraphic.CreateEllipse();
                var boundableGraphic = roiGraphic.Subject as BoundableGraphic;
                if (boundableGraphic != null)
                {
                    roiGraphic.Suspend();
                    roiGraphic.Name = shapeLabel;
                    boundableGraphic.TopLeft = new PointF(firstMajorAxisPt.X, firstMinorAxisPt.Y);
                    boundableGraphic.BottomRight = new PointF(secondMajorAxisPt.X, secondMinorAxisPt.Y);
                    roiGraphic.Resume(true);
                }
                graphic = roiGraphic;
            }
            else if (geoShape is aim_dotnet.Point)
            {
                var shapePoint = geoShape as aim_dotnet.Point;
                var callout = new CalloutGraphic(shapeLabel);
                callout.LineStyle = LineStyle.Solid;
                callout.ShowArrowhead = true;
                callout.AnchorPoint = AsPointF(shapePoint.Center);
                callout.TextLocation = callout.AnchorPoint - new SizeF(30, 30);
                var statefulGraphic = new StandardStatefulGraphic(callout);
                statefulGraphic.State = statefulGraphic.CreateInactiveState();
                graphic = statefulGraphic;
            }
            else if (geoShape is aim_dotnet.MultiPoint)
            {
                // How this case works:
                // If we have 2 points, it's a line
                // If we have 3 points, it's a protractor
                // All others - unknown unclosed object (not supported)
                var shapeMultiPoint = geoShape as aim_dotnet.MultiPoint;
                switch (shapeMultiPoint.SpatialCoordinateCollection.Count)
                {
                    case 2:
                        {
                            // Line
                            var interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new PolylineGraphic()));
                            var firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]);
                            var secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]);
                            interactiveGraphic.Subject.Points.Add(firstPt);
                            interactiveGraphic.Subject.Points.Add(secondPt);
                            var roiGraphic = CreateRoiGraphic(interactiveGraphic, null);
                            roiGraphic.Name = shapeLabel;
                            roiGraphic.Resume(true);
                            graphic = roiGraphic;
                        }
                        break;
                    case 3:
                        {
                            // Protractor
                            var interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new ProtractorGraphic()));
                            var firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]);
                            var secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]);
                            var thirdPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[2]);
                            interactiveGraphic.Subject.Points.Add(firstPt);
                            interactiveGraphic.Subject.Points.Add(secondPt);
                            interactiveGraphic.Subject.Points.Add(thirdPt);
                            var roiGraphic = CreateRoiGraphic(interactiveGraphic,  new ProtractorRoiCalloutLocationStrategy());
                            roiGraphic.Name = shapeLabel;
                            roiGraphic.Resume(true);
                            graphic = roiGraphic;
                        }
                        break;
                    default:
                        throw new NotImplementedException("Reading non-linear or non-triangular MultiPoint shape is not implemented");
                }
            }
            else if (geoShape is aim_dotnet.Polyline)
            {
                var shapePolyline = geoShape as aim_dotnet.Polyline;
                var isRectangle = false;
                if (shapePolyline.SpatialCoordinateCollection.Count == 4)
                {
                    var twoDPoint1 = AsPointF(shapePolyline.SpatialCoordinateCollection[0]);
                    var twoDPoint2 = AsPointF(shapePolyline.SpatialCoordinateCollection[1]);
                    var twoDPoint3 = AsPointF(shapePolyline.SpatialCoordinateCollection[2]);
                    var twoDPoint4 = AsPointF(shapePolyline.SpatialCoordinateCollection[3]);
                    if ((twoDPoint1.X == twoDPoint2.X && twoDPoint2.Y == twoDPoint3.Y && twoDPoint3.X == twoDPoint4.X && twoDPoint4.Y == twoDPoint1.Y) ||
                        (twoDPoint1.Y == twoDPoint2.Y && twoDPoint2.X == twoDPoint3.X && twoDPoint3.Y == twoDPoint4.Y && twoDPoint4.X == twoDPoint1.X))
                    {
                        isRectangle = true;

                        RoiGraphic roiGraphic = AimRoiGraphic.CreateRectangle();
                        var boundableGraphic = roiGraphic.Subject as BoundableGraphic;
                        if (boundableGraphic != null)
                        {
                            roiGraphic.Suspend();
                            roiGraphic.Name = shapeLabel;
                            boundableGraphic.TopLeft = twoDPoint1;
                            boundableGraphic.BottomRight = twoDPoint3;
                            roiGraphic.Resume(true);
                        }

                        graphic = roiGraphic;
                    }
                }
                if (!isRectangle)
                {
                    RoiGraphic roiGraphic = AimRoiGraphic.CreatePolygon();
                    var polylineGraphic = roiGraphic.Subject as PolylineGraphic;
                    if (polylineGraphic != null)
                    {
                        roiGraphic.Suspend();
                        for (var i = 0; i < shapePolyline.SpatialCoordinateCollection.Count; i++)
                        {
                            var twoDPoint = AsPointF(shapePolyline.SpatialCoordinateCollection[i]);
                            polylineGraphic.Points.Add(twoDPoint);
                        }
                        // We deal with closed polygons only
                        if (polylineGraphic.Points.Count > 0)
                            polylineGraphic.Points.Add(polylineGraphic.Points[0]);
                        roiGraphic.Name = shapeLabel;
                        roiGraphic.Resume(true);
                    }

                    graphic = roiGraphic;
                }
            }
            else
                throw new Exception("Unknown shape type encountered: " + geoShape.GetType().FullName);

            return graphic;
        }
		private static RoiGraphic GeoShapeToRoiGraphic(aim_dotnet.IGeometricShape geoShape)
		{
			RoiGraphic roiGraphic = null;

			if (geoShape.SpatialCoordinateCollection == null || geoShape.SpatialCoordinateCollection.Count == 0)
				return null;

			if (geoShape is aim_dotnet.Circle)
			{
				// Ellipse
				aim_dotnet.Circle shapeCircle = geoShape as aim_dotnet.Circle;
				PointF centerPt = AsPointF(shapeCircle.Center);
				PointF radiusPt = AsPointF(shapeCircle.RadiusPoint);
				double radiusLength = Vector.Distance(centerPt, radiusPt);
				roiGraphic = RoiGraphic.CreateEllipse();
				BoundableGraphic boundableGraphic = roiGraphic.Subject as BoundableGraphic;
				if (boundableGraphic != null)
				{
					roiGraphic.Suspend(); // prevent callout location calculation untill all points are set
					boundableGraphic.TopLeft = new PointF((float) (centerPt.X - radiusLength), (float) (centerPt.Y - radiusLength));
					boundableGraphic.BottomRight = new PointF((float) (centerPt.X + radiusLength), (float) (centerPt.Y + radiusLength));
					roiGraphic.Resume(true); // Force callout location calculation
				}
			}
			else if (geoShape is aim_dotnet.Ellipse)
			{
				// Ellipse
				aim_dotnet.Ellipse shapeEllipse = geoShape as aim_dotnet.Ellipse;
				PointF firstMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[0]);
				PointF secondMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[1]);
				PointF firstMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[2]);
				PointF secondMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[3]);

				roiGraphic = RoiGraphic.CreateEllipse();
				BoundableGraphic boundableGraphic = roiGraphic.Subject as BoundableGraphic;
				if (boundableGraphic != null)
				{
					roiGraphic.Suspend(); // prevent callout location calculation untill all points are set
					boundableGraphic.TopLeft = new PointF(firstMajorAxisPt.X, firstMinorAxisPt.Y);
					boundableGraphic.BottomRight = new PointF(secondMajorAxisPt.X, secondMinorAxisPt.Y);
					roiGraphic.Resume(true); // Force callout location calculation
				}
			}
			else if (geoShape is aim_dotnet.Point)
			{
				throw new NotImplementedException("Reading Point shape is not implemented");
			}
			else if (geoShape is aim_dotnet.MultiPoint)
			{
				// How this case works:
				// If we have 2 points, it's a line
				// If we have 3 points, it's a protractor
				// All others - unknown unclosed object (not supported)

				aim_dotnet.MultiPoint shapeMultiPoint = geoShape as aim_dotnet.MultiPoint;
				switch (shapeMultiPoint.SpatialCoordinateCollection.Count)
				{
					case 2:
						{
							// Line
							VerticesControlGraphic interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new PolylineGraphic()));
							PointF firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]);
							PointF secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]);
							interactiveGraphic.Subject.Points.Add(firstPt);
							interactiveGraphic.Subject.Points.Add(secondPt);

							roiGraphic = CreateRoiGraphic(interactiveGraphic, null);
							roiGraphic.Resume(true); // Force callout location calculation
						}
						break;
					case 3:
						{
							// Protractor
							VerticesControlGraphic interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new ProtractorGraphic()));
							PointF firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]);
							PointF secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]);
							PointF thirdPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[2]);
							interactiveGraphic.Subject.Points.Add(firstPt);
							interactiveGraphic.Subject.Points.Add(secondPt);
							interactiveGraphic.Subject.Points.Add(thirdPt);

							roiGraphic = CreateRoiGraphic(interactiveGraphic, new ProtractorRoiCalloutLocationStrategy());
							roiGraphic.Resume(true); // Force callout location calculation
						}
						break;
					default:
						throw new NotImplementedException("Reading non-linear or non-triangular MultiPoint shape is not implemented");
				}
			}
			else if (geoShape is aim_dotnet.Polyline)
			{
				aim_dotnet.Polyline shapePolyline = geoShape as aim_dotnet.Polyline;

				bool isRectangle = false; // true - if we have CC's rectangle coordinates
				// Check if this is a non-rotated rectangle
				if (shapePolyline.SpatialCoordinateCollection.Count == 4)
				{
					PointF twoDPoint1 = AsPointF(shapePolyline.SpatialCoordinateCollection[0]);
					PointF twoDPoint2 = AsPointF(shapePolyline.SpatialCoordinateCollection[1]);
					PointF twoDPoint3 = AsPointF(shapePolyline.SpatialCoordinateCollection[2]);
					PointF twoDPoint4 = AsPointF(shapePolyline.SpatialCoordinateCollection[3]);
					// If it's a rectangle with sides parallel to the axes
					if ((twoDPoint1.X == twoDPoint2.X && twoDPoint2.Y == twoDPoint3.Y && twoDPoint3.X == twoDPoint4.X && twoDPoint4.Y == twoDPoint1.Y) ||
					    (twoDPoint1.Y == twoDPoint2.Y && twoDPoint2.X == twoDPoint3.X && twoDPoint3.Y == twoDPoint4.Y && twoDPoint4.X == twoDPoint1.X))
					{
						isRectangle = true;

						roiGraphic = RoiGraphic.CreateRectangle();
						BoundableGraphic boundableGraphic = roiGraphic.Subject as BoundableGraphic;
						if (boundableGraphic != null)
						{
							roiGraphic.Suspend(); // prevent callout location calculation untill all points are set
							// Assume that the points are in order and start at the top left corner.
							boundableGraphic.TopLeft = twoDPoint1;
							boundableGraphic.BottomRight = twoDPoint3;

							roiGraphic.Resume(true); // Force callout location calculation
						}
					}
				}
				// It's a CC's polygon if it's not a rectangle
				if (!isRectangle)
				{
					roiGraphic = RoiGraphic.CreatePolygon();
					PolylineGraphic polylineGraphic = roiGraphic.Subject as PolylineGraphic;
					if (polylineGraphic != null)
					{
						roiGraphic.Suspend();
						for (int i = 0; i < shapePolyline.SpatialCoordinateCollection.Count; i++)
						{
							PointF twoDPoint = AsPointF(shapePolyline.SpatialCoordinateCollection[i]);
							polylineGraphic.Points.Add(twoDPoint);
						}
						// We deal with closed polygons only
						if (polylineGraphic.Points.Count > 0)
							polylineGraphic.Points.Add(polylineGraphic.Points[0]);
						roiGraphic.Resume(true); // Force callout location calculation
					}
				}
			}
			else
				throw new Exception("Unknown shape type encountered: " + geoShape.GetType().FullName);

			return roiGraphic;
		}