http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/EffectsInspector.mxml
----------------------------------------------------------------------
diff --git 
a/Radii8Library/src/com/flexcapacitor/views/panels/EffectsInspector.mxml 
b/Radii8Library/src/com/flexcapacitor/views/panels/EffectsInspector.mxml
new file mode 100644
index 0000000..7922a41
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/panels/EffectsInspector.mxml
@@ -0,0 +1,951 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"; 
+                xmlns:s="library://ns.adobe.com/flex/spark" 
+                xmlns:mx="library://ns.adobe.com/flex/mx" 
+                xmlns:controls="com.flexcapacitor.controls.*"
+                
+                width="400" 
+                height="200" 
+                >
+       
+       <fx:Script>
+               <![CDATA[
+                       import mx.core.mx_internal;
+                       
+                       use namespace mx_internal;
+                       
+                       [Bindable]
+                       public var openAllBranchesAtStart:Boolean = true;
+                       
+                       
+                       public function set targets(value:Array):void {
+                               
+                               effectsCollection.source = value;
+                               effectsCollection.refresh();
+                               
+                               if (openAllBranchesAtStart) {
+                                       callLater(openAllBranches);
+                               }
+                       
+                       }
+                       
+                       public function openAllBranches():void {
+                               var items:Array = effectsCollection.toArray();
+                               
+                               effectsTree.validateNow();
+                               effectsTree.collectionLength;
+                               
+                               if (items) {
+                                       var length:int = items.length;
+                                       
+                                       for (var i:int; i < length; i++) {
+                                               
effectsTree.expandItem(items[i], true);
+                                               // 
effectsTree.expandChildrenOf(items[i], true);
+                                               effectsTree.validateNow();
+                                       }
+                               }
+                       }
+                       
+                       protected function 
effectsTree_enterFrameHandler(event:Event):void {
+                               var newTreeHeight:int = 
effectsTree.collectionLength*effectsTree.rowHeight;
+                               newTreeHeight = Math.max(newTreeHeight, 
effectsTree.minHeight);
+                               //trace("new tree height=" + newTreeHeight);
+                               
+                               if (newTreeHeight!=treeHeight) {
+                                       treeHeight = Math.max(newTreeHeight, 
effectsTree.minHeight);
+                                       trace("updating tree height");
+                               }
+                       }
+                       
+               ]]>
+       </fx:Script>
+       
+       
+       <fx:Declarations>
+               <s:ArrayCollection id="effectsCollection"/>
+               <fx:int id="treeHeight">200</fx:int>
+       </fx:Declarations>
+       
+       
+       <s:VGroup width="100%" height="100%">
+               
+               <!--<s:HGroup verticalAlign="middle" width="100%">
+                       <s:Spacer width="100%"/>
+                       <s:Label text="Total ({effectsCollection.length})"/>
+               </s:HGroup>-->
+               
+               <mx:Tree id="effectsTree" 
+                                width="100%" 
+                                minHeight="100"
+                                height="{treeHeight}"
+                                borderVisible="false"
+                                borderColor="#CCCCCC"
+                                dataProvider="{effectsCollection}"
+                                rollOverColor="#FFFFFF88"
+                                selectionColor="#FFFFFFaa"
+                                
enterFrame="effectsTree_enterFrameHandler(event)"
+                                rowHeight="30">
+                       
+                       <mx:itemRenderer>
+                               <fx:Component>
+                                       <s:MXTreeItemRenderer 
xmlns:fx="http://ns.adobe.com/mxml/2009"; 
+                                                                               
  xmlns:s="library://ns.adobe.com/flex/spark" 
+                                                                               
  xmlns:mx="library://ns.adobe.com/flex/mx"
+                                                                               
  autoDrawBackground="false"
+                                                                               
  >
+                                               
+                                               <fx:Script>
+                                                       <![CDATA[
+                                                               import 
com.flexcapacitor.utils.StringUtils;
+                                                               
+                                                               import 
mx.core.mx_internal;
+                                                               import 
mx.effects.CompositeEffect;
+                                                               import 
mx.effects.Effect;
+                                                               import 
mx.effects.Pause;
+                                                               import 
mx.effects.Sequence;
+                                                               import 
mx.events.EffectEvent;
+                                                               
+                                                               use namespace 
mx_internal;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               [Bindable]
+                                                               private var 
item:Effect;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               [Bindable]
+                                                               private var 
compositeEffect:CompositeEffect;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               [Bindable]
+                                                               private var 
sequenceEffect:Sequence;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               [Bindable]
+                                                               private var 
isPaused:Boolean;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectStartCount:int;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectUpdateCount:int;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectStopCount:int;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectRepeatCount:int;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectEndCount:int;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectEnabledAlpha:int = 1;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private var 
effectDisabledAlpha:int = .9;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               public var 
playedOnceCharacter:String = " ";
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               public var 
eventPlayedColor:Number = 0x00FF00;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               public var 
eventColor:Number = 0x888888;
+                                                               
+                                                               /**
+                                                                * Show 
playhead time label
+                                                                * */
+                                                               public var 
showPlayheadTimeLabel:Boolean = true;
+                                                               
+                                                               /**
+                                                                * Show 
duration time label
+                                                                * */
+                                                               public var 
showDurationTimeLabel:Boolean = true;
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               override public 
function set data(value:Object):void {
+                                                                       
super.data = value;
+                                                                       
+                                                                       
+                                                                       // 
remove previous listeners
+                                                                       if 
(item) {
+                                                                               
removeListeners(item);
+                                                                               
compositeEffect = null;
+                                                                               
sequenceEffect = null;
+                                                                               
item = null;
+                                                                       }
+                                                                       
+                                                                       if 
(value==null) {
+                                                                               
return;
+                                                                       }
+                                                                       
+                                                                       if 
(value is Effect) {
+                                                                               
item = value as Effect;
+                                                                       }
+                                                                       
+                                                                       if 
(value is CompositeEffect) {
+                                                                               
compositeEffect = value as CompositeEffect;
+                                                                       }
+                                                                       
+                                                                       if 
(value is Sequence) {
+                                                                               
sequenceEffect = value as Sequence;
+                                                                       }
+                                                                       
+                                                                       
nameLabel.text = item.className;
+                                                                       
+                                                                       try {
+                                                                               
var idname:String = item["id"];
+                                                                               
if (idname) {
+                                                                               
        nameLabel.text = item.className + "." + idname;
+                                                                               
}
+                                                                               
trace("************found id=" + idname);
+                                                                       }
+                                                                       catch 
(e:*) {
+                                                                               
+                                                                       }
+                                                                       
+                                                                       
resetEffectEvents();
+                                                                       
+                                                                       // 
remove these at some point
+                                                                       
addListeners(item);
+                                                                       
+                                                                       
updateEffectStatus();
+                                                               }
+                                                               
+                                                               /**
+                                                                * Updates the 
controls as the effect or effect parent is playing
+                                                                * */
+                                                               private 
function updateEffectStatus(event:EffectEvent=null):void {
+                                                                       var 
type:String = event ? event.type : "";
+                                                                       var 
duration:int = compositeEffect ? compositeEffect.compositeDuration : 
item.duration;
+                                                                       var 
playheadTime:int = item.playheadTime;
+                                                                       var 
itemPlaying:Boolean = item.isPlaying;
+                                                                       var 
ancestorPlaying:Boolean = isAncestorPlaying(item);
+                                                                       var 
ancesterRoot:Effect = getItemRoot(item);
+                                                                       
+                                                                       
//playingLabel.text = "";
+                                                                       
+                                                                       
updateEffectEventCount(type);
+                                                                       
+                                                                       
+                                                                       // if 
composite or pause listen for start and end of child effects
+                                                                       if 
(compositeEffect || item is Pause) {
+                                                                               
+                                                                               
if (type==EffectEvent.EFFECT_START) {
+                                                                               
        addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true);
+                                                                               
}
+                                                                               
+                                                                               
if (type==EffectEvent.EFFECT_END) {
+                                                                               
        removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
+                                                                               
}
+                                                                       }
+                                                                       else if 
(type==EffectEvent.EFFECT_START) {
+                                                                               
if (item.parentCompositeEffect && 
+                                                                               
        item.parentCompositeEffect.isPlaying) {
+                                                                               
        //resetEffectEvents();
+                                                                               
}
+                                                                       }
+                                                                       
+                                                                       
+                                                                       
+                                                                       // get 
position in time
+                                                                       
playheadTimeLabel.text = sanitizeTime(playheadTime);
+                                                                       
durationLabel.text = sanitizeTime(duration, "seconds", 1);
+                                                                       
+                                                                       
+                                                                       // show 
or hide playhead time label
+                                                                       if 
(showPlayheadTimeLabel) {
+                                                                               
if (itemPlaying) {
+                                                                               
        playheadTimeLabel.visible = true;
+                                                                               
}
+                                                                               
else {
+                                                                               
        playheadTimeLabel.visible = false;
+                                                                               
}
+                                                                       }
+                                                                       else {
+                                                                               
playheadTimeLabel.visible = false;
+                                                                       }
+                                                                       
+                                                                       
+                                                                       // show 
or hide duration time label
+                                                                       if 
(showDurationTimeLabel) {
+                                                                               
if (duration==0) {
+                                                                               
        durationLabel.visible = false;
+                                                                               
}
+                                                                               
else {
+                                                                               
        durationLabel.visible = true;
+                                                                               
}
+                                                                       }
+                                                                       else {
+                                                                               
durationLabel.visible = false;
+                                                                       }
+                                                                       
+                                                                       
+                                                                       // 
update divider position
+                                                                       if 
(itemPlaying) {
+                                                                               
var position:int = (effectDurationRect.width*item.playheadTime)/duration;
+                                                                               
+                                                                               
if (isNaN(position)) {
+                                                                               
        position = 0;
+                                                                               
}
+                                                                               
+                                                                               
divider.x = position - divider.width/2;
+                                                                               
divider.visible = true;
+                                                                       }
+                                                                       else {
+                                                                               
divider.visible = false;
+                                                                       }
+                                                                       
+                                                                       
+                                                                       // 
check if need to show playing indicator
+                                                                       if 
(itemPlaying) {
+                                                                               
playingIndicator.visible = true;
+                                                                               
+                                                                               
if (isPaused) {
+                                                                               
        //playingLabel.text = "Paused";
+                                                                               
        playImage.enableBlink = true;
+                                                                               
}
+                                                                               
else {
+                                                                               
        //playingLabel.text = "Playing";
+                                                                               
        playImage.enableBlink = false;
+                                                                               
}
+                                                                               
+                                                                               
// if part of a composite effect that is also playing then disable controls
+                                                                               
if (ancestorPlaying) {
+                                                                               
        
+                                                                               
        if (playImage.source != Radii8LibraryEffectsAssets.pause) {
+                                                                               
                playImage.source = Radii8LibraryEffectsAssets.pause;
+                                                                               
        }
+                                                                               
        
+                                                                               
        //playingLabel.text += " (parent playing)";
+                                                                               
        playImage.enabled = false;
+                                                                               
        reverseImage.enabled = false;
+                                                                               
        stopImage.enabled = false;
+                                                                               
        endImage.enabled = false;
+                                                                               
}
+                                                                               
else {
+                                                                               
        
+                                                                               
        if (playImage.source != Radii8LibraryEffectsAssets.pause) {
+                                                                               
                playImage.source = Radii8LibraryEffectsAssets.pause;
+                                                                               
        }
+                                                                               
        
+                                                                               
        playImage.enabled = true;
+                                                                               
        reverseImage.enabled = true;
+                                                                               
        stopImage.enabled = true;
+                                                                               
        endImage.enabled = true;
+                                                                               
}
+                                                                               
+                                                                               
// select list item?
+                                                                               
//ListBase(treeListData.owner).selectedItem = data;
+                                                                       }
+                                                                       
+                                                                       // 
effect is not playing
+                                                                       else {
+                                                                               
+                                                                               
playingIndicator.visible = false;
+                                                                               
+                                                                               
// if part of a composite effect that is playing then disable controls
+                                                                               
if (ancestorPlaying) {
+                                                                               
        
+                                                                               
        if (playImage.source != Radii8LibraryEffectsAssets.play) {
+                                                                               
                playImage.source = Radii8LibraryEffectsAssets.play;
+                                                                               
        }
+                                                                               
        
+                                                                               
        //playingLabel.text += "(parent playing)";
+                                                                               
        
+                                                                               
        stopImage.enabled = false;
+                                                                               
        endImage.enabled = false;
+                                                                               
        playImage.enableBlink = false;
+                                                                               
        playImage.enabled = false;
+                                                                               
        reverseImage.enabled = false;
+                                                                               
}
+                                                                               
// no parent effect or parent effect is not playing
+                                                                               
else {
+                                                                               
        
+                                                                               
        if (playImage.source != Radii8LibraryEffectsAssets.play) {
+                                                                               
                playImage.source = Radii8LibraryEffectsAssets.play;
+                                                                               
        }
+                                                                               
        
+                                                                               
        //playingLabel.text += "Idle";
+                                                                               
        stopImage.enabled = false;
+                                                                               
        endImage.enabled = false;
+                                                                               
        playImage.enableBlink = false;
+                                                                               
        playImage.enabled = true;
+                                                                               
        reverseImage.enabled = true;
+                                                                               
}
+                                                                       }
+                                                                       
+                                                                       
+                                                                       
+                                                                       // 
effect ended - enable controls or wait and then enable controls
+                                                                       if 
(event && event.type==EffectEvent.EFFECT_END) {
+                                                                               
//trace("effect type=" + item.className);
+                                                                               
//trace("effect end");
+                                                                               
+                                                                               
if (sequenceEffect && sequenceEffect.children.length>4) {
+                                                                               
        //trace("more than one");
+                                                                               
}
+                                                                               
+                                                                               
// set back to play icon
+                                                                               
if (playImage.source != Radii8LibraryEffectsAssets.play) {
+                                                                               
        playImage.source = Radii8LibraryEffectsAssets.play;
+                                                                               
}
+                                                                               
+                                                                               
isPaused = false;
+                                                                               
playImage.enableBlink = false;
+                                                                               
playingIndicator.visible = false;
+                                                                               
+                                                                               
// if part of a composite effect that is also playing then disable controls 
until it's done
+                                                                               
if (ancestorPlaying) {
+                                                                               
        
+                                                                               
        // add listeners to ancestor effects to know when to enable controls 
again
+                                                                               
        if (item.parentCompositeEffect.isPlaying) {
+                                                                               
                
item.parentCompositeEffect.addEventListener(EffectEvent.EFFECT_END, 
enterFrameHandler);
+                                                                               
                //playImage.enabled = true;
+                                                                               
        }
+                                                                               
        else {
+                                                                               
                
item.parentCompositeEffect.removeEventListener(EffectEvent.EFFECT_END, 
enterFrameHandler);
+                                                                               
                playImage.enabled = true;
+                                                                               
                reverseImage.enabled = true;
+                                                                               
        }
+                                                                               
}
+                                                                               
+                                                                               
// no ancestor playing enable controls
+                                                                               
else {
+                                                                               
        playImage.enabled = true;
+                                                                               
        reverseImage.enabled = true;
+                                                                               
}
+                                                                               
+                                                                       }
+                                                                       
+                                                                       
//playingLabel.text += " " + type;
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               protected 
function playImage_clickHandler(event:MouseEvent):void {
+                                                                       if 
(item.parentCompositeEffect) {
+                                                                               
//item.pause();
+                                                                       }
+                                                                       
+                                                                       if 
(item.isPlaying) {
+                                                                               
+                                                                               
if (!isPaused) {
+                                                                               
        item.pause();
+                                                                               
        isPaused = true;
+                                                                               
}
+                                                                               
else {
+                                                                               
        item.resume();
+                                                                               
        isPaused = false;
+                                                                               
}
+                                                                       }
+                                                                       else {
+                                                                               
resetEffectEvents();
+                                                                               
item.play();
+                                                                       }
+                                                                       
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               protected 
function stopImage_clickHandler(event:MouseEvent):void {
+                                                                       
item.stop();
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               protected 
function endImage_clickHandler(event:MouseEvent):void {
+                                                                       
item.end();
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               protected 
function reverseImage_clickHandler(event:MouseEvent):void {
+                                                                       if 
(item.isPlaying) {
+                                                                               
item.reverse();
+                                                                       }
+                                                                       else {
+                                                                               
resetEffectEvents();
+                                                                               
item.play(null, true);
+                                                                       }
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               public function 
sanitizeTime(value:Number, units:String = "seconds", places:int = 2):String {
+                                                                       
+                                                                       if 
(units=="seconds") {
+                                                                               
value = value / 1000;
+                                                                       }
+                                                                       
+                                                                       return 
StringUtils.padLeft(value.toFixed(places), places, "0", true);
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private 
function enterFrameHandler(event:Event):void {
+                                                                       
updateEffectStatus();
+                                                                       
//trace("enterframe");
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private 
function resetEffectEvents():void {
+                                                                       
+                                                                       /* 
effectStartRect.alpha        = effectDisabledAlpha;
+                                                                       
effectUpdateRect.alpha  = effectDisabledAlpha;
+                                                                       
effectStopRect.alpha    = effectDisabledAlpha;
+                                                                       
effectRepeatRect.alpha  = effectDisabledAlpha;
+                                                                       
effectEndRect.alpha     = effectDisabledAlpha; */
+                                                                       
+                                                                       
effectStartLabel.text   = "";
+                                                                       
effectUpdateLabel.text  = "";
+                                                                       
effectEndLabel.text     = "";
+                                                                       
effectStopLabel.text    = "";
+                                                                       
effectRepeatLabel.text  = "";
+                                                                       
effectDurationRectFill.color = eventColor;
+                                                                       
+                                                                       
effectStartLabel.setStyle("backgroundColor",    eventColor);
+                                                                       
effectUpdateLabel.setStyle("backgroundColor",   eventColor);
+                                                                       
effectEndLabel.setStyle("backgroundColor",              eventColor);
+                                                                       
effectStopLabel.setStyle("backgroundColor",     eventColor);
+                                                                       
effectRepeatLabel.setStyle("backgroundColor",   eventColor);
+                                                                       
+                                                                       
effectStartCount        = 0;
+                                                                       
effectUpdateCount       = 0;
+                                                                       
effectStopCount         = 0;
+                                                                       
effectRepeatCount       = 0;
+                                                                       
effectEndCount          = 0;
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private 
function updateEffectEventCount(type:String):void {
+                                                                       
+                                                                       if 
(type==EffectEvent.EFFECT_START) {
+                                                                               
effectStartCount++;
+                                                                               
effectStartLabel.text = effectStartCount>1 ? String(effectStartCount) : 
playedOnceCharacter;
+                                                                               
effectStartLabel.setStyle("backgroundColor", eventPlayedColor);
+                                                                       }
+                                                                       else if 
(type==EffectEvent.EFFECT_UPDATE) {
+                                                                               
effectUpdateCount++;
+                                                                               
//effectUpdateLabel.text = effectUpdateCount>1 ? String(effectUpdateCount) : 
playedOnceCharacter;
+                                                                               
effectUpdateLabel.text = effectUpdateCount>1000 ? String(effectUpdateCount) : 
playedOnceCharacter;
+                                                                               
effectUpdateLabel.setStyle("backgroundColor", eventPlayedColor);
+                                                                       }
+                                                                       else if 
(type==EffectEvent.EFFECT_STOP) {
+                                                                               
effectStopCount++;
+                                                                               
effectStopLabel.text = effectStopCount>1 ? String(effectStopCount) : 
playedOnceCharacter;
+                                                                               
effectStopLabel.setStyle("backgroundColor", eventPlayedColor);
+                                                                       }
+                                                                       else if 
(type==EffectEvent.EFFECT_REPEAT) {
+                                                                               
effectRepeatCount++;
+                                                                               
effectRepeatLabel.text = effectRepeatCount>1 ? String(effectRepeatCount) : 
playedOnceCharacter;
+                                                                               
effectRepeatLabel.setStyle("backgroundColor", eventPlayedColor);
+                                                                       }
+                                                                       else if 
(type==EffectEvent.EFFECT_END) {
+                                                                               
effectEndCount++;
+                                                                               
effectEndLabel.text = effectEndCount>1 ? String(effectEndCount) : 
playedOnceCharacter;
+                                                                               
effectEndLabel.setStyle("backgroundColor", eventPlayedColor);
+                                                                       }
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private 
function removeListeners(item:Effect):void {
+                                                                       
+                                                                       
item.removeEventListener(EffectEvent.EFFECT_START,              
updateEffectStatus);
+                                                                       
item.removeEventListener(EffectEvent.EFFECT_UPDATE,     updateEffectStatus);
+                                                                       
item.removeEventListener(EffectEvent.EFFECT_END,                
updateEffectStatus);
+                                                                       
item.removeEventListener(EffectEvent.EFFECT_REPEAT,     updateEffectStatus);
+                                                                       
item.removeEventListener(EffectEvent.EFFECT_STOP,               
updateEffectStatus);
+                                                                       
+                                                                       
+                                                                       if 
(item.parentCompositeEffect) {
+                                                                               
item.parentCompositeEffect.removeEventListener(EffectEvent.EFFECT_START, 
parentStartEffectHandler);
+                                                                       }
+                                                                       
+                                                               }
+                                                               
+                                                               /**
+                                                                * 
+                                                                * */
+                                                               private 
function addListeners(item:Effect):void {
+                                                                       
+                                                                       
item.addEventListener(EffectEvent.EFFECT_START,         updateEffectStatus, 
false, 0, true);
+                                                                       
item.addEventListener(EffectEvent.EFFECT_UPDATE,        updateEffectStatus, 
false, 0, true);
+                                                                       
item.addEventListener(EffectEvent.EFFECT_END,           updateEffectStatus, 
false, 0, true);
+                                                                       
item.addEventListener(EffectEvent.EFFECT_REPEAT,        updateEffectStatus, 
false, 0, true);
+                                                                       
item.addEventListener(EffectEvent.EFFECT_STOP,          updateEffectStatus, 
false, 0, true);
+                                                                       
+                                                                       if 
(item.parentCompositeEffect) {
+                                                                               
item.parentCompositeEffect.addEventListener(EffectEvent.EFFECT_START, 
parentStartEffectHandler, false, 0, true);
+                                                                       }
+                                                               }
+                                                               
+                                                               /**
+                                                                * Reset effect 
counters when parent effect plays for the first time
+                                                                * */
+                                                               protected 
function parentStartEffectHandler(event:EffectEvent):void {
+                                                                       
resetEffectEvents();
+                                                               }
+                                                               
+                                                               /**
+                                                                * Reset effect 
counters when parent effect plays for the first time
+                                                                * */
+                                                               protected 
function clearImage_clickHandler(event:MouseEvent):void {
+                                                                       
resetEffectEvents();
+                                                               }
+                                                               
+                                                               /**
+                                                                * Check if 
ancestor effect is playing
+                                                                * */
+                                                               private 
function isAncestorPlaying(item:Effect):Boolean {
+                                                                       
+                                                                       while 
(item.parentCompositeEffect) {
+                                                                               
+                                                                               
if (item.parentCompositeEffect.isPlaying) {
+                                                                               
        return true;
+                                                                               
}
+                                                                               
item = item.parentCompositeEffect;
+                                                                       }
+                                                                       return 
false;
+                                                               }
+                                                               
+                                                               /**
+                                                                * Get greatest 
ancestor effect
+                                                                * */
+                                                               private 
function getItemRoot(item:Effect, isAlsoPlaying:Boolean = false):Effect {
+                                                                       var 
parentCompositeEffect:Effect = item.parentCompositeEffect;
+                                                                       var 
isPlaying:Boolean;
+                                                                       
+                                                                       
+                                                                       if 
(isAlsoPlaying) {
+                                                                               
+                                                                               
isPlaying = parentCompositeEffect ? parentCompositeEffect.isPlaying : false;
+                                                                               
+                                                                               
while (isPlaying) {
+                                                                               
        
+                                                                               
        if (parentCompositeEffect.parentCompositeEffect && 
parentCompositeEffect.parentCompositeEffect.isPlaying) {
+                                                                               
                parentCompositeEffect = 
parentCompositeEffect.parentCompositeEffect;
+                                                                               
        }
+                                                                               
        else {
+                                                                               
                return parentCompositeEffect;
+                                                                               
        }
+                                                                               
}
+                                                                               
+                                                                               
if (isPlaying) {
+                                                                               
        return parentCompositeEffect;
+                                                                               
}
+                                                                               
else {
+                                                                               
        return null;
+                                                                               
}
+                                                                       }
+                                                                       else {
+                                                                               
+                                                                               
while (parentCompositeEffect) {
+                                                                               
        
+                                                                               
        if (parentCompositeEffect.parentCompositeEffect) {
+                                                                               
                parentCompositeEffect = 
parentCompositeEffect.parentCompositeEffect;
+                                                                               
        }
+                                                                               
        else {
+                                                                               
                return parentCompositeEffect;
+                                                                               
        }
+                                                                               
}
+                                                                               
return parentCompositeEffect;
+                                                                       }
+                                                                       
+                                                                       return 
null;
+                                                               }
+                                                               
+                                                               protected 
function loopButton_changeHandler(event:Event):void {
+                                                                       
+                                                                       if 
(loopButton.selected) {
+                                                                               
item.repeatCount = 0;
+                                                                       }
+                                                                       else {
+                                                                               
item.repeatCount = 1;
+                                                                       }
+                                                               }
+                                                               
+                                                       ]]>
+                                               </fx:Script>
+                                               
+                                               <s:states>
+                                                       <s:State name="normal" 
/>            
+                                                       <s:State name="hovered" 
/>
+                                                       <s:State 
name="selected" />
+                                               </s:states>
+                                               
+                                               <s:HGroup left="1" right="1" 
top="1" bottom="1" verticalAlign="middle">
+                                                       
+                                                       <s:Rect 
id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" 
alpha="0">
+                                                               <s:fill>
+                                                                       
<s:SolidColor color="0xFFFFFF" />
+                                                               </s:fill>
+                                                       </s:Rect>
+                                                       
+                                                       <s:Group 
id="disclosureGroup"
+                                                                        
useHandCursor="true"
+                                                                        
buttonMode="true">
+                                                               <s:BitmapImage 
source="{treeListData.disclosureIcon}" 
+                                                                               
           visible="{treeListData.hasChildren}" 
+                                                                               
           />
+                                                       </s:Group>
+                                                       
+                                                       <!--<s:HGroup 
id="controlsGroup" 
+                                                                         
height="100%"
+                                                                         
paddingRight="8"
+                                                                         
verticalAlign="middle"
+                                                                         
width="80"
+                                                                         >
+                                                               
+                                                       </s:HGroup>
+                                                       -->
+                                                       
+                                                       <s:Label id="nameLabel" 
+                                                                        
text="" 
+                                                                        
paddingTop="2"/>
+                                                       
+                                                       <s:Spacer width="100%"/>
+                                                       
+                                                       <!-- Events-->
+                                                       <s:Group height="100%"
+                                                                        
width="100%">
+                                                               
+                                                               <s:HGroup 
width="100%"
+                                                                               
  height="100%"
+                                                                               
  paddingRight="8"
+                                                                               
  paddingTop="1"
+                                                                               
  paddingBottom="1"
+                                                                               
  verticalAlign="middle"
+                                                                               
  fontSize="10"
+                                                                               
  gap="1">
+                                                                       
+                                                                       
<controls:BlinkingImageButton id="playImage" 
+                                                                               
                                                  dim="true"
+                                                                               
                                                  
click="playImage_clickHandler(event)"
+                                                                               
                                                  useHandCursor="true"
+                                                                               
                                                  buttonMode="true"/>
+                                                                       
<s:Image id="reverseImage"
+                                                                               
         click="reverseImage_clickHandler(event)"
+                                                                               
         source="{Radii8LibraryEffectsAssets.reverse}" 
+                                                                               
         useHandCursor="true"
+                                                                               
         buttonMode="true"/>
+                                                                       
+                                                                       
<s:Image id="stopImage"
+                                                                               
         click="stopImage_clickHandler(event)"
+                                                                               
         source="{Radii8LibraryEffectsAssets.stop}"
+                                                                               
         useHandCursor="true"
+                                                                               
         buttonMode="true" />
+                                                                       
+                                                                       
<s:Image id="endImage"
+                                                                               
         click="endImage_clickHandler(event)"
+                                                                               
         source="{Radii8LibraryEffectsAssets.end}" 
+                                                                               
         useHandCursor="true"
+                                                                               
         buttonMode="true"/>
+                                                                       
+                                                                       
<s:Image id="clearImage"
+                                                                               
         click="clearImage_clickHandler(event)"
+                                                                               
         source="{Radii8LibraryEffectsAssets.clear}" 
+                                                                               
         useHandCursor="true"
+                                                                               
         buttonMode="true"/>
+                                                                       
+                                                                       
<s:ToggleButton id="loopButton" 
+                                                                               
                        skinClass="com.flexcapacitor.views.skins.LoopButton"
+                                                                               
                        change="loopButton_changeHandler(event)"
+                                                                               
                        useHandCursor="true"
+                                                                               
                        buttonMode="true"/>
+                                                                       
+                                                                       
<s:Spacer width="10" />
+                                                                       
+                                                                       
<s:BitmapImage id="playingIndicator" 
source="{Radii8LibraryEffectsAssets.selected}"  />
+                                                                       
+                                                                       
+                                                                       
<s:Label id="effectStartLabel"
+                                                                               
         backgroundColor="#00ff00"
+                                                                               
         height="100%" 
+                                                                               
         width="10" 
+                                                                               
         paddingTop="2"
+                                                                               
         textAlign="center"
+                                                                               
         verticalAlign="middle"/>
+                                                                       
+                                                                       
<s:Group width="250"
+                                                                               
         height="100%"
+                                                                               
         >
+                                                                               
+                                                                               
<s:Rect id="effectDurationRect" width="100%" percentHeight="100">
+                                                                               
        <s:fill>
+                                                                               
                <s:SolidColor id="effectDurationRectFill" color="0x00FF00" />
+                                                                               
        </s:fill>
+                                                                               
</s:Rect>
+                                                                               
+                                                                               
<s:BitmapImage id="divider" source="{Radii8LibraryEffectsAssets.playhead}" 
+                                                                               
                           height="100%"
+                                                                               
                           bottom="0"/>
+                                                                               
+                                                                               
<s:Spacer width="10"/>
+                                                                               
+                                                                               
<s:Label id="playheadTimeLabel" 
+                                                                               
                 text="" 
+                                                                               
                 paddingTop="2" 
+                                                                               
                 left="8"
+                                                                               
                 height="100%"
+                                                                               
                 verticalAlign="middle"
+                                                                               
                 color="white"/>
+                                                                               
+                                                                               
+                                                                               
<s:Label id="durationLabel" 
+                                                                               
                 text="" 
+                                                                               
                 paddingTop="2" 
+                                                                               
                 right="8"
+                                                                               
                 height="100%"
+                                                                               
                 verticalAlign="middle"
+                                                                               
                 color="white"/>
+                                                                               
+                                                                               
<s:HGroup width="100%" 
+                                                                               
                  height="100%"
+                                                                               
                  horizontalAlign="right"
+                                                                               
                  verticalAlign="middle"
+                                                                               
                  >
+                                                                               
</s:HGroup>
+                                                                       
</s:Group>
+                                                                       
+                                                                       
<s:Label id="effectEndLabel" 
+                                                                               
         backgroundColor="#00ff00"
+                                                                               
         paddingTop="2" 
+                                                                               
         height="100%"
+                                                                               
         width="10"
+                                                                               
         textAlign="center"
+                                                                               
         verticalAlign="middle"/>
+                                                                       
+                                                                       
<s:Spacer width="10" />
+                                                                       
+                                                                       
<s:Label id="effectStopLabel" 
+                                                                               
         backgroundColor="#00ff00"
+                                                                               
         paddingTop="2"
+                                                                               
         height="100%" 
+                                                                               
         width="10"
+                                                                               
         textAlign="center"
+                                                                               
         verticalAlign="middle"/>
+                                                                       
<s:Label id="effectRepeatLabel" 
+                                                                               
         backgroundColor="#00ff00"
+                                                                               
         paddingTop="2" 
+                                                                               
         height="100%"
+                                                                               
         width="10"
+                                                                               
         textAlign="center"
+                                                                               
         verticalAlign="middle"/>
+                                                                       
<s:Label id="effectUpdateLabel" 
+                                                                               
         backgroundColor="#00ff00"
+                                                                               
         paddingTop="2"
+                                                                               
         height="100%"
+                                                                               
         width="10"
+                                                                               
         includeInLayout="false"
+                                                                               
         visible="false"
+                                                                               
         maxDisplayedLines="1"
+                                                                               
         textAlign="center"
+                                                                               
         verticalAlign="middle"/>
+                                                               </s:HGroup>
+                                                       </s:Group>
+                                                       
+                                               </s:HGroup>
+                                               
+                                               
+                                               
+                                               <s:HGroup width="100%"
+                                                                 height="100%"
+                                                                 
paddingRight="8"
+                                                                 gap="1"
+                                                                 
visible="false"
+                                                                 
includeInLayout="false">
+                                                       
+                                                       <s:Rect 
id="effectStartRect" width="10" percentHeight="100">
+                                                               <s:fill>
+                                                                       
<s:SolidColor color="0x00FF00" />
+                                                               </s:fill>
+                                                       </s:Rect>
+                                                       <s:Rect 
id="effectUpdateRect" width="10" percentHeight="100">
+                                                               <s:fill>
+                                                                       
<s:SolidColor color="0x00FF00" />
+                                                               </s:fill>
+                                                       </s:Rect>
+                                                       <s:Rect 
id="effectEndRect" width="10" percentHeight="100">
+                                                               <s:fill>
+                                                                       
<s:SolidColor color="0x00FF00" />
+                                                               </s:fill>
+                                                       </s:Rect>
+                                                       <s:Rect 
id="effectStopRect" width="10" percentHeight="100">
+                                                               <s:fill>
+                                                                       
<s:SolidColor color="0x00FF00" />
+                                                               </s:fill>
+                                                       </s:Rect>
+                                                       <s:Rect 
id="effectRepeatRect" width="10" percentHeight="100">
+                                                               <s:fill>
+                                                                       
<s:SolidColor color="0x00FF00" />
+                                                               </s:fill>
+                                                       </s:Rect>
+                                               </s:HGroup>
+                                       </s:MXTreeItemRenderer>
+                               </fx:Component>
+                       </mx:itemRenderer>
+               </mx:Tree>
+       </s:VGroup>
+</s:Group>

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/EventListeners.mxml
----------------------------------------------------------------------
diff --git 
a/Radii8Library/src/com/flexcapacitor/views/panels/EventListeners.mxml 
b/Radii8Library/src/com/flexcapacitor/views/panels/EventListeners.mxml
new file mode 100644
index 0000000..ad1e691
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/panels/EventListeners.mxml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<s:Group xmlns:fc="com.flexcapacitor.controls.*"
+                xmlns:fx="http://ns.adobe.com/mxml/2009"; 
+                xmlns:local="*"
+                xmlns:mx="library://ns.adobe.com/flex/mx"
+                xmlns:s="library://ns.adobe.com/flex/spark"
+                xmlns:utils="com.flexcapacitor.utils.*" 
+                xmlns:handlers="com.flexcapacitor.handlers.*"
+                
xmlns:supportClasses="com.flexcapacitor.effects.supportClasses.*"
+                
+                styleName="constraintStyles"
+                creationComplete="creationCompleteHandler(event)"
+                width="100%"
+                height="100%"
+                >
+       <!--- 
+       http://dougmccune.com/blog/source-code-license/
+       
+       Any source code released on this blog, unless otherwise explicitly 
noted, is licensed under the MIT license:
+       Copyright (c) 2013 Doug McCune
+       
+       Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files (the “Software”), 
to deal in the Software without restriction, including without limitation the 
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
sell copies of the Software, and to permit persons to whom the Software is 
furnished to do so, subject to the following conditions:
+       
+       The above copyright notice and this permission notice shall be included 
in all copies or substantial portions of the Software.
+       
+       THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
OR OTHER
+       LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE SOFTWARE.
+
+       
http://dougmccune.com/blog/2008/02/21/monkey-patching-flexsprite-to-list-all-event-listeners-on-any-flex-component/
+       -->
+       
+
+               <fx:Style>
+                       @namespace s "library://ns.adobe.com/flex/spark";
+                       @namespace fc "com.flexcapacitor.controls.*";
+                       @namespace local "*";
+                       @namespace mx "library://ns.adobe.com/flex/mx";
+                       @namespace utils "com.flexcapacitor.utils.*";
+                       @namespace handlers "com.flexcapacitor.handlers.*";
+                       @namespace supportClasses 
"com.flexcapacitor.effects.supportClasses.*";
+                       
+                       .constraintStyles {
+                               fontSize:12;
+                       }
+                       .inputStyles {
+                               fontSize:12;
+                               focusAlpha : 0;
+                               borderColor: #b8b8b8;
+                       }
+               </fx:Style>
+       
+       <fx:Script>
+               <![CDATA[
+                       import com.flexcapacitor.controller.Radiate;
+                       import com.flexcapacitor.events.RadiateEvent;
+                       
+                       import mx.core.FlexSprite;
+                       import mx.core.IVisualElement;
+                       import mx.events.FlexEvent;
+                       
+                       
+                       public var radiate:Radiate;
+                       
+                       protected function 
creationCompleteHandler(event:FlexEvent):void {
+                               target = null;
+                               
+                               var radiate:Radiate = Radiate.getInstance();
+                               
radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler);
+                               
radiate.addEventListener(RadiateEvent.PROPERTY_CHANGED, propertyChangeHandler);
+                               
radiate.addEventListener(RadiateEvent.HISTORY_CHANGE, historyChangeHandler);
+                               
+                               if (radiate.target) {
+                                       target = radiate.target as FlexSprite;
+                                       
+                                       if (target is FlexSprite) {
+                                               showEventListeners(target as 
FlexSprite);
+                                       }
+                               }
+                       }
+                       
+                       private var _target:FlexSprite;
+                       private var _visualElement:IVisualElement;
+                       public function get target():FlexSprite {
+                               return _target;
+                       }
+
+                       [Bindable]
+                       public function set target(value:FlexSprite):void {
+                               
+                               if (!(value is FlexSprite)) {
+                                       _target = null;
+                                       return;
+                               }
+                               
+                               _target = value;
+                       }
+                       
+                       /**
+                        * Get current target
+                        * */
+                       protected function 
targetChangeHandler(event:RadiateEvent):void {
+                               target = event.selectedItem as FlexSprite;
+                               
+                               showEventListeners(target);
+                       }
+                       
+                       /**
+                        * Updates the view when a property is changed 
externally
+                        * */
+                       protected function 
propertyChangeHandler(event:RadiateEvent):void {
+                               var properties:Array = event.properties;
+                               var length:int = event.properties.length;
+                               
+                               if (!target) return;
+                               
+                               for (var i:int;i<length;i++) {
+                                       if 
(watchedProperties.indexOf(properties[i])!=-1) {
+                                               //updateView();
+                                               break;
+                                       }
+                               }
+                       }
+                       
+                       protected function 
historyChangeHandler(event:RadiateEvent):void {
+                               if (event.newIndex==-1 || 
!event.historyEventItem) return;
+                               var properties:Array = 
event.historyEventItem.properties;
+                               var length:int = properties ? properties.length 
: 0;
+                               
+                               if (!target) return;
+                               
+                               for (var i:int;i<length;i++) {
+                                       if 
(watchedProperties.indexOf(properties[i])!=-1) {
+                                               //updateView();
+                                               break;
+                                       }
+                               }
+                       }
+                       
+                       private const watchedProperties:Array = [ "width", 
"height", "percentWidth", "percentHeight", "x",
+                                                                               
                        "y", "top", "left", "right", "bottom", "verticalCenter",
+                                                                               
                        "horizontalCenter", "baseline"]
+               
+                       /**
+                        * Show event listeners on target.
+                        * */
+                       public function showEventListeners(sprite:FlexSprite): 
void {
+                               this.sprite = sprite; 
+                               grid.dataProvider = sprite != null ? 
Object(sprite).eventListeners : null;
+                               grid.selectedIndex = 0;
+                               
+                               if (grid.dataProvider.length>0) {
+                                       selectedTracker = 
grid.dataProvider[0];// as ListenerTracker;
+                               }
+                       }
+                       
+                       private var sprite:FlexSprite;
+                       
+                       public function removeListener(listener:Object):void {
+                       //public function 
removeListener(listener:ListenerTracker):void {
+                               sprite.removeEventListener(listener.type, 
listener.listener, listener.useCapture);
+                               
+                               grid.dataProvider = 
Object(sprite).eventListeners;
+                       }
+                       
+                       private function removeAll():void {
+                               if (sprite) {
+                                       
Object(sprite).removeAllEventListeners();
+                                       grid.dataProvider = 
Object(sprite).eventListeners;
+                               }
+                       }
+                       
+                       [Bindable]
+                       //private var selectedTracker:ListenerTracker;
+                       private var selectedTracker:Object;
+               ]]>
+       </fx:Script>
+               
+       <s:layout>
+               <s:VerticalLayout paddingRight="10"/>
+       </s:layout>
+
+       <s:Button label="Remove All Event Listeners" click="removeAll()" />
+       
+       <mx:DataGrid id="grid" 
+                                width="100%" 
+                                minWidth="100"
+                                minHeight="100"
+                                change="selectedTracker = grid.selectedItem"
+                                >
+                                <!--change="selectedTracker = 
grid.selectedItem as ListenerTracker"-->
+               <mx:columns>
+                       <mx:DataGridColumn dataField="type" headerText="Type" />
+                       <mx:DataGridColumn dataField="callingClassName" 
headerText="Added By" />
+
+                       <mx:DataGridColumn dataField="type" headerText="" 
width="50" >
+                               <mx:itemRenderer>
+                                       <fx:Component>
+                                               <!--<mx:Button label="Remove" 
click="outerDocument.removeListener(data as mx.core.ListenerTracker)" />-->
+                                               <mx:Button label="Remove" 
click="outerDocument.removeListener(data)" />
+                                       </fx:Component>
+                               </mx:itemRenderer>
+                       </mx:DataGridColumn>
+               </mx:columns>
+       </mx:DataGrid>
+       
+       <mx:Panel title="Details: {selectedTracker.type}" 
+                         width="100%" 
+                         height="100%" 
+                         minHeight="150"
+                         minWidth="100"
+                         dropShadowVisible="false"
+                         >
+               <mx:Form width="100%" height="100%">
+                       <mx:FormItem label="Type">
+                               <mx:Label text="{selectedTracker.type}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Added by">
+                               <mx:Label 
text="{selectedTracker.callingClassName}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Method">
+                               <mx:Label 
text="{selectedTracker.callingMethod}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Line">
+                               <mx:Label 
text="{selectedTracker.callingLineNumber}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Priority">
+                               <mx:Label text="{selectedTracker.priority}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Use Capture">
+                               <mx:Label text="{selectedTracker.useCapture}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Weak Reference">
+                               <mx:Label 
text="{selectedTracker.useWeakReference}" />
+                       </mx:FormItem>
+                       <mx:FormItem label="Time Created">
+                               <mx:Label text="{selectedTracker.timeCreated}" 
/>
+                       </mx:FormItem>
+               </mx:Form>
+       </mx:Panel>
+
+</s:Group>

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/Events.mxml
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/Events.mxml 
b/Radii8Library/src/com/flexcapacitor/views/panels/Events.mxml
new file mode 100644
index 0000000..276147a
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/panels/Events.mxml
@@ -0,0 +1,832 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"; 
+                xmlns:s="library://ns.adobe.com/flex/spark" 
+                xmlns:mx="library://ns.adobe.com/flex/mx" 
+                xmlns:c="com.flexcapacitor.controls.*"
+                xmlns:handlers="com.flexcapacitor.handlers.*" 
+                xmlns:collections="com.flexcapacitor.effects.collections.*"
+                
+                minWidth="200" 
+                minHeight="100"
+                creationComplete="group1_creationCompleteHandler(event)"
+                >
+       
+       
+       <!-- 
+       TODO:
+       
+       
+       -->
+       
+       <fx:Script>
+               <![CDATA[
+                       import com.flexcapacitor.controller.Radiate;
+                       import com.flexcapacitor.events.RadiateEvent;
+                       import com.flexcapacitor.model.EventMetaData;
+                       import com.flexcapacitor.model.MetaData;
+                       import com.flexcapacitor.utils.ClassUtils;
+                       import com.flexcapacitor.utils.InspectorUtils;
+                       import com.flexcapacitor.utils.TypeUtils;
+                       
+                       import mx.collections.XMLListCollection;
+                       import mx.core.IDataRenderer;
+                       import mx.core.UIComponent;
+                       import mx.effects.effectClasses.PropertyChanges;
+                       import mx.events.FlexEvent;
+                       import mx.utils.ObjectUtil;
+                       
+                       import spark.collections.Sort;
+                       import spark.collections.SortField;
+                       import 
spark.components.gridClasses.DefaultGridItemEditor;
+                       import spark.components.gridClasses.GridColumn;
+                       import spark.events.GridItemEditorEvent;
+                       import spark.events.GridSelectionEvent;
+                       import spark.events.TextOperationEvent;
+                       
+                       import 
flashx.textLayout.operations.SplitParagraphOperation;
+                       
+                       
+                       public var CUSTOM_ITEM_SORT_CHARACTER:String = "~";
+                       
+                       private var allItems:XMLListCollection = new 
XMLListCollection();
+                       private var objectPropertiesList:XMLListCollection = 
new XMLListCollection();
+                       private var _dataProviderProperties:XMLListCollection;
+                       
+                       public var describedTypeXML:XML;
+                       
+                       
+                       
+                       protected function 
group1_creationCompleteHandler(event:FlexEvent):void {
+                               radiate = Radiate.getInstance();
+                               
+                               if (!showHeader) {
+                                       
//propertiesGrid.columnHeaderGroup.visible = showHeader;
+                                       eventsGrid.columnHeaderGroup.height = 
hiddenHeaderHeight;
+                               }
+                               
+                               
radiate.addEventListener(RadiateEvent.TARGET_CHANGE, handleTargetChange);
+                               
radiate.addEventListener(RadiateEvent.PROPERTY_CHANGED, propertyChangeHandler);
+                               
+                               if (radiate.target) {
+                                       target = radiate.target;
+                               }
+                               
+                       }
+                       
+                       protected function 
handleTargetChange(event:RadiateEvent):void {
+                               target = event.selectedItem;
+                       }
+                       
+                       public function get 
dataProviderProperties():XMLListCollection {
+                               return _dataProviderProperties;
+                       }
+                       
+                       [Bindable]
+                       public function set 
dataProviderProperties(value:XMLListCollection):void {
+                               if (_dataProviderProperties) {
+                                       _dataProviderProperties = new 
XMLListCollection(new XMLList());
+                               }
+                               
+                               value.sort = new Sort();
+                               value.sort.fields = [ new SortField("@name", 
false)];
+                               value.refresh();
+                               _dataProviderProperties = value;
+                       }
+                       
+                       /**
+                        * Get Name or ID of target object
+                        * */
+                       public function getName(element:Object):String {
+                               var id:String;
+                               
+                               if (element is UIComponent && element.id != 
null) {
+                                       id = UIComponent(element).id;
+                               }
+                               else if (element.hasOwnProperty("id") && 
element.id != null) {
+                                       id = element.id;
+                               }
+                               else if (element.hasOwnProperty("name") && 
element.name != null) {
+                                       id = element.name;
+                               }
+                               else {
+                                       id = "";
+                               }
+                               return id;
+                       }
+                       
+                       /**
+                        * Populates the datagrid with all the properties that 
describe type returns for the given object
+                        * */
+                       public function 
populatePropertiesGrid(target:Object):void {
+                               var eventsList:XMLListCollection;
+                               var propertyName:String;
+                               var fontLookup:String;
+                               var fontFamily:String;
+                               var renderingMode:String;
+                               var properties:String;
+                               var inheritingStyles:Object;
+                               var nonInheritingStyles:Object;
+                               var property:String;
+                               var item:XML;
+                               
+                               if (target != null) {
+                                       //describedTypeXML = 
describeType(target);
+                                       //var type:Type = 
Type.forInstance(target);
+                                       //var type2:Type = 
Type.forName(type.extendsClasses[0]);
+                                       //describedTypeXML = 
describeType(getDefinitionByName(type.extendsClasses[0]));
+                                       //var describedType:XML = 
ClassUtils.describeTypeCache(target);
+                                       var data:XMLList = 
ClassUtils.concatenateMetaDataXMLItems(target, "Event", new XMLList());
+                                       
+                                       //describedTypeXML = 
describeType(target);
+                                       eventsList = new 
XMLListCollection(data);
+                                       
+                                       // ADD ACCESSORS LIST
+                                       allItems.addAll(eventsList);
+                                       
+                                       // if item is an object enumerate 
+                                       /*if (describedTypeXML.@name=="Object") 
{
+                                               for (property in target) {
+                                                       item = 
createXMLItem(property, target[property], true, true);
+                                                       
objectPropertiesList.addItem(item); // we could use allItems.addItem();
+                                               }
+                                       }*/
+                                       
+                                       //allItems.addAll(objectPropertiesList);
+                                       
+                                       /* var blah:Object = 
getMemberNames(this, true);
+                                       blah = getMemberNames(this);
+                                       blah = nonInheritingStyles;
+                                       blah = styleDeclaration;
+                                       blah = styleName;
+                                       blah = styleManager.inheritingStyles;
+                                       blah = 
styleManager.qualifiedTypeSelectors;
+                                       blah = styleManager.selectors;
+                                       blah = styleManager.stylesRoot;
+                                       blah = styleManager.typeHierarchyCache;
+                                       blah = styleManager.typeSelectorCache;
+                                       blah = 
styleManager.hasAdvancedSelectors(); */
+                                       
+                                       if (filterInput) filterInput.text = "";
+                                       
+                                       // we check for the text flow property 
so we can see if fonts are embedded
+                                       if (target.hasOwnProperty("textFlow")) {
+                                               /* if 
(target.textFlow.computedFormat) {
+                                                       fontLookup = 
target.textFlow.computedFormat.fontLookup;
+                                                       fontFamily = 
target.textFlow.computedFormat.fontFamily;
+                                                       renderingMode = 
target.textFlow.computedFormat.renderingMode;
+                                                       fontLookup = "<accessor 
name='fontLookup' value='" + fontLookup + "'/>";
+                                                       fontFamily = "<accessor 
name='fontFamily' value='" + fontFamily + "'/>";
+                                                       renderingMode = 
"<accessor name='renderingMode' value='" + renderingMode + "'/>";
+                                                       properties = fontLookup 
+ fontFamily + renderingMode + propertiesList.toString();
+                                                       propertiesList = new 
XMLList(properties);
+                                               } */
+                                       }
+                                       
+                                       //allItems.addAll(propertiesList);
+                                       
+                                       // attempts to get the values of the 
properties on the current target
+                                       for each (var node:XML in allItems) {
+                                               propertyName = node.@name;
+                                               
+                                               if (node.@access != 
"writeonly") {
+                                                       
+                                                       if (propertyName in 
target) {
+                                                               
+                                                               try {
+                                                                       
node.@value = target[propertyName];
+                                                                       
node.@isObject = (target[propertyName] is Object);
+                                                               }
+                                                               catch 
(error:Error) {
+                                                                       
node.@value = error.message;
+                                                                       
node.@valueError = true;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       
+                                       // Add in inheriting styles
+                                       /*if ("inheritingStyles" in target) {
+                                               inheritingStyles = 
target.inheritingStyles as Object;
+                                               
+                                               for (property in 
inheritingStyles) {
+                                                       item = 
createXMLItem(property, inheritingStyles[property], true, true);
+                                                       
inheritingStylesList.addItem(item);
+                                               }
+                                               
+                                               //trace("Inheriting style 
count", inheritingStylesList.length);
+                                               
+                                               
//allItems.addAll(inheritingStylesList);
+                                       }*/
+                                       
+                                       // Add in non inheriting styles - 
+                                       /*if 
(target.hasOwnProperty("nonInheritingStyles")) {
+                                               nonInheritingStyles = 
target.nonInheritingStyles as Object;
+                                               
+                                               for (property in 
nonInheritingStyles) {
+                                                       item = 
createXMLItem(property, nonInheritingStyles[property], true, false);
+                                                       
nonInheritingStylesList.addItem(item);
+                                               }
+                                               
+                                               //trace("Non-Inheriting style 
count", nonInheritingStylesList.length);
+                                               
+                                               
//allItems.addAll(nonInheritingStylesList);
+                                       }*/
+                                       
+                                       // create an item for unnamed style
+                                       var customItem:XML = 
createXMLItem(CUSTOM_ITEM_SORT_CHARACTER, "");
+                                       customItem.@search = true;
+                                       //allItems.addItem(customItem);
+                                       
+                                       dataProviderProperties = allItems;
+                               }
+                               else {
+                                       dataProviderProperties = new 
XMLListCollection();
+                               }
+                       }
+                       
+                       private var _target:Object;
+                       
+                       public function get target():Object {
+                               return _target;
+                       }
+                       
+                       [Bindable]
+                       public function set target(value:Object):void {
+                               
+                               _target = value;
+                               
+                               if (_target) {
+                                       clear();
+                                       populatePropertiesGrid(_target);
+                               }
+                               else {
+                                       clear();
+                               }
+                       }
+                       
+                       public function createXMLItem(name:String, value:*, 
style:Boolean=false, inheriting:Boolean=false):XML {
+                               var xml:XML = <accessor />;
+                               xml.@name = name;
+                               xml.@style = style;
+                               xml.@inheriting = inheriting;
+                               xml.@access = "readwrite";
+                               xml.@type = InspectorUtils.getValueType(value);
+                               xml.@value = String(value);
+                               return xml;
+                       }
+                       
+                       protected function 
filterDisplayObjectChangeHandler(item:XML):Boolean {
+                               var itemName:String = item.attribute("name") ? 
item.attribute("name") : "";
+                               var value:String = filterInput.text;
+                               
+                               if (itemName.toLowerCase().indexOf(value) != 
-1) {
+                                       return true;
+                               }
+                               return false;
+                       }
+                       
+                       /**
+                        * Filters the property list
+                        * if we type a period or a space at the end of the 
word then 
+                        * the value and the name have to match exactly 
(case-insensitive)
+                        * */
+                       protected function 
filterPropertyChangeHandler(item:XML):Boolean {
+                               var itemName:String = item.attribute("name") ? 
item.attribute("name") : "";
+                               var value:String = filterInput.text;
+                               var valueLength:int = value.length;
+                               var itemNameLength:int = itemName.length;
+                               var valueLowerCase:String = value.toLowerCase();
+                               var itemNameLowerCase:String = 
itemName.toLowerCase();
+                               
+                               // show all items if search is empty
+                               if (valueLength==0) {
+                                       return true;
+                               }
+                               
+                               // show custom item in case of style
+                               /*if (item.@search=="true") {
+                                       item.@name = CUSTOM_ITEM_SORT_CHARACTER 
+ value;
+                                       
filteredPropertiesCollection.enableAutoUpdate();
+                                       return true;
+                               }
+                               else {
+                                       
filteredPropertiesCollection.disableAutoUpdate();
+                               }*/
+                               
+                               // if we type a period or a space at the end of 
the word then 
+                               // the value and the name have to match exactly 
(case-insensitive)
+                               if (value.lastIndexOf(".")==valueLength-1 || 
value.lastIndexOf(" ")==valueLength-1) {
+                                       if 
(itemNameLowerCase+"."==valueLowerCase || itemNameLowerCase+" 
"==valueLowerCase) {
+                                               return true;
+                                       }
+                                       else {
+                                               return false;
+                                       }
+                               }
+                               
+                               // we filter from any index
+                               if (itemNameLowerCase.indexOf(valueLowerCase) 
!= -1) {
+                                       return true;
+                               }
+                               
+                               return false;
+                       }
+                       
+                       protected function 
findPropertyChangeHandler(event:TextOperationEvent):void {
+                               filteredPropertiesCollection.refresh();
+                       }
+                       
+                       /**
+                        * Attempts to drill into the selected property
+                        * */
+                       protected function 
gridDoubleClickHandler(event:MouseEvent):void {
+                               
+                               return;
+                               // if the user switches applications and the 
editor is not closed
+                               // we get the text control of the editor. we 
don't want that so return
+                               if (!(event.target is IDataRenderer)) return;
+                               
+                               var instance:Object = event.currentTarget;
+                               var itemRenderer:IDataRenderer = 
IDataRenderer(event.target);
+                               var data:XML = itemRenderer.data as XML;
+                               
+                               // this is a check for double click on 
dataGridColumn
+                               if (data==null) return;
+                               var currentValue:String = String(data.@value);
+                               var propertyName:String = data.@name;
+                               var type:String = String(data.@type);
+                               var something:*;
+                               
+                               if (propertyName in target) {
+                                       something = target[propertyName];
+                                       
+                                       // if object set new target
+                                       if (!ObjectUtil.isSimple(something)) {
+                                               target = something;
+                                               
radiate.dispatchTargetChangeEvent(something);
+                                               
//InspectorUtils.dispatchTargetChangeEvent(something, this);
+                                       }
+                               }
+                       }
+                       
+                       protected function 
propertiesGrid_itemEditEndHandler(oldValue:Object, newValue:Object, 
editor:DefaultGridItemEditor):void {
+                               throw new Error("Is this used?");
+                               var instance:Object = editor.column.itemEditor;
+                               if (instance==null) return;
+                               var data:XML = editor.column.grid.selectedItem 
as XML; //event.itemRenderer.data as XML;
+                               var currentValue:String = 
String(data[editor.column.dataField]);
+                               var propertyName:String = data.@name;
+                               var searchField:String = data.@search;
+                               var isSearchField:Boolean = searchField=="" || 
searchField==null ? false : searchField as Boolean;;
+                               var type:String = String(data.@type);
+                               var styleAttribute:String = data.@style;
+                               var isStyle:Boolean = styleAttribute=="" || 
styleAttribute==null ? false : styleAttribute as Boolean;
+                               var newAssignedValue:*;
+                               var isChanged:Boolean;
+                               
+                               if (isSearchField) {
+                                       propertyName = 
propertyName.replace(CUSTOM_ITEM_SORT_CHARACTER, "");
+                                       isStyle = true;
+                               }
+                               
+                               if (target) {
+                                       newAssignedValue = 
TypeUtils.getTypedValue(newValue, type)
+                                       
+                                       
InspectorUtils.setTargetProperty(target, propertyName, newAssignedValue, type, 
isStyle);
+                                       
+                               }
+                               
+                               callLater(maintainFocus);
+                       }
+                       
+                       private function maintainFocus():void {
+                               //propertiesGrid.editedItemPosition = null;
+                       }
+
+                       protected function 
filterInput_enterHandler(event:FlexEvent):void {
+                               var searchText:String = filterInput.text;
+                               var item:XML;
+                               
+                               if (filteredPropertiesCollection.length==1) {
+                                       item = 
filteredPropertiesCollection.getItemAt(0) as XML;
+                                       if (item) {
+                                               item.@value = target is 
UIComponent ? UIComponent(target).getStyle(searchText) : "";
+                                               
filteredPropertiesCollection.itemUpdated(item, "@value");
+                                               
filteredPropertiesCollection.refresh();
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Called when... 
+                        * */
+                       protected function 
changeHandler(event:GridItemEditorEvent):void {
+                               
+                               // This could probably all be rewritten
+                               // we could use inspector utils setProperty
+                               // ... 
+                               //trace("");
+                               var column:GridColumn = event.column;
+                               if 
(column.grid.dataGrid.itemEditorInstance==null) return;
+                               var data:XML = event.currentTarget.selectedItem 
as XML; //event.itemRenderer.data as XML;
+                               var currentValue:String = 
String(data[column.dataField]);
+                               var propertyName:String = data.@name;
+                               var searchField:String = data.@search;
+                               var isSearchField:Boolean = searchField=="" || 
searchField==null ? false : searchField as Boolean;;
+                               var type:String = String(data.@type);
+                               var styleAttribute:String = data.@style;
+                               var isStyle:Boolean = styleAttribute=="" || 
styleAttribute==null ? false : styleAttribute as Boolean;
+                               var newValue:* = 
DefaultGridItemEditor(column.grid.dataGrid.itemEditorInstance).value;
+                               
+                               if (isSearchField) {
+                                       propertyName = 
propertyName.replace(CUSTOM_ITEM_SORT_CHARACTER, "");
+                                       isStyle = true;
+                               }
+                               
+                               if (target) {
+                                       newValue = 
TypeUtils.getTypedValue(newValue, type)
+                                       
+                                       
InspectorUtils.setTargetProperty(target, propertyName, newValue, type, isStyle);
+                               }
+                               
+                       }
+                       
+                       [Bindable]
+                       public var showSearchBox:Boolean = true;
+                       
+                       [Bindable]
+                       public var showValueBox:Boolean = true;
+                       
+                       [Bindable]
+                       public var showHeader:Boolean = false;
+                       
+                       /**
+                        * Reference to Radiate
+                        * */
+                       public var radiate:Radiate;
+                       
+                       /**
+                        * Height of the header when not show (to allow 
resizing of columns)
+                        * */
+                       public var hiddenHeaderHeight:uint = 0;
+
+                       
+                       /**
+                        * 
+                        * */
+                       public function clear():void {
+                               
+                               allItems.removeAll();
+                               allItems.refresh();
+                               filterInput.text = "";
+                               targetValueText.text = "";
+                               dataProviderProperties = new 
XMLListCollection();
+                       }
+                       /*
+                       protected function 
saveSessionHandler(event:GridItemEditorEvent):void {
+                               //trace("Save session");
+                               var item:XML = 
eventsGrid.dataProvider.getItemAt(event.rowIndex) as XML;
+                               var value:String = String(item.@value);
+                               var property:String = String(item.@name);
+                               
+                               //trace("New Value= ", value);
+                               Radiate.setProperty(target, property, value);
+                       }*/
+                       /*
+                       protected function 
startSessionHandler(event:GridItemEditorEvent):void {
+                               //trace("Start session");
+                       }
+                       *//*
+                       protected function 
savingSessionHandler(event:GridItemEditorEvent):void
+                       {
+                               //trace("Saving session");
+                       }*/
+                       /*
+                       protected function 
startingSessionHandler(event:GridItemEditorEvent):void
+                       {
+                               //trace("Starting session");
+                               var item:XML = 
eventsGrid.dataProvider.getItemAt(event.rowIndex) as XML;
+                               if (String(item.@access).indexOf("write")<0) {
+                                       // event.preventDefault();
+                                       // NOTIFY OF READ ONLY 
+                               }
+                       }*/
+                       
+                       protected function 
propertyChangeHandler(event:RadiateEvent):void
+                       {
+                               // radiate property change event
+                               updatePropertyChangeValue(event.changes);
+                       }
+                       
+                       protected function 
targetValueText_keyUpHandler(event:KeyboardEvent):void {
+                               if (event.keyCode==Keyboard.ENTER) {
+                                       updateTargetValue();
+                                       event.preventDefault();
+                               }
+                               else if (event.keyCode==Keyboard.ESCAPE) {
+                                       var item:XML = eventsGrid.selectedItem 
as XML;
+                                       var value:String = String(item.@value);
+                                       targetValueText.text = value;
+                                       event.preventDefault();
+                               }
+                       }
+                       
+                       /**
+                        * Set the property to the value in the textarea.
+                        * */
+                       public function updateTargetValue():void {
+                               var item:XML = eventsGrid.selectedItem as XML;
+                               var actualValue:*;
+                               
+                               if (item) {
+                                       var value:String = String(item.@value);
+                                       var property:String = 
String(item.@name);
+                                       var propertyType:String = 
String(item.@type);
+                                       
+                                       if (value!=targetValueText.text) {
+                                               actualValue = 
Radiate.getTypedValue(targetValueText.text, propertyType);
+                                               //trace("New Value= ", value);
+                                               Radiate.setProperty(target, 
property, actualValue);
+                                       }
+                               }
+                       }
+                       
+                       protected function 
targetValueText_changingHandler(event:TextOperationEvent):void {
+                               
+                               // prevent line breaks
+                               if(event.operation is SplitParagraphOperation) {
+                                       event.preventDefault();
+                               }
+                       }
+                       
+                       /**
+                        * Update the property value in the datagrid when it 
changes 
+                        * without reloading all the properties.
+                        * */
+                       public function 
updatePropertyChangeValue(changes:Array):void {
+                               var length:int = allItems.length;
+                               var itemList:XMLList;
+                               var propertyName:String;
+                               
+                               if (length>0 && changes.length>0) {
+                                       //itemList = allItems.source; 
+                                       
+                                       for each (var node:XML in allItems) {
+                                               propertyName = node.@name;
+                                               
+                                               // TypeError: Error #1034: Type 
Coercion failed: cannot convert mx.states::AddItems@1132558c9 to 
mx.effects.effectClasses.PropertyChanges.
+                                               // for each (var 
change:PropertyChanges in changes) {
+                                               for each (var change:Object in 
changes) {
+                                                       
+                                                       if (change is 
mx.effects.effectClasses.PropertyChanges) {
+                                                               var 
changeObject:Object = change.end;
+                                                               
+                                                               for (var 
property:String in changeObject) {
+                                                                       if 
(propertyName==property) {
+                                                                               
//node.@value = changeObject[property] ? Object(changeObject[property]) : "";
+                                                                               
node.@value = Object(changeObject[property]).toString();
+                                                                               
filteredPropertiesCollection.itemUpdated(node, "@value");
+                                                                               
filteredPropertiesCollection.refresh();
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       protected function 
filterInput_clearTextHandler(event:TextOperationEvent):void {
+                               
+                       }
+                       
+                       /**
+                        * Dispatch a property selected event
+                        * */
+                       protected function 
eventsGrid_clickHandler(event:MouseEvent):void {
+                               dispatchPropertySelected();
+                       }
+                       
+                       protected function 
eventsGrid_selectionChangeHandler(event:GridSelectionEvent):void {
+                               dispatchPropertySelected();
+                       }
+                       
+                       
+                       
+                       private function dispatchPropertySelected():void {
+                               var item:XML = eventsGrid.selectedItem as XML;
+                               var propertyObject:MetaData;
+                               var property:String;
+                               var nodename:String;
+                               
+                               
+                               if (item) {
+                                       nodename = item.name();
+                                       
+                                       propertyObject = new 
EventMetaData(item, target);
+                                       
+                                       
radiate.dispatchPropertySelectedEvent(property, propertyObject);
+                               }
+                       }
+                       
+               ]]>
+       </fx:Script>
+       
+       
+       <fx:Declarations>
+               
+               <s:NumberFormatter id="formatter" 
+                                                  useGrouping="false"/>
+               
+               <s:ArrayCollection id="filteredPropertiesCollection"
+                                                  
list="{dataProviderProperties}"/>
+               
+               <!-- SORT BY NAME -->
+               <handlers:EventHandler eventName="creationComplete" >
+                       <collections:SortCollection 
target="{filteredPropertiesCollection}" 
+                                                                
fields="{['@name']}" />
+               </handlers:EventHandler>
+               
+               <!-- FILTER BY NAME -->
+               <handlers:EventHandler eventName="change" 
+                                                          
targets="{[filterInput,showAllItemsOnEmpty,caseSensitive,searchAtStart]}"
+                                                          >
+                       <collections:FilterCollection 
target="{filteredPropertiesCollection}" 
+                                                                  
source="{filterInput}" 
+                                                                  
sourcePropertyName="text"
+                                                                  
fieldName="@name"
+                                                                  
showAllItemsOnEmpty="{showAllItemsOnEmpty.selected}"
+                                                                  
caseSensitive="{caseSensitive.selected}"
+                                                                  
searchAtStart="{searchAtStart.selected}"
+                                                                  />
+               </handlers:EventHandler>
+       </fx:Declarations>
+       
+       <fx:Style>
+               @namespace s "library://ns.adobe.com/flex/spark";
+               @namespace c "com.flexcapacitor.controls.*";
+               @namespace mx "library://ns.adobe.com/flex/mx";
+               @namespace collections 
"com.flexcapacitor.effects.collections.*";
+               @namespace handlers "com.flexcapacitor.handlers.*";
+               
+               .eventsGrid {
+                       
+               }
+       </fx:Style>
+
+       
+       <mx:VDividedBox id="verticalContainer" 
+                                       width="100%" height="100%"
+                                       top="0"
+                                       left="8" 
+                                       right="8" 
+                                       bottom="8"
+                                       >
+               <s:Group height="24" width="100%">
+                                       
+                       <c:SearchTextInput id="filterInput" 
+                                                          top="0" 
+                                                          width="100%"
+                                                          minWidth="60" 
+                                                          borderAlpha=".2"
+                                                          color="#2F3030" 
+                                                          focusAlpha="0" 
+                                                          fontWeight="normal" 
+                                                          prompt="Search"
+                                                          
enter="filterInput_enterHandler(event)"
+                                                          
clearText="filterInput_clearTextHandler(event)"
+                                                          />
+                       <s:HGroup width="100%" top="32" paddingLeft="2">
+                               <s:CheckBox id="showAllItemsOnEmpty" 
label="All" selected="true"/>
+                               <s:CheckBox id="caseSensitive" label="Case" 
selected="false"/>
+                               <s:CheckBox id="searchAtStart" label="At start" 
selected="false"/>
+                       </s:HGroup>
+               </s:Group>
+               
+               <c:DataGrid id="eventsGrid"
+                                       styleName="eventsGrid"
+                                       borderAlpha=".2"
+                                       height="100%" 
+                                       width="100%"
+                                       minWidth="80"
+                                       minHeight="48"
+                                       rowHeight="18"
+                                       variableRowHeight="true"
+                                       click="eventsGrid_clickHandler(event)"
+                                       
selectionChange="eventsGrid_selectionChangeHandler(event)"
+                                       
dataProvider="{filteredPropertiesCollection}"
+                                       >
+                       <c:columns>
+                               <s:ArrayCollection>
+                                       <s:GridColumn dataField="@name" 
+                                                                 minWidth="50"
+                                                                 
editable="false" 
+                                                                 
resizable="true"
+                                                                 
headerText="Name"/>
+                                       
+                                       <s:GridColumn dataField="@className" 
+                                                                 
editable="false" 
+                                                                 
resizable="true"
+                                                                 
headerText="DISPATCHED BY"
+                                                                 
visible="false"/>
+                               </s:ArrayCollection>
+                       </c:columns>
+                       
+                       <!--
+                       <c:columns>
+                               <s:ArrayCollection>
+                                       
+                                       <s:GridColumn dataField="@name" 
+                                                                 minWidth="50"
+                                                                 
editable="false" 
+                                                                 
resizable="true"
+                                                                 
headerText="PROPERTY">
+                                               <s:itemRenderer>
+                                                       <fx:Component 
className="defaultItemRenderer">
+                                                               
<s:GridItemRenderer minHeight="14">
+                                                                       
<s:Label id="labelDisplay"
+                                                                               
         verticalCenter="1" left="0" right="0" top="0" bottom="0"
+                                                                               
         fontSize="12"
+                                                                               
         paddingTop="3"
+                                                                               
         paddingBottom="3"
+                                                                               
         paddingLeft="3"
+                                                                               
         paddingRight="3"
+                                                                               
         textAlign="start"
+                                                                               
         verticalAlign="middle"
+                                                                               
         width="100%" 
+                                                                               
         maxDisplayedLines="1"
+                                                                               
         showTruncationTip="true"/>
+                                                               
</s:GridItemRenderer>
+                                                       </fx:Component>
+                                               </s:itemRenderer>
+                                       </s:GridColumn>
+                                       
+                                       <s:GridColumn dataField="@value" 
+                                                                 minWidth="50"
+                                                                 
editable="false" 
+                                                                 
resizable="true"
+                                                                 
headerText="VALUE">
+                                               <s:itemRenderer>
+                                                       <fx:Component >
+                                                               
<s:GridItemRenderer minHeight="14">
+                                                                       
<s:Label id="labelDisplay" 
+                                                                               
         verticalCenter="1" left="0" right="0" top="0" bottom="0"
+                                                                               
         fontSize="12"
+                                                                               
         paddingTop="3"
+                                                                               
         paddingBottom="3"
+                                                                               
         paddingLeft="3"
+                                                                               
         paddingRight="3"
+                                                                               
         textAlign="start"
+                                                                               
         verticalAlign="middle"
+                                                                               
         maxDisplayedLines="1"
+                                                                               
         showTruncationTip="true" />
+                                                               
</s:GridItemRenderer>
+                                                       </fx:Component>
+                                               </s:itemRenderer>
+                                       </s:GridColumn>
+                                       
+                                       <s:GridColumn headerText="" 
+                                                                 minWidth="30"
+                                                                 width="30"
+                                                                 
editable="false"
+                                                                 
labelFunction="{function(data:Object, column:GridColumn):String{return'...';}}">
+                                       </s:GridColumn>
+                                       
+                                       
+
+                               </s:ArrayCollection>
+                       </c:columns>-->
+               </c:DataGrid>
+               
+               <s:TextArea id="targetValueText" 
+                                       
text="{XML(eventsGrid.selectedItem).@value}"
+                                       width="100%" 
+                                       heightInLines="2" 
+                                       
skinClass="spark.skins.spark.TextAreaSkin"
+                                       minHeight="10" 
+                                       visible="false"
+                                       includeInLayout="false"
+                                       
keyUp="targetValueText_keyUpHandler(event)"
+                                       
changing="targetValueText_changingHandler(event)">
+               </s:TextArea>
+               
+       </mx:VDividedBox>
+       
+</s:Group>

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/HistoryInspector.mxml
----------------------------------------------------------------------
diff --git 
a/Radii8Library/src/com/flexcapacitor/views/panels/HistoryInspector.mxml 
b/Radii8Library/src/com/flexcapacitor/views/panels/HistoryInspector.mxml
new file mode 100644
index 0000000..8271b6b
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/panels/HistoryInspector.mxml
@@ -0,0 +1,495 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"; 
+                xmlns:s="library://ns.adobe.com/flex/spark" 
+                xmlns:mx="library://ns.adobe.com/flex/mx" 
+                xmlns:filters="com.flexcapacitor.filters.*" 
+                xmlns:controls="com.flexcapacitor.controls.*"
+                xmlns:renderers="com.flexcapacitor.views.renderers.*" 
+                
+                styleName="radiateInspector"
+                width="100%" 
+                minHeight="20"
+                creationComplete="creationCompleteHandler(event)" 
+                >
+       
+       <fx:Script>
+               <![CDATA[
+                       import com.flexcapacitor.controller.Radiate;
+                       import com.flexcapacitor.events.HistoryEvent;
+                       import com.flexcapacitor.events.HistoryEventItem;
+                       import com.flexcapacitor.events.RadiateEvent;
+                       
+                       import flash.utils.getTimer;
+                       
+                       import mx.collections.ArrayCollection;
+                       import mx.events.FlexEvent;
+                       
+                       import spark.core.NavigationUnit;
+                       import spark.events.IndexChangeEvent;
+                       
+                       /**
+                        * Not used. Possible use store sets of changes between 
targets
+                        * */
+                       [Bindable]
+                       public var history:ArrayCollection = new 
ArrayCollection();
+                       
+                       /**
+                        * When true removes all the items in the history when 
the target is null
+                        * */
+                       public var clearOnTargetChange:Boolean = true;
+                       
+                       private var radiate:Radiate = Radiate.instance;
+                       
+                       public var debug:Boolean = false;
+                       
+                       private var _target:*;
+                       
+                       public function get target():* {
+                               return _target;
+                       }
+                       
+                       [Bindable]
+                       public function set target(value:*):void {
+                               _target = value;
+                               
+                               if (value==null) {
+                                       if (clearOnTargetChange) {
+                                               Radiate.removeAllHistory();
+                                       }
+                               }
+                       }
+                       
+                       protected function 
creationCompleteHandler(event:FlexEvent):void {
+                               
radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler, 
false, 0, true);
+                               
radiate.addEventListener(RadiateEvent.HISTORY_CHANGE, historyChangeHandler, 
false, 0, true);
+                               
radiate.addEventListener(RadiateEvent.DOCUMENT_CHANGE, documentChangeHandler, 
false, 0, true);
+                               
+                               
+                               //Radiate.history.refresh();
+                               
+                               list.selectedIndex = Radiate.historyIndex;
+                               
+                               scrollToBottom();
+                               
+                               updateNavigationButtons();
+                       }
+                       
+                       /**
+                        * 
+                        * */
+                       protected function 
targetChangeHandler(event:RadiateEvent):void {
+                               target = event.selectedItem;
+                       }
+                       
+                       /**
+                        * 
+                        * */
+                       public function redo():void {
+                               var historyIndex:int = Radiate.redo(true);
+                               
+                               if (historyIndex>-1) {
+                                       list.ensureIndexIsVisible(historyIndex);
+                               }
+                               else {
+                                       list.ensureIndexIsVisible(0);
+                               }
+                               
+                               
+                               //Radiate.history.refresh();
+                               
+                               //list.selectedIndex = historyIndex;
+                               
+                               updateNavigationButtons();
+                               
+                               if (debug) Radiate.log.info("3 SELECTED ITEM 
INDEX: " + list.selectedIndex);
+                       }
+                       
+                       /**
+                        * 
+                        * */
+                       public function undo():void {
+                               var historyIndex:int = Radiate.undo(true);
+                               
+                               //Radiate.history.refresh();
+                               
+                               if (historyIndex>-1) {
+                                       list.ensureIndexIsVisible(historyIndex);
+                               }
+                               else {
+                                       list.ensureIndexIsVisible(0);
+                               }
+                               
+                               //list.selectedIndex = Radiate.historyIndex;
+                               
+                               updateNavigationButtons();
+                               if (debug) Radiate.log.info("4 SELECTED ITEM 
INDEX: " + list.selectedIndex);
+                       }
+                       
+                       /**
+                        * Label for the history item
+                        * */
+                       public function labelFunction(item:Object):String {
+                               var historyItem:HistoryEvent = item as 
HistoryEvent;
+                               var historyEvents:Array = 
historyItem.historyEventItems;
+                               var historyEvent:HistoryEventItem = 
historyEvents && historyEvents.length ? historyEvents[0] : null;
+                               var label:String;
+                               
+                               
+                               if 
(historyEvent.action==RadiateEvent.PROPERTY_CHANGED) {
+                                       if (historyEvent.properties.length) {
+                                               label = 
historyEvent.description || historyEvent.properties + " changed";
+                                       }
+                                       else {
+                                               label = 
historyEvent.description || historyEvent.styles + " changed";
+                                       }
+                               }
+                               else if 
(historyEvent.action==RadiateEvent.ADD_ITEM) {
+                                       label = historyEvent.description || 
"Item added";
+                               }
+                               else if 
(historyEvent.action==RadiateEvent.REMOVE_ITEM) {
+                                       label = historyEvent.description || 
"Item removed";
+                               }
+                               else if 
(historyEvent.action==RadiateEvent.MOVE_ITEM) {
+                                       label = historyEvent.description || 
"Moved";
+                               }
+                               else {
+                                       label = "Something Changed";
+                               }
+                               
+                               if (!historyEvent) return "";
+                               
+                               return label;
+                       }
+                       
+                       /**
+                        * Show the last item in the list
+                        * */
+                       private function scrollToBottom():void {
+                               // update the verticalScrollPosition to the end 
of the List
+                               // virtual layout may require us to validate a 
few times
+                               // code posted by a Flex SDK developer
+                               var delta:Number = 0;
+                               var count:int = 0;
+                               var iterations:int = 10;
+                               
+                               while (count++ < iterations) {
+                                       list.validateNow();
+                                       delta = 
list.layout.getVerticalScrollPositionDelta(NavigationUnit.END);
+                                       list.layout.verticalScrollPosition += 
delta;
+                                       
+                                       if (delta == 0) {
+                                               break;
+                                       }
+                               }
+                       }
+                       
+                       protected function 
list1_clickHandler(event:MouseEvent):void {
+                               if (list.selectedItem) {
+                                       //Radiate.history.refresh();
+                               }
+                       }
+                       
+                       
+                       public var updatingChanges:Boolean;
+                       
+                       /**
+                        * 
+                        * */
+                       protected function 
changeHandler(event:IndexChangeEvent):void {
+                               if (debug) Radiate.log.info("SELECTED ITEM 
INDEX: " + list.selectedIndex);
+                               if (debug && updatingChanges) 
Radiate.log.info("ALREADY APPLYING CHANGES. SELECTED ITEM INDEX: " + 
list.selectedIndex);
+                                       
+                               if (updatingChanges) {
+                                       //event.preventDefault();
+                                       return;
+                               }
+                               var newIndex:int = event.newIndex;
+                               var oldIndex:int = Radiate.historyIndex;
+                               var dispatch:Boolean = false;
+                               var time:int = getTimer();
+                               var historyIndex:int;
+                               var length:int;
+                               
+                               updatingChanges = true;
+                               
+                               //ensureIndexIsVisible(newIndex);
+                               
+                               if (debug) Radiate.log.info("goToHistoryIndex: 
" + newIndex);
+                               
+                               Radiate.goToHistoryIndex(newIndex);
+                               //trace("changes:"+(getTimer()-time));
+                               
+                               //list.selectedIndex = Radiate.historyIndex;
+                               
+                               
+                               //Radiate.history.refresh();
+                               
+                               //updateNavigationButtons();
+                               
+                               if (debug) Radiate.log.info("2 SELECTED ITEM 
INDEX: " + list.selectedIndex);
+                               
+                               updatingChanges = false;
+                               
+                               //ensureIndexIsVisible(newIndex);
+                       }
+                       
+                       
+                       public function updateNavigationButtons():void {
+                               var historyIndex:int = Radiate.historyIndex;
+                               var totalItems:int = Radiate.history ? 
Radiate.history.length : 0;
+                               var hasItems:Boolean = totalItems>0;
+                               
+                               // has forward history
+                               if (hasItems && historyIndex+1<totalItems) {
+                                       forwardButton.enabled = true;
+                               }
+                               else {
+                                       forwardButton.enabled = false;
+                               }
+                               
+                               // has previous items
+                               if (hasItems && historyIndex>-1) {
+                                       backButton.enabled = true;
+                               }
+                               else {
+                                       backButton.enabled = false;
+                               }
+                       }
+                       
+                       /**
+                        * Document change handler. Clear history
+                        * */
+                       protected function 
documentChangeHandler(event:Event):void {
+                               if (debug) Radiate.log.info("DOCUMENT CHANGE");
+                               
+                               list.selectedIndex = Radiate.historyIndex;
+                               
+                               scrollToBottom();
+                               
+                               updateNavigationButtons();
+                               
+                               // Radiate.removeAllHistory();
+                       }
+                       
+                       /**
+                        * 
+                        * */
+                       public function ensureIndexIsVisible(index:int=0):void {
+                               
+                               if (index!=-1) {
+                                       list.ensureIndexIsVisible(index);
+                               }
+                               else {
+                                       list.dataGroup.verticalScrollPosition = 
0;
+                               }
+                               //list.validateNow();
+                               //list.ensureIndexIsVisible(index);
+                               //list.validateNow();
+                       }
+                       
+                       /**
+                        * 
+                        * */
+                       public function ensureLastItemVisible():void {
+                               if (list.dataProvider.length>0) {
+                                       
ensureIndexIsVisible(list.dataProvider.length-1);
+                                       scrollToBottom();
+                               }
+                       }
+                       
+                       /**
+                        * 
+                        * */
+                       protected function revertHandler(event:MouseEvent):void 
{
+                               var length:int = Radiate.history.length;
+                               var dispatch:Boolean = false;
+                               var time:int = getTimer();
+                               var i:int;
+                               
+                               //trace("revert start: " + time);
+                               
+                               // it is 22 times faster to not dispatch events 
until the end
+                               // each change takes 85ms per change with 
dispatch events 
+                               // and 2.58ms without
+                               
+                               Radiate.goToHistoryIndex(-1);
+                               
+                               //ensureIndexIsVisible(0);
+                               
+                               //Radiate.history.refresh();
+                               
+                               //trace("revert start: " + (getTimer()-time));
+                               //list.selectedIndex = -1;
+                               
+                               //Radiate.history.refresh();
+                               
+                               //updateNavigationButtons();
+                               if (debug) Radiate.log.info("5 SELECTED ITEM 
INDEX: " + list.selectedIndex);
+                       }
+                       
+                       protected function 
list_valueCommitHandler(event:FlexEvent):void {
+                               //Radiate.log.info("Value commit. Index : " + 
list.selectedIndex);
+                               //Radiate.log.info("History Index : " + 
Radiate.historyIndex);
+                               
+                               if (list.selectedIndex!= Radiate.historyIndex) {
+                                       //list.selectedIndex = 
Radiate.historyIndex;
+                                       //Radiate.history.refresh();
+                                       //Radiate.log.info("History OUT OF 
SYNC");
+                               }
+                       }
+                       
+                       protected function 
list_caretChangeHandler(event:IndexChangeEvent):void {
+                               //Radiate.log.info("Caret changed. Index : " + 
list.selectedIndex);
+                               //Radiate.log.info("History Index : " + 
Radiate.historyIndex);
+                       }
+                       
+                       /**
+                        * History changed. Select the last applied item in the 
history array. 
+                        * */
+                       protected function 
historyChangeHandler(event:Event):void {
+                               if (debug) Radiate.log.info("HISTORY CHANGE");
+                               
+                               //Radiate.log.info("historyChangeHandler. Index 
: " + list.selectedIndex);
+                               //Radiate.log.info("History Index : " + 
Radiate.historyIndex);
+                               
+                               // must call validate now since 
history.refresh() may have been called
+                               list.validateNow();
+                               
+                               if (Radiate.historyIndex==-1) {
+                                       list.selectedItem = null;
+                               }
+                               else {
+                                       list.selectedIndex = 
Radiate.historyIndex;
+                               }
+                               
+                               ensureIndexIsVisible(Radiate.historyIndex);
+                               updateNavigationButtons();
+                       }
+                       
+                       
+               ]]>
+       </fx:Script>
+       
+       <fx:Declarations>
+               
+       </fx:Declarations>
+       
+       <s:Group width="100%" height="100%" left="5" right="5" bottom="5">
+               
+               <s:List id="list" 
+                               top="26"
+                               focusAlpha="0"
+                               minHeight="20"
+                               width="100%" height="100%"
+                               dataProvider="{Radiate.history}" 
+                               labelFunction="labelFunction"
+                               borderVisible="false"
+                               change="changeHandler(event)"
+                               valueCommit="list_valueCommitHandler(event)"
+                               caretChange="list_caretChangeHandler(event)"
+                               
itemRenderer="com.flexcapacitor.views.renderers.HistoryItemRenderer"
+                               >
+                       
+                       <s:layout>
+                               <s:VerticalLayout useVirtualLayout="true" 
gap="1"/>
+                       </s:layout>
+                       
+               </s:List>
+               
+               <renderers:HistoryItemRenderer id="openLabel" 
+                                                                          
label="Open" 
+                                                                          
width="100%"
+                                                                          
right="100"
+                                                                          
useHandCursor="true" 
+                                                                          
buttonMode="true"
+                                                                          
autoDrawBackground="true"
+                                                                          
click="revertHandler(event)" />
+                                                                          
+               <controls:HorizontalLine top="22" 
+                                                                
strokeColor="#000000" 
+                                                                alpha=".15"
+                                                                />
+               
+               <!--- triangle -->
+               <s:Group height="14" width="10" top="4" 
visible="{Radiate.historyIndex==-1}">
+                       <s:Path data="M 0 0 L 0 16 L 16 8 z" width="100%" 
height="100%">
+                               <s:fill>
+                                       <s:SolidColor color="#000000" 
alpha=".25"/>
+                               </s:fill>
+                               <s:stroke>
+                                       <s:SolidColorStroke weight="0" 
color="#ffffff" />
+                               </s:stroke>
+                       </s:Path>
+                       <!--<s:Line width="40" x="13" y="5" >
+                               <s:stroke>
+                                       <s:SolidColorStroke alpha=".15"/>
+                               </s:stroke>
+                       </s:Line>-->
+               </s:Group>
+               
+               
+               <!--- UNDO REDO BUTTONS -->
+               <s:HGroup width="100%" right="0" top="0" verticalAlign="top">
+                       
+                       <!--- revert to beginning -->
+                       <!--<s:Group width="50%" height="8" >
+                               <s:Rect width="100%" height="8" >
+                                       <s:fill>
+                                               <s:SolidColor alpha="0"/>
+                                       </s:fill>
+                               </s:Rect>
+                       </s:Group>-->
+                       
+                       <s:Spacer width="100%"/>
+                       
+                       <!--- go back -->
+                       <s:Group id="backButton" 
+                                        click="undo()" 
+                                        width="20"
+                                        height="15"
+                                        useHandCursor="true"
+                                        buttonMode="true"
+                                        >
+                               <s:Path data="M 8 0 L 8 16 L 0 8 Z" height="14" 
width="14">
+                                       <s:fill>
+                                               <s:SolidColor color="#000000" 
alpha=".5"/>
+                                       </s:fill>
+                               </s:Path>
+                       </s:Group>
+                       
+                       
+                       <!--- go forward -->
+                       <s:Group id="forwardButton" 
+                                        click="redo()" 
+                                        width="20"
+                                        height="15"
+                                        useHandCursor="true"
+                                        buttonMode="true">
+                               <s:Path data="M 0 0 L 0 16 L 16 8 L 0 0 Z" 
height="14" width="14">
+                                       <s:fill>
+                                               <s:SolidColor color="#000000" 
alpha=".5"/>
+                                       </s:fill>
+                               </s:Path>
+                       </s:Group>
+               </s:HGroup>
+       </s:Group>
+       
+</s:Group>

Reply via email to