         switch (horizontalPos)
         {
             case CalloutPosition.BEFORE:
+            {
+                // The full width of the callout is before the owner
+                // All arrow directions are ArrowDirection.RIGHT x=(width - arrow.width)
                 registrationPoint.x = -width;
                 break;
+            }
             case CalloutPosition.START:
+            {
+                // ArrowDirection.LEFT is at x=0
                 registrationPoint.x = 0;
                 break;
+            }
             case CalloutPosition.END:
-                registrationPoint.x = ownerWidth - width;
-                break;
+            {
+                // The ends of the owner and callout are aligned
+                registrationPoint.x = (ownerWidth - width);
+                break;
+            }
             case CalloutPosition.AFTER:
+            {
+                // The full width of the callout is after the owner
+                // All arrow directions are ArrowDirection.LEFT (x=0)
                 registrationPoint.x = ownerWidth;
                 break;
+            }
             default: // case CalloutPosition.MIDDLE:
+            {
                 registrationPoint.x = Math.floor((ownerWidth - width) / 2);
                 break;
+            }
         }
 
         switch (verticalPos)
         {
             case CalloutPosition.BEFORE:
+            {
+                // The full height of the callout is before the owner
+                // All arrow directions are ArrowDirection.DOWN y=(height - arrow.height)
                 registrationPoint.y = -height;
                 break;
+            }
             case CalloutPosition.START:
+            {
+                // ArrowDirection.UP is at y=0
                 registrationPoint.y = 0;
                 break;
+            }
             case CalloutPosition.MIDDLE:
+            {
                 registrationPoint.y = Math.floor((ownerHeight - height) / 2);
                 break;
+            }
             case CalloutPosition.END:
-                registrationPoint.y = ownerHeight - height;
-                break;
+            {
+                // The ends of the owner and callout are aligned
+                registrationPoint.y = (ownerHeight - height);
+                break;
+            }
             default: //case CalloutPosition.AFTER:
+            {
+                // The full height of the callout is after the owner
+                // All arrow directions are ArrowDirection.UP (y=0)
                 registrationPoint.y = ownerHeight;
                 break;
+            }
         }
 
         var topLeft:Point = registrationPoint.clone();
         var size:Point = MatrixUtil.transformBounds(width, height, matrix, topLeft);
+        var bounds:Rectangle = new Rectangle();
+        
         bounds.left = topLeft.x;
         bounds.top = topLeft.y;
         bounds.width = size.x;
         bounds.height = size.y;
+        
+        return bounds;
+    }
+    
+    /**
+     * @private
+     */
+    mx_internal function get isArrowHorizontal():Boolean
+    {
+        return (arrowDirection == ArrowDirection.LEFT ||
+                arrowDirection == ArrowDirection.RIGHT);
+    }
+    
+    /**
+     * @private
+     */
+    mx_internal function get isArrowVertical():Boolean
+    {
+        return (arrowDirection == ArrowDirection.UP ||
+                arrowDirection == ArrowDirection.DOWN);
     }
 
     //--------------------------------------------------------------------------

     */
    override public function open(owner:DisplayObjectContainer, modal:Boolean=false):void
    {
        if ((horizontalPosition == CalloutPosition.AUTO)
            || (verticalPosition == CalloutPosition.AUTO))
        {
            // invalidate the arrow direction before opening
            invalidateArrowState = true;
            invalidateProperties();
        }

        // add to PopUpManager, calls positionPopUp(), and change state
        super.open(owner, modal);
    }

    /**
     *  @private
     */

        if (!arrow || (arrowDirection == ArrowDirection.NONE))
            return;

        var isStartPosition:Boolean = false;
        var isMiddlePosition:Boolean = false;
        var isEndPosition:Boolean = false;

        var position:String = (isArrowVertical) ? actualHorizontalPosition : actualVerticalPosition;

        isStartPosition = (position == CalloutPosition.START);
        isMiddlePosition = (position == CalloutPosition.MIDDLE);
