         redispatchError(event);
     }
 
+    /**
+     * Redispatch some error we received to our listeners.
+     */
     protected function redispatchError (event :Event) :void
     {
         dispatchEvent(new ValueEvent(VIDEO_ERROR, event));
     }
 
-    public function callbackCalled (name :String, args :Array) :*
-    {
-        trace("Callback: " + name + ", args: " + args);
-        return undefined;
-    }
-
-    public function onMetaData (obj :Object) :void
-    {
-        trace("Got metadata..");
+    /**
+     * Called when metadata (if any) is found in the video stream.
+     */
+    protected function metaDataReceived (obj :Object) :void
+    {
+        trace("Got video metadata:");
         for (var n :String in obj) {
-            trace("name " + n + " -> " + obj[n]);
-        }
-    }
-
+            trace("    " + n + ": " + obj[n]);
+        }
+    }
+    
     protected var _vid :Video;
 
+    protected var _paused :Boolean = false;
+
     protected var _netCon :NetConnection;
 
     protected var _netStream :NetStream;
+
+    protected var _pauser :Sprite;
 
     /** Checks the video every 100ms to see if the dimensions are now know.
      * Yes, this is how to do it. We could trigger on ENTER_FRAME, but then

    protected var _videoChecker :Timer = new Timer(100);
}
}

import flash.utils.Proxy;

import flash.utils.flash_proxy;

import com.threerings.util.VideoDisplayer;

use namespace flash_proxy;

/**
 */
internal class Callbacker extends Proxy
{
    public function Callbacker (displayer :VideoDisplayer)
    {
        _displayer = displayer;

        _props
    }

    override flash_proxy function hasProperty (name :*) :Boolean
    {
        return (_props[name] !== undefined);
    }

    override flash_proxy function getProperty (name :*) :*
    {
        trace("Damn thing asked about '" + name + "'.");
        return _props[name];
    }

    override flash_proxy function setProperty (name :*, value :*) :void
    {
        trace("Damn thing tried to set '" + name + "' to '" + value + "'.");
        _props[name] = value;
    }

    override flash_proxy function deleteProperty (name :*) :Boolean
    {
        trace("Damn thing tried to delete '" + name + "'.");
        return (delete _props[name]);
    }

    override flash_proxy function callProperty (name :*, ... args) :*
    {
        return _displayer.callbackCalled(name, args);
    }

    protected var _props :Object = {};

    protected var _displayer :VideoDisplayer;
}

{
    /** A value event dispatched when the size of the video is known.
     * Value: [ width, height ]. */
    public static const SIZE_KNOWN :String = "videoDisplayerSizeKnown";

    /** A value event sent when there's an error loading the video.
     * Value: original error event. */
    public static const VIDEO_ERROR :String = "videoDisplayerError";

    /**
     * Create a video displayer.
     */
    public function VideoDisplayer ()
    {
        _vid = new Video();
        addChild(_vid);

        addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
        addEventListener(MouseEvent.ROLL_OUT, handleRollOut);

        _videoChecker.addEventListener(TimerEvent.TIMER, handleVideoCheck);

        _pauser = new Sprite();
        _pauser.addEventListener(MouseEvent.CLICK, handleClick);
        redrawPauser();
    }

    /**
     * Start playing a video!
     */
    public function setup (url :String) :void
    {
        _netCon = new NetConnection();
