start css reorg; support shorthand css properties
diff --git a/weinre.build/debug.sh b/weinre.build/debug.sh
index 4abc85c..48774e1 100755
--- a/weinre.build/debug.sh
+++ b/weinre.build/debug.sh
@@ -10,4 +10,6 @@
 	-Dfile.encoding=UTF-8 \
 	-classpath $CP \
 	weinre.server.Main \
-	--verbose true
\ No newline at end of file
+	--verbose      true \
+	--deathTimeout 120
+	
\ No newline at end of file
diff --git a/weinre.web/demo/weinre-demo.css b/weinre.web/demo/weinre-demo.css
index f4715b2..7c02463 100644
--- a/weinre.web/demo/weinre-demo.css
+++ b/weinre.web/demo/weinre-demo.css
@@ -6,7 +6,9 @@
  */
 
 h1 {
-    color: green;
+    color:        green;
+    margin:       0.5em;
+    margin-right: 1.0em;
 }
 
 .blue {
diff --git a/weinre.web/modules/weinre/common/IDGenerator.scoop b/weinre.web/modules/weinre/common/IDGenerator.scoop
index 0b91770..4829267 100644
--- a/weinre.web/modules/weinre/common/IDGenerator.scoop
+++ b/weinre.web/modules/weinre/common/IDGenerator.scoop
@@ -12,9 +12,38 @@
 //-----------------------------------------------------------------------------
 init
     var nextId = 1
+    var idName = "__weinre__id"
 
 //-----------------------------------------------------------------------------
-static method next
+static method checkId(object)
+    return object[idName]
+    
+//-----------------------------------------------------------------------------
+static method getId(object, map)
+    var id = IDGenerator.checkId(object)
+    
+    if (!id) {
+        id = next()
+        
+        // note:
+        // attempted to use Object.defineProperty() to make
+        // the id property non-enumerable, etc, but doesn't 
+        // work in JSC (TypeError), and still shows up in
+        // Web Inspector property views anyway.
+        object[idName] = id
+    }
+    
+    if (map) {
+        if (map[id] != object) {
+            map[id] = object
+        }
+    }
+    
+    return id
+    
+//-----------------------------------------------------------------------------
+function next
     var result = nextId
     nextId += 1
-    return result
\ No newline at end of file
+    return result
+
diff --git a/weinre.web/modules/weinre/target/CSSStore.scoop b/weinre.web/modules/weinre/target/CSSStore.scoop
index 3f1edf7..179682b 100644
--- a/weinre.web/modules/weinre/target/CSSStore.scoop
+++ b/weinre.web/modules/weinre/target/CSSStore.scoop
@@ -6,10 +6,15 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
+requireClass ../common/IDGenerator
+requireClass ../common/Weinre
+
 //-----------------------------------------------------------------------------
 class CSSStore
-    this.__styleMap    = {}
-    this.__nextId      = 0
+    this.styleSheetMap = {}
+    this.styleRuleMap  = {}
+    this.styleDeclMap  = {}
+    this.testElement = document.createElement("div")
 
 //-----------------------------------------------------------------------------
 init
@@ -20,23 +25,8 @@
     Properties = properties
 
 //-----------------------------------------------------------------------------
-method getStyle(styleId)
-    return this.__styleMap[styleId]
-
-//-----------------------------------------------------------------------------
-method getStyleId(style)
-    if (style.__weinre_id) { 
-        return style.__weinre_id
-    }
-    
-    style.__weinre_id = this._nextId()
-    this.__styleMap[style.__weinre_id] = style
-    
-    return style.__weinre_id
-
-//-----------------------------------------------------------------------------
 method getInlineStyle(node)
-    var styleObject = this.buildObjectForStyle(node.style, true)
+    var styleObject = this._buildObjectForStyle(node.style, true)
     for (var i=0; i<styleObject.cssProperties.length; i++) {
         styleObject.cssProperties[i].status = "style"
     }
@@ -47,7 +37,7 @@
     if (!node) return {}
     if (node.nodeType != Node.ELEMENT_NODE) return {}
     
-    var styleObject = this.buildObjectForStyle(window.getComputedStyle(node), false)
+    var styleObject = this._buildObjectForStyle(window.getComputedStyle(node), false)
     return styleObject
 
 //-----------------------------------------------------------------------------
@@ -55,20 +45,20 @@
     var result = []
     
     for (var i=0; i<document.styleSheets.length; i++) {
-        var cssStyleSheet = document.styleSheets[i]
+        var styleSheet = document.styleSheets[i]
         
-        if (!cssStyleSheet.cssRules) continue
+        if (!styleSheet.cssRules) continue
         
-        for (var j=0; j<cssStyleSheet.cssRules.length; j++) {
-            var cssRule = cssStyleSheet.cssRules[j]
+        for (var j=0; j<styleSheet.cssRules.length; j++) {
+            var cssRule = styleSheet.cssRules[j]
             
-            if (!elementMatchesSelector(node, cssRule.selectorText)) continue
+            if (!_elementMatchesSelector(node, cssRule.selectorText)) continue
             
             var object = {}
             
-            object.ruleId = this.getStyleId(cssRule)
+            object.ruleId = this._getStyleRuleId(cssRule)
             object.selectorText = cssRule.selectorText
-            object.style = this.buildObjectForStyle(cssRule.style, true)
+            object.style = this._buildObjectForStyle(cssRule.style, true)
             result.push(object)
         }
     }
@@ -88,7 +78,7 @@
     return result
 
 //-----------------------------------------------------------------------------
-method buildObjectForStyle(style, bind)
+method _buildObjectForStyle(styleDecl, bind)
     var result = {
         width:         null,
         height:        null,
@@ -96,48 +86,42 @@
         cssProperties: []
     }
     
-    if (!style) return result
+    if (!styleDecl) return result
     
     if (bind) {
-        var styleId = this.getStyleId(style)
-        result.id = styleId
-
-        /*
-        CSSStyleSheet* parentStyleSheet = InspectorCSSStore::getParentStyleSheet(style);
-        if (parentStyleSheet)
-            result->setNumber("parentStyleSheetId", cssStore()->bindStyleSheet(parentStyleSheet));
-
-        DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(styleId, false);
-        if (disabledStyle)
-            result->setArray("disabled", buildArrayForDisabledStyleProperties(disabledStyle));
-        */
+        result.styleId = this._getStyleDeclId(styleDecl)
     }
     
-    result.width  = style.getPropertyValue("width")
-    result.height = style.getPropertyValue("height")
+    result.width  = styleDecl.getPropertyValue("width")
+    result.height = styleDecl.getPropertyValue("height")
 
-    this.populateObjectWithStyleProperties(style, result)
+    this._populateObjectWithStyleDeclProperties(styleDecl, result)
     
     return result
 
 //-----------------------------------------------------------------------------
-method populateObjectWithStyleProperties(style, result)
+method _populateObjectWithStyleDeclProperties(styleDecl, result)
     var properties = []
     var shorthandValues = {}
 
-    if (style) {
-        var foundShorthands = {}
-        for (var i=0; i < style.length; i++) {
+    if (styleDecl) {
+        for (var i=0; i < styleDecl.length; i++) {
             var property = {}
-            var name = style.item(i)
+            var name = styleDecl.item(i)
 
-            property.name = name
-            property.priority = style.getPropertyPriority(name)
-            property.implicit = false // style.isPropertyImplicit(name)
-            property.shorthand = ""
-            property.status    = "active"
-            property.parsedOk  = true
-            property.value     = style.getPropertyValue(name)
+            property.name          = name
+            property.priority      = styleDecl.getPropertyPriority(name)
+            property.implicit      = styleDecl.isPropertyImplicit(name)
+            property.shorthandName = styleDecl.getPropertyShorthand(name)
+            property.status        = "active"
+            property.parsedOk      = true
+            property.value         = styleDecl.getPropertyValue(name)
+            
+            if (property.shorthandName) {
+                if (!shorthandValues[property.shorthandName]) {
+                    shorthandValues[property.shorthandName] = styleDecl.getPropertyValue(property.shorthandName)
+                }
+            }
 
             properties.push(property);
         }
@@ -147,27 +131,64 @@
     result.shorthandValues = shorthandValues
 
 //-----------------------------------------------------------------------------
-method _nextId
-    return "" + (++this.__nextId)
+method _getStyleSheet(id)
+    return _getMappableObject(id, this.styleSheetMap)
+
+//-----------------------------------------------------------------------------
+method _getStyleSheetId(styleSheet)
+    return _getMappableId(styleSheet, this.styleSheetMap)
+
+//-----------------------------------------------------------------------------
+method _getStyleRule(id)
+    return _getMappableObject(id, this.styleRuleMap)
+
+//-----------------------------------------------------------------------------
+method _getStyleRuleId(styleRule)
+    return _getMappableId(styleRule, this.styleRuleMap)
+
+//-----------------------------------------------------------------------------
+method _getStyleDecl(id)
+    return _getMappableObject(id, this.styleDeclMap)
+
+//-----------------------------------------------------------------------------
+method _getStyleDeclId(styleDecl)
+    var id = _getMappableId(styleDecl, this.styleDeclMap)
+    
+    this._buildShadowDecl(styleDecl)
+    
+    return id
+
+//-----------------------------------------------------------------------------
+method _buildShadowDecl(styleDecl)
+    
+
+//-----------------------------------------------------------------------------
+function _getMappableObject(id, map)
+    return map[id]
+
+//-----------------------------------------------------------------------------
+function _getMappableId(object, map)
+    return IDGenerator.getId(object, map)
     
 //-----------------------------------------------------------------------------
-function mozMatchesSelector(element, selector)
+function _mozMatchesSelector(element, selector)
     if (!element.mozMatchesSelector) return false
     return element.mozMatchesSelector(selector)
 
 //-----------------------------------------------------------------------------
-function webkitMatchesSelector(element, selector)
+function _webkitMatchesSelector(element, selector)
     if (!element.webkitMatchesSelector) return false
     return element.webkitMatchesSelector(selector)
 
 //-----------------------------------------------------------------------------
-function fallbackMatchesSelector(element, selector)
+function _fallbackMatchesSelector(element, selector)
     return false
+
     
 //-----------------------------------------------------------------------------
 init
-    var elementMatchesSelector
+    var _elementMatchesSelector
     
-    if      (Element.prototype.webkitMatchesSelector) elementMatchesSelector = webkitMatchesSelector 
-    else if (Element.prototype.mozMatchesSelector)    elementMatchesSelector = mozMatchesSelector
-    else                                              elementMatchesSelector = fallbackMatchesSelector
\ No newline at end of file
+    if      (Element.prototype.webkitMatchesSelector) _elementMatchesSelector = _webkitMatchesSelector 
+    else if (Element.prototype.mozMatchesSelector)    _elementMatchesSelector = _mozMatchesSelector
+    else                                              _elementMatchesSelector = _fallbackMatchesSelector
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/target/NodeStore.scoop b/weinre.web/modules/weinre/target/NodeStore.scoop
index 3c77093..f8b288f 100644
--- a/weinre.web/modules/weinre/target/NodeStore.scoop
+++ b/weinre.web/modules/weinre/target/NodeStore.scoop
@@ -38,18 +38,16 @@
 
 //-----------------------------------------------------------------------------
 method checkNodeId(node)
-    return node.__weinre_id
+    return IDGenerator.checkId(node)
 
 //-----------------------------------------------------------------------------
 method getNodeId(node)
-    if (node.__weinre_id) { 
-        return node.__weinre_id
+    var id = this.checkNodeId(node)
+    if (id) {
+        return id
     }
-    
-    node.__weinre_id = this.nextNodeId()
-    this.__nodeMap[node.__weinre_id]     = node
-    
-    return node.__weinre_id
+
+    return IDGenerator.getId(node, this.__nodeMap)    
 
 //-----------------------------------------------------------------------------
 method getNodeData(nodeId, depth)
diff --git a/weinre.web/modules/weinre/target/Timeline.scoop b/weinre.web/modules/weinre/target/Timeline.scoop
index 4614dc6..4e9629b 100644
--- a/weinre.web/modules/weinre/target/Timeline.scoop
+++ b/weinre.web/modules/weinre/target/Timeline.scoop
@@ -263,7 +263,7 @@
 //-----------------------------------------------------------------------------
 function wrapped_XMLHttpRequest
     var xhr = new Native.XMLHttpRequest()
-    xhr.__weinre_id = IDGenerator.next()
+    IDGenerator.getId(xhr)
     xhr.addEventListener("readystatechange", getXhrEventHandler(xhr), false)
     return xhr
 
@@ -287,7 +287,7 @@
 //-----------------------------------------------------------------------------
 function getXhrEventHandler(xhr)
     return function(event) {
-        Timeline.addRecord_XHRReadyStateChange(xhr.__weinre_method, xhr.__weinre_url, xhr.__weinre_id, xhr)
+        Timeline.addRecord_XHRReadyStateChange(xhr.__weinre_method, xhr.__weinre_url, IDGenerator.getId(xhr), xhr)
     }
     
 //-----------------------------------------------------------------------------
diff --git a/weinre.web/modules/weinre/target/WiCSSImpl.scoop b/weinre.web/modules/weinre/target/WiCSSImpl.scoop
index ad4cd05..916345d 100644
--- a/weinre.web/modules/weinre/target/WiCSSImpl.scoop
+++ b/weinre.web/modules/weinre/target/WiCSSImpl.scoop
@@ -10,6 +10,7 @@
 
 //-----------------------------------------------------------------------------
 class WiCSSImpl
+    this.dummyComputedStyle = false
 
 //-----------------------------------------------------------------------------
 method getStylesForNode(/*int*/ nodeId, callback)
@@ -21,16 +22,30 @@
         return
     }
     
+    var computedStyle
+    
+    if (this.dummyComputedStyle) {
+        computedStyle = {
+            styleId:            null,
+            properties:         [],
+            shorthandValues:    [],
+            cssProperties:      []
+        }
+    }
+    else {
+        computedStyle =  Weinre.cssStore.getComputedStyle(node)
+    }
+    
     var result = {
         inlineStyle:     Weinre.cssStore.getInlineStyle(node),
-        computedStyle:   Weinre.cssStore.getComputedStyle(node),
+        computedStyle:   computedStyle,
         matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(node),
         styleAttributes: Weinre.cssStore.getStyleAttributes(node),
         pseudoElements:  Weinre.cssStore.getPseudoElements(node),
         inherited:       []
     }
     
-    var parentNode   = node.parentNode
+    var parentNode = node.parentNode
     
     while (parentNode) {
         var parentStyle = {
@@ -102,8 +117,53 @@
 //-----------------------------------------------------------------------------
 method setPropertyText(/*any*/ styleId, /*int*/ propertyIndex, /*string*/ text, /*boolean*/ overwrite, callback)
     // callback: function(/*any*/ style)
-    Weinre.notImplemented(arguments.callee.signature)
+    var style = Weinre.cssStore.getStyle(styleId)
+    if (!style) {
+        Weinre.logWarning("requested style not available: " + styleId)
+        return
+    }
+    
+    var newProperties = []
+    newPropertyLines = text.split(";")
+    for (var i=0; i<newPropertyLines.length; i++) {
+        var parts = newPropertyLines[i].split(":", 2)
+        if (parts[0] && parts[1]) {
+            newProperties.push([parts[0], parts[1]])
+        }
+    }
+    
+    var oldProperties = []
+    for (var i=0; i<style.length; i++) {
+        var name = style.item(i)
+        var value = style.getPropertyValue(name)
+        oldProperties.push([name, value])
+    }
 
+    for (var i=0; i<oldProperties.length; i++) {
+        style.removeProperty(oldProperties[i][0])
+    }
+        
+    for (var i=0; i<oldProperties.length; i++) {
+        if (i == propertyIndex) {
+            for (var j=0; j<newProperties.length; j++) {
+                style.setProperty(newProperties[j][0], newProperties[j][1])
+            }
+            continue
+        }
+        
+        style.setProperty(oldProperties[i][0], oldProperties[i][1])
+    }
+    
+    if (propertyIndex >= oldProperties.length) {
+        for (var j=0; j<newProperties.length; j++) {
+            style.setProperty(newProperties[j][0], newProperties[j][1])
+        }
+    }
+    
+    if (callback) {
+        var result = Weinre.cssStore.buildObjectForStyle(style, true)
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
 
 //-----------------------------------------------------------------------------
 method toggleProperty(/*any*/ styleId, /*int*/ propertyIndex, /*boolean*/ disable, callback)