protected override void OnRender (DrawingContext dc)
		{
			var anialias = dc.Antialias;
			
			dc.Antialias = SnapsToDevicePixels ? Antialias.None : anialias;

			var rect = new Rect (StrokeThickness / 2, StrokeThickness / 2, 
			                     Width - StrokeThickness / 2, Height - StrokeThickness / 2);

			dc.DrawRectangle (Fill, new Pen (Stroke, StrokeThickness), rect);

			dc.Antialias = anialias;
		}
		public Rect TransformBounds (Rect rect)
		{
			var inverse = this;
			var points = new [] {
				inverse.TransformPoint (rect.TopLeft),
				inverse.TransformPoint (rect.TopRight),
				inverse.TransformPoint (rect.BottomLeft) ,
				inverse.TransformPoint (rect.BottomRight)
			};

			var x1 = points.Min (p => p.X);
			var y1 = points.Min (p => p.Y);

			var x2 = points.Max (p => p.X);
			var y2 = points.Max (p => p.Y);

			return new Rect (x1, y1, x2 - x1, y2 - y1);
		}
		protected sealed override void ArrangeCore (Rect finalRect)
		{	
			base.ArrangeCore (finalRect);
			
			Height = VerticalAlignment == VerticalAlignment.Stretch ? finalRect.Height : DesiredSize.Height;
			Width = HorizontalAlignment == HorizontalAlignment.Stretch ? finalRect.Width : DesiredSize.Width;
			
			if (LayoutTransform != null) {
				//TODO: adjust height and width depends on vertical/horizontal aligments
				Height = savedSize.Height;
				Width = savedSize.Width;
			}
			
			ArrangeOverride (new Size (Width, Height));
		}
		public override void DrawRectangle (Brush brush, Pen pen, Rect rectangle)
		{
			if (brush != null) {
				if (brush is SolidColorBrush) {
					var b = brush as SolidColorBrush;
					cr.Color = new Cairo.Color (b.Color.R, b.Color.G, b.Color.B, b.Color.Alfa);	
					cr.Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);			
			
					cr.Fill ();
				} else if (brush is LinearGradientBrush) {
					var b = brush as LinearGradientBrush;
					
					var pattern = new Cairo.LinearGradient (b.StartPoint.X, b.StartPoint.Y, b.EndPoint.X, b.EndPoint.Y);
					foreach (var stop in b.GradientStops) {
						pattern.AddColorStop (stop.Offset, new Cairo.Color (stop.Color.R, stop.Color.G, stop.Color.B, stop.Color.Alfa));						
					}
					
					cr.Pattern = pattern;
					cr.Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);			
					cr.Fill ();
				}
			}

			if (pen != null) {
				cr.Color = new Cairo.Color (pen.Color.R, pen.Color.G, pen.Color.B, pen.Color.Alfa);	
				cr.LineWidth = pen.Thickness;
				cr.Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);			
			
				cr.Stroke ();
			}			
		}
		public override void DrawRoundedRectangle (Brush brush, Pen pen, Rect rectangle, double radiusX, double radiusY)
		{
			var figure = new PathFigure ();
			figure.StartPoint = new Point (rectangle.X + radiusX, rectangle.Y);
			figure.Segments.Add (new LineSegment () { Point = new Point(rectangle.X + rectangle.Width - radiusX, rectangle.Y) });
			figure.Segments.Add (new ArcSegment () 
			    {
					Point = new Point(rectangle.X + rectangle.Width, rectangle.Y + radiusY),
					Size = new Size(radiusX, radiusY),
					SweepDirection = SweepDirection.Clockwise,
					IsLargeArc = false
				}
			);
			figure.Segments.Add (new LineSegment () { Point = new Point(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height - radiusY) });
			figure.Segments.Add (new ArcSegment () 
			    {
					Point = new Point(rectangle.X + rectangle.Width - radiusX, rectangle.Y + rectangle.Height),
					Size = new Size(radiusX, radiusY),
					SweepDirection = SweepDirection.Clockwise,
					IsLargeArc = false
				}
			);
			figure.Segments.Add (new LineSegment () { Point = new Point(rectangle.X + radiusX, rectangle.Y + rectangle.Height) });
			figure.Segments.Add (new ArcSegment () 
			    {
					Point = new Point(rectangle.X, rectangle.Y + rectangle.Height - radiusY),
					Size = new Size(radiusX, radiusY),
					SweepDirection = SweepDirection.Clockwise,
					IsLargeArc = false
				}
			);
			figure.Segments.Add (new LineSegment () { Point = new Point(rectangle.X, rectangle.Y + radiusY) });
			figure.Segments.Add (new ArcSegment () 
			    {
					Point = new Point(rectangle.X + radiusX, rectangle.Y),
					Size = new Size(radiusX, radiusY),
					SweepDirection = SweepDirection.Clockwise,
					IsLargeArc = false
				}
			);
			
			var path = new PathGeometry ();
			path.Figures.Add (figure);			
		}
		public abstract void DrawRoundedRectangle (Brush brush, Pen pen, Rect rectangle, double radiusX, double radiusY);
		public abstract void DrawRectangle (Brush brush, Pen pen, Rect rectangle);
		protected virtual void ArrangeCore (Rect finalRect)
		{			
			VisualTransform = new TranslateTransform (finalRect.X, finalRect.Y);

			if (RenderTransform != null)
				VisualTransform = new TransformGroup (new [] {VisualTransform, RenderTransform});
		}
		public void Arrange (Rect finalRect)
		{
			ArrangeCore (finalRect);
		}